diff --git a/cmd/root.go b/cmd/root.go index 68404a1..d8f37a1 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -133,8 +133,12 @@ func rootCmdRun(*cobra.Command, []string) { config.SetDebugViaFlag(debug) if err := c.System.ConfigureDirectories(); err != nil { - log.WithError(err).Fatal("failed to configure system directories for pterodactyl") - os.Exit(1) + log.WithField("error", err).Fatal("failed to configure system directories for pterodactyl") + return + } + + if err := c.System.EnableLogRotation(); err != nil { + log.WithField("error", err).Fatal("failed to configure log rotation on the system") return } diff --git a/config/config_system.go b/config/config_system.go index b865cd9..fab3479 100644 --- a/config/config_system.go +++ b/config/config_system.go @@ -3,6 +3,7 @@ package config import ( "github.com/apex/log" "github.com/pkg/errors" + "html/template" "os" "path" "path/filepath" @@ -46,6 +47,10 @@ type SystemConfiguration struct { // frequently modifying a servers' files. CheckPermissionsOnBoot bool `default:"true" yaml:"check_permissions_on_boot"` + // If set to false Wings will not attempt to write a log rotate configuration to the disk + // when it boots and one is not detected. + EnableLogRotate bool `default:"true" yaml:"enable_log_rotate"` + Sftp SftpConfiguration `yaml:"sftp"` } @@ -91,6 +96,47 @@ func (sc *SystemConfiguration) ConfigureDirectories() error { return nil } +// Writes a logrotate file for wings to the system logrotate configuration directory if one +// exists and a logrotate file is not found. This allows us to basically automate away the log +// rotatation for most installs, but also enable users to make modifications on their own. +func (sc *SystemConfiguration) EnableLogRotation() error { + // Do nothing if not enabled. + if sc.EnableLogRotate == false { + log.Info("skipping log rotate configuration, disabled in wings config file") + + return nil + } + + if st, err := os.Stat("/etc/logrotate.d"); err != nil && !os.IsNotExist(err) { + return errors.WithStack(err) + } else if (err != nil && os.IsNotExist(err)) || !st.IsDir() { + return nil + } + + if _, err := os.Stat("/etc/logrotate.d/wings"); err != nil && !os.IsNotExist(err) { + return errors.WithStack(err) + } else if err == nil { + return nil + } + + log.Info("no log rotation configuration found, system is configured to support it, adding file now") + // If we've gotten to this point it means the logrotate directory exists on the system + // but there is not a file for wings already. In that case, let us write a new file to + // it so files can be rotated easily. + f, err := os.Create("/etc/logrotate.d/wings") + if err != nil { + return errors.WithStack(err) + } + defer f.Close() + + t, err := template.ParseFiles("templates/logrotate.tpl") + if err != nil { + return errors.WithStack(err) + } + + return errors.Wrap(t.Execute(f, sc), "failed to write logrotate file to disk") +} + // Returns the location of the JSON file that tracks server states. func (sc *SystemConfiguration) GetStatesPath() string { return path.Join(sc.RootDirectory, "states.json") diff --git a/go.mod b/go.mod index e46bd66..d2d9e57 100644 --- a/go.mod +++ b/go.mod @@ -70,7 +70,7 @@ require ( golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 - golang.org/x/text v0.3.3 // indirect + golang.org/x/text v0.3.3 golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect diff --git a/templates/logrotate.tpl b/templates/logrotate.tpl new file mode 100644 index 0000000..d848699 --- /dev/null +++ b/templates/logrotate.tpl @@ -0,0 +1,13 @@ +{{.LogDirectory}}/wings.log { + size 10M + compress + delaycompress + dateext + maxage 7 + missingok + notifempty + create 0640 {{.User.Uid}} {{.User.Gid}} + postrotate + killall -SIGHUP wings + endscript +} \ No newline at end of file