Compare commits
1
Commits
05689e6f72
...
next
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bce8bdbb2e |
+25
-10
@@ -1,19 +1,28 @@
|
|||||||
# .dockerignore does NOT use .gitignore semantics. Docker matches with
|
# .dockerignore does NOT use .gitignore semantics. Docker matches with
|
||||||
# moby/patternmatcher: filepath.Match plus `**`, so `*` does not cross
|
# moby/patternmatcher: filepath.Match plus `**`, so `*` does not cross
|
||||||
# `/` and an unprefixed pattern is anchored at the context root. Every
|
# `/` and an unprefixed pattern is anchored at the context root. Every
|
||||||
# depth-independent pattern therefore needs `**/`; only genuinely
|
# depth-independent pattern therefore needs `**/`, or `config/.env` and
|
||||||
# root-anchored entries go unprefixed. Never transplant these into
|
# `certs/server.key` still ship while this file reads as solved. Only
|
||||||
# .gitignore, where `**/` is wrong.
|
# genuinely root-anchored entries go unprefixed. Never transplant these
|
||||||
|
# into .gitignore, where `**/` is wrong.
|
||||||
#
|
#
|
||||||
# Matching is case-sensitive, so secrets use character ranges rather
|
# Matching is case-sensitive, so secrets use character ranges rather
|
||||||
# than an ALL-CAPS twin, which would still miss `Server.Key`.
|
# than an ALL-CAPS twin, which would still miss `Server.Key`.
|
||||||
|
#
|
||||||
|
# Extend with this repo's own host-built artifacts, written anchored:
|
||||||
|
# `/myapp`, never `**/myapp`, which also matches `cmd/myapp/` and
|
||||||
|
# deletes the package directory from the context.
|
||||||
|
|
||||||
# Excluding .git means `git describe` cannot run in any build stage and
|
# .git is sent without its config. Without a VERSION build argument the
|
||||||
# fails quietly there; rtnetmon embeds no version, so this is safe.
|
# stage that compiles runs `git describe --tags --always` on .git, which
|
||||||
.git
|
# does not need .git/config; that file can hold a credential, such as a
|
||||||
|
# password in a remote URL or the token the CI checkout step stores there.
|
||||||
|
.git/config
|
||||||
|
|
||||||
# Agent scratch: one full checkout of the repo per in-flight agent.
|
# Agent scratch: one full checkout of the repo per in-flight agent.
|
||||||
# Anchored because agents run at the repo root here.
|
# Anchored because it occurs once where agents run at the repo root.
|
||||||
|
# KNOWN GAP: a repo running agents in subdirectories still ships
|
||||||
|
# `services/api/.claude/` and must add its own anchored entry.
|
||||||
.claude
|
.claude
|
||||||
|
|
||||||
# This repo's own host-built artifacts, root-anchored so `bin/` is not
|
# This repo's own host-built artifacts, root-anchored so `bin/` is not
|
||||||
@@ -22,12 +31,15 @@
|
|||||||
/rtnetmon
|
/rtnetmon
|
||||||
main.go.old
|
main.go.old
|
||||||
|
|
||||||
# Environment files.
|
# Environment files. `*.env` covers bare `.env` and the `prod.env`
|
||||||
|
# convention. Re-include a committed template with a negation if the
|
||||||
|
# build needs one: `!docs/example.env`.
|
||||||
**/*.[eE][nN][vV]
|
**/*.[eE][nN][vV]
|
||||||
**/.[eE][nN][vV].*
|
**/.[eE][nN][vV].*
|
||||||
**/.[eE][nN][vV][rR][cC]
|
**/.[eE][nN][vV][rR][cC]
|
||||||
|
|
||||||
# Private keys and the bundles carrying them.
|
# Private keys and the bundles carrying them. Public certificates
|
||||||
|
# (*.crt, *.cer) are deliberately absent: they are legitimate inputs.
|
||||||
**/*.[pP][eE][mM]
|
**/*.[pP][eE][mM]
|
||||||
**/*.[kK][eE][yY]
|
**/*.[kK][eE][yY]
|
||||||
**/*.[pP]12
|
**/*.[pP]12
|
||||||
@@ -37,11 +49,14 @@ main.go.old
|
|||||||
**/[iI][dD]_[eE][cC][dD][sS][aA]
|
**/[iI][dD]_[eE][cC][dD][sS][aA]
|
||||||
**/[iI][dD]_[eE][dD]25519
|
**/[iI][dD]_[eE][dD]25519
|
||||||
|
|
||||||
|
# Dependencies: restored inside the image, never copied in.
|
||||||
|
**/node_modules
|
||||||
|
|
||||||
# OS metadata.
|
# OS metadata.
|
||||||
**/.DS_Store
|
**/.DS_Store
|
||||||
**/Thumbs.db
|
**/Thumbs.db
|
||||||
|
|
||||||
# Editor state.
|
# Editor state: never a build input, and it churns COPY.
|
||||||
**/*.swp
|
**/*.swp
|
||||||
**/*.swo
|
**/*.swo
|
||||||
**/*~
|
**/*~
|
||||||
|
|||||||
+15
-1
@@ -34,4 +34,18 @@ WORKDIR /src
|
|||||||
COPY go.mod go.sum ./
|
COPY go.mod go.sum ./
|
||||||
RUN go mod download
|
RUN go mod download
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN CGO_ENABLED=0 go build -trimpath -o /rtnetmon ./cmd/rtnetmon/
|
# The version stamped into the binary: the VERSION build argument when one
|
||||||
|
# is given, otherwise `git describe --tags --always` of the .git the build
|
||||||
|
# context carries: the tag on a tagged commit, tag-N-gHASH on a commit after
|
||||||
|
# one, the short commit when no tag is reachable. git ships in this base
|
||||||
|
# image. A context that carries .git and still yields no version fails the
|
||||||
|
# build. With neither, as from a source tarball, the binary reports dev.
|
||||||
|
ARG VERSION
|
||||||
|
RUN version="${VERSION:-$(git describe --tags --always)}"; \
|
||||||
|
if [ -e .git ] && { [ -z "$version" ] || [ "$version" = dev ] || \
|
||||||
|
[ "$version" = unknown ]; }; then \
|
||||||
|
echo "no version could be derived although the build context carries .git" >&2; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
CGO_ENABLED=0 go build -trimpath -ldflags="-X main.Version=${version:-dev}" \
|
||||||
|
-o /rtnetmon ./cmd/rtnetmon/
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
# below are thin shims that call them.
|
# below are thin shims that call them.
|
||||||
.DEFAULT_GOAL := check
|
.DEFAULT_GOAL := check
|
||||||
|
|
||||||
|
VERSION ?= $(shell git describe --tags --always)
|
||||||
|
|
||||||
bootstrap:
|
bootstrap:
|
||||||
@script/bootstrap
|
@script/bootstrap
|
||||||
|
|
||||||
@@ -36,13 +38,14 @@ hooks:
|
|||||||
@script/install-precommit
|
@script/install-precommit
|
||||||
|
|
||||||
build:
|
build:
|
||||||
CGO_ENABLED=0 go build -trimpath -o bin/rtnetmon ./cmd/rtnetmon
|
CGO_ENABLED=0 go build -trimpath -ldflags "-X main.Version=$(VERSION)" \
|
||||||
|
-o bin/rtnetmon ./cmd/rtnetmon
|
||||||
|
|
||||||
run: build
|
run: build
|
||||||
./bin/rtnetmon
|
./bin/rtnetmon
|
||||||
|
|
||||||
dev:
|
dev:
|
||||||
go run ./cmd/rtnetmon
|
go run -ldflags "-X main.Version=$(VERSION)" ./cmd/rtnetmon
|
||||||
|
|
||||||
deps:
|
deps:
|
||||||
go mod download
|
go mod download
|
||||||
|
|||||||
@@ -8,8 +8,12 @@ import (
|
|||||||
"git.eeqj.de/sneak/rtnetmon/internal/cli"
|
"git.eeqj.de/sneak/rtnetmon/internal/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Version is the git tag or short commit, set at link time with -X by the
|
||||||
|
// Makefile and the Dockerfile. Builds that do not set it report dev.
|
||||||
|
var Version = "dev" //nolint:gochecknoglobals // set at link time with -X
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := cli.Execute()
|
err := cli.Execute(Version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ package cli
|
|||||||
import "github.com/spf13/cobra"
|
import "github.com/spf13/cobra"
|
||||||
|
|
||||||
// NewRootCmd exposes newRootCmd for external tests.
|
// NewRootCmd exposes newRootCmd for external tests.
|
||||||
func NewRootCmd() *cobra.Command { return newRootCmd() }
|
func NewRootCmd() *cobra.Command { return newRootCmd("dev") }
|
||||||
|
|||||||
@@ -51,8 +51,9 @@ func defaultTCPHosts() []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRootCmd builds the cobra root command with its flags bound.
|
// newRootCmd builds the cobra root command with its flags bound. version is
|
||||||
func newRootCmd() *cobra.Command {
|
// logged at startup.
|
||||||
|
func newRootCmd(version string) *cobra.Command {
|
||||||
cfg := &config{}
|
cfg := &config{}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "rtnetmon",
|
Use: "rtnetmon",
|
||||||
@@ -60,7 +61,7 @@ func newRootCmd() *cobra.Command {
|
|||||||
Long: `rtnetmon is a dual-interface network monitoring dashboard that provides
|
Long: `rtnetmon is a dual-interface network monitoring dashboard that provides
|
||||||
real-time visibility into network health, packet loss, and latency.`,
|
real-time visibility into network health, packet loss, and latency.`,
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
return runMonitor(cmd, cfg)
|
return runMonitor(cmd, cfg, version)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
registerFlags(cmd, cfg)
|
registerFlags(cmd, cfg)
|
||||||
@@ -88,8 +89,8 @@ func registerFlags(cmd *cobra.Command, cfg *config) {
|
|||||||
|
|
||||||
// runMonitor detects the interfaces to monitor, then constructs and runs the
|
// runMonitor detects the interfaces to monitor, then constructs and runs the
|
||||||
// monitor from cfg.
|
// monitor from cfg.
|
||||||
func runMonitor(cmd *cobra.Command, cfg *config) error {
|
func runMonitor(cmd *cobra.Command, cfg *config, version string) error {
|
||||||
monitor.Logf(cfg.LogFile, "Starting rtnetmon")
|
monitor.Logf(cfg.LogFile, "Starting rtnetmon %s", version)
|
||||||
|
|
||||||
specs, err := detectInterfaces(cmd, cfg)
|
specs, err := detectInterfaces(cmd, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -169,7 +170,7 @@ func detectInterfaces(
|
|||||||
return specs, nil
|
return specs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute builds the root command and runs it.
|
// Execute builds the root command and runs it. version is logged at startup.
|
||||||
func Execute() error {
|
func Execute(version string) error {
|
||||||
return newRootCmd().Execute()
|
return newRootCmd(version).Execute()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user