This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
# Build Go binary
|
# Build Go binary
|
||||||
FROM golang:1.25-alpine AS builder
|
FROM golang:1.22-alpine AS builder
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
RUN apk add --no-cache ca-certificates tzdata
|
RUN apk add --no-cache ca-certificates tzdata
|
||||||
COPY go.mod ./
|
COPY go.mod ./
|
||||||
@@ -13,7 +13,7 @@ RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/ntfywui ./cmd/ntfy
|
|||||||
FROM binwiederhier/ntfy:latest AS ntfy
|
FROM binwiederhier/ntfy:latest AS ntfy
|
||||||
|
|
||||||
# Runtime
|
# Runtime
|
||||||
FROM alpine:3.23
|
FROM alpine:3.20
|
||||||
RUN apk add --no-cache ca-certificates tzdata \
|
RUN apk add --no-cache ca-certificates tzdata \
|
||||||
&& addgroup -S ntfywui && adduser -S -G ntfywui -h /home/ntfywui ntfywui
|
&& addgroup -S ntfywui && adduser -S -G ntfywui -h /home/ntfywui ntfywui
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|||||||
@@ -62,25 +62,25 @@ func main() {
|
|||||||
logger := log.New(os.Stdout, "", log.LstdFlags)
|
logger := log.New(os.Stdout, "", log.LstdFlags)
|
||||||
|
|
||||||
s := app.NewServer(app.Config{
|
s := app.NewServer(app.Config{
|
||||||
BasePath: strings.TrimRight(*basePath, "/"),
|
BasePath: strings.TrimRight(*basePath, "/"),
|
||||||
DataDir: *dataDir,
|
DataDir: *dataDir,
|
||||||
Secret: secKey,
|
Secret: secKey,
|
||||||
CookieSecure: *cookieSecure,
|
CookieSecure: *cookieSecure,
|
||||||
TrustedProxies: trusted,
|
TrustedProxies: trusted,
|
||||||
NtfyBin: *ntfyBin,
|
NtfyBin: *ntfyBin,
|
||||||
NtfyConfig: *ntfyConfig,
|
NtfyConfig: *ntfyConfig,
|
||||||
NtfyTimeout: *reqTimeout,
|
NtfyTimeout: *reqTimeout,
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
})
|
})
|
||||||
|
|
||||||
httpSrv := &http.Server{
|
httpSrv := &http.Server{
|
||||||
Addr: *listenAddr,
|
Addr: *listenAddr,
|
||||||
Handler: s.Handler(),
|
Handler: s.Handler(),
|
||||||
ReadTimeout: 15 * time.Second,
|
ReadTimeout: 15 * time.Second,
|
||||||
ReadHeaderTimeout: 10 * time.Second,
|
ReadHeaderTimeout: 10 * time.Second,
|
||||||
WriteTimeout: 30 * time.Second,
|
WriteTimeout: 30 * time.Second,
|
||||||
IdleTimeout: 60 * time.Second,
|
IdleTimeout: 60 * time.Second,
|
||||||
MaxHeaderBytes: 1 << 20,
|
MaxHeaderBytes: 1 << 20,
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -45,41 +46,67 @@ func (c *Client) Run(ctx context.Context, args []string, env map[string]string,
|
|||||||
if c.Bin == "" {
|
if c.Bin == "" {
|
||||||
return "", "", 0, errors.New("ntfy binary not set")
|
return "", "", 0, errors.New("ntfy binary not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Many (newer) ntfy versions support `--config/-c` for server-side commands
|
||||||
|
// (serve/user/access/token). Some older builds do not. We try with --config
|
||||||
|
// first (if configured) and fall back to running without it if the binary
|
||||||
|
// rejects the flag.
|
||||||
|
withConfig := args
|
||||||
if c.Config != "" {
|
if c.Config != "" {
|
||||||
args = append([]string{"--config", c.Config}, args...)
|
withConfig = append([]string{"--config", c.Config}, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
tctx := ctx
|
tctx := ctx
|
||||||
var cancel context.CancelFunc
|
var cancel context.CancelFunc
|
||||||
if c.Timeout > 0 {
|
if c.Timeout > 0 {
|
||||||
tctx, cancel = context.WithTimeout(ctx, c.Timeout)
|
tctx, cancel = context.WithTimeout(ctx, c.Timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
}
|
}
|
||||||
cmd := exec.CommandContext(tctx, c.Bin, args...)
|
// helper to execute once
|
||||||
if stdin != "" {
|
runOnce := func(a []string) (string, string, int, error) {
|
||||||
cmd.Stdin = strings.NewReader(stdin)
|
cmd := exec.CommandContext(tctx, c.Bin, a...)
|
||||||
|
if stdin != "" {
|
||||||
|
cmd.Stdin = strings.NewReader(stdin)
|
||||||
|
}
|
||||||
|
var outb, errb bytes.Buffer
|
||||||
|
cmd.Stdout = &outb
|
||||||
|
cmd.Stderr = &errb
|
||||||
|
if env != nil {
|
||||||
|
// inherit env + add/override provided vars
|
||||||
|
cmd.Env = append([]string{}, os.Environ()...)
|
||||||
|
for k, v := range env {
|
||||||
|
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err := cmd.Run()
|
||||||
|
exit := 0
|
||||||
|
if err != nil {
|
||||||
|
var ee *exec.ExitError
|
||||||
|
if errors.As(err, &ee) {
|
||||||
|
exit = ee.ExitCode()
|
||||||
|
} else if errors.Is(err, context.DeadlineExceeded) {
|
||||||
|
return outb.String(), errb.String(), -1, fmt.Errorf("ntfy timeout")
|
||||||
|
} else {
|
||||||
|
return outb.String(), errb.String(), -1, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outb.String(), errb.String(), exit, nil
|
||||||
}
|
}
|
||||||
var outb, errb bytes.Buffer
|
|
||||||
cmd.Stdout = &outb
|
// first attempt (maybe with --config)
|
||||||
cmd.Stderr = &errb
|
out, errOut, exit, err := runOnce(withConfig)
|
||||||
if env != nil {
|
if c.Config == "" {
|
||||||
// inherit env automatically
|
return out, errOut, exit, err
|
||||||
for k, v := range env {
|
}
|
||||||
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v))
|
// fallback for older ntfy binaries that don't know --config
|
||||||
|
if exit != 0 {
|
||||||
|
errTrim := strings.TrimSpace(errOut)
|
||||||
|
if strings.Contains(errTrim, "flag provided but not defined: -config") ||
|
||||||
|
strings.Contains(errTrim, "unknown flag") && strings.Contains(errTrim, "config") {
|
||||||
|
return runOnce(args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := cmd.Run()
|
return out, errOut, exit, err
|
||||||
exit := 0
|
|
||||||
if err != nil {
|
|
||||||
var ee *exec.ExitError
|
|
||||||
if errors.As(err, &ee) {
|
|
||||||
exit = ee.ExitCode()
|
|
||||||
} else if errors.Is(err, context.DeadlineExceeded) {
|
|
||||||
return outb.String(), errb.String(), -1, fmt.Errorf("ntfy timeout")
|
|
||||||
} else {
|
|
||||||
return outb.String(), errb.String(), -1, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return outb.String(), errb.String(), exit, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ListUsers(ctx context.Context) ([]User, error) {
|
func (c *Client) ListUsers(ctx context.Context) ([]User, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user