v0.27.1 packaging update, install and initial config
This commit is contained in:
1 parent
60abc97eb0
commit
4513a9e62b
15 files changed
+431
-110
No files matched your search
@@ -7,7 +7,7 @@ on:
|
|||||||
- Dockerfile
|
- Dockerfile
|
||||||
- go.mod
|
- go.mod
|
||||||
- go.sum
|
- go.sum
|
||||||
- config/logwisp.toml
|
- config/**
|
||||||
- doc/lw.1
|
- doc/lw.1
|
||||||
- deploy/package/**
|
- deploy/package/**
|
||||||
- .github/workflows/package.yml
|
- .github/workflows/package.yml
|
||||||
@@ -17,9 +17,9 @@ on:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
jobs:
|
jobs:
|
||||||
# The AUR package from this commit: makepkg finds the tarball the PKGBUILD
|
# make arch builds the AUR package from this checkout; the package installs
|
||||||
# names next to it and skips the download, then builds, tests and packages.
|
# over an edited configuration make install left, reinstalls keeping it, and
|
||||||
# checkout's safe.directory lasts only its own step; root owns .git here.
|
# goes. makepkg refuses root, so a user that owns the checkout runs it.
|
||||||
arch:
|
arch:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
@@ -28,24 +28,52 @@ jobs:
|
|||||||
- run: pacman -Syu --noconfirm --needed git go
|
- run: pacman -Syu --noconfirm --needed git go
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
- run: |
|
- run: |
|
||||||
ver=$(sed -n 's/^pkgver=//p' deploy/package/arch/PKGBUILD)
|
|
||||||
dir=$(mktemp -d)
|
|
||||||
git -c safe.directory="$PWD" archive --prefix="logwisp-$ver/" -o "$dir/logwisp-$ver.tar.gz" HEAD
|
|
||||||
cp deploy/package/arch/PKGBUILD "$dir"
|
|
||||||
useradd -m build
|
useradd -m build
|
||||||
chown -R build "$dir"
|
chown -R build .
|
||||||
su build -c "cd '$dir' && makepkg --noconfirm"
|
su build -c 'make arch'
|
||||||
pacman -U --noconfirm "$dir"/logwisp-*.pkg.tar.zst
|
|
||||||
- run: |
|
- run: |
|
||||||
|
for f in bin/arch/logwisp-*.pkg.tar.zst; do case $f in *-debug-*) ;; *) pkg=$f ;; esac; done
|
||||||
|
install -D -m 0644 config/logwisp.toml /etc/logwisp/logwisp.toml
|
||||||
|
echo '# edited' >> /etc/logwisp/logwisp.toml
|
||||||
|
pacman -U --noconfirm "$pkg"
|
||||||
|
test -f /etc/logwisp/logwisp.toml.pacnew
|
||||||
lw --version
|
lw --version
|
||||||
test -f /usr/share/bash-completion/completions/lw
|
test -f /usr/share/bash-completion/completions/lw
|
||||||
test -f /usr/share/zsh/site-functions/_lw
|
test -f /usr/share/zsh/site-functions/_lw
|
||||||
test -f /usr/share/fish/vendor_completions.d/lw.fish
|
test -f /usr/share/fish/vendor_completions.d/lw.fish
|
||||||
|
pacman -U --noconfirm "$pkg"
|
||||||
|
grep -q '^# edited' /etc/logwisp/logwisp.toml
|
||||||
|
lw --check -c /etc/logwisp/logwisp.toml
|
||||||
pacman -R --noconfirm logwisp
|
pacman -R --noconfirm logwisp
|
||||||
test ! -e /usr/bin/lw
|
test ! -e /usr/bin/lw
|
||||||
|
test -f /etc/logwisp/logwisp.toml.pacsave
|
||||||
|
# make install SERVICE=no into a home, twice, then lw config init places the
|
||||||
|
# configuration lw reads without -c, and never replaces it
|
||||||
|
user:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 10
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v5
|
||||||
|
- uses: actions/setup-go@v6
|
||||||
|
with:
|
||||||
|
go-version-file: go.mod
|
||||||
|
- run: make release
|
||||||
|
- run: |
|
||||||
|
make install SERVICE=no PREFIX="$HOME/.local"
|
||||||
|
make install SERVICE=no PREFIX="$HOME/.local"
|
||||||
|
export PATH="$HOME/.local/bin:$PATH"
|
||||||
|
test ! -e "$HOME/.local/lib/systemd/system/logwisp.service"
|
||||||
|
test ! -e /etc/logwisp/logwisp.toml
|
||||||
|
lw config init
|
||||||
|
lw --check
|
||||||
|
lw --dump | grep -q 'id = "default_source"'
|
||||||
|
if lw config init; then exit 1; fi
|
||||||
|
make uninstall PREFIX="$HOME/.local"
|
||||||
|
test ! -e "$HOME/.local/bin/lw"
|
||||||
|
test -f "$HOME/.config/logwisp/logwisp.toml"
|
||||||
# make deb on a host with systemd: the service runs from the package's
|
# make deb on a host with systemd: the service runs from the package's
|
||||||
# configuration; remove stops and disables it and leaves the conffile, purge
|
# configuration and survives a reinstall that keeps an edited one; remove
|
||||||
# removes that too
|
# stops and disables it and leaves the conffile, purge removes that too
|
||||||
deb:
|
deb:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
@@ -62,6 +90,11 @@ jobs:
|
|||||||
sudo systemctl enable --now logwisp
|
sudo systemctl enable --now logwisp
|
||||||
sleep 3
|
sleep 3
|
||||||
systemctl is-active logwisp || { sudo journalctl -u logwisp --no-pager; exit 1; }
|
systemctl is-active logwisp || { sudo journalctl -u logwisp --no-pager; exit 1; }
|
||||||
|
echo '# edited' | sudo tee -a /etc/logwisp/logwisp.toml
|
||||||
|
sudo apt-get install --reinstall -y ./bin/logwisp_*.deb
|
||||||
|
grep -q '^# edited' /etc/logwisp/logwisp.toml
|
||||||
|
sleep 3
|
||||||
|
systemctl is-active logwisp || { sudo journalctl -u logwisp --no-pager; exit 1; }
|
||||||
sudo apt-get remove -y logwisp
|
sudo apt-get remove -y logwisp
|
||||||
test ! -e /usr/bin/lw
|
test ! -e /usr/bin/lw
|
||||||
test ! -e /usr/lib/systemd/system/logwisp.service
|
test ! -e /usr/lib/systemd/system/logwisp.service
|
||||||
@@ -70,7 +103,8 @@ jobs:
|
|||||||
test -f /etc/logwisp/logwisp.toml
|
test -f /etc/logwisp/logwisp.toml
|
||||||
sudo apt-get purge -y logwisp
|
sudo apt-get purge -y logwisp
|
||||||
test ! -e /etc/logwisp/logwisp.toml
|
test ! -e /etc/logwisp/logwisp.toml
|
||||||
# BSD make on FreeBSD: build, install, run the rc.d service, uninstall
|
# BSD make on FreeBSD: build, install twice keeping an edited configuration,
|
||||||
|
# run the rc.d service, uninstall
|
||||||
freebsd:
|
freebsd:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
@@ -85,6 +119,9 @@ jobs:
|
|||||||
set -e
|
set -e
|
||||||
make release
|
make release
|
||||||
make install
|
make install
|
||||||
|
echo '# edited' >> /usr/local/etc/logwisp/logwisp.toml
|
||||||
|
make install
|
||||||
|
grep -q '^# edited' /usr/local/etc/logwisp/logwisp.toml
|
||||||
lw --version
|
lw --version
|
||||||
pw groupadd logwisp
|
pw groupadd logwisp
|
||||||
pw useradd logwisp -g logwisp -d /nonexistent -s /usr/sbin/nologin
|
pw useradd logwisp -g logwisp -d /nonexistent -s /usr/sbin/nologin
|
||||||
|
|||||||
@@ -77,9 +77,9 @@ change touches.
|
|||||||
keys must fail at any depth. Set defaults on the options struct before the
|
keys must fail at any depth. Set defaults on the options struct before the
|
||||||
call; `TestEveryPluginRejectsUnknownKeys` covers every registered plugin.
|
call; `TestEveryPluginRejectsUnknownKeys` covers every registered plugin.
|
||||||
- `cmd/lw/cli.go` owns the command line: lw's own flags, and the commands
|
- `cmd/lw/cli.go` owns the command line: lw's own flags, and the commands
|
||||||
table whose groups (`auth`, `tls`, `preset`) share one flag mechanism;
|
table whose groups (`auth`, `tls`, `preset`, `config`) share one flag
|
||||||
`config.Load` takes the parsed `config.Args`. Presets are rows of one table
|
mechanism; `config.Load` takes the parsed `config.Args`. Presets are rows of
|
||||||
in `internal/config/preset.go`.
|
one table in `internal/config/preset.go`.
|
||||||
- Network security has three seams: `tlsx` (TLS configs, certificates made at
|
- Network security has three seams: `tlsx` (TLS configs, certificates made at
|
||||||
startup or by `lw tls`, pins, startup warnings), `authz`, and `netacl`
|
startup or by `lw tls`, pins, startup warnings), `authz`, and `netacl`
|
||||||
(address rules and per-client limits: a listener wraps the socket
|
(address rules and per-client limits: a listener wraps the socket
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ IMAGE_RUN = $(CONTAINER_ENGINE) run --read-only --user 65532:65532 \
|
|||||||
--network none --cap-drop ALL --security-opt no-new-privileges
|
--network none --cap-drop ALL --security-opt no-new-privileges
|
||||||
|
|
||||||
DESTDIR ?=
|
DESTDIR ?=
|
||||||
|
# SERVICE=no installs lw alone: no service files and no system configuration,
|
||||||
|
# which lw config init then places where the user wants it.
|
||||||
|
SERVICE ?= yes
|
||||||
INSTALL_OS_DEFAULT != uname -s
|
INSTALL_OS_DEFAULT != uname -s
|
||||||
INSTALL_OS ?= $(INSTALL_OS_DEFAULT)
|
INSTALL_OS ?= $(INSTALL_OS_DEFAULT)
|
||||||
# FreeBSD keeps everything outside the base system under /usr/local.
|
# FreeBSD keeps everything outside the base system under /usr/local.
|
||||||
@@ -66,7 +69,7 @@ DEB_MAINTAINER ?= Maintainer <maintainer@example.org>
|
|||||||
|
|
||||||
.DEFAULT_GOAL := help
|
.DEFAULT_GOAL := help
|
||||||
|
|
||||||
.PHONY: help check-go build release dev test verify e2e image image-check install uninstall deb completion clean version
|
.PHONY: help check-go build release dev test verify e2e image image-check install uninstall deb arch completion clean version
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Usage: make <target> [VARIABLE=value ...]"
|
@echo "Usage: make <target> [VARIABLE=value ...]"
|
||||||
@@ -87,12 +90,13 @@ help:
|
|||||||
@echo " image-check Run it read-only, offline, without capabilities: --version, then"
|
@echo " image-check Run it read-only, offline, without capabilities: --version, then"
|
||||||
@echo " --check on $(IMAGE_CHECK_CONFIG)"
|
@echo " --check on $(IMAGE_CHECK_CONFIG)"
|
||||||
@echo "Install (build or release first):"
|
@echo "Install (build or release first):"
|
||||||
@echo " install Binary, manual, sample config, service files, shell completion,"
|
@echo " install Binary, manual, shell completion, licence and docs; unless SERVICE=no,"
|
||||||
@echo " licence and docs"
|
@echo " the service files and $(SYSCONFDIR)/logwisp/logwisp.toml (kept if present)"
|
||||||
@echo " uninstall Remove them, keeping $(SYSCONFDIR)/logwisp"
|
@echo " uninstall Remove them, keeping $(SYSCONFDIR)/logwisp"
|
||||||
@echo " deb Package a release build as $(BIN_DIR)/logwisp_VERSION_ARCH.deb (dpkg-deb)"
|
@echo " deb Package a release build as $(BIN_DIR)/logwisp_VERSION_ARCH.deb (dpkg-deb)"
|
||||||
|
@echo " arch Build the Arch package from this working tree in $(BIN_DIR)/arch (makepkg)"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Variables: GO=$(GO) PREFIX=$(PREFIX) SYSCONFDIR=$(SYSCONFDIR) DESTDIR=$(DESTDIR)"
|
@echo "Variables: GO=$(GO) PREFIX=$(PREFIX) SYSCONFDIR=$(SYSCONFDIR) DESTDIR=$(DESTDIR) SERVICE=$(SERVICE)"
|
||||||
@echo " INSTALL_OS=$(INSTALL_OS) (the layout install uses: FreeBSD or any other)"
|
@echo " INSTALL_OS=$(INSTALL_OS) (the layout install uses: FreeBSD or any other)"
|
||||||
@echo " GO_BUILDFLAGS, GO_LDFLAGS (extra go build and linker flags), E2E (scripts),"
|
@echo " GO_BUILDFLAGS, GO_LDFLAGS (extra go build and linker flags), E2E (scripts),"
|
||||||
@echo " CONTAINER_ENGINE, IMAGE, IMAGE_TAG, BUILD_CA, IMAGE_BUILD_FLAGS, IMAGE_CHECK_CONFIG,"
|
@echo " CONTAINER_ENGINE, IMAGE, IMAGE_TAG, BUILD_CA, IMAGE_BUILD_FLAGS, IMAGE_CHECK_CONFIG,"
|
||||||
@@ -131,10 +135,10 @@ verify: test
|
|||||||
$(GO) vet ./...
|
$(GO) vet ./...
|
||||||
@base='$(GOFMT_BASE)'; \
|
@base='$(GOFMT_BASE)'; \
|
||||||
if [ -n "$$base" ] && fork=$$(git merge-base "$$base" HEAD 2>/dev/null); then \
|
if [ -n "$$base" ] && fork=$$(git merge-base "$$base" HEAD 2>/dev/null); then \
|
||||||
files=$$( { git diff --name-only --find-renames=100% --diff-filter=dr "$$fork" -- cmd internal; \
|
files=$$( { git diff --name-only --find-renames=100% --diff-filter=dr "$$fork" -- cmd config internal; \
|
||||||
git ls-files --others --exclude-standard -- cmd internal; } | grep '\.go$$' || true); \
|
git ls-files --others --exclude-standard -- cmd config internal; } | grep '\.go$$' || true); \
|
||||||
else \
|
else \
|
||||||
files=$$(find cmd internal -name '*.go'); \
|
files=$$(find cmd config internal -name '*.go'); \
|
||||||
fi; \
|
fi; \
|
||||||
bad=$$( [ -z "$$files" ] || "$$($(GO) env GOROOT)/bin/gofmt" -l $$files ); \
|
bad=$$( [ -z "$$files" ] || "$$($(GO) env GOROOT)/bin/gofmt" -l $$files ); \
|
||||||
if [ -n "$$bad" ]; then echo "gofmt -l reports:"; echo "$$bad"; exit 1; fi
|
if [ -n "$$bad" ]; then echo "gofmt -l reports:"; echo "$$bad"; exit 1; fi
|
||||||
@@ -192,10 +196,11 @@ image-check:
|
|||||||
|
|
||||||
# install stages what a package ships and compiles nothing, so a packager owns
|
# install stages what a package ships and compiles nothing, so a packager owns
|
||||||
# the build flags. The service files get the installed paths substituted; a
|
# the build flags. The service files get the installed paths substituted; a
|
||||||
# configuration already in place is kept.
|
# configuration already in place is kept, on every system alike.
|
||||||
install:
|
install:
|
||||||
@set -eu; \
|
@set -eu; \
|
||||||
[ -x $(BIN_DIR)/$(BINARY) ] || { echo "no $(BIN_DIR)/$(BINARY): run make build or make release first" >&2; exit 1; }; \
|
[ -x $(BIN_DIR)/$(BINARY) ] || { echo "no $(BIN_DIR)/$(BINARY): run make build or make release first" >&2; exit 1; }; \
|
||||||
|
case '$(SERVICE)' in yes|no) ;; *) echo "SERVICE is yes or no, not '$(SERVICE)'" >&2; exit 2 ;; esac; \
|
||||||
put() { install -d -m 0755 "$${3%/*}"; install -m "$$1" "$$2" "$$3"; echo "install $$3"; }; \
|
put() { install -d -m 0755 "$${3%/*}"; install -m "$$1" "$$2" "$$3"; echo "install $$3"; }; \
|
||||||
sub() { install -d -m 0755 "$${3%/*}"; \
|
sub() { install -d -m 0755 "$${3%/*}"; \
|
||||||
sed -e 's|@BINDIR@|$(BINDIR)|g' -e 's|@SYSCONFDIR@|$(SYSCONFDIR)|g' -e 's|%%BINDIR%%|$(BINDIR)|g' \
|
sed -e 's|@BINDIR@|$(BINDIR)|g' -e 's|@SYSCONFDIR@|$(SYSCONFDIR)|g' -e 's|%%BINDIR%%|$(BINDIR)|g' \
|
||||||
@@ -209,14 +214,13 @@ install:
|
|||||||
put 0644 $(PKG_DIR)/completion/lw.fish "$$root$(FISHCOMPDIR)/lw.fish"; \
|
put 0644 $(PKG_DIR)/completion/lw.fish "$$root$(FISHCOMPDIR)/lw.fish"; \
|
||||||
put 0644 LICENSE "$$root$(LICENSEDIR)/LICENSE"; \
|
put 0644 LICENSE "$$root$(LICENSEDIR)/LICENSE"; \
|
||||||
for src in README.md doc/*.md; do put 0644 "$$src" "$$root$(DOCDIR)/$$src"; done; \
|
for src in README.md doc/*.md; do put 0644 "$$src" "$$root$(DOCDIR)/$$src"; done; \
|
||||||
|
if [ '$(SERVICE)' = no ]; then echo "skip the service and $$etc (SERVICE=no): lw config init writes a configuration"; exit 0; fi; \
|
||||||
|
if [ -e "$$etc/logwisp.toml" ]; then echo "keep $$etc/logwisp.toml"; \
|
||||||
|
else put 0644 config/logwisp.toml "$$etc/logwisp.toml"; fi; \
|
||||||
case '$(INSTALL_OS)' in \
|
case '$(INSTALL_OS)' in \
|
||||||
FreeBSD) \
|
FreeBSD) \
|
||||||
put 0644 config/logwisp.toml "$$etc/logwisp.toml.sample"; \
|
|
||||||
if [ -z "$$root" ] && [ ! -e "$$etc/logwisp.toml" ]; then put 0644 config/logwisp.toml "$$etc/logwisp.toml"; fi; \
|
|
||||||
sub 0755 $(PKG_DIR)/logwisp.rc "$$root$(PREFIX)/etc/rc.d/logwisp" ;; \
|
sub 0755 $(PKG_DIR)/logwisp.rc "$$root$(PREFIX)/etc/rc.d/logwisp" ;; \
|
||||||
*) \
|
*) \
|
||||||
if [ -e "$$etc/logwisp.toml" ]; then echo "keep $$etc/logwisp.toml"; \
|
|
||||||
else put 0644 config/logwisp.toml "$$etc/logwisp.toml"; fi; \
|
|
||||||
sub 0644 $(PKG_DIR)/logwisp.service "$$root$(PREFIX)/lib/systemd/system/logwisp.service"; \
|
sub 0644 $(PKG_DIR)/logwisp.service "$$root$(PREFIX)/lib/systemd/system/logwisp.service"; \
|
||||||
sub 0644 $(PKG_DIR)/logwisp.sysusers "$$root$(PREFIX)/lib/sysusers.d/logwisp.conf"; \
|
sub 0644 $(PKG_DIR)/logwisp.sysusers "$$root$(PREFIX)/lib/sysusers.d/logwisp.conf"; \
|
||||||
sub 0644 $(PKG_DIR)/logwisp.tmpfiles "$$root$(PREFIX)/lib/tmpfiles.d/logwisp.conf" ;; \
|
sub 0644 $(PKG_DIR)/logwisp.tmpfiles "$$root$(PREFIX)/lib/tmpfiles.d/logwisp.conf" ;; \
|
||||||
@@ -228,14 +232,14 @@ uninstall:
|
|||||||
"$$root$(BASHCOMPDIR)/lw" "$$root$(ZSHCOMPDIR)/_lw" "$$root$(FISHCOMPDIR)/lw.fish" \
|
"$$root$(BASHCOMPDIR)/lw" "$$root$(ZSHCOMPDIR)/_lw" "$$root$(FISHCOMPDIR)/lw.fish" \
|
||||||
"$$root$(PREFIX)/lib/systemd/system/logwisp.service" \
|
"$$root$(PREFIX)/lib/systemd/system/logwisp.service" \
|
||||||
"$$root$(PREFIX)/lib/sysusers.d/logwisp.conf" "$$root$(PREFIX)/lib/tmpfiles.d/logwisp.conf" \
|
"$$root$(PREFIX)/lib/sysusers.d/logwisp.conf" "$$root$(PREFIX)/lib/tmpfiles.d/logwisp.conf" \
|
||||||
"$$root$(PREFIX)/etc/rc.d/logwisp" "$$root$(SYSCONFDIR)/logwisp/logwisp.toml.sample"; do \
|
"$$root$(PREFIX)/etc/rc.d/logwisp"; do \
|
||||||
if [ -e "$$f" ]; then rm -f "$$f"; echo "remove $$f"; fi; \
|
if [ -e "$$f" ]; then rm -f "$$f"; echo "remove $$f"; fi; \
|
||||||
done; \
|
done; \
|
||||||
for d in "$$root$(DOCDIR)" "$$root$(LICENSEDIR)"; do \
|
for d in "$$root$(DOCDIR)" "$$root$(LICENSEDIR)"; do \
|
||||||
case "$$d" in */logwisp) ;; *) echo "keep $$d (not a logwisp directory)"; continue ;; esac; \
|
case "$$d" in */logwisp) ;; *) echo "keep $$d (not a logwisp directory)"; continue ;; esac; \
|
||||||
if [ -d "$$d" ]; then rm -rf "$$d"; echo "remove $$d"; fi; \
|
if [ -d "$$d" ]; then rm -rf "$$d"; echo "remove $$d"; fi; \
|
||||||
done; \
|
done; \
|
||||||
echo "keep $$root$(SYSCONFDIR)/logwisp (configuration and credentials)"
|
if [ -d "$$root$(SYSCONFDIR)/logwisp" ]; then echo "keep $$root$(SYSCONFDIR)/logwisp (configuration and credentials)"; fi
|
||||||
|
|
||||||
# deb stages install in Debian's layout and takes the architecture from the
|
# deb stages install in Debian's layout and takes the architecture from the
|
||||||
# binary. An untagged or modified tree's version sorts below every release and
|
# binary. An untagged or modified tree's version sorts below every release and
|
||||||
@@ -268,7 +272,23 @@ deb: release
|
|||||||
sed -e 's/^$$/./' -e 's/^/ /' $(PKG_DIR)/freebsd/pkg-descr; } > "$$stage/DEBIAN/control"; \
|
sed -e 's/^$$/./' -e 's/^/ /' $(PKG_DIR)/freebsd/pkg-descr; } > "$$stage/DEBIAN/control"; \
|
||||||
dpkg-deb --root-owner-group --build "$$stage" "$(BIN_DIR)/logwisp_$${version}_$$arch.deb"
|
dpkg-deb --root-owner-group --build "$$stage" "$(BIN_DIR)/logwisp_$${version}_$$arch.deb"
|
||||||
|
|
||||||
|
# arch builds the PKGBUILD from this working tree, tracked and new files, as
|
||||||
|
# the release tarball it names; no tag or download is needed. Untagged, the
|
||||||
|
# version is 0.rCOUNT.gHASH, below every release and rising with each commit.
|
||||||
|
# The package and build tree stay in bin/arch whatever makepkg.conf says.
|
||||||
|
arch:
|
||||||
|
@set -eu; dir=$(BIN_DIR)/arch; [ ! -d "$$dir" ] || chmod -R u+w "$$dir"; rm -rf "$$dir"; mkdir -p "$$dir"; \
|
||||||
|
ver=$$(echo '$(VERSION)' | sed -e 's/^v//' -e 's/-\([0-9][0-9]*\)-g/.r\1.g/' -e 's/-/./g'); \
|
||||||
|
case '$(VERSION)' in v[0-9]*) ;; *) ver="0.r$$(git rev-list --count HEAD).g$$ver" ;; esac; \
|
||||||
|
git ls-files -z --cached --others --exclude-standard | tar --null -T - --ignore-failed-read \
|
||||||
|
--transform "s,^,logwisp-$$ver/,S" -czf "$$dir/logwisp-$$ver.tar.gz"; \
|
||||||
|
sed "s/^pkgver=.*/pkgver=$$ver/" $(PKG_DIR)/arch/PKGBUILD > "$$dir/PKGBUILD"; \
|
||||||
|
cd "$$dir"; export PKGDEST="$$PWD" BUILDDIR="$$PWD"; makepkg; \
|
||||||
|
echo "install or reinstall: sudo pacman -U $$(makepkg --packagelist | grep -v -- -debug-)"
|
||||||
|
|
||||||
|
# A toolchain go downloaded into make arch's GOPATH is read-only.
|
||||||
clean:
|
clean:
|
||||||
|
[ ! -d $(BIN_DIR) ] || chmod -R u+w $(BIN_DIR)
|
||||||
rm -rf $(BIN_DIR)
|
rm -rf $(BIN_DIR)
|
||||||
|
|
||||||
version:
|
version:
|
||||||
|
|||||||
@@ -186,8 +186,11 @@ docker run --rm --read-only --cap-drop ALL --security-opt no-new-privileges \
|
|||||||
```
|
```
|
||||||
|
|
||||||
`sudo make install` installs the binary, the manual, shell completion, a
|
`sudo make install` installs the binary, the manual, shell completion, a
|
||||||
sample configuration and a systemd unit or FreeBSD rc.d script; `make deb`
|
systemd unit or FreeBSD rc.d script and its configuration; `make deb` and
|
||||||
packages them for Debian and Ubuntu. See [Installation](doc/installation.md).
|
`make arch` package them for Debian, Ubuntu and Arch. Without a service,
|
||||||
|
`make install SERVICE=no PREFIX="$HOME/.local"` installs `lw` alone and
|
||||||
|
`lw config init` writes the annotated configuration it reads. See
|
||||||
|
[Installation](doc/installation.md).
|
||||||
|
|
||||||
## System Requirements
|
## System Requirements
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,15 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
shipped "github.com/lixenwraith/logwisp/config"
|
||||||
"github.com/lixenwraith/logwisp/internal/config"
|
"github.com/lixenwraith/logwisp/internal/config"
|
||||||
|
|
||||||
"github.com/lixenwraith/toml"
|
"github.com/lixenwraith/toml"
|
||||||
@@ -37,6 +41,8 @@ var commands = []command{
|
|||||||
"Files are never overwritten; keys are written mode 0600.", tlsCommands},
|
"Files are never overwritten; keys are written mode 0600.", tlsCommands},
|
||||||
{"preset", "Show the pipeline a preset makes, as TOML",
|
{"preset", "Show the pipeline a preset makes, as TOML",
|
||||||
"lw --preset NAME,key=value runs one; flags here are its keys.", presetCommands()},
|
"lw --preset NAME,key=value runs one; flags here are its keys.", presetCommands()},
|
||||||
|
{"config", "Place the annotated default configuration",
|
||||||
|
"Files are never overwritten; lw --dump prints the effective configuration.", configCommands},
|
||||||
}
|
}
|
||||||
|
|
||||||
// shorts are lw's one-letter flags, each its long flag in every command that
|
// shorts are lw's one-letter flags, each its long flag in every command that
|
||||||
@@ -287,3 +293,41 @@ func presetCommands() []subcommand {
|
|||||||
}
|
}
|
||||||
return subs
|
return subs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var configCommands = []subcommand{
|
||||||
|
{"init", "[--out FILE]",
|
||||||
|
"Write the annotated default configuration, to edit and run",
|
||||||
|
nil, defineConfigInit},
|
||||||
|
}
|
||||||
|
|
||||||
|
func defineConfigInit(flags *flag.FlagSet) func(stdout, stderr io.Writer) error {
|
||||||
|
out := flags.String("out", "", "`file` to write (default: ~/.config/logwisp/logwisp.toml)")
|
||||||
|
return func(_, stderr io.Writer) error {
|
||||||
|
user, err := config.UserFile()
|
||||||
|
path := cmp.Or(*out, user)
|
||||||
|
if path == "" {
|
||||||
|
return fmt.Errorf("no home directory for the default file (%v): name one with --out", err)
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := writeNew(path, shipped.Sample, 0o644); errors.Is(err, fs.ErrExist) {
|
||||||
|
if fi, err := os.Stat(path); err == nil && fi.IsDir() {
|
||||||
|
return fmt.Errorf("%s is a directory: name the file, as in %s", path, filepath.Join(path, "logwisp.toml"))
|
||||||
|
}
|
||||||
|
return fmt.Errorf("%s exists; remove it to replace it", path)
|
||||||
|
} else if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// -c refuses a path that climbs out with ..; an absolute one loads anywhere
|
||||||
|
if abs, err := filepath.Abs(path); err == nil {
|
||||||
|
path = abs
|
||||||
|
}
|
||||||
|
if found, err := filepath.Abs(config.DefaultPath()); err == nil && found == path {
|
||||||
|
fmt.Fprintf(stderr, "wrote %s; lw reads it without -c\n", path)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(stderr, "wrote %s; run it with lw -c %s\n", path, path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
shipped "github.com/lixenwraith/logwisp/config"
|
||||||
"github.com/lixenwraith/logwisp/internal/config"
|
"github.com/lixenwraith/logwisp/internal/config"
|
||||||
"github.com/lixenwraith/logwisp/internal/testutil"
|
"github.com/lixenwraith/logwisp/internal/testutil"
|
||||||
"github.com/lixenwraith/logwisp/internal/tlsx"
|
"github.com/lixenwraith/logwisp/internal/tlsx"
|
||||||
@@ -261,6 +262,35 @@ func TestTLSCommandsIssueAVerifiableChain(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lw config init writes the shipped configuration to the file lw reads without
|
||||||
|
// -c, or to --out, says how lw finds it, and never replaces a file
|
||||||
|
func TestConfigInitWritesTheShippedFileOnce(t *testing.T) {
|
||||||
|
home := t.TempDir()
|
||||||
|
t.Setenv("HOME", home)
|
||||||
|
t.Setenv("LOGWISP_CONFIG_FILE", "")
|
||||||
|
t.Setenv("LOGWISP_CONFIG_DIR", "")
|
||||||
|
other := filepath.Join(t.TempDir(), "etc", "logwisp.toml")
|
||||||
|
for _, c := range []struct {
|
||||||
|
args []string
|
||||||
|
hint string
|
||||||
|
}{
|
||||||
|
{[]string{"init"}, "lw reads it without -c"},
|
||||||
|
{[]string{"init", "--out", other}, "lw -c " + other},
|
||||||
|
} {
|
||||||
|
if code, _, stderr := runCommand(t, "config", c.args...); code != 0 || !strings.Contains(stderr, c.hint) {
|
||||||
|
t.Fatalf("lw config %v: exit %d: %s", c.args, code, stderr)
|
||||||
|
}
|
||||||
|
if code, _, stderr := runCommand(t, "config", c.args...); code != 1 || !strings.Contains(stderr, "exists") {
|
||||||
|
t.Fatalf("lw config %v again: exit %d: %s", c.args, code, stderr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, path := range []string{filepath.Join(home, ".config", "logwisp", "logwisp.toml"), other} {
|
||||||
|
if data, err := os.ReadFile(path); err != nil || !bytes.Equal(data, shipped.Sample) {
|
||||||
|
t.Errorf("%s is not the shipped configuration: %v", path, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var update = flag.Bool("update", false, "rewrite the completion scripts: make completion")
|
var update = flag.Bool("update", false, "rewrite the completion scripts: make completion")
|
||||||
|
|
||||||
// The installed completion scripts are what lw's tables generate
|
// The installed completion scripts are what lw's tables generate
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// Package config ships logwisp.toml, the annotated default configuration that
|
||||||
|
// make install and the packages place and lw config init writes.
|
||||||
|
package config
|
||||||
|
|
||||||
|
import _ "embed"
|
||||||
|
|
||||||
|
//go:embed logwisp.toml
|
||||||
|
var Sample []byte
|
||||||
@@ -150,12 +150,29 @@ preset:*)
|
|||||||
'(-h --help)'{-h,--help}'[print the flags]' ;;
|
'(-h --help)'{-h,--help}'[print the flags]' ;;
|
||||||
esac
|
esac
|
||||||
return ;;
|
return ;;
|
||||||
|
config:2) ;;
|
||||||
|
config:3)
|
||||||
|
described=(
|
||||||
|
'init:Write the annotated default configuration, to edit and run'
|
||||||
|
)
|
||||||
|
_describe -t commands 'lw config command' described
|
||||||
|
return ;;
|
||||||
|
config:*)
|
||||||
|
shift 2 words
|
||||||
|
(( CURRENT -= 2 ))
|
||||||
|
case ${words[1]} in
|
||||||
|
init) _arguments -S \
|
||||||
|
'--out=[file to write (default: ~/.config/logwisp/logwisp.toml)]:value:_default' \
|
||||||
|
'(-h --help)'{-h,--help}'[print the flags]' ;;
|
||||||
|
esac
|
||||||
|
return ;;
|
||||||
esac
|
esac
|
||||||
if (( CURRENT == 2 )) && [[ $PREFIX != -* ]]; then
|
if (( CURRENT == 2 )) && [[ $PREFIX != -* ]]; then
|
||||||
described=(
|
described=(
|
||||||
'auth:SCRAM users, bearer tokens, tcp sink viewing'
|
'auth:SCRAM users, bearer tokens, tcp sink viewing'
|
||||||
'tls:A CA and certificates for TLS and mTLS'
|
'tls:A CA and certificates for TLS and mTLS'
|
||||||
'preset:Show the pipeline a preset makes, as TOML'
|
'preset:Show the pipeline a preset makes, as TOML'
|
||||||
|
'config:Place the annotated default configuration'
|
||||||
'help:Print the help and exit'
|
'help:Print the help and exit'
|
||||||
)
|
)
|
||||||
_describe -t commands 'lw command' described
|
_describe -t commands 'lw command' described
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ _lw() {
|
|||||||
elif [[ $prev == = ]]; then prev=${COMP_WORDS[i-2]}
|
elif [[ $prev == = ]]; then prev=${COMP_WORDS[i-2]}
|
||||||
fi
|
fi
|
||||||
case ${COMP_WORDS[1]}:$i in
|
case ${COMP_WORDS[1]}:$i in
|
||||||
*:1) words='--auto_reload --check -t --color --config -c --dump --filter --format --heartbeat --help -h --logging.console.target --logging.file.directory --logging.file.max_size_mb --logging.file.max_total_size_mb --logging.file.name --logging.file.retention_hours --logging.format --logging.level --logging.output --logging.sanitization --pipeline --preset -p --quiet -q --rate-limit --sink --source --status_reporter --version -V auth tls preset help' ;;
|
*:1) words='--auto_reload --check -t --color --config -c --dump --filter --format --heartbeat --help -h --logging.console.target --logging.file.directory --logging.file.max_size_mb --logging.file.max_total_size_mb --logging.file.name --logging.file.retention_hours --logging.format --logging.level --logging.output --logging.sanitization --pipeline --preset -p --quiet -q --rate-limit --sink --source --status_reporter --version -V auth tls preset config help' ;;
|
||||||
auth:2) words='add-user remove-user token stream' ;;
|
auth:2) words='add-user remove-user token stream' ;;
|
||||||
auth:*)
|
auth:*)
|
||||||
case ${COMP_WORDS[2]} in
|
case ${COMP_WORDS[2]} in
|
||||||
@@ -80,6 +80,15 @@ _lw() {
|
|||||||
esac
|
esac
|
||||||
words='--allow --cert --client_ca --deny --format --hosts --issuer_cert --issuer_key --key --listen --out --tls --transport --users --help -h' ;;
|
words='--allow --cert --client_ca --deny --format --hosts --issuer_cert --issuer_key --key --listen --out --tls --transport --users --help -h' ;;
|
||||||
esac ;;
|
esac ;;
|
||||||
|
config:2) words='init' ;;
|
||||||
|
config:*)
|
||||||
|
case ${COMP_WORDS[2]} in
|
||||||
|
init)
|
||||||
|
case $prev in
|
||||||
|
--out|-out) COMPREPLY=(); return ;;
|
||||||
|
esac
|
||||||
|
words='--out --help -h' ;;
|
||||||
|
esac ;;
|
||||||
*)
|
*)
|
||||||
case $prev in
|
case $prev in
|
||||||
--logging.file.directory) _lw_reply -d; return ;;
|
--logging.file.directory) _lw_reply -d; return ;;
|
||||||
|
|||||||
@@ -12,34 +12,35 @@ set -l __lw_first 'test (count (commandline -opc)) -eq 1'
|
|||||||
complete -c lw -n $__lw_first -a auth -d 'SCRAM users, bearer tokens, tcp sink viewing'
|
complete -c lw -n $__lw_first -a auth -d 'SCRAM users, bearer tokens, tcp sink viewing'
|
||||||
complete -c lw -n $__lw_first -a tls -d 'A CA and certificates for TLS and mTLS'
|
complete -c lw -n $__lw_first -a tls -d 'A CA and certificates for TLS and mTLS'
|
||||||
complete -c lw -n $__lw_first -a preset -d 'Show the pipeline a preset makes, as TOML'
|
complete -c lw -n $__lw_first -a preset -d 'Show the pipeline a preset makes, as TOML'
|
||||||
|
complete -c lw -n $__lw_first -a config -d 'Place the annotated default configuration'
|
||||||
complete -c lw -n $__lw_first -a help -d 'Print the help and exit'
|
complete -c lw -n $__lw_first -a help -d 'Print the help and exit'
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l auto_reload
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l auto_reload
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l check -o t
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l check -o t
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l color
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l color
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l config -o c -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l config -o c -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l dump
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l dump
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l filter -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l filter -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l format -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l format -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l heartbeat -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l heartbeat -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l help -o h
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l help -o h
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l logging.console.target -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l logging.console.target -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l logging.file.directory -x -a '(__fish_complete_directories)'
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l logging.file.directory -x -a '(__fish_complete_directories)'
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l logging.file.max_size_mb -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l logging.file.max_size_mb -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l logging.file.max_total_size_mb -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l logging.file.max_total_size_mb -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l logging.file.name -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l logging.file.name -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l logging.file.retention_hours -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l logging.file.retention_hours -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l logging.format -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l logging.format -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l logging.level -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l logging.level -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l logging.output -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l logging.output -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l logging.sanitization -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l logging.sanitization -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l pipeline -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l pipeline -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l preset -o p -x -a 'pipe tail serve edge aggregator'
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l preset -o p -x -a 'pipe tail serve edge aggregator'
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l quiet -o q
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l quiet -o q
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l rate-limit -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l rate-limit -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l sink -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l sink -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l source -r -F
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l source -r -F
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l status_reporter
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l status_reporter
|
||||||
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset' -l version -o V
|
complete -c lw -n 'not __lw_in auth; and not __lw_in tls; and not __lw_in preset; and not __lw_in config' -l version -o V
|
||||||
|
|
||||||
complete -c lw -n '__lw_in auth; and test (count (commandline -opc)) -eq 2' -a add-user -d 'Add a user to a credentials file, or replace its password'
|
complete -c lw -n '__lw_in auth; and test (count (commandline -opc)) -eq 2' -a add-user -d 'Add a user to a credentials file, or replace its password'
|
||||||
complete -c lw -n '__lw_in auth; and test (count (commandline -opc)) -eq 2' -a remove-user -d 'Remove a user from a credentials file'
|
complete -c lw -n '__lw_in auth; and test (count (commandline -opc)) -eq 2' -a remove-user -d 'Remove a user from a credentials file'
|
||||||
@@ -143,3 +144,7 @@ complete -c lw -n '__lw_in preset aggregator' -l tls -r -F -d 'self|issuer|files
|
|||||||
complete -c lw -n '__lw_in preset aggregator' -l transport -r -F -d 'tcp|http: tcp_chain or http_chain'
|
complete -c lw -n '__lw_in preset aggregator' -l transport -r -F -d 'tcp|http: tcp_chain or http_chain'
|
||||||
complete -c lw -n '__lw_in preset aggregator' -l users -r -F -d 'credentials file (lw auth add-user): edges log in with SCRAM'
|
complete -c lw -n '__lw_in preset aggregator' -l users -r -F -d 'credentials file (lw auth add-user): edges log in with SCRAM'
|
||||||
complete -c lw -n '__lw_in preset aggregator' -l help -o h -d 'print the flags'
|
complete -c lw -n '__lw_in preset aggregator' -l help -o h -d 'print the flags'
|
||||||
|
|
||||||
|
complete -c lw -n '__lw_in config; and test (count (commandline -opc)) -eq 2' -a init -d 'Write the annotated default configuration, to edit and run'
|
||||||
|
complete -c lw -n '__lw_in config init' -l out -r -F -d 'file to write (default: ~/.config/logwisp/logwisp.toml)'
|
||||||
|
complete -c lw -n '__lw_in config init' -l help -o h -d 'print the flags'
|
||||||
+25
-3
@@ -9,6 +9,7 @@ lw --dump [options]
|
|||||||
lw auth COMMAND [flags]
|
lw auth COMMAND [flags]
|
||||||
lw tls COMMAND [flags]
|
lw tls COMMAND [flags]
|
||||||
lw preset NAME [flags]
|
lw preset NAME [flags]
|
||||||
|
lw config init [--out FILE]
|
||||||
lw help | -h | --help
|
lw help | -h | --help
|
||||||
lw -V | --version
|
lw -V | --version
|
||||||
```
|
```
|
||||||
@@ -21,7 +22,9 @@ service.
|
|||||||
A [preset](#presets) builds a common pipeline from a few keys. `lw auth`
|
A [preset](#presets) builds a common pipeline from a few keys. `lw auth`
|
||||||
manages SCRAM credentials and logs in to `scram` listeners
|
manages SCRAM credentials and logs in to `scram` listeners
|
||||||
([below](#lw-auth)); `lw tls` makes a certificate authority and certificates
|
([below](#lw-auth)); `lw tls` makes a certificate authority and certificates
|
||||||
([below](#lw-tls)). A command is recognized only as the first argument.
|
([below](#lw-tls)); `lw config init` writes the annotated default
|
||||||
|
configuration ([below](#lw-config)). A command is recognized only as the
|
||||||
|
first argument.
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
@@ -43,8 +46,7 @@ manages SCRAM credentials and logs in to `scram` listeners
|
|||||||
`--password-file`); configuration keys, spec keys and preset keys keep
|
`--password-file`); configuration keys, spec keys and preset keys keep
|
||||||
TOML's `_` and `.` (`--status_reporter`, `--sink http,tls.cert_file=F`,
|
TOML's `_` and `.` (`--status_reporter`, `--sink http,tls.cert_file=F`,
|
||||||
`lw preset edge --password_file F`).
|
`lw preset edge --password_file F`).
|
||||||
- `lw auth`, `lw tls` and `lw preset` also take a long option after one dash
|
- The commands also take a long option after one dash (`-user NAME`).
|
||||||
(`-user NAME`), as earlier releases documented.
|
|
||||||
|
|
||||||
Any scalar configuration key is settable as a flag using its TOML path;
|
Any scalar configuration key is settable as a flag using its TOML path;
|
||||||
pipelines have [their own flags](#pipelines):
|
pipelines have [their own flags](#pipelines):
|
||||||
@@ -540,3 +542,23 @@ lw tls ca --dir /etc/logwisp/pki
|
|||||||
lw tls cert --ca-dir /etc/logwisp/pki --name agg.example.org --server
|
lw tls cert --ca-dir /etc/logwisp/pki --name agg.example.org --server
|
||||||
lw tls cert --ca-dir /etc/logwisp/pki --name edge-01 --client
|
lw tls cert --ca-dir /etc/logwisp/pki --name edge-01 --client
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## `lw config`
|
||||||
|
|
||||||
|
```
|
||||||
|
lw config init [--out FILE]
|
||||||
|
```
|
||||||
|
|
||||||
|
`init` writes the annotated configuration that ships as
|
||||||
|
`config/logwisp.toml`, every option with its default, to edit and run. It
|
||||||
|
never replaces a file (remove one to replace it). Without `--out` it writes
|
||||||
|
`~/.config/logwisp/logwisp.toml`, the file lw reads without `-c` unless a
|
||||||
|
`LOGWISP_CONFIG_*` variable names another; with that file in place, lw
|
||||||
|
without pipeline options runs its pipelines rather than filtering stdin.
|
||||||
|
Any other path is run with `-c FILE`; lw prints which applies. `lw --dump` prints the
|
||||||
|
effective configuration instead, flags and environment included.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lw config init
|
||||||
|
sudo lw config init --out /usr/local/etc/logwisp/logwisp.toml
|
||||||
|
```
|
||||||
+111
-23
@@ -42,7 +42,8 @@ The Makefile works with GNU make and BSD make alike. Targets:
|
|||||||
- Container
|
- Container
|
||||||
- `make image`, `make image-check`: see [Container Image](#container-image)
|
- `make image`, `make image-check`: see [Container Image](#container-image)
|
||||||
- Install
|
- Install
|
||||||
- `make install`, `make uninstall`, `make deb`: see [Installing](#installing)
|
- `make install`, `make uninstall`, `make deb`, `make arch`: see
|
||||||
|
[Installing](#installing)
|
||||||
|
|
||||||
Variables:
|
Variables:
|
||||||
|
|
||||||
@@ -64,8 +65,9 @@ checkout.
|
|||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
`make install` copies what a package ships and compiles nothing, so build
|
`make install` copies what a package ships and compiles nothing, so build
|
||||||
first. It honours `DESTDIR`, `PREFIX`, `SYSCONFDIR` and `BINDIR` (default
|
first. It honours `DESTDIR`, `PREFIX`, `SYSCONFDIR`, `BINDIR` (default
|
||||||
`$PREFIX/bin`, the path the systemd unit and the rc.d script run `lw` from):
|
`$PREFIX/bin`, the path the systemd unit and the rc.d script run `lw` from)
|
||||||
|
and `SERVICE`:
|
||||||
|
|
||||||
- Linux defaults: `PREFIX=/usr`, `SYSCONFDIR=/etc`. Outside a package
|
- Linux defaults: `PREFIX=/usr`, `SYSCONFDIR=/etc`. Outside a package
|
||||||
manager, prefer `PREFIX=/usr/local`; systemd reads units, sysusers and
|
manager, prefer `PREFIX=/usr/local`; systemd reads units, sysusers and
|
||||||
@@ -73,6 +75,8 @@ first. It honours `DESTDIR`, `PREFIX`, `SYSCONFDIR` and `BINDIR` (default
|
|||||||
- FreeBSD defaults: `PREFIX=/usr/local`, `SYSCONFDIR=/usr/local/etc`.
|
- FreeBSD defaults: `PREFIX=/usr/local`, `SYSCONFDIR=/usr/local/etc`.
|
||||||
- `INSTALL_OS` (default: `uname -s`) picks the layout, so
|
- `INSTALL_OS` (default: `uname -s`) picks the layout, so
|
||||||
`INSTALL_OS=FreeBSD DESTDIR=...` stages the FreeBSD one on another system.
|
`INSTALL_OS=FreeBSD DESTDIR=...` stages the FreeBSD one on another system.
|
||||||
|
- `SERVICE`: `yes` (default) adds the service and its configuration; `no`
|
||||||
|
installs `lw` alone ([Without a Service](#without-a-service)).
|
||||||
- `BASHCOMPDIR`, `ZSHCOMPDIR`, `FISHCOMPDIR`: where the shell completion
|
- `BASHCOMPDIR`, `ZSHCOMPDIR`, `FISHCOMPDIR`: where the shell completion
|
||||||
goes, by default `$PREFIX/share/bash-completion/completions`,
|
goes, by default `$PREFIX/share/bash-completion/completions`,
|
||||||
`$PREFIX/share/zsh/site-functions` (`/usr/share/zsh/vendor-completions`
|
`$PREFIX/share/zsh/site-functions` (`/usr/share/zsh/vendor-completions`
|
||||||
@@ -84,7 +88,7 @@ make release
|
|||||||
sudo make install PREFIX=/usr/local
|
sudo make install PREFIX=/usr/local
|
||||||
```
|
```
|
||||||
|
|
||||||
Every system gets:
|
Every install gets:
|
||||||
|
|
||||||
- `$BINDIR/lw` and the manual `$PREFIX/share/man/man1/lw.1`
|
- `$BINDIR/lw` and the manual `$PREFIX/share/man/man1/lw.1`
|
||||||
- completion for `lw`, its commands, flags, files and preset names:
|
- completion for `lw`, its commands, flags, files and preset names:
|
||||||
@@ -92,10 +96,13 @@ Every system gets:
|
|||||||
- `$PREFIX/share/doc/logwisp/` (this documentation) and
|
- `$PREFIX/share/doc/logwisp/` (this documentation) and
|
||||||
`$PREFIX/share/licenses/logwisp/LICENSE`
|
`$PREFIX/share/licenses/logwisp/LICENSE`
|
||||||
|
|
||||||
|
A service install also gets the service files below and, on Linux and
|
||||||
|
FreeBSD alike, `$SYSCONFDIR/logwisp/logwisp.toml`: the annotated sample
|
||||||
|
configuration, placed when none is there and otherwise kept. Edit it before
|
||||||
|
starting the service.
|
||||||
|
|
||||||
### Linux (systemd)
|
### Linux (systemd)
|
||||||
|
|
||||||
- `$SYSCONFDIR/logwisp/logwisp.toml`: the annotated sample configuration,
|
|
||||||
kept when one is already there. Edit it before starting the service.
|
|
||||||
- `$PREFIX/lib/systemd/system/logwisp.service`: runs
|
- `$PREFIX/lib/systemd/system/logwisp.service`: runs
|
||||||
`lw -c $SYSCONFDIR/logwisp/logwisp.toml` as the `logwisp` user, from
|
`lw -c $SYSCONFDIR/logwisp/logwisp.toml` as the `logwisp` user, from
|
||||||
`/var/lib/logwisp`; `systemctl reload` sends `SIGHUP`.
|
`/var/lib/logwisp`; `systemctl reload` sends `SIGHUP`.
|
||||||
@@ -133,11 +140,11 @@ sudo systemctl reload logwisp
|
|||||||
|
|
||||||
### FreeBSD (rc.d)
|
### FreeBSD (rc.d)
|
||||||
|
|
||||||
- `$SYSCONFDIR/logwisp/logwisp.toml.sample`, copied to `logwisp.toml` when
|
`$PREFIX/etc/rc.d/logwisp` runs `lw` through `daemon(8)` as `logwisp_user`,
|
||||||
none exists and `DESTDIR` is empty
|
with its output in syslog under the tag `logwisp`; `service logwisp reload`
|
||||||
- `$PREFIX/etc/rc.d/logwisp`: runs `lw` through `daemon(8)` as
|
sends `SIGHUP`. The port in `deploy/package/freebsd/` places the
|
||||||
`logwisp_user`, with its output in syslog under the tag `logwisp`;
|
configuration the ports way, to the same effect: `@sample` installs
|
||||||
`service logwisp reload` sends `SIGHUP`
|
`logwisp.toml.sample` and copies it to `logwisp.toml` when none exists.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo pw useradd logwisp -d /nonexistent -s /usr/sbin/nologin -c "LogWisp log transport"
|
sudo pw useradd logwisp -d /nonexistent -s /usr/sbin/nologin -c "LogWisp log transport"
|
||||||
@@ -172,18 +179,93 @@ sudo systemctl enable --now logwisp
|
|||||||
|
|
||||||
- Installing creates the `logwisp` account and its directories where
|
- Installing creates the `logwisp` account and its directories where
|
||||||
`systemd-sysusers` and `systemd-tmpfiles` exist; the service waits to be
|
`systemd-sysusers` and `systemd-tmpfiles` exist; the service waits to be
|
||||||
enabled, and an upgrade restarts it if it runs.
|
enabled, and an upgrade or reinstall restarts it if it runs.
|
||||||
- `/etc/logwisp/logwisp.toml` is a conffile: an upgrade keeps your edits,
|
- `/etc/logwisp/logwisp.toml` is a conffile: an upgrade or reinstall keeps
|
||||||
and only a purge removes it.
|
your edits, and only a purge removes it.
|
||||||
|
- The same version again: `sudo apt install --reinstall ./bin/logwisp_*.deb`.
|
||||||
- Removing stops and disables the service. The account, its directories
|
- Removing stops and disables the service. The account, its directories
|
||||||
and any credentials in `/etc/logwisp` stay, as with `make uninstall`.
|
and any credentials in `/etc/logwisp` stay, as with `make uninstall`.
|
||||||
|
|
||||||
|
### Arch Linux (makepkg)
|
||||||
|
|
||||||
|
`make arch` builds the PKGBUILD in `deploy/package/arch/` from the working
|
||||||
|
tree, committed or not, into `bin/arch/`, then prints the `pacman -U` line
|
||||||
|
that installs the package. It needs `base-devel` and `go`, and runs as a
|
||||||
|
user: `makepkg` refuses root.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make arch
|
||||||
|
sudo pacman -U bin/arch/logwisp-<version>-1-x86_64.pkg.tar.zst
|
||||||
|
sudo systemctl enable --now logwisp
|
||||||
|
```
|
||||||
|
|
||||||
|
- pacman's hooks create the `logwisp` account and its directories; the
|
||||||
|
service waits to be enabled.
|
||||||
|
- `/etc/logwisp/logwisp.toml` is a `backup` file: an upgrade or reinstall
|
||||||
|
keeps your edits, and a shipped version that changed lands beside it as
|
||||||
|
`logwisp.toml.pacnew`. `pacman -R` keeps an edited one as
|
||||||
|
`logwisp.toml.pacsave`.
|
||||||
|
- Reinstall: `make arch` and the same `pacman -U`. pacman does not restart
|
||||||
|
the service: `sudo systemctl restart logwisp`.
|
||||||
|
- An earlier `sudo make install` conflicts with the package
|
||||||
|
(`PREFIX=/usr`) or overrides it (`PREFIX=/usr/local`, whose unit and `lw`
|
||||||
|
come first): `sudo make uninstall` with that `PREFIX` first. The
|
||||||
|
configuration it keeps is no conflict: pacman keeps it, and when it was
|
||||||
|
edited, the shipped one lands beside it as `logwisp.toml.pacnew`.
|
||||||
|
|
||||||
|
### Reinstalling
|
||||||
|
|
||||||
|
Every method runs again over its own installation, for an upgrade or the
|
||||||
|
same version, and keeps an edited configuration: `make install` leaves an
|
||||||
|
existing `$SYSCONFDIR/logwisp/logwisp.toml` alone, and the packages treat it
|
||||||
|
as above. Only the `.deb` restarts a running service; otherwise restart it
|
||||||
|
(`sudo systemctl restart logwisp`, `sudo service logwisp restart`). To see
|
||||||
|
what a release changed in the shipped configuration:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
d=$(mktemp -d); lw config init --out "$d/logwisp.toml"; diff "$d/logwisp.toml" /etc/logwisp/logwisp.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Without a Service
|
||||||
|
|
||||||
|
`SERVICE=no` installs `lw`, its manual, completion and documentation, and
|
||||||
|
nothing else: no service files, account or configuration. For one user,
|
||||||
|
without root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make release
|
||||||
|
make install SERVICE=no PREFIX="$HOME/.local"
|
||||||
|
lw config init
|
||||||
|
```
|
||||||
|
|
||||||
|
- `~/.local/bin` goes on `PATH`. `man lw` then finds the manual, and bash
|
||||||
|
and fish the completion; zsh needs
|
||||||
|
`fpath=(~/.local/share/zsh/site-functions $fpath)` before `compinit`.
|
||||||
|
- `make uninstall PREFIX="$HOME/.local"` removes it.
|
||||||
|
|
||||||
|
For every user: `sudo make install SERVICE=no PREFIX=/usr/local`.
|
||||||
|
|
||||||
|
`lw config init` writes the shipped, annotated configuration, never over an
|
||||||
|
existing file, where you choose:
|
||||||
|
|
||||||
|
- `lw config init`: `~/.config/logwisp/logwisp.toml`, which `lw` reads
|
||||||
|
without `-c` unless a `LOGWISP_CONFIG_*` variable names another file. With
|
||||||
|
it in place, `lw` without pipeline options runs its
|
||||||
|
pipelines instead of copying stdin to stdout; pipeline options and presets
|
||||||
|
still replace them.
|
||||||
|
- `sudo lw config init --out /usr/local/etc/logwisp/logwisp.toml`: a file
|
||||||
|
for every user, named with `-c`, or without it by
|
||||||
|
`LOGWISP_CONFIG_DIR=/usr/local/etc/logwisp`
|
||||||
|
([File Location](configuration.md#file-location)).
|
||||||
|
|
||||||
|
`lw --check` (with the same `-c`) then validates it.
|
||||||
|
|
||||||
### Uninstall
|
### Uninstall
|
||||||
|
|
||||||
`sudo make uninstall` (with the `PREFIX` used to install) removes everything
|
`sudo make uninstall` (with the `PREFIX` used to install) removes everything
|
||||||
`make install` wrote except `$SYSCONFDIR/logwisp`, which holds configuration
|
`make install` wrote except `$SYSCONFDIR/logwisp`, which holds configuration
|
||||||
and credentials. Remove that, the working directories and the account by
|
and credentials, and any file `lw config init` wrote. Remove those, the
|
||||||
hand.
|
working directories and the account by hand.
|
||||||
|
|
||||||
## Container Image
|
## Container Image
|
||||||
|
|
||||||
@@ -269,15 +351,21 @@ docker run -d --name logwisp \
|
|||||||
|
|
||||||
In place:
|
In place:
|
||||||
|
|
||||||
- `make install` with `DESTDIR`, `PREFIX` and `SYSCONFDIR`, the manual,
|
- `make install` with `DESTDIR`, `PREFIX`, `SYSCONFDIR` and `SERVICE`, the
|
||||||
shell completion and the service files in `deploy/package/`
|
manual, shell completion and the service files in `deploy/package/`
|
||||||
- `make deb`
|
- `make deb`, and `make arch` building the PKGBUILD from the working tree
|
||||||
- skeletons: `deploy/package/arch/PKGBUILD` and a `sysutils/logwisp` port in
|
- skeletons: `deploy/package/arch/PKGBUILD` and a `sysutils/logwisp` port in
|
||||||
`deploy/package/freebsd/`
|
`deploy/package/freebsd/`
|
||||||
- `.github/workflows/package.yml`, on changes to them: `makepkg` on the
|
- `.github/workflows/package.yml`, on changes to them:
|
||||||
PKGBUILD in an Arch container, the `.deb` installed, started, removed and
|
- Arch container: `make arch`, installed over an edited configuration,
|
||||||
purged on Ubuntu, BSD make building, installing and running the rc.d
|
reinstalled keeping it, removed
|
||||||
service on FreeBSD, and `make image image-check`
|
- Ubuntu: the `.deb` installed, started, reinstalled keeping an edited
|
||||||
|
configuration, removed and purged
|
||||||
|
- Ubuntu, without a service: `make install SERVICE=no` into a home twice,
|
||||||
|
then `lw config init` writing the file `lw` reads, once
|
||||||
|
- FreeBSD: BSD make building, installing twice keeping an edited
|
||||||
|
configuration, and running the rc.d service
|
||||||
|
- `make image image-check`
|
||||||
|
|
||||||
Still missing: release tags, which both skeletons download; submitting the
|
Still missing: release tags, which both skeletons download; submitting the
|
||||||
AUR package and the port; a Debian source package for a PPA or the archive.
|
AUR package and the port; a Debian source package for a PPA or the archive.
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
.Op Fl \-rate\-limit Ar spec
|
.Op Fl \-rate\-limit Ar spec
|
||||||
.Op Fl \-heartbeat Ar spec
|
.Op Fl \-heartbeat Ar spec
|
||||||
.Nm
|
.Nm
|
||||||
.Cm auth | tls | preset
|
.Cm auth | tls | preset | config
|
||||||
.Ar command
|
.Ar command
|
||||||
.Op Ar flags
|
.Op Ar flags
|
||||||
.Nm
|
.Nm
|
||||||
@@ -124,12 +124,7 @@ The options of
|
|||||||
join words with
|
join words with
|
||||||
.Ql - ;
|
.Ql - ;
|
||||||
a configuration or preset key keeps its TOML spelling.
|
a configuration or preset key keeps its TOML spelling.
|
||||||
The
|
The commands also take a long option after a single dash.
|
||||||
.Cm auth ,
|
|
||||||
.Cm tls
|
|
||||||
and
|
|
||||||
.Cm preset
|
|
||||||
commands also take a long option after a single dash.
|
|
||||||
.Pp
|
.Pp
|
||||||
The options are as follows:
|
The options are as follows:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
@@ -549,6 +544,19 @@ An IPv6
|
|||||||
.Ar host
|
.Ar host
|
||||||
is written in brackets, as in
|
is written in brackets, as in
|
||||||
.Li [2001:db8::1]:8443 .
|
.Li [2001:db8::1]:8443 .
|
||||||
|
.Ss Configuration command
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Cm config init Op Fl \-out Ar file
|
||||||
|
Write the annotated configuration
|
||||||
|
.Nm
|
||||||
|
ships, every option with its default, to
|
||||||
|
.Ar file ,
|
||||||
|
by default
|
||||||
|
.Pa ~/.config/logwisp/logwisp.toml ,
|
||||||
|
the first file in
|
||||||
|
.Sx FILES .
|
||||||
|
An existing file is never replaced.
|
||||||
|
.El
|
||||||
.Sh ENVIRONMENT
|
.Sh ENVIRONMENT
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Ev LOGWISP_ Ns Ar KEY
|
.It Ev LOGWISP_ Ns Ar KEY
|
||||||
@@ -611,7 +619,11 @@ reads the first of these that exists:
|
|||||||
.Pa ./logwisp.toml
|
.Pa ./logwisp.toml
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
Packages install a sample configuration and service files that pass it with
|
.Nm
|
||||||
|
.Cm config init
|
||||||
|
writes the first.
|
||||||
|
A service installation places the annotated configuration, keeping one
|
||||||
|
already there, and service files that pass it with
|
||||||
.Fl c :
|
.Fl c :
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Pa /etc/logwisp/logwisp.toml
|
.It Pa /etc/logwisp/logwisp.toml
|
||||||
@@ -620,9 +632,7 @@ The configuration on Linux, used by
|
|||||||
.It Pa /usr/local/etc/logwisp/logwisp.toml
|
.It Pa /usr/local/etc/logwisp/logwisp.toml
|
||||||
The configuration on
|
The configuration on
|
||||||
.Fx ,
|
.Fx ,
|
||||||
installed as
|
used by
|
||||||
.Pa logwisp.toml.sample
|
|
||||||
and used by
|
|
||||||
.Pa /usr/local/etc/rc.d/logwisp .
|
.Pa /usr/local/etc/rc.d/logwisp .
|
||||||
.It Pa /var/lib/logwisp , /var/db/logwisp
|
.It Pa /var/lib/logwisp , /var/db/logwisp
|
||||||
The service's working directory on Linux and on
|
The service's working directory on Linux and on
|
||||||
@@ -668,9 +678,10 @@ the shell reports status 141.
|
|||||||
.Pp
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
.Cm auth ,
|
.Cm auth ,
|
||||||
.Cm tls
|
.Cm tls ,
|
||||||
and
|
|
||||||
.Cm preset
|
.Cm preset
|
||||||
|
and
|
||||||
|
.Cm config
|
||||||
do the same: 0 on success or help, 1 on failure, and 2 on a usage error.
|
do the same: 0 on success or help, 1 on failure, and 2 on a usage error.
|
||||||
.Sh SIGNALS
|
.Sh SIGNALS
|
||||||
.Bl -tag -width "SIGINT, SIGTERM"
|
.Bl -tag -width "SIGINT, SIGTERM"
|
||||||
@@ -749,6 +760,16 @@ edge# lw \-\-preset edge,path=/var/log/app,to=agg.example.org:9000,\e
|
|||||||
ca=/etc/logwisp/pki/ca.crt,user=edge-01,password_file=/root/edge-01.pass
|
ca=/etc/logwisp/pki/ca.crt,user=edge-01,password_file=/root/edge-01.pass
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
|
Write the annotated configuration to the file
|
||||||
|
.Nm
|
||||||
|
reads without
|
||||||
|
.Fl c ,
|
||||||
|
edit it, then check it:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
$ lw config init
|
||||||
|
$ lw \-\-check
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
Check a configuration without binding a port or touching a log file:
|
Check a configuration without binding a port or touching a log file:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
$ lw \-\-check \-c /etc/logwisp/logwisp.toml
|
$ lw \-\-check \-c /etc/logwisp/logwisp.toml
|
||||||
|
|||||||
+11
-8
@@ -11,15 +11,18 @@ The foundation exists:
|
|||||||
24.04 and 26.04, and the FreeBSD 15.1 ports tree.
|
24.04 and 26.04, and the FreeBSD 15.1 ports tree.
|
||||||
- The canonical module path `github.com/lixenwraith/logwisp`, which
|
- The canonical module path `github.com/lixenwraith/logwisp`, which
|
||||||
`go install`, FreeBSD's `USES=go:modules` and Debian's dh-golang expect.
|
`go install`, FreeBSD's `USES=go:modules` and Debian's dh-golang expect.
|
||||||
- `make install` with `DESTDIR`, `PREFIX` and `SYSCONFDIR`: the binary, the
|
- `make install` with `DESTDIR`, `PREFIX`, `SYSCONFDIR` and `SERVICE`: the
|
||||||
`doc/lw.1` manual, bash, zsh and fish completion generated from `cmd/lw`'s
|
binary, the `doc/lw.1` manual, bash, zsh and fish completion generated from
|
||||||
`shorts` and `commands` tables, and the service files in `deploy/package/`
|
`cmd/lw`'s `shorts` and `commands` tables, and the service files in
|
||||||
(systemd unit, sysusers, tmpfiles, FreeBSD rc.d script).
|
`deploy/package/` (systemd unit, sysusers, tmpfiles, FreeBSD rc.d script)
|
||||||
- `make deb`, a binary package built with `dpkg-deb`.
|
with the configuration, kept on reinstall.
|
||||||
|
- `make deb`, a binary package built with `dpkg-deb`, and `make arch`, the
|
||||||
|
PKGBUILD built from the working tree.
|
||||||
- Skeletons in `deploy/package/arch/` and `deploy/package/freebsd/`.
|
- Skeletons in `deploy/package/arch/` and `deploy/package/freebsd/`.
|
||||||
- `.github/workflows/package.yml`: `makepkg` on the PKGBUILD, the `.deb`
|
- `.github/workflows/package.yml`: `make arch`, the `.deb` and BSD make on
|
||||||
installed, started and purged, BSD make and the rc.d service on FreeBSD
|
FreeBSD 15.1, each reinstalled over an edited configuration; the systemd
|
||||||
15.1, and `make image image-check`.
|
and rc.d services run; a home install with `SERVICE=no` and
|
||||||
|
`lw config init`; and `make image image-check`.
|
||||||
|
|
||||||
What remains is the maintainer's: it needs push rights, an identity or a
|
What remains is the maintainer's: it needs push rights, an identity or a
|
||||||
release tag, and both skeletons download the tagged source.
|
release tag, and both skeletons download the tagged source.
|
||||||
|
|||||||
@@ -219,11 +219,25 @@ func resolveConfigPath(file string) (path string, isExplicit bool) {
|
|||||||
if configDir := os.Getenv("LOGWISP_CONFIG_DIR"); configDir != "" {
|
if configDir := os.Getenv("LOGWISP_CONFIG_DIR"); configDir != "" {
|
||||||
return filepath.Join(configDir, "logwisp.toml"), true
|
return filepath.Join(configDir, "logwisp.toml"), true
|
||||||
}
|
}
|
||||||
if homeDir, err := os.UserHomeDir(); err == nil {
|
if path, err := UserFile(); err == nil {
|
||||||
path = filepath.Join(homeDir, ".config", "logwisp", "logwisp.toml")
|
|
||||||
if _, err := os.Stat(path); err == nil {
|
if _, err := os.Stat(path); err == nil {
|
||||||
return path, false
|
return path, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "logwisp.toml", false
|
return "logwisp.toml", false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DefaultPath is the file lw reads without -c
|
||||||
|
func DefaultPath() string {
|
||||||
|
path, _ := resolveConfigPath("")
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserFile is ~/.config/logwisp/logwisp.toml, the file lw reads first without -c
|
||||||
|
func UserFile() (string, error) {
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return filepath.Join(home, ".config", "logwisp", "logwisp.toml"), nil
|
||||||
|
}
|
||||||
Reference in new issue
Block a user