Move config files and folders

pull/60/head
Philipp Heckel 2021-12-18 22:02:36 -05:00
parent 2c1989beb0
commit fa9d6444f5
18 changed files with 70 additions and 52 deletions

View File

@ -47,14 +47,20 @@ nfpms:
- rpm
bindir: /usr/bin
contents:
- src: config/config.yml
dst: /etc/ntfy/config.yml
- src: server/server.yml
dst: /etc/ntfy/server.yml
type: config
- src: config/ntfy.service
- src: server/ntfy.service
dst: /lib/systemd/system/ntfy.service
- src: client/client.yml
dst: /etc/ntfy/client.yml
type: config
- src: client/ntfy-client.service
dst: /lib/systemd/system/ntfy-client.service
- dst: /var/cache/ntfy
type: dir
scripts:
preinstall: "scripts/preinst.sh"
postinstall: "scripts/postinst.sh"
preremove: "scripts/prerm.sh"
postremove: "scripts/postrm.sh"
@ -64,8 +70,10 @@ archives:
files:
- LICENSE
- README.md
- config/config.yml
- config/ntfy.service
- server/server.yml
- server/ntfy.service
- client/client.yml
- client/ntfy-client.service
replacements:
386: i386
amd64: x86_64

View File

@ -115,7 +115,7 @@ build-simple: clean
"-linkmode=external -extldflags=-static -s -w -X main.version=$(VERSION) -X main.commit=$(shell git rev-parse --short HEAD) -X main.date=$(shell date +%s)"
clean: .PHONY
rm -rf dist build
rm -rf dist build server/docs
# Releasing targets

View File

