diff --git a/ChangeLog b/ChangeLog index 65ddd732..8a23dccd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,7 @@ as. This fixes permission issues at startup time. forced to use TCP. - The `ct` parameter has been removed from DoH queries, as Google doesn't require it any more. + - Service installation is now supported on FreeBSD. * Version 2.0.42 - The current versions of the `dnsdist` load balancer (presumably used diff --git a/vendor/github.com/kardianos/service/.travis.yml b/vendor/github.com/kardianos/service/.travis.yml index 295af232..891714c8 100644 --- a/vendor/github.com/kardianos/service/.travis.yml +++ b/vendor/github.com/kardianos/service/.travis.yml @@ -3,8 +3,8 @@ go_import_path: github.com/kardianos/service sudo: required go: - - 1.10.x - - 1.11.x + - 1.12.x + - 1.14.x - master before_install: diff --git a/vendor/github.com/kardianos/service/go.mod b/vendor/github.com/kardianos/service/go.mod index 2e998db6..5582a1e2 100644 --- a/vendor/github.com/kardianos/service/go.mod +++ b/vendor/github.com/kardianos/service/go.mod @@ -1,5 +1,5 @@ module github.com/kardianos/service -go 1.10 +go 1.12 require golang.org/x/sys v0.0.0-20190204203706-41f3e6584952 diff --git a/vendor/github.com/kardianos/service/service.go b/vendor/github.com/kardianos/service/service.go index cec456c5..7040a602 100644 --- a/vendor/github.com/kardianos/service/service.go +++ b/vendor/github.com/kardianos/service/service.go @@ -83,6 +83,8 @@ const ( optionRunWait = "RunWait" optionReloadSignal = "ReloadSignal" optionPIDFile = "PIDFile" + optionLimitNOFILE = "LimitNOFILE" + optionLimitNOFILEDefault = -1 // -1 = don't set in configuration optionRestart = "Restart" optionSuccessExitStatus = "SuccessExitStatus" @@ -147,6 +149,9 @@ type Config struct { // - Restart string (always) - How shall service be restarted. // - SuccessExitStatus string () - The list of exit status that shall be considered as successful, // in addition to the default ones. + // * Linux (systemd) + // - LimitNOFILE int - Maximum open files (ulimit -n) (https://serverfault.com/questions/628610/increasing-nproc-for-processes-launched-by-systemd-on-centos-7) + Option KeyValue } @@ -223,7 +228,7 @@ func (kv KeyValue) float64(name string, defaultValue float64) float64 { return defaultValue } -// funcSingle returns the value of the given name, assuming the value is a float64. +// funcSingle returns the value of the given name, assuming the value is a func(). // If the value isn't found or is not of the type, the defaultValue is returned. func (kv KeyValue) funcSingle(name string, defaultValue func()) func() { if v, found := kv[name]; found { @@ -310,7 +315,7 @@ type System interface { // 8. Service.Run returns. // 9. User program should quickly exit. type Interface interface { - // Start provides a place to initiate the service. The service doesn't not + // Start provides a place to initiate the service. The service doesn't // signal a completed start until after this function returns, so the // Start function must not take more then a few seconds at most. Start(s Service) error diff --git a/vendor/github.com/kardianos/service/service_freebsd.go b/vendor/github.com/kardianos/service/service_freebsd.go new file mode 100644 index 00000000..66bb5746 --- /dev/null +++ b/vendor/github.com/kardianos/service/service_freebsd.go @@ -0,0 +1,220 @@ +// Copyright 2019 Daniel Theophanes. +// Use of this source code is governed by a zlib-style +// license that can be found in the LICENSE file. + +package service + +import ( + "fmt" + "os" + "os/signal" + "syscall" + "text/template" +) + +const version = "freebsd" + +type freebsdSystem struct{} + +func (freebsdSystem) String() string { + return version +} +func (freebsdSystem) Detect() bool { + return true +} +func (freebsdSystem) Interactive() bool { + return interactive +} +func (freebsdSystem) New(i Interface, c *Config) (Service, error) { + s := &freebsdService{ + i: i, + Config: c, + } + + return s, nil +} + +func init() { + ChooseSystem(freebsdSystem{}) +} + +var interactive = false + +func init() { + var err error + interactive, err = isInteractive() + if err != nil { + panic(err) + } +} + +func isInteractive() (bool, error) { + return os.Getenv("IS_DAEMON") != "1", nil +} + +type freebsdService struct { + i Interface + *Config +} + +func (s *freebsdService) String() string { + if len(s.DisplayName) > 0 { + return s.DisplayName + } + return s.Name +} + +func (s *freebsdService) Platform() string { + return version +} + +func (s *freebsdService) template() *template.Template { + functions := template.FuncMap{ + "bool": func(v bool) string { + if v { + return "true" + } + return "false" + }, + } + + customConfig := s.Option.string(optionSysvScript, "") + + if customConfig != "" { + return template.Must(template.New("").Funcs(functions).Parse(customConfig)) + } else { + return template.Must(template.New("").Funcs(functions).Parse(rcScript)) + } +} + +func (s *freebsdService) configPath() (cp string, err error) { + cp = "/usr/local/etc/rc.d/" + s.Config.Name + return +} + +func (s *freebsdService) Install() error { + path, err := s.execPath() + if err != nil { + return err + } + + // write start script + confPath, err := s.configPath() + if err != nil { + return err + } + _, err = os.Stat(confPath) + if err == nil { + return fmt.Errorf("Init already exists: %s", confPath) + } + + f, err := os.Create(confPath) + if err != nil { + return err + } + defer f.Close() + + var to = &struct { + *Config + Path string + }{ + s.Config, + path, + } + + err = s.template().Execute(f, to) + if err != nil { + return err + } + + if err = os.Chmod(confPath, 0755); err != nil { + return err + } + + return nil +} + +func (s *freebsdService) Uninstall() error { + cp, err := s.configPath() + if err != nil { + return err + } + return os.Remove(cp) +} + +func (s *freebsdService) Status() (Status, error) { + cp, err := s.configPath() + if err != nil { + return StatusUnknown, err + } + + if _, err = os.Stat(cp); os.IsNotExist(err) { + return StatusStopped, ErrNotInstalled + } + + status, _, err := runCommand("service", false, s.Name, "status") + if status == 1 { + return StatusStopped, nil + } else if err != nil { + return StatusUnknown, err + } + return StatusRunning, nil +} + +func (s *freebsdService) Start() error { + return run("service", s.Name, "start") +} + +func (s *freebsdService) Stop() error { + return run("service", s.Name, "stop") +} + +func (s *freebsdService) Restart() error { + return run("service", s.Name, "restart") +} + +func (s *freebsdService) Run() error { + var err error + + err = s.i.Start(s) + if err != nil { + return err + } + + s.Option.funcSingle(optionRunWait, func() { + var sigChan = make(chan os.Signal, 3) + signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt) + <-sigChan + })() + + return s.i.Stop(s) +} + +func (s *freebsdService) Logger(errs chan<- error) (Logger, error) { + if interactive { + return ConsoleLogger, nil + } + return s.SystemLogger(errs) +} + +func (s *freebsdService) SystemLogger(errs chan<- error) (Logger, error) { + return newSysLogger(s.Name, errs) +} + +var rcScript = `#!/bin/sh + +# PROVIDE: {{.Name}} +# REQUIRE: SERVERS +# KEYWORD: shutdown + +. /etc/rc.subr + +name="{{.Name}}" +{{.Name}}_env="IS_DAEMON=1" +pidfile="/var/run/${name}.pid" +command="/usr/sbin/daemon" +daemon_args="-P ${pidfile} -r -t \"${name}: daemon\"{{if .WorkingDirectory}} -c {{.WorkingDirectory}}{{end}}" +command_args="${daemon_args} {{.Path}}{{range .Arguments}} {{.}}{{end}}" + +run_rc_command "$1" +` diff --git a/vendor/github.com/kardianos/service/service_systemd_linux.go b/vendor/github.com/kardianos/service/service_systemd_linux.go index 99c5e2a8..3ce78bf5 100644 --- a/vendor/github.com/kardianos/service/service_systemd_linux.go +++ b/vendor/github.com/kardianos/service/service_systemd_linux.go @@ -10,6 +10,7 @@ import ( "fmt" "os" "os/signal" + "path/filepath" "regexp" "strconv" "strings" @@ -66,15 +67,21 @@ func (s *systemd) Platform() string { return s.platform } -// Systemd services should be supported, but are not currently. -var errNoUserServiceSystemd = errors.New("User services are not supported on systemd.") - func (s *systemd) configPath() (cp string, err error) { - if s.Option.bool(optionUserService, optionUserServiceDefault) { - err = errNoUserServiceSystemd + if !s.Option.bool(optionUserService, optionUserServiceDefault) { + cp = "/etc/systemd/system/" + s.Config.Name + ".service" return } - cp = "/etc/systemd/system/" + s.Config.Name + ".service" + homeDir, err := os.UserHomeDir() + if err != nil { + return + } + systemdUserDir := filepath.Join(homeDir, ".config/systemd/user") + err = os.MkdirAll(systemdUserDir, os.ModePerm) + if err != nil { + return + } + cp = filepath.Join(systemdUserDir, s.Config.Name + ".service") return } @@ -132,7 +139,7 @@ func (s *systemd) Install() error { return fmt.Errorf("Init already exists: %s", confPath) } - f, err := os.Create(confPath) + f, err := os.OpenFile(confPath, os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return err } @@ -149,6 +156,7 @@ func (s *systemd) Install() error { HasOutputFileSupport bool ReloadSignal string PIDFile string + LimitNOFILE int Restart string SuccessExitStatus string LogOutput bool @@ -158,6 +166,7 @@ func (s *systemd) Install() error { s.hasOutputFileSupport(), s.Option.string(optionReloadSignal, ""), s.Option.string(optionPIDFile, ""), + s.Option.int(optionLimitNOFILE, optionLimitNOFILEDefault), s.Option.string(optionRestart, "always"), s.Option.string(optionSuccessExitStatus, ""), s.Option.bool(optionLogOutput, optionLogOutputDefault), @@ -168,15 +177,30 @@ func (s *systemd) Install() error { return err } - err = run("systemctl", "enable", s.Name+".service") + if s.Option.bool(optionUserService, optionUserServiceDefault) { + err = run("systemctl", "enable", "--user", s.Name+".service") + } else { + err = run("systemctl", "enable", s.Name+".service") + } if err != nil { return err } - return run("systemctl", "daemon-reload") + + if s.Option.bool(optionUserService, optionUserServiceDefault) { + err = run("systemctl", "daemon-reload", "--user") + } else { + err = run("systemctl", "daemon-reload") + } + return err } func (s *systemd) Uninstall() error { - err := run("systemctl", "disable", s.Name+".service") + var err error + if s.Option.bool(optionUserService, optionUserServiceDefault) { + err = run("systemctl", "disable", "--user", s.Name+".service") + } else { + err = run("systemctl", "disable", s.Name+".service") + } if err != nil { return err } @@ -226,6 +250,8 @@ func (s *systemd) Status() (Status, error) { return StatusRunning, nil case strings.HasPrefix(out, "inactive"): return StatusStopped, nil + case strings.HasPrefix(out, "activating"): + return StatusRunning, nil case strings.HasPrefix(out, "failed"): return StatusUnknown, errors.New("service in failed state") default: @@ -264,6 +290,7 @@ ExecStart={{.Path|cmdEscape}}{{range .Arguments}} {{.|cmd}}{{end}} StandardOutput=file:/var/log/{{.Name}}.out StandardError=file:/var/log/{{.Name}}.err {{- end}} +{{if gt .LimitNOFILE -1 }}LimitNOFILE={{.LimitNOFILE}}{{end}} {{if .Restart}}Restart={{.Restart}}{{end}} {{if .SuccessExitStatus}}SuccessExitStatus={{.SuccessExitStatus}}{{end}} RestartSec=120 diff --git a/vendor/github.com/kardianos/service/service_unix.go b/vendor/github.com/kardianos/service/service_unix.go index b98189f1..69596224 100644 --- a/vendor/github.com/kardianos/service/service_unix.go +++ b/vendor/github.com/kardianos/service/service_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a zlib-style // license that can be found in the LICENSE file. -// +build linux darwin solaris aix +// +build linux darwin solaris aix freebsd package service diff --git a/vendor/github.com/kardianos/service/service_windows.go b/vendor/github.com/kardianos/service/service_windows.go index 09ded239..11c9af50 100644 --- a/vendor/github.com/kardianos/service/service_windows.go +++ b/vendor/github.com/kardianos/service/service_windows.go @@ -296,6 +296,7 @@ func (ws *windowsService) Status() (Status, error) { } return StatusUnknown, err } + defer s.Close() status, err := s.Query() if err != nil { diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 942a4bbf..7b7c7275 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -97,6 +97,12 @@ func IoctlSetRTCTime(fd int, value *RTCTime) error { return err } +func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error { + err := ioctl(fd, RTC_WKALM_SET, uintptr(unsafe.Pointer(value))) + runtime.KeepAlive(value) + return err +} + func IoctlGetUint32(fd int, req uint) (uint32, error) { var value uint32 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) @@ -109,6 +115,12 @@ func IoctlGetRTCTime(fd int) (*RTCTime, error) { return &value, err } +func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) { + var value RTCWkAlrm + err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value))) + return &value, err +} + //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) func Link(oldpath string, newpath string) (err error) { diff --git a/vendor/modules.txt b/vendor/modules.txt index 4f70e2a1..a48b9b1e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -42,7 +42,7 @@ github.com/jedisct1/go-minisign github.com/jedisct1/xsecretbox # github.com/k-sone/critbitgo v1.4.0 github.com/k-sone/critbitgo -# github.com/kardianos/service v1.0.1-0.20191211031725-3c356ae54c8a +# github.com/kardianos/service v1.1.0 github.com/kardianos/service # github.com/miekg/dns v1.1.29 github.com/miekg/dns @@ -55,7 +55,7 @@ github.com/powerman/check # github.com/smartystreets/goconvey v1.6.4 github.com/smartystreets/goconvey/convey/gotest github.com/smartystreets/goconvey/convey/reporting -# golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 +# golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 golang.org/x/crypto/blake2b golang.org/x/crypto/curve25519 golang.org/x/crypto/ed25519 @@ -77,7 +77,7 @@ golang.org/x/net/internal/socks golang.org/x/net/ipv4 golang.org/x/net/ipv6 golang.org/x/net/proxy -# golang.org/x/sys v0.0.0-20200602100848-8d3cce7afc34 +# golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 golang.org/x/sys/cpu golang.org/x/sys/internal/unsafeheader golang.org/x/sys/unix