diff --git a/.github/workflows/commit.yml b/.github/workflows/commit.yml
new file mode 100644
index 0000000..0d3a6cb
--- /dev/null
+++ b/.github/workflows/commit.yml
@@ -0,0 +1,41 @@
+name: commit
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+
+permissions:
+ contents: read
+
+jobs:
+ golangci:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-go@v4
+ with:
+ go-version: "1.20"
+ cache: false
+
+ - name: golangci-lint
+ uses: golangci/golangci-lint-action@v3
+ with:
+ version: v1.53
+ build_test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-go@v4
+ with:
+ go-version: "1.20"
+ cache: false
+
+ - name: Verify dependencies
+ run: go mod verify
+
+ - name: Build
+ run: go build -v ./...
+
+ - name: Test
+ run: go test -v ./...
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 4ef2534..5458dda 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,4 +1,4 @@
-name: goreleaser
+name: release
on:
push:
@@ -10,7 +10,7 @@ permissions:
contents: write
jobs:
- goreleaser:
+ release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
diff --git a/.goreleaser.yaml b/.goreleaser.yaml
index e11bde4..c8c57f3 100644
--- a/.goreleaser.yaml
+++ b/.goreleaser.yaml
@@ -12,9 +12,10 @@ builds:
- linux
- darwin
goarch:
- - amd64
- - arm
- - arm64
+ - "386"
+ - "amd64"
+ - "arm"
+ - "arm64"
goarm:
- "6"
- "7"
@@ -34,7 +35,7 @@ release:
target_commitish: "{{ .Commit }}"
mode: replace
header: |
- ## âī¸ The `{{ .Tag }}` release
+ ## âšī¸ For information on how to install and use please see `README.md`
footer: |
Your PRs & issues are welcome! Thanks đ
disable: false
diff --git a/README.md b/README.md
index 6d807dd..4f1dc31 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,88 @@
-# go-avahi-cname
+
+
+![GitHub tag (with filter)](https://img.shields.io/github/v/tag/grishy/go-avahi-cname)
+[![Go Report Card](https://goreportcard.com/badge/github.com/grishy/go-avahi-cname)](https://goreportcard.com/report/github.com/grishy/go-avahi-cname)
+![Build Status](https://github.com/grishy/go-avahi-cname/actions/workflows/release.yml/badge.svg)
+
+## About go-avahi-cname
+
+This project publishe CNAME records pointing to the local host over multicast DNS using the **Avahi** daemon found in all major Linux distributions.
+Since Avahi is compatible with Apple's Bonjour, these names are usable from MacOS X and Windows too.
+
+### Goals
+
+- â
No dependencies
+- â
Small footprint, less than 3MB binary
+- â
Support x86_64 and ARM
+- â
Release binaries and containers
+
+### Architecture
+
+![Architecture](./docs/arch.excalidraw.svg)
+
+## Usege and installation
+
+All CNAMEs are specified as program arguments, no length limit.
+You can use either just the name (`name1`), which will create a record as a subdomain for the current machine, or you can write the full FQDN (`name1.hostname.local.` domain with a dot on the end) format.
+
+Example output on machine with hostname `lab`:
+
+```plain
+> ./go-avahi-cname git photo.local. example.lab.local.
+2023/07/27 08:37:14 Creating publisher
+2023/07/27 08:37:14 Formating CNAMEs:
+2023/07/27 08:37:14 > 'git.lab.local.' (added current FQDN)
+2023/07/27 08:37:14 > 'photo.local.'
+2023/07/27 08:37:14 > 'example.lab.local.'
+2023/07/27 08:37:14 Publishing every 5m0s and CNAME TTL=600s.
+^C
+2023/07/27 08:37:16 Closing publisher...
+```
+
+### Installation
+
+#### Binary
+
+Binary files can be taken as artifacts for [the Release](https://github.com/grishy/go-avahi-cname/releases). In this case, it would be better to create a systemd service.
+
+#### Container
+
+The images for each version are in [the Packages section](https://github.com/grishy/go-avahi-cname/pkgs/container/go-avahi-cname).
+You need to provide the `/var/run/dbus/system_bus_socket` file to the container to be able to communicate with the host's Avahi daemon.
+
+One-liner to run the container `v0.3.1`:
+
+```bash
+> docker run --restart=unless-stopped -d -v /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket ghcr.io/grishy/go-avahi-cname:v0.3.1 name1 name2.lab.local.
+5a19790e06cca93016af6651d7af4046c24095a6909ace2fe26c3451fb98ceee
+
+> docker logs 5a19790e06cca93016af6651d7af4046c24095a6909ace2fe26c3451fb98ceee
+2023/07/27 08:49:02 Creating publisher
+2023/07/27 08:49:02 Formating CNAMEs:
+2023/07/27 08:49:02 > 'name1.lab.local.' (added current FQDN)
+2023/07/27 08:49:02 > 'name2.lab.local.'
+2023/07/27 08:49:02 Publishing every 5m0s ans CNAME TTL=600s.
+```
+
+Ansible task to run the container:
+
+```yaml
+- name: go-avahi-cname | Start container
+ community.docker.docker_container:
+ name: "go-avahi-cname"
+ image: "ghcr.io/grishy/go-avahi-cname:v0.3.1"
+ restart_policy: unless-stopped
+ volumes:
+ - "/var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket" # access to avahi-daemon
+ command: "name1 name2 git"
+```
## Source of inspiration
-- https://gist.github.com/gdamjan/3168336
-- https://github.com/tomoasleep/k8s-avahi
+- https://web.archive.org/web/20151016190620/http://www.avahi.org/wiki/Examples/PythonPublishAlias
+- https://pypi.org/project/mdns-publisher/
-## TODO
+## License
-- [ ] Add FreeBSD support (https://github.com/godbus/dbus/issues/315)
+Copyright Š 2022 [Sergei G.](https://github.com/grishy)
+This project is [MIT](./LICENSE) licensed.
diff --git a/docs/arch.excalidraw.svg b/docs/arch.excalidraw.svg
new file mode 100644
index 0000000..329f22d
--- /dev/null
+++ b/docs/arch.excalidraw.svg
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/docs/logo_x3.png b/docs/logo_x3.png
new file mode 100644
index 0000000..3353916
Binary files /dev/null and b/docs/logo_x3.png differ
diff --git a/main.go b/main.go
index c5505fa..0316344 100644
--- a/main.go
+++ b/main.go
@@ -2,6 +2,7 @@ package main
import (
"context"
+ "fmt"
"log"
"os"
"os/signal"
@@ -11,23 +12,14 @@ import (
"github.com/miekg/dns"
)
-const TTL = uint32(60 * 10) // seconds
-
-func main() {
- ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
- defer stop()
-
- log.Println("Creating publisher")
- publisher, err := publisher.NewPublisher()
- if err != nil {
- log.Fatalf("Can't create publisher: %v", err)
- }
+const TTL = uint32(10 * 60) // in seconds
+func formatCname(hostnameFqdn string, cnames []string) []string {
log.Println("Formating CNAMEs:")
- cnames := os.Args[1:]
+
for i, cname := range cnames {
if !dns.IsFqdn(cname) {
- cnames[i] = dns.Fqdn(cname + "." + publisher.Fqdn())
+ cnames[i] = dns.Fqdn(cname + "." + hostnameFqdn)
log.Printf(" > '%s' (added current FQDN)", cnames[i])
continue
@@ -36,18 +28,27 @@ func main() {
log.Printf(" > '%s'", cname)
}
+ return cnames
+}
+
+func publishing(ctx context.Context, publisher *publisher.Publisher, cnames []string) {
resendDuration := time.Duration(TTL/2) * time.Second
- log.Printf("Publishing every %v ans CNAME TTL=%ds.", resendDuration, TTL)
+ log.Printf("Publishing every %v and CNAME TTL=%ds.", resendDuration, TTL)
// To start publishing immediately
// https://github.com/golang/go/issues/17601
- publisher.PublishCNAMES(os.Args[1:], TTL)
+ if err := publisher.PublishCNAMES(cnames, TTL); err != nil {
+ log.Fatalf("can't publish CNAMEs: %v", err)
+ }
for {
select {
case <-time.Tick(resendDuration):
- publisher.PublishCNAMES(os.Args[1:], TTL)
+ if err := publisher.PublishCNAMES(cnames, TTL); err != nil {
+ log.Fatalf("can't publish CNAMEs: %v", err)
+ }
case <-ctx.Done():
+ fmt.Println()
log.Println("Closing publisher...")
if err := publisher.Close(); err != nil {
log.Fatalf("Can't close publisher: %v", err)
@@ -56,3 +57,17 @@ func main() {
}
}
}
+
+func main() {
+ ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
+ defer stop()
+
+ log.Println("Creating publisher")
+ publisher, err := publisher.NewPublisher()
+ if err != nil {
+ log.Fatalf("Can't create publisher: %v", err)
+ }
+
+ cnames := formatCname(publisher.Fqdn(), os.Args[1:])
+ publishing(ctx, publisher, cnames)
+}