@ -50,7 +50,8 @@ func New(config *Config) *Client {
}
}
func (c *Client) Publish(topicURL, message string, options ...PublishOption) error {
func (c *Client) Publish(topic, message string, options ...PublishOption) error {
topicURL := c.expandTopicURL(topic)
req, _ := http.NewRequest("POST", topicURL, strings.NewReader(message))
for _, option := range options {
if err := option(req); err != nil {

View File

@ -5,7 +5,6 @@ import (
"errors"
"github.com/urfave/cli/v2"
"github.com/urfave/cli/v2/altsrc"
"heckel.io/ntfy/config"
"heckel.io/ntfy/server"
"heckel.io/ntfy/util"
"log"
@ -13,20 +12,20 @@ import (
)
var flagsServe = []cli.Flag{
&cli.StringFlag{Name: "config", Aliases: []string{"c"}, EnvVars: []string{"NTFY_CONFIG_FILE"}, Value: "/etc/ntfy/config.yml", DefaultText: "/etc/ntfy/config.yml", Usage: "config file"},
altsrc.NewStringFlag(&cli.StringFlag{Name: "listen-http", Aliases: []string{"l"}, EnvVars: []string{"NTFY_LISTEN_HTTP"}, Value: config.DefaultListenHTTP, Usage: "ip:port used to as HTTP listen address"}),
&cli.StringFlag{Name: "config", Aliases: []string{"c"}, EnvVars: []string{"NTFY_CONFIG_FILE"}, Value: "/etc/ntfy/server.yml", DefaultText: "/etc/ntfy/server.yml", Usage: "config file"},
altsrc.NewStringFlag(&cli.StringFlag{Name: "listen-http", Aliases: []string{"l"}, EnvVars: []string{"NTFY_LISTEN_HTTP"}, Value: server.DefaultListenHTTP, Usage: "ip:port used to as HTTP listen address"}),
altsrc.NewStringFlag(&cli.StringFlag{Name: "listen-https", Aliases: []string{"L"}, EnvVars: []string{"NTFY_LISTEN_HTTPS"}, Usage: "ip:port used to as HTTPS listen address"}),
altsrc.NewStringFlag(&cli.StringFlag{Name: "key-file", Aliases: []string{"K"}, EnvVars: []string{"NTFY_KEY_FILE"}, Usage: "private key file, if listen-https is set"}),
altsrc.NewStringFlag(&cli.StringFlag{Name: "cert-file", Aliases: []string{"E"}, EnvVars: []string{"NTFY_CERT_FILE"}, Usage: "certificate file, if listen-https is set"}),
altsrc.NewStringFlag(&cli.StringFlag{Name: "firebase-key-file", Aliases: []string{"F"}, EnvVars: []string{"NTFY_FIREBASE_KEY_FILE"}, Usage: "Firebase credentials file; if set additionally publish to FCM topic"}),
altsrc.NewStringFlag(&cli.StringFlag{Name: "cache-file", Aliases: []string{"C"}, EnvVars: []string{"NTFY_CACHE_FILE"}, Usage: "cache file used for message caching"}),
altsrc.NewDurationFlag(&cli.DurationFlag{Name: "cache-duration", Aliases: []string{"b"}, EnvVars: []string{"NTFY_CACHE_DURATION"}, Value: config.DefaultCacheDuration, Usage: "buffer messages for this time to allow `since` requests"}),
altsrc.NewDurationFlag(&cli.DurationFlag{Name: "keepalive-interval", Aliases: []string{"k"}, EnvVars: []string{"NTFY_KEEPALIVE_INTERVAL"}, Value: config.DefaultKeepaliveInterval, Usage: "interval of keepalive messages"}),
altsrc.NewDurationFlag(&cli.DurationFlag{Name: "manager-interval", Aliases: []string{"m"}, EnvVars: []string{"NTFY_MANAGER_INTERVAL"}, Value: config.DefaultManagerInterval, Usage: "interval of for message pruning and stats printing"}),
altsrc.NewIntFlag(&cli.IntFlag{Name: "global-topic-limit", Aliases: []string{"T"}, EnvVars: []string{"NTFY_GLOBAL_TOPIC_LIMIT"}, Value: config.DefaultGlobalTopicLimit, Usage: "total number of topics allowed"}),
altsrc.NewIntFlag(&cli.IntFlag{Name: "visitor-subscription-limit", Aliases: []string{"V"}, EnvVars: []string{"NTFY_VISITOR_SUBSCRIPTION_LIMIT"}, Value: config.DefaultVisitorSubscriptionLimit, Usage: "number of subscriptions per visitor"}),
altsrc.NewIntFlag(&cli.IntFlag{Name: "visitor-request-limit-burst", Aliases: []string{"B"}, EnvVars: []string{"NTFY_VISITOR_REQUEST_LIMIT_BURST"}, Value: config.DefaultVisitorRequestLimitBurst, Usage: "initial limit of requests per visitor"}),
altsrc.NewDurationFlag(&cli.DurationFlag{Name: "visitor-request-limit-replenish", Aliases: []string{"R"}, EnvVars: []string{"NTFY_VISITOR_REQUEST_LIMIT_REPLENISH"}, Value: config.DefaultVisitorRequestLimitReplenish, Usage: "interval at which burst limit is replenished (one per x)"}),
altsrc.NewDurationFlag(&cli.DurationFlag{Name: "cache-duration", Aliases: []string{"b"}, EnvVars: []string{"NTFY_CACHE_DURATION"}, Value: server.DefaultCacheDuration, Usage: "buffer messages for this time to allow `since` requests"}),
altsrc.NewDurationFlag(&cli.DurationFlag{Name: "keepalive-interval", Aliases: []string{"k"}, EnvVars: []string{"NTFY_KEEPALIVE_INTERVAL"}, Value: server.DefaultKeepaliveInterval, Usage: "interval of keepalive messages"}),
altsrc.NewDurationFlag(&cli.DurationFlag{Name: "manager-interval", Aliases: []string{"m"}, EnvVars: []string{"NTFY_MANAGER_INTERVAL"}, Value: server.DefaultManagerInterval, Usage: "interval of for message pruning and stats printing"}),
altsrc.NewIntFlag(&cli.IntFlag{Name: "global-topic-limit", Aliases: []string{"T"}, EnvVars: []string{"NTFY_GLOBAL_TOPIC_LIMIT"}, Value: server.DefaultGlobalTopicLimit, Usage: "total number of topics allowed"}),
altsrc.NewIntFlag(&cli.IntFlag{Name: "visitor-subscription-limit", Aliases: []string{"V"}, EnvVars: []string{"NTFY_VISITOR_SUBSCRIPTION_LIMIT"}, Value: server.DefaultVisitorSubscriptionLimit, Usage: "number of subscriptions per visitor"}),
altsrc.NewIntFlag(&cli.IntFlag{Name: "visitor-request-limit-burst", Aliases: []string{"B"}, EnvVars: []string{"NTFY_VISITOR_REQUEST_LIMIT_BURST"}, Value: server.DefaultVisitorRequestLimitBurst, Usage: "initial limit of requests per visitor"}),
altsrc.NewDurationFlag(&cli.DurationFlag{Name: "visitor-request-limit-replenish", Aliases: []string{"R"}, EnvVars: []string{"NTFY_VISITOR_REQUEST_LIMIT_REPLENISH"}, Value: server.DefaultVisitorRequestLimitReplenish, Usage: "interval at which burst limit is replenished (one per x)"}),
altsrc.NewBoolFlag(&cli.BoolFlag{Name: "behind-proxy", Aliases: []string{"P"}, EnvVars: []string{"NTFY_BEHIND_PROXY"}, Value: false, Usage: "if set, use X-Forwarded-For header to determine visitor IP address (for rate limiting)"}),
}
@ -39,7 +38,7 @@ var cmdServe = &cli.Command{
Before: initConfigFileInputSource("config", flagsServe),
Description: `Run the ntfy server and listen for incoming requests
The command will load the configuration from /etc/ntfy/config.yml. Config options can
The command will load the configuration from /etc/ntfy/server.yml. Config options can
be overridden using the command line options.
Examples:
@ -82,7 +81,7 @@ func execServe(c *cli.Context) error {
}
// Run server
conf := config.New(listenHTTP)
conf := server.NewConfig(listenHTTP)
conf.ListenHTTPS = listenHTTPS
conf.KeyFile = keyFile
conf.CertFile = certFile

View File

@ -20,10 +20,14 @@ var cmdSubscribe = &cli.Command{
Usage: "Subscribe to one or more topics on a ntfy server",
UsageText: "ntfy subscribe [OPTIONS..] [TOPIC]",
Action: execSubscribe,
OnUsageError: func(context *cli.Context, err error, isSubcommand bool) error {
println("ee")
return nil
},
Flags: []cli.Flag{
&cli.StringFlag{Name: "config", Aliases: []string{"c"}, Usage: "config file"},
&cli.StringFlag{Name: "exec", Aliases: []string{"e"}, Usage: "execute command for each message event"},
&cli.StringFlag{Name: "since", Aliases: []string{"s"}, Usage: "return events since (Unix timestamp, or all)"},
&cli.StringFlag{Name: "config", Aliases: []string{"c"}, Usage: "config file `FILE`"},
&cli.StringFlag{Name: "since", Aliases: []string{"s"}, Usage: "return events since `SINCE` (Unix timestamp, or all)"},
&cli.BoolFlag{Name: "from-config", Aliases: []string{"C"}, Usage: "read subscriptions from config file (service mode)"},
&cli.BoolFlag{Name: "poll", Aliases: []string{"p"}, Usage: "return events and exit, do not listen for new events"},
&cli.BoolFlag{Name: "scheduled", Aliases: []string{"sched", "S"}, Usage: "also return scheduled/delayed events"},
@ -72,8 +76,6 @@ ntfy subscribe --from-config
}
func execSubscribe(c *cli.Context) error {
fmt.Fprintln(c.App.ErrWriter, "\x1b[1;33mThis command is incubating. The interface may change without notice.\x1b[0m")
// Read config and options
conf, err := loadConfig(c)
if err != nil {
@ -100,7 +102,7 @@ func execSubscribe(c *cli.Context) error {
options = append(options, client.WithScheduled())
}
if topic == "" && len(conf.Subscribe) == 0 {
return errors.New("must specify topic, or have at least one topic defined in config")
return errors.New("must specify topic, type 'ntfy subscribe --help' for help")
}
// Execute poll or subscribe

View File

@ -1,6 +1,6 @@
# Configuring the ntfy server
The ntfy server can be configured in three ways: using a config file (typically at `/etc/ntfy/config.yml`,
see [config.yml](https://github.com/binwiederhier/ntfy/blob/main/config/config.yml)), via command line arguments
The ntfy server can be configured in three ways: using a config file (typically at `/etc/ntfy/server.yml`,
see [server.yml](https://github.com/binwiederhier/ntfy/blob/main/config/server.yml)), via command line arguments
or using environment variables.
## Quick start
@ -50,7 +50,7 @@ flag. This will instruct the [rate limiting](#rate-limiting) logic to use the `X
identifier for a visitor, as opposed to the remote IP address. If the `behind-proxy` flag is not set, all visitors will
be counted as one, because from the perspective of the ntfy server, they all share the proxy's IP address.
=== "/etc/ntfy/config.yml"
=== "/etc/ntfy/server.yml"
```
# Tell ntfy to use "X-Forwarded-For" to identify visitors
behind-proxy: true
@ -200,7 +200,7 @@ To configure FCM for your self-hosted instance of the ntfy server, follow these
1. Sign up for a [Firebase account](https://console.firebase.google.com/)
2. Create a Firebase app and download the key file (e.g. `myapp-firebase-adminsdk-...json`)
3. Place the key file in `/etc/ntfy`, set the `firebase-key-file` in `config.yml` accordingly and restart the ntfy server
3. Place the key file in `/etc/ntfy`, set the `firebase-key-file` in `server.yml` accordingly and restart the ntfy server
4. Build your own Android .apk following [these instructions](develop.md#android-app)
Example:
@ -294,7 +294,7 @@ to maintain the client connection and the connection to ntfy.
```
## Config options
Each config option can be set in the config file `/etc/ntfy/config.yml` (e.g. `listen-http: :80`) or as a
Each config option can be set in the config file `/etc/ntfy/server.yml` (e.g. `listen-http: :80`) or as a
CLI option (e.g. `--listen-http :80`. Here's a list of all available options. Alternatively, you can set an environment
variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
@ -327,7 +327,7 @@ USAGE:
ntfy [OPTION..]
GLOBAL OPTIONS:
--config value, -c value config file (default: /etc/ntfy/config.yml) [$NTFY_CONFIG_FILE]
--config value, -c value config file (default: /etc/ntfy/server.yml) [$NTFY_CONFIG_FILE]
--listen-http value, -l value ip:port used to as listen address (default: ":80") [$NTFY_LISTEN_HTTP]
--firebase-key-file value, -F value Firebase credentials file; if set additionally publish to FCM topic [$NTFY_FIREBASE_KEY_FILE]
--cache-file value, -C value cache file used for message caching [$NTFY_CACHE_FILE]

View File

@ -17,7 +17,7 @@ subscribed to a topic.
## Will you know what topics exist, can you spy on me?
If you don't trust me or your messages are sensitive, run your own server. It's <a href="https://github.com/binwiederhier/ntfy">open source</a>.
That said, the logs do not contain any topic names or other details about you.
Messages are cached for the duration configured in `config.yml` (12h by default) to facilitate service restarts, message polling and to overcome
Messages are cached for the duration configured in `server.yml` (12h by default) to facilitate service restarts, message polling and to overcome
client network disruptions.
## Can I self-host it?

View File

@ -13,7 +13,7 @@ The ntfy server comes as a statically linked binary and is shipped as tarball, d
We support amd64, armv7 and arm64.
1. Install ntfy using one of the methods described below
2. Then (optionally) edit `/etc/ntfy/config.yml` (see [configuration](config.md))
2. Then (optionally) edit `/etc/ntfy/server.yml` (see [configuration](config.md))
To run the ntfy server, then just run `ntfy serve` (or `systemctl start ntfy` when using the deb/rpm).
To send messages, use `ntfy publish`. To subscribe to topics, use `ntfy subscribe` (see [subscribing via CLI][subscribe/cli.md]
@ -138,7 +138,7 @@ straight forward to use.
The server exposes its web UI and the API on port 80, so you need to expose that in Docker. To use the persistent
[message cache](config.md#message-cache), you also need to map a volume to `/var/cache/ntfy`. To change other settings,
you should map `/etc/ntfy`, so you can edit `/etc/ntfy/config.yml`.
you should map `/etc/ntfy`, so you can edit `/etc/ntfy/server.yml`.
Basic usage (no cache or additional config):
```
@ -156,7 +156,7 @@ docker run \
serve
```
With other config options (configured via `/etc/ntfy/config.yml`, see [configuration](config.md) for details):
With other config options (configured via `/etc/ntfy/server.yml`, see [configuration](config.md) for details):
```bash
docker run \
-v /etc/ntfy:/etc/ntfy \

View File

@ -13,7 +13,7 @@ if [ "$1" = "configure" ] && [ -d /run/systemd/system ]; then
chmod 700 /var/cache/ntfy
# Hack to change permissions on cache file
configfile="/etc/ntfy/config.yml"
configfile="/etc/ntfy/server.yml"
if [ -f "$configfile" ]; then
cachefile="$(cat "$configfile" | perl -n -e'/^\s*cache-file: ["'"'"']?([^"'"'"']+)["'"'"']?/ && print $1')" # Oh my, see #47
if [ -n "$cachefile" ]; then

View File

@ -4,7 +4,7 @@ set -e
# Delete the config if package is purged
if [ "$1" = "purge" ]; then
id ntfy >/dev/null 2>&1 && userdel ntfy
rm -f /etc/ntfy/config.yml
rm -f /etc/ntfy/server.yml
rmdir /etc/ntfy || true
fi

11
scripts/preinst.sh 100755
View File

@ -0,0 +1,11 @@
#!/bin/sh
set -e
if [ "$1" = "install" ] || [ "$1" = "upgrade" ]; then
# Migration of old to new config file name
oldconfigfile="/etc/ntfy/config.yml"
configfile="/etc/ntfy/server.yml"
if [ -f "$oldconfigfile" ] && [ ! -f "$configfile" ]; then
mv "$oldconfigfile" "$configfile" || true
fi
fi

View File

@ -1,5 +1,4 @@
// Package config provides the main configuration
package config
package server
import (
"time"
@ -53,7 +52,7 @@ type Config struct {
}
// New instantiates a default new config
func New(listenHTTP string) *Config {
func NewConfig(listenHTTP string) *Config {
return &Config{
ListenHTTP: listenHTTP,
ListenHTTPS: "",

View File

@ -1,12 +1,12 @@
package config_test
package server_test
import (
"github.com/stretchr/testify/assert"
"heckel.io/ntfy/config"
"heckel.io/ntfy/server"
"testing"
)
func TestConfig_New(t *testing.T) {
c := config.New(":1234")
c := server.NewConfig(":1234")
assert.Equal(t, ":1234", c.ListenHTTP)
}

View File

@ -9,7 +9,6 @@ import (
"firebase.google.com/go/messaging"
"fmt"
"google.golang.org/api/option"
"heckel.io/ntfy/config"
"heckel.io/ntfy/util"
"html/template"
"io"
@ -28,7 +27,7 @@ import (
// Server is the main server, providing the UI and API for ntfy
type Server struct {
config *config.Config
config *Config
topics map[string]*topic
visitors map[string]*visitor
firebase subscriber
@ -112,7 +111,7 @@ const (
// New instantiates a new Server. It creates the cache and adds a Firebase
// subscriber (if configured).
func New(conf *config.Config) (*Server, error) {
func New(conf *Config) (*Server, error) {
var firebaseSubscriber subscriber
if conf.FirebaseKeyFile != "" {
var err error
@ -138,7 +137,7 @@ func New(conf *config.Config) (*Server, error) {
}, nil
}
func createCache(conf *config.Config) (cache, error) {
func createCache(conf *Config) (cache, error) {
if conf.CacheDuration == 0 {
return newNopCache(), nil
} else if conf.CacheFile != "" {
@ -147,7 +146,7 @@ func createCache(conf *config.Config) (cache, error) {
return newMemCache(), nil
}
func createFirebaseSubscriber(conf *config.Config) (subscriber, error) {
func createFirebaseSubscriber(conf *Config) (subscriber, error) {
fb, err := firebase.NewApp(context.Background(), nil, option.WithCredentialsFile(conf.FirebaseKeyFile))
if err != nil {
return nil, err

View File

@ -1,4 +1,4 @@
# ntfy config file
# ntfy server config file
# Listen address for the HTTP & HTTPS web server. If "listen-https" is set, you must also
# set "key-file" and "cert-file".

View File

@ -2,7 +2,6 @@ package server
import (
"golang.org/x/time/rate"
"heckel.io/ntfy/config"
"heckel.io/ntfy/util"
"sync"
"time"
@ -14,14 +13,14 @@ const (
// visitor represents an API user, and its associated rate.Limiter used for rate limiting
type visitor struct {
config *config.Config
config *Config
limiter *rate.Limiter
subscriptions *util.Limiter
seen time.Time
mu sync.Mutex
}
func newVisitor(conf *config.Config) *visitor {
func newVisitor(conf *Config) *visitor {
return &visitor{
config: conf,
limiter: rate.NewLimiter(rate.Every(conf.VisitorRequestLimitReplenish), conf.VisitorRequestLimitBurst),