diff --git a/.envrc b/.envrc index 1443b8e..7dedd3a 100644 --- a/.envrc +++ b/.envrc @@ -2,3 +2,10 @@ use nix export WORKSPACE="$(pwd)" export GOFLAGS="-count=1" + +PATH_add "$(pwd)/dev" + +export SERVICE_DIR="/tmp/services/sv" +export ACTIVE_SERVICE_DIR="/tmp/services/active" +export LOG_DIR="/tmp/services/log" + diff --git a/README.md b/README.md index 7bbbc75..8df3733 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ manage runit # features + - manage multiple service matching via patterns - easily create and manage runit service - import/export service configuration diff --git a/cmd/runitcmd/command.go b/cmd/runitcmd/command.go index 8c3df57..53c818f 100644 --- a/cmd/runitcmd/command.go +++ b/cmd/runitcmd/command.go @@ -9,17 +9,28 @@ import ( "github.com/urfave/cli/v2" ) -func makeCommand(name string, fn func(*cli.Context) error) *cli.Command { +func makeCommand(app *Application, name, action, description string) *cli.Command { + if action == "" { + action = name + } cmd := &cli.Command{ Name: name, Usage: name + " a service", - Description: name + " a service", - Action: fn, + Description: description, + Action: app.MakeCommandFn(action), } return cmd - } +func (app *Application) MakeCommandFn(action string) func(*cli.Context) error { + fn := func(c *cli.Context) error { + for _, service := range app.MatchingServices(c) { + app.runCommand(service.Name, action) + } + return nil + } + return fn +} func (app *Application) MatchingServices(c *cli.Context) []*runit.Service { services := make([]*runit.Service, 0) args := c.Args() @@ -143,153 +154,3 @@ func (app *Application) runCommand(name, action string) error { } return err } - -// some helpful commands -func (app *Application) Delete(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "delete") - } - return nil -} -func (app *Application) Activate(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "activate") - } - return nil -} -func (app *Application) Deactivate(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "deactivate") - } - return nil -} -func (app *Application) Enable(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "enable") - } - return nil -} -func (app *Application) Disable(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "disable") - } - return nil -} -func (app *Application) Reset(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "reset") - } - return nil -} - -// sv commands -func (app *Application) Up(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "up") - } - return nil -} -func (app *Application) Down(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "down") - } - return nil -} -func (app *Application) Once(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "once") - } - return nil -} -func (app *Application) Pause(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "pause") - } - return nil -} -func (app *Application) Cont(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "cont") - } - return nil -} -func (app *Application) Hup(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "hup") - } - return nil -} -func (app *Application) Alarm(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "alarm") - } - return nil -} -func (app *Application) Interrupt(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "interrupt") - } - return nil -} -func (app *Application) Quit(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "quit") - } - return nil -} -func (app *Application) Usr1(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "1") - } - return nil -} -func (app *Application) Usr2(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "2") - } - return nil -} -func (app *Application) Term(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "term") - } - return nil -} -func (app *Application) Kill(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "kill") - } - return nil -} - -// lsb compatible -func (app *Application) Start(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "start") - } - return nil -} -func (app *Application) Stop(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "stop") - } - return nil -} -func (app *Application) Reload(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "reload") - } - return nil -} -func (app *Application) Restart(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "restart") - } - return nil -} -func (app *Application) Shutdown(c *cli.Context) error { - for _, service := range app.MatchingServices(c) { - app.runCommand(service.Name, "shutdown") - } - return nil -} diff --git a/cmd/runitcmd/main.go b/cmd/runitcmd/main.go index c151263..1e61dca 100644 --- a/cmd/runitcmd/main.go +++ b/cmd/runitcmd/main.go @@ -39,12 +39,20 @@ func main() { Usage: "change log level", }, &cli.StringFlag{ - Name: "service-dir", - Usage: "change service dir", + Name: "log-dir", + Usage: "change service dir", + EnvVars: []string{"LOG_DIR"}, + Value: runit.DefaultLogDir, }, &cli.StringFlag{ - Name: "active-dir", - Usage: "change active service dir", + Name: "service-dir", + Usage: "change service dir", + EnvVars: []string{"SERVICE_DIR"}, + }, + &cli.StringFlag{ + Name: "active-dir", + Usage: "change active service dir", + EnvVars: []string{"ACTIVE_SERVICE_DIR"}, }, } @@ -141,33 +149,35 @@ func main() { initExport(app), // more commands - makeCommand("delete", app.Delete), - makeCommand("activate", app.Activate), - makeCommand("deactivate", app.Deactivate), - makeCommand("enable", app.Enable), - makeCommand("disable", app.Disable), - makeCommand("reset", app.Reset), + makeCommand(app, "delete", "", "delete service"), + makeCommand(app, "activate", "", "create service symlink"), + makeCommand(app, "deactivate", "", "delete service symlink"), + makeCommand(app, "enable", "", "enable service at boot"), + makeCommand(app, "disable", "", "disable service at boot"), + makeCommand(app, "reset", "", "reset service state"), // commands - makeCommand("up", app.Up), - makeCommand("down", app.Down), - makeCommand("pause", app.Pause), - makeCommand("cont", app.Cont), - makeCommand("hup", app.Cont), - makeCommand("alarm", app.Cont), - makeCommand("interrupt", app.Cont), - makeCommand("quit", app.Quit), - makeCommand("usr1", app.Usr1), - makeCommand("usr2", app.Usr2), - makeCommand("term", app.Term), - makeCommand("kill", app.Kill), + makeCommand(app, "up", "", "bring service up"), + makeCommand(app, "down", "", "bring service down"), + makeCommand(app, "pause", "", "pause service"), + + // signals + makeCommand(app, "cont", "", "send service CONT signal"), + makeCommand(app, "hup", "", "send service HUP signal"), + makeCommand(app, "alarm", "", "send service ALRM signal"), + makeCommand(app, "interrupt", "", "send service INT signal"), + makeCommand(app, "quit", "", "send service QUIT signal"), + makeCommand(app, "usr1", "1", "send service USR1 signal"), + makeCommand(app, "usr2", "2", "send service USR2 signal"), + makeCommand(app, "term", "", "send service TERM signal"), + makeCommand(app, "kill", "", "send service KILL signal"), // lsb - makeCommand("start", app.Start), - makeCommand("stop", app.Stop), - makeCommand("reload", app.Reload), - makeCommand("restart", app.Restart), - makeCommand("shutdown", app.Shutdown), + makeCommand(app, "start", "", "start service"), + makeCommand(app, "stop", "", "stop service"), + makeCommand(app, "reload", "", "reload service config"), + makeCommand(app, "restart", "", "restsart service"), + makeCommand(app, "shutdown", "", "shutdown service"), } app.Run(os.Args) diff --git a/cmd/runitcmd/setup.go b/cmd/runitcmd/setup.go index 6c47b46..a8ed790 100644 --- a/cmd/runitcmd/setup.go +++ b/cmd/runitcmd/setup.go @@ -16,29 +16,10 @@ func initSetup(app *Application) *cli.Command { usage := "setup a service" flags := []cli.Flag{ - &cli.StringFlag{ - Name: "log-level, l", - Usage: "log level", - Value: "warn", - }, &cli.BoolFlag{ Name: "verbose, v", Usage: "be verbose", }, - &cli.StringFlag{ - Name: "service-dir", - Usage: "service directory", - Value: runit.DefaultServiceDir, - }, - &cli.StringFlag{ - Name: "active-service-dir", - Usage: "active service directory", - Value: runit.DefaultActiveDir, - }, - &cli.StringFlag{ - Name: "log-dir", - Usage: "log to directory", - }, &cli.BoolFlag{ Name: "enable, e", Usage: "setup service and enable it", @@ -88,10 +69,9 @@ func initSetup(app *Application) *cli.Command { } func (app *Application) Setup(c *cli.Context) error { - log_level := c.String("log-level") verbose := c.Bool("verbose") service_dir := c.String("service-dir") - active_dir := c.String("active-service-dir") + active_dir := c.String("active-dir") log_dir := c.String("log-dir") enable := c.Bool("enable") disable := c.Bool("disable") @@ -106,13 +86,12 @@ func (app *Application) Setup(c *cli.Context) error { args := c.Args() name := args.First() + log.Tracef("setup service-dir:%s active-dir:%s log-dir:%s", + service_dir, active_dir, log_dir) + if verbose { gologging.SetLogLevel("trace") } - if log_level != "" { - gologging.SetLogLevel(log_level) - } - // template does nothing // make the runit api locally for these flags to function @@ -141,11 +120,7 @@ func (app *Application) Setup(c *cli.Context) error { log.Tracef("setup %s", name) lcfg := runit.DefaultLoggingConfig() - if log_dir == "" { - lcfg.Directory = filepath.Join(runit.DefaultLogDir, name) - } else { - lcfg.Directory = log_dir - } + lcfg.Directory = filepath.Join(log_dir, name) var exec string if uid != 0 || gid != 0 { diff --git a/dev/gi b/dev/gi new file mode 100755 index 0000000..aa9406e --- /dev/null +++ b/dev/gi @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -x +go install github.com/sigmonsays/runitcmd/... diff --git a/dev/mkdirs.sh b/dev/mkdirs.sh new file mode 100755 index 0000000..b9e9d3e --- /dev/null +++ b/dev/mkdirs.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +mkdir -pv $SERVICE_DIR $ACTIVE_SERVICE_DIR $LOG_DIR diff --git a/go.mod b/go.mod index f6bb887..915cd28 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,11 @@ module github.com/sigmonsays/runitcmd go 1.13 require ( + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sigmonsays/go-logging v0.0.0-20170415192813-93f4813d2694 - github.com/urfave/cli/v2 v2.2.0 + github.com/urfave/cli/v2 v2.27.1 + github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect gopkg.in/yaml.v2 v2.2.8 ) diff --git a/go.sum b/go.sum index ae83dd0..4ae4bb7 100644 --- a/go.sum +++ b/go.sum @@ -1,18 +1,30 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sigmonsays/go-logging v0.0.0-20170415192813-93f4813d2694 h1:Mj7zYpc19leanFgX83o107yxP2f89/F1TFjZSQxoEhI= github.com/sigmonsays/go-logging v0.0.0-20170415192813-93f4813d2694/go.mod h1:6+xYjK0jIspthgQ2ScYbhbfKk/rAbwkniV704uQJsxA= github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= +github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI= +github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/runit/apply.go b/runit/apply.go index a043dcb..faeecdd 100644 --- a/runit/apply.go +++ b/runit/apply.go @@ -21,7 +21,7 @@ func (runit *Runit) Apply(cfg *ServiceConfig) error { if err != nil { return err } - fmt.Fprintf(f, "#!/bin/bash\n") + fmt.Fprintf(f, "#!/usr/bin/env bash\n") if cfg.RedirectStderr { fmt.Fprintf(f, "exec 2>&1\n") } diff --git a/runit/logging.go b/runit/logging.go index d9245ce..3b7766d 100644 --- a/runit/logging.go +++ b/runit/logging.go @@ -65,7 +65,7 @@ func (cfg *LoggingConfig) WriteRunFile(path string) error { log.Warnf("invalid timestamp value: %d", cfg.Timestamp) } - fmt.Fprintf(f, "#!/bin/bash\n") + fmt.Fprintf(f, "#!/usr/bin/env bash\n") fmt.Fprintf(f, "exec svlogd %s %s\n", svlogd_flags, cfg.Directory) log.Tracef("log/run svlogd %s %s", svlogd_flags, cfg.Directory) diff --git a/shell.nix b/shell.nix index 6d05188..74cb5f4 100644 --- a/shell.nix +++ b/shell.nix @@ -4,8 +4,8 @@ with pkgs; mkShell { buildInputs = [ - go - gopls + #go + #gopls runit ]; }