diff --git a/README.md b/README.md index 98f6ee7..b6f8684 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ ExecStopPost=/path/to/iptables -w -F reaction ExecStopPost=/path/to/iptables -w -X reaction StateDirectory=reaction +RuntimeDirectory=reaction WorkingDirectory=/var/lib/reaction ``` See [reaction.service](./config/reaction.service) and [reaction.yml](./config/reaction.yml) for the fully commented examples. @@ -74,6 +75,10 @@ See [reaction.service](./config/reaction.service) and [reaction.yml](./config/re the working directory of `reaction` will be used to create and read from the embedded database. if you don't know where to start it, `/var/lib/reaction` should be a sane choice. +### socket + +the socket allowing communication between the cli and server will be created at `/run/reaction/reaction.socket`. + ### terminology - **streams** are commands. they're run and their ouptut is captured. *example:* `tail -f /var/log/nginx/access.log` diff --git a/app/cli.go b/app/cli.go index a2ced71..7d73126 100644 --- a/app/cli.go +++ b/app/cli.go @@ -23,12 +23,10 @@ type Response struct { Actions ReadableMap } -func SocketPath() string { - return fmt.Sprintf("/run/user/%v/reaction.sock", os.Getuid()) -} +const SocketPath = "/run/reaction/reaction.sock" func SendAndRetrieve(data Request) Response { - conn, err := net.Dial("unix", SocketPath()) + conn, err := net.Dial("unix", SocketPath) if err != nil { log.Fatalln("Error opening connection top daemon:", err) } diff --git a/app/pipe.go b/app/pipe.go index 46f5dbc..5718242 100644 --- a/app/pipe.go +++ b/app/pipe.go @@ -5,6 +5,7 @@ import ( "log" "net" "os" + "path" "sync" "gopkg.in/yaml.v3" @@ -110,18 +111,21 @@ func (r ReadableMap) ToString() string { // Socket-related, server-related functions func createOpenSocket() net.Listener { - socketPath := SocketPath() - _, err := os.Stat(socketPath) + err := os.MkdirAll(path.Dir(SocketPath), 0755) + if err != nil { + log.Fatalln("FATAL Failed to create socket directory") + } + _, err = os.Stat(SocketPath) if err == nil { - log.Println("WARN socket", socketPath, "already exists: Is the daemon already running? Deleting.") - err = os.Remove(socketPath) + log.Println("WARN socket", SocketPath, "already exists: Is the daemon already running? Deleting.") + err = os.Remove(SocketPath) if err != nil { - log.Println("FATAL Failed to remove socket:", err) + log.Fatalln("FATAL Failed to remove socket:", err) } } - ln, err := net.Listen("unix", socketPath) + ln, err := net.Listen("unix", SocketPath) if err != nil { - log.Println("FATAL Failed to create socket:", err) + log.Fatalln("FATAL Failed to create socket:", err) } return ln } diff --git a/app/reaction.go b/app/reaction.go index f8a16d3..a892912 100644 --- a/app/reaction.go +++ b/app/reaction.go @@ -235,7 +235,10 @@ func quit() { // wait for them to complete wgActions.Wait() // delete pipe - os.Remove(SocketPath()) + err := os.Remove(SocketPath) + if err != nil { + log.Println("Failed to remove socket:", err) + } os.Exit(3) } diff --git a/config/reaction.service b/config/reaction.service index 2e08088..49513e0 100644 --- a/config/reaction.service +++ b/config/reaction.service @@ -2,6 +2,7 @@ [Unit] WantedBy=multi-user.target +# See `man systemd.exec` and `man systemd.service` for most options below [Service] ExecStart=/path/to/reaction -c /etc/reaction.yml @@ -24,5 +25,7 @@ ExecStopPost=/path/to/iptables -w -X reaction # Ask systemd to create /var/lib/reaction (/var/lib/ is implicit) StateDirectory=reaction +# Ask systemd to create /run/reaction at runtime (/run/ is implicit) +RuntimeDirectory=reaction # Start reaction in its state directory WorkingDirectory=/var/lib/reaction diff --git a/go.sum b/go.sum index d542811..a62c313 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ +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.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=