Merge pull request #1229 from anderbubble/warewulfd-foreground
Simplify `wwctl server` command and logging
This commit is contained in:
@@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Add flag `--build` to `wwctl container copy`. #1378
|
||||
- Add `wwctl clean` to remove OCI cache and overlays from deleted nodes
|
||||
- Add `wwctl container import --platform`. #1381
|
||||
- Read environment variables from `/etc/default/warewulfd` #725
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -44,12 +45,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Switched from yaml.v2 to yaml.v3 #1462
|
||||
- Make OCIBlobCache a seperate path and point it to `/var/cache` #1459
|
||||
- Updated various shell scripts for POSIX compatibility. #1464
|
||||
- Update `wwctl server` to always run in the foreground #508
|
||||
- Update `wwctl server` to log to stdout rather than a file #503
|
||||
- Changed `wwctl server` to use "INFO" for send and receive logs #725
|
||||
|
||||
|
||||
### Removed
|
||||
|
||||
- `wwctl node list --fullall` has been removed
|
||||
- `wwctl profile list --fullall` has been removed
|
||||
- Remove `wwctl server <start,stop,status,restart,reload>` #508
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
@@ -112,11 +112,7 @@ Default: true
|
||||
.TP
|
||||
\fBsyslog\fP
|
||||
|
||||
When true, Warewulf server logs are written to syslog, rather than a
|
||||
local file.
|
||||
|
||||
When false, Warewulf server logs are written to
|
||||
`/var/log/warewulfd.log'.
|
||||
When true, Warewulf server logs are written to syslog.
|
||||
|
||||
Default: false
|
||||
.IP
|
||||
|
||||
@@ -5,15 +5,12 @@ After=network-online.target
|
||||
AssertFileIsExecutable=@BINDIR@/wwctl
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Type=exec
|
||||
EnvironmentFile=-/etc/default/warewulfd
|
||||
User=root
|
||||
Group=root
|
||||
|
||||
ExecStart=@BINDIR@/wwctl server start
|
||||
ExecReload=@BINDIR@/wwctl server reload
|
||||
ExecStop=@BINDIR@/wwctl server stop
|
||||
|
||||
PIDFile=/var/run/warewulfd.pid
|
||||
ExecStart=@BINDIR@/wwctl server
|
||||
ExecReload=/bin/kill -HUP "$MAINPID"
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package reload
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/warewulf/warewulf/internal/pkg/warewulfd"
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
return errors.Wrap(warewulfd.DaemonReload(), "failed to reload Warewulf server")
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package reload
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
DisableFlagsInUseLine: true,
|
||||
Use: "reload [OPTIONS]",
|
||||
Short: "Reload the Warewulf server configuration",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package restart
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/warewulf/warewulf/internal/pkg/warewulfd"
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
err := warewulfd.DaemonStop()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to stop Warewulf server")
|
||||
}
|
||||
return errors.Wrap(warewulfd.DaemonStart(), "failed to start Warewulf server")
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package restart
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
DisableFlagsInUseLine: true,
|
||||
Use: "restart [OPTIONS]",
|
||||
Short: "Restart the Warewulf server",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
@@ -1,33 +1,27 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/warewulf/warewulf/internal/app/wwctl/server/reload"
|
||||
"github.com/warewulf/warewulf/internal/app/wwctl/server/restart"
|
||||
"github.com/warewulf/warewulf/internal/app/wwctl/server/start"
|
||||
"github.com/warewulf/warewulf/internal/app/wwctl/server/status"
|
||||
"github.com/warewulf/warewulf/internal/app/wwctl/server/stop"
|
||||
"github.com/warewulf/warewulf/internal/pkg/warewulfd"
|
||||
)
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
DisableFlagsInUseLine: true,
|
||||
Use: "server COMMAND [OPTIONS]",
|
||||
Short: "Warewulf server process commands",
|
||||
Long: "This command will allow you to control the Warewulf daemon process.",
|
||||
Use: "server [OPTIONS]",
|
||||
Short: "Start Warewulf server",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
baseCmd.AddCommand(start.GetCommand())
|
||||
baseCmd.AddCommand(status.GetCommand())
|
||||
baseCmd.AddCommand(stop.GetCommand())
|
||||
baseCmd.AddCommand(restart.GetCommand())
|
||||
baseCmd.AddCommand(reload.GetCommand())
|
||||
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
if err := warewulfd.DaemonInitLogging(); err != nil {
|
||||
return errors.Wrap(err, "failed to configure logging")
|
||||
}
|
||||
return errors.Wrap(warewulfd.RunServer(), "failed to start Warewulf server")
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
package start
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
|
||||
"github.com/warewulf/warewulf/internal/pkg/warewulfd"
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
|
||||
if SetForeground {
|
||||
conf := warewulfconf.Get()
|
||||
conf.Warewulf.Syslog = false
|
||||
return errors.Wrap(warewulfd.RunServer(), "failed to start Warewulf server")
|
||||
} else {
|
||||
return errors.Wrap(warewulfd.DaemonStart(), "failed to start Warewulf server")
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package start
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
DisableFlagsInUseLine: true,
|
||||
Use: "start [OPTIONS]",
|
||||
Short: "Start Warewulf server",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
SetForeground bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
baseCmd.PersistentFlags().BoolVarP(&SetForeground, "foreground", "f", false, "Run daemon process in the foreground")
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/warewulf/warewulf/internal/pkg/warewulfd"
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
return warewulfd.DaemonStatus()
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package status
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
DisableFlagsInUseLine: true,
|
||||
Use: "status [OPTIONS]",
|
||||
Short: "Warewulf server status",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
)
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package stop
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/warewulf/warewulf/internal/pkg/warewulfd"
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
return errors.Wrap(warewulfd.DaemonStop(), "failed to stop Warewulf server")
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package stop
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
DisableFlagsInUseLine: true,
|
||||
Use: "stop [OPTIONS]",
|
||||
Short: "Stop Warewulf server",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
)
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
@@ -53,14 +53,14 @@ func DaemonInitLogging() error {
|
||||
wwlog.SetLogLevel(level)
|
||||
}
|
||||
} else {
|
||||
wwlog.SetLogLevel(wwlog.SERV)
|
||||
wwlog.SetLogLevel(wwlog.INFO)
|
||||
}
|
||||
|
||||
conf := warewulfconf.Get()
|
||||
|
||||
if conf.Warewulf.Syslog {
|
||||
|
||||
wwlog.Debug("Changingq log output to syslog")
|
||||
wwlog.Debug("Changing log output to syslog")
|
||||
|
||||
logwriter, err := syslog.New(syslog.LOG_NOTICE, "warewulfd")
|
||||
if err != nil {
|
||||
@@ -165,33 +165,15 @@ func DaemonReload() error {
|
||||
if nodaemon {
|
||||
return nil
|
||||
}
|
||||
if !util.IsFile(WAREWULFD_PIDFILE) {
|
||||
return errors.New("Warewulf server is not running")
|
||||
}
|
||||
|
||||
dat, err := os.ReadFile(WAREWULFD_PIDFILE)
|
||||
cmd := exec.Command("/usr/sbin/service", "warewulfd", "reload")
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not read Warewulfd PID file")
|
||||
return errors.Wrap(err, "failed to reload warewulfd")
|
||||
}
|
||||
|
||||
pid, _ := strconv.Atoi(string(dat))
|
||||
process, err := os.FindProcess(pid)
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to find running PID")
|
||||
} else {
|
||||
err := process.Signal(syscall.Signal(syscall.SIGHUP))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to send process SIGHUP")
|
||||
}
|
||||
return errors.Wrap(err, "failed to reload warewulfd")
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
wwlog.Recv("hwaddr: %s, ipaddr: %s, stage: %s", rinfo.hwaddr, req.RemoteAddr, rinfo.stage)
|
||||
wwlog.Info("request from hwaddr:%s ipaddr:%s | stage:%s", rinfo.hwaddr, req.RemoteAddr, rinfo.stage)
|
||||
|
||||
if (rinfo.stage == "runtime" || len(rinfo.overlay) > 0) && conf.Warewulf.Secure {
|
||||
if rinfo.remoteport >= 1024 {
|
||||
@@ -276,7 +276,7 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) {
|
||||
wwlog.ErrorExc(err, "")
|
||||
}
|
||||
|
||||
wwlog.Send("%15s: %s", remoteNode.Id(), stage_file)
|
||||
wwlog.Info("send %s -> %s", stage_file, remoteNode.Id())
|
||||
|
||||
} else {
|
||||
if rinfo.compress == "gz" {
|
||||
|
||||
@@ -39,7 +39,7 @@ func sendFile(
|
||||
stat.ModTime(),
|
||||
fd)
|
||||
|
||||
wwlog.Send("%15s: %s", sendto, filename)
|
||||
wwlog.Info("send %s -> %s", filename, sendto)
|
||||
req.Body.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -34,11 +34,6 @@ func (h *slashFix) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func RunServer() error {
|
||||
err := DaemonInitLogging()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to initialize logging")
|
||||
}
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGHUP)
|
||||
|
||||
@@ -57,7 +52,7 @@ func RunServer() error {
|
||||
}
|
||||
}()
|
||||
|
||||
err = LoadNodeDB()
|
||||
err := LoadNodeDB()
|
||||
if err != nil {
|
||||
wwlog.Error("Could not load database: %s", err)
|
||||
}
|
||||
@@ -84,17 +79,6 @@ func RunServer() error {
|
||||
conf := warewulfconf.Get()
|
||||
|
||||
daemonPort := conf.Warewulf.Port
|
||||
/*
|
||||
wwlog.Serv("Starting HTTPD REST service on port %d", daemonPort)
|
||||
s := &http.Server{
|
||||
Addr: ":" + strconv.Itoa(daemonPort),
|
||||
Handler: &slashFix{&wwHandler},
|
||||
ReadTimeout: 10 * time.Second,
|
||||
IdleTimeout: 10 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
}
|
||||
err = s.ListenAndServe()
|
||||
*/
|
||||
err = http.ListenAndServe(":"+strconv.Itoa(daemonPort), &slashFix{&wwHandler})
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -37,8 +37,6 @@ var (
|
||||
SECWARN = SetLevelName(31, "SECWARN")
|
||||
WARN = SetLevelName(30, "WARN")
|
||||
ERROUT = SetLevelName(29, "ERROUT")
|
||||
SEND = SetLevelName(27, "SEND")
|
||||
RECV = SetLevelName(26, "RECV")
|
||||
SERV = SetLevelName(25, "SERV")
|
||||
OUT = SetLevelName(22, "OUT")
|
||||
SECINFO = SetLevelName(21, "SECINFO")
|
||||
@@ -206,7 +204,7 @@ func LogCaller(level int, skip int, err error, message string, a ...interface{})
|
||||
}
|
||||
|
||||
message = logFormatter(logLevel, &rec)
|
||||
if level == INFO || level == RECV || level == SEND || level == OUT {
|
||||
if level == INFO || level == OUT {
|
||||
fmt.Fprint(logOut, message)
|
||||
} else {
|
||||
fmt.Fprint(logErr, message)
|
||||
@@ -271,14 +269,6 @@ 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{}) {
|
||||
LogCaller(WARN, 1, nil, message, a...)
|
||||
}
|
||||
|
||||
@@ -126,20 +126,6 @@ func Test_Log(t *testing.T) {
|
||||
expect: "SERV : Serv\n",
|
||||
exactMatch: true,
|
||||
},
|
||||
{
|
||||
name: "Recv",
|
||||
msgTypeFunc: Recv,
|
||||
message: "Recv",
|
||||
expect: "RECV : Recv\n",
|
||||
exactMatch: true,
|
||||
},
|
||||
{
|
||||
name: "Send",
|
||||
msgTypeFunc: Send,
|
||||
message: "Send",
|
||||
expect: "SEND : Send\n",
|
||||
exactMatch: true,
|
||||
},
|
||||
{
|
||||
name: "Warn",
|
||||
msgTypeFunc: Warn,
|
||||
|
||||
@@ -114,8 +114,7 @@ explained as follows:
|
||||
services.)
|
||||
|
||||
* ``warewulf:syslog``: This determines whether Warewulf server logs go
|
||||
to syslog or are written directly to a log file. (e.g.,
|
||||
``/var/log/warewulfd.log``)
|
||||
to syslog.
|
||||
|
||||
* ``nfs:export paths``: Warewulf can automatically set up these NFS
|
||||
exports.
|
||||
|
||||
@@ -48,22 +48,3 @@ systemd service:
|
||||
.. code-block:: console
|
||||
|
||||
# systemctl enable --now warewulfd
|
||||
|
||||
You can also check and control the Warewulf service using the ``wwctl``
|
||||
command line program as follows:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# wwctl server status
|
||||
|
||||
.. note::
|
||||
|
||||
If the Warewulf service is running via systemd, restarting
|
||||
stopping, and starting it from the ``wwctl`` command may result in
|
||||
unexpected results.
|
||||
|
||||
Logs
|
||||
----
|
||||
|
||||
The Warewulf server logs are by default written to
|
||||
``/var/log/warewulfd.log``.
|
||||
|
||||
@@ -121,8 +121,6 @@ Build and install Warewulf on wwdev
|
||||
sudo wwctl overlay build -a
|
||||
|
||||
# Start the Warewulf daemon
|
||||
sudo wwctl ready
|
||||
sudo wwctl server start
|
||||
sudo wwctl server status
|
||||
sudo wwctl server &
|
||||
|
||||
Boot your node and watch the bash and the output of the Warewulfd process
|
||||
|
||||
@@ -223,7 +223,7 @@ Vagrantfile
|
||||
systemd name: nfs-server
|
||||
CONF
|
||||
|
||||
sed -i 's@ExecStart=/usr/bin/wwctl server start@ExecStart=/usr/bin/wwctl server start -d -v@' /usr/lib/systemd/system/warewulfd.service
|
||||
sed -i 's@ExecStart=/usr/bin/wwctl server@ExecStart=/usr/bin/wwctl server -d -v@' /usr/lib/systemd/system/warewulfd.service
|
||||
systemctl enable --now warewulfd
|
||||
|
||||
wwctl configure --all
|
||||
|
||||
@@ -137,9 +137,7 @@ I have VirtualBox running on my desktop.
|
||||
sudo wwctl overlay build -a
|
||||
|
||||
# Start the Warewulf daemon
|
||||
sudo wwctl ready
|
||||
sudo wwctl server start
|
||||
sudo wwctl server status
|
||||
sudo wwctl server &
|
||||
|
||||
4. Create a new guest VM instance inside the VirtualBox to be the
|
||||
Warewulf client/compute node. Under the system configuration make
|
||||
|
||||
Reference in New Issue
Block a user