diff --git a/etc/ipxe/default.ipxe b/etc/ipxe/default.ipxe index 04792a02..4f22c3d3 100644 --- a/etc/ipxe/default.ipxe +++ b/etc/ipxe/default.ipxe @@ -34,9 +34,6 @@ imgextract --name system ${uri_base}&stage=system&compress=gz || goto noco echo Container image: imgextract --name container ${uri_base}&stage=container&compress=gz || goto reboot -echo Runtime image: -imgextract --name runtime ${uri_base}&stage=runtime&compress=gz || goto reboot - {{if ne .KernelOverride "" -}} echo Kernel modules image: imgextract --name kmods ${uri_base}&stage=kmods&compress=gz || goto reboot @@ -54,8 +51,6 @@ initrd --name system ${uri_base}&stage=system || goto reboot echo Container image: initrd --name container ${uri_base}&stage=container || goto reboot -echo Runtime image: -initrd --name runtime ${uri_base}&stage=runtime || goto reboot {{if ne .KernelOverride "" -}} echo Kernel modules image: @@ -67,13 +62,13 @@ initrd --name kmods ${uri_base}&stage=kmods || goto reboot echo Booting in 3s... {{if ne .KernelOverride "" -}} -echo boot kernel initrd=container initrd=kmods initrd=system initrd=runtime wwid={{.Hwaddr}} {{.KernelArgs}} +echo boot kernel initrd=container initrd=kmods initrd=system wwid={{.Hwaddr}} {{.KernelArgs}} sleep 3 -boot kernel initrd=container initrd=kmods initrd=system initrd=runtime wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot +boot kernel initrd=container initrd=kmods initrd=system wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot {{- else -}} -echo boot kernel initrd=container initrd=system initrd=runtime wwid={{.Hwaddr}} {{.KernelArgs}} +echo boot kernel initrd=container initrd=system wwid={{.Hwaddr}} {{.KernelArgs}} sleep 3 -boot kernel initrd=container initrd=system initrd=runtime wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot +boot kernel initrd=container initrd=system wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot {{- end}} :reboot diff --git a/internal/pkg/warewulfd/daemon.go b/internal/pkg/warewulfd/daemon.go index 2879fbd6..4eec8c21 100644 --- a/internal/pkg/warewulfd/daemon.go +++ b/internal/pkg/warewulfd/daemon.go @@ -41,6 +41,8 @@ func DaemonInitLogging() error { if err == nil { wwlog.SetLogLevel(level) } + }else{ + wwlog.SetLogLevel(wwlog.SERV) } conf, err := warewulfconf.New() @@ -57,9 +59,8 @@ func DaemonInitLogging() error { return errors.Wrap(err, "Could not create syslog writer") } - wwlog.SetLogWriters(logwriter, logwriter) - wwlog.SetLogFormatter(wwlog.DefaultFormatter) + wwlog.SetLogWriters(logwriter, logwriter) } @@ -81,7 +82,13 @@ func DaemonStart() error { } os.Setenv("WAREWULFD_BACKGROUND", "1") - os.Setenv("WAREWULFD_LOGLEVEL", strconv.Itoa(wwlog.GetLogLevel())) + + logLevel := wwlog.GetLogLevel() + if logLevel == wwlog.INFO { + os.Setenv("WAREWULFD_LOGLEVEL", strconv.Itoa(wwlog.SERV)) + }else{ + os.Setenv("WAREWULFD_LOGLEVEL", strconv.Itoa(logLevel)) + } f, err := os.OpenFile(WAREWULFD_LOGFILE, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) if err != nil { @@ -105,7 +112,7 @@ func DaemonStart() error { fmt.Fprintf(p, "%d", pid) - wwlog.Info("Started Warewulf (%s) server at PID: %d", version.GetVersion(), pid) + wwlog.Serv("Started Warewulf (%s) server at PID: %d", version.GetVersion(), pid) } @@ -131,7 +138,7 @@ func DaemonStatus() error { if err != nil { return errors.Wrap(err, "failed to send process SIGCONT") } else { - wwlog.Info("Warewulf server is running at PID: %d", pid) + wwlog.Serv("Warewulf server is running at PID: %d", pid) } } @@ -159,7 +166,12 @@ func DaemonReload() error { } } - os.Setenv("WAREWULFD_LOGLEVEL", strconv.Itoa(wwlog.GetLogLevel())) + logLevel := wwlog.GetLogLevel() + if logLevel == wwlog.INFO { + os.Setenv("WAREWULFD_LOGLEVEL", strconv.Itoa(wwlog.SERV)) + }else{ + os.Setenv("WAREWULFD_LOGLEVEL", strconv.Itoa(logLevel)) + } return nil } @@ -187,7 +199,7 @@ func DaemonStop() error { if err != nil { return errors.Wrap(err, "failed to send process SIGTERM") } else { - wwlog.Info("Terminated Warewulf server at PID: %d", pid) + wwlog.Serv("Terminated Warewulf server at PID: %d", pid) } } diff --git a/internal/pkg/warewulfd/provision.go b/internal/pkg/warewulfd/provision.go index 5ed383e5..06ad9750 100644 --- a/internal/pkg/warewulfd/provision.go +++ b/internal/pkg/warewulfd/provision.go @@ -49,9 +49,11 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { return } - if conf.Warewulf.Secure { + wwlog.Recv("hwaddr: %s, ipaddr: %s, stage: %s", rinfo.hwaddr, req.RemoteAddr, rinfo.stage ) + + if rinfo.stage == "runtime" && conf.Warewulf.Secure { if rinfo.remoteport >= 1024 { - wwlog.Error("DENIED: Non-privledged port: %s", req.RemoteAddr) + wwlog.Denied("Non-privledged port: %s", req.RemoteAddr) w.WriteHeader(http.StatusUnauthorized) return } @@ -64,8 +66,6 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { "system": "SYSTEM_OVERLAY", "runtime": "RUNTIME_OVERLAY" } - wwlog.Info("REQ: %s: %s", rinfo.hwaddr, rinfo.stage ) - status_stage := status_stages[rinfo.stage] var stage_overlays []string var stage_file string = "" @@ -77,7 +77,7 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { // If we failed to find a node, let's see if we can add one... var netdev string - wwlog.Info("%s (node not configured)", rinfo.hwaddr) + wwlog.Warn("%s (node not configured)", rinfo.hwaddr) nodeDB, err := nodepkg.New() if err != nil { @@ -92,18 +92,18 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { n.Discoverable.SetB(false) err := nodeDB.NodeUpdate(n) if err != nil { - wwlog.Info("%s (failed to set node configuration)", rinfo.hwaddr) + wwlog.Serv("%s (failed to set node configuration)", rinfo.hwaddr) } else { err := nodeDB.Persist() if err != nil { - wwlog.Info("%s (failed to persist node configuration)", rinfo.hwaddr) + wwlog.Serv("%s (failed to persist node configuration)", rinfo.hwaddr) } else { node = n _ = overlay.BuildAllOverlays([]nodepkg.NodeInfo{n}) - wwlog.Info("%s (node automatically configured)", rinfo.hwaddr) + wwlog.Serv("%s (node automatically configured)", rinfo.hwaddr) err := LoadNodeDB() if err != nil { @@ -117,7 +117,7 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { if node.AssetKey.Defined() && node.AssetKey.Get() != rinfo.assetkey { w.WriteHeader(http.StatusUnauthorized) - wwlog.Error("Incorrect asset key for node: %s", node.Id.Get()) + wwlog.Denied("Incorrect asset key for node: %s", node.Id.Get()) updateStatus(node.Id.Get(), status_stage, "BAD_ASSET", rinfo.ipaddr) return } @@ -199,13 +199,13 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { oneoverlaynewer = oneoverlaynewer || util.PathIsNewer(stage_file, overlay.OverlaySourceDir(overlayname)) } if !util.IsFile(stage_file) || util.PathIsNewer(stage_file, nodepkg.ConfigFile) || oneoverlaynewer { - wwlog.Info("BUILD %15s, overlays %v", node.Id.Get(), stage_overlays) + wwlog.Serv("BUILD %15s, overlays %v", node.Id.Get(), stage_overlays) _ = overlay.BuildOverlay(node, stage_overlays) } } } - wwlog.Info("stage_file '%s'", stage_file ) + wwlog.Serv("stage_file '%s'", stage_file ) if util.IsFile(stage_file) { @@ -241,7 +241,7 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { wwlog.ErrorExc(err, "") } - wwlog.Info("SEND: %15s: %s", node.Id.Get(), stage_file) + wwlog.Send("%15s: %s", node.Id.Get(), stage_file) }else{ if rinfo.compress == "gz" { diff --git a/internal/pkg/warewulfd/util.go b/internal/pkg/warewulfd/util.go index 13ebd310..63e89718 100644 --- a/internal/pkg/warewulfd/util.go +++ b/internal/pkg/warewulfd/util.go @@ -48,7 +48,7 @@ func sendFile(w http.ResponseWriter, filename string, sendto string) error { w.Header().Set("Content-Length", FileSize) _, err = buf.WriteTo(w) - wwlog.Info("SEND: %15s: %s", sendto, filename) + wwlog.Send("%15s: %s", sendto, filename) return err } diff --git a/internal/pkg/warewulfd/warewulfd.go b/internal/pkg/warewulfd/warewulfd.go index 3a72d230..c689136b 100644 --- a/internal/pkg/warewulfd/warewulfd.go +++ b/internal/pkg/warewulfd/warewulfd.go @@ -64,7 +64,7 @@ func RunServer() error { } daemonPort := conf.Warewulf.Port - wwlog.Info("Starting HTTPD REST service on port %d", daemonPort) + wwlog.Serv("Starting HTTPD REST service on port %d", daemonPort) err = http.ListenAndServe(":"+strconv.Itoa(daemonPort), nil) if err != nil { diff --git a/internal/pkg/wwlog/wwlog.go b/internal/pkg/wwlog/wwlog.go index 2ddb18f1..7879c728 100644 --- a/internal/pkg/wwlog/wwlog.go +++ b/internal/pkg/wwlog/wwlog.go @@ -8,22 +8,7 @@ import ( "time" "runtime" "reflect" -) - -const ( - SECCRITICAL = 51 - CRITICAL = 50 - SECERROR = 41 - ERROR = 40 - SECWARN = 31 - WARN = 30 - SECINFO = 21 - INFO = 20 - SECVERBOSE = 16 - VERBOSE = 15 - SECDEBUG = 11 - DEBUG = 10 - NOTSET = 0 + "sort" ) type LogRecord struct { @@ -39,52 +24,78 @@ type LogRecord struct { /* Format a log message from a record - rec.level >= logLevel + Only called if rec.level >= logLevel */ type LogFormatter func(logLevel int, rec *LogRecord) string -/* - Get string level name for level number -*/ -func LevelName(level int) string { - if level >= SECCRITICAL { - return "SECCRITICAL" - } - if level >= CRITICAL { - return "CRITICAL" - } - if level >= SECERROR { - return "SECERROR" - } - if level >= ERROR { - return "ERROR" - } - if level >= SECWARN { - return "SECWARN" - } - if level >= WARN { - return "WARN" - } - if level >= SECINFO { - return "SECINFO" - } - if level >= INFO { - return "INFO" - } - if level >= SECVERBOSE { - return "SECVERBOSE" - } - if level >= VERBOSE { - return "VERBOSE" - } - if level >= SECDEBUG { - return "SECDEBUG" - } - if level >= DEBUG { - return "DEBUG" - } +var ( + SECCRITICAL = SetLevelName(51, "SECCRITICAL") + CRITICAL = SetLevelName(50, "CRITICAL") + DENIED = SetLevelName(42, "DENIED") + SECERROR = SetLevelName(41, "SECERROR") + ERROR = SetLevelName(40, "ERROR") + SECWARN = SetLevelName(31, "SECWARN") + WARN = SetLevelName(30, "WARN") + SEND = SetLevelName(27, "SEND") + RECV = SetLevelName(26, "RECV") + SERV = SetLevelName(25, "SERV") + SECINFO = SetLevelName(21, "SECINFO") + INFO = SetLevelName(20, "INFO") + SECVERBOSE = SetLevelName(16, "SECVERBOSE") + VERBOSE = SetLevelName(15, "VERBOSE") + SECDEBUG = SetLevelName(11, "SECDEBUG") + DEBUG = SetLevelName(10, "DEBUG") +) - return "NOTSET" +var levelNums = []int{0} +var levelNames = []string{"NOTSET"} +var logLevel = INFO +var logOut io.Writer = os.Stdout +var logErr io.Writer = os.Stderr +var logFormatter LogFormatter = DefaultFormatter + +func LevelNameEff(level int) (int, int, string) { + n := len(levelNums) + idx := sort.SearchInts(levelNums, level) + + if idx >= n { + idx = n-1 + } + + eff_level := levelNums[idx] + eff_name := levelNames[idx] + + return idx, eff_level, eff_name +} + +func LevelName(level int) string { + + _, _, name := LevelNameEff(level) + return name +} + +func SetLevelName(level int, name string) int { + n := len(levelNums) + idx := sort.SearchInts(levelNums, level) + + if idx < n && levelNums[idx] == level { + levelNames[idx] = name + + }else{ + + levelNums = append(levelNums, level) + levelNames = append(levelNames, name) + + if idx < n { + copy(levelNums[idx+1:], levelNums[idx:]) + copy(levelNames[idx+1:], levelNames[idx:]) + + levelNums[idx] = level + levelNames[idx] = name + } + } + + return level } func DefaultFormatter(logLevel int, rec *LogRecord) string { @@ -96,7 +107,7 @@ func DefaultFormatter(logLevel int, rec *LogRecord) string { } if rec.Err != nil { - if logLevel <= VERBOSE { + if logLevel < VERBOSE { // when debugging errors, add file and line number, and any stack trace message += fmt.Sprintf("%s:%d\n%+v\n", rec.File, rec.Line, rec.Err ) @@ -113,13 +124,15 @@ func DefaultFormatter(logLevel int, rec *LogRecord) string { return message } - return fmt.Sprintf("%-7s: %s", LevelName(rec.Level), message) + name := LevelName(rec.Level) + + if len(name) <= 7 { + return fmt.Sprintf("%-7s: %s", name, message) + } + + return fmt.Sprintf("%-11s: %s", name, message) } -var logLevel = INFO -var logOut io.Writer = os.Stdout -var logErr io.Writer = os.Stderr -var logFormatter LogFormatter = DefaultFormatter func EnabledForLevel(level int) bool { return level >= logLevel @@ -169,10 +182,10 @@ func GetLogFormatter() LogFormatter { /* Internal method to create a log record */ -func recordLog(level int, err error, message string, a ...interface{}) { +func LogCaller(level int, skip int, err error, message string, a ...interface{}) { if EnabledForLevel(level) { - pc, file, line, ok := runtime.Caller(2) + pc, file, line, ok := runtime.Caller(skip + 1) if !ok { file = "[unknown]" } @@ -198,92 +211,108 @@ func recordLog(level int, err error, message string, a ...interface{}) { } func Println(level int, message string) { - recordLog(level, nil, message) + LogCaller(level, 1, nil, message) } func Printf(level int, message string, a ...interface{}) { - recordLog(level, nil, message, a...) + LogCaller(level, 1, nil, message, a...) } /******************************************************************************* Named log level functions */ func Log(level int, message string, a ...interface{}) { - recordLog(level, nil, message, a...) + LogCaller(level, 1, nil, message, a...) } func LogExc(level int, err error, message string, a ...interface{}) { - recordLog(level, err, message, a...) + LogCaller(level, 1, err, message, a...) } func Debug(message string, a ...interface{}) { - recordLog(DEBUG, nil, message, a...) + LogCaller(DEBUG, 1, nil, message, a...) } func DebugExc(err error, message string, a ...interface{}) { - recordLog(DEBUG, err, message, a...) + LogCaller(DEBUG, 1, err, message, a...) } func SecDebug(message string, a ...interface{}) { - recordLog(SECDEBUG, nil, message, a...) + LogCaller(SECDEBUG, 1, nil, message, a...) } func Verbose(message string, a ...interface{}) { - recordLog(VERBOSE, nil, message, a...) + LogCaller(VERBOSE, 1, nil, message, a...) } func VerboseExc(err error, message string, a ...interface{}) { - recordLog(VERBOSE, err, message, a...) + LogCaller(VERBOSE, 1, err, message, a...) } func SecVerbose(message string, a ...interface{}) { - recordLog(SECVERBOSE, nil, message, a...) + LogCaller(SECVERBOSE, 1, nil, message, a...) } func Info(message string, a ...interface{}) { - recordLog(INFO, nil, message, a...) + LogCaller(INFO, 1, nil, message, a...) } func InfoExc(err error, message string, a ...interface{}) { - recordLog(INFO, err, message, a...) + LogCaller(INFO, 1, err, message, a...) } func SecInfo(message string, a ...interface{}) { - recordLog(SECINFO, nil, message, a...) + LogCaller(SECINFO, 1, nil, message, a...) +} + +func Serv(message string, a ...interface{}) { + LogCaller(SERV, 1, nil, message, a...) +} + +func Recv(message string, a ...interface{}) { + LogCaller(RECV, 1, nil, message, a...) +} + +func Send(message string, a ...interface{}) { + LogCaller(SEND, 1, nil, message, a...) } func Warn(message string, a ...interface{}) { - recordLog(WARN, nil, message, a...) + LogCaller(WARN, 1, nil, message, a...) } func WarnExc(err error, message string, a ...interface{}) { - recordLog(WARN, err, message, a...) + LogCaller(WARN, 1, err, message, a...) } func SecWarn(message string, a ...interface{}) { - recordLog(SECWARN, nil, message, a...) + LogCaller(SECWARN, 1, nil, message, a...) } func Error(message string, a ...interface{}) { - recordLog(ERROR, nil, message, a...) + LogCaller(ERROR, 1, nil, message, a...) } func ErrorExc(err error, message string, a ...interface{}) { - recordLog(ERROR, err, message, a...) + LogCaller(ERROR, 1, err, message, a...) } func SecError(message string, a ...interface{}) { - recordLog(SECERROR, nil, message, a...) + LogCaller(SECERROR, 1, nil, message, a...) +} + +func Denied(message string, a ...interface{}) { + LogCaller(DENIED, 1, nil, message, a...) } func Critical(message string, a ...interface{}) { - recordLog(CRITICAL, nil, message, a...) + LogCaller(CRITICAL, 1, nil, message, a...) } func CriticalExc(err error, message string, a ...interface{}) { - recordLog(CRITICAL, err, message, a...) + LogCaller(CRITICAL, 1, err, message, a...) } func SecCritical(message string, a ...interface{}) { - recordLog(SECCRITICAL, nil, message, a...) + LogCaller(SECCRITICAL, 1, nil, message, a...) }