Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reuse EntryGroup - reset+(re)commit #14

Merged
merged 1 commit into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 22 additions & 14 deletions avahi/publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ const (
)

type Publisher struct {
dbusConn *dbus.Conn
avahiServer *avahi.Server
fqdn string
rdataField []byte
dbusConn *dbus.Conn
avahiServer *avahi.Server
avahiEntryGroup *avahi.EntryGroup
fqdn string
rdataField []byte
}

// NewPublisher creates a new service for Publisher.
Expand All @@ -39,6 +40,11 @@ func NewPublisher() (*Publisher, error) {
return nil, fmt.Errorf("failed to get FQDN from Avahi: %v", err)
}

group, err := server.EntryGroupNew()
if err != nil {
return nil, fmt.Errorf("failed to create entry group: %v", err)
}

fqdn := dns.Fqdn(avahiFqdn)

// RDATA: a variable length string of octets that describes the resource. CNAME in our case
Expand All @@ -50,10 +56,11 @@ func NewPublisher() (*Publisher, error) {
}

return &Publisher{
dbusConn: conn,
avahiServer: server,
fqdn: fqdn,
rdataField: rdataField,
dbusConn: conn,
avahiServer: server,
avahiEntryGroup: group,
fqdn: fqdn,
rdataField: rdataField,
}, nil
}

Expand All @@ -64,13 +71,14 @@ func (p *Publisher) Fqdn() string {

// PublishCNAMES send via Avahi-daemon CNAME records with the provided TTL.
func (p *Publisher) PublishCNAMES(cnames []string, ttl uint32) error {
group, err := p.avahiServer.EntryGroupNew()
if err != nil {
return fmt.Errorf("failed to create entry group: %v", err)
// Reset the entry group to remove all records.
// Because we can't update records without it after the `Commit`.
if err := p.avahiEntryGroup.Reset(); err != nil {
return fmt.Errorf("failed to reset entry group: %v", err)
}

for _, cname := range cnames {
err := group.AddRecord(
err := p.avahiEntryGroup.AddRecord(
avahi.InterfaceUnspec,
avahi.ProtoUnspec,
uint32(0), // From Avahi Python bindings https://gist.github.com/gdamjan/3168336#file-avahi-alias-py-L42
Expand All @@ -85,7 +93,7 @@ func (p *Publisher) PublishCNAMES(cnames []string, ttl uint32) error {
}
}

if err := group.Commit(); err != nil {
if err := p.avahiEntryGroup.Commit(); err != nil {
return fmt.Errorf("failed to commit entry group: %v", err)
}

Expand All @@ -94,5 +102,5 @@ func (p *Publisher) PublishCNAMES(cnames []string, ttl uint32) error {

// Close associated resources.
func (p *Publisher) Close() {
p.avahiServer.Close() // It also close the DBus connection
p.avahiServer.Close() // It also closes the DBus connection and free the entry group
}
3 changes: 1 addition & 2 deletions cmd/subdomain.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@ func runSubdomain(ctx context.Context, publisher *avahi.Publisher, fqdn string,

if len(found) > 0 {
if err := publisher.PublishCNAMES(found, ttl); err != nil {
log.Printf("Failed to publish CNAMEs: %v", err)
continue
return fmt.Errorf("failed to publish CNAMEs: %w", err)
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package main
import (
"context"
"fmt"
"log"
"os"
"os/signal"
"time"

"github.com/carlmjohnson/versioninfo"
"github.com/urfave/cli/v2"
Expand All @@ -16,6 +18,15 @@ func main() {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer stop()

// Add a handler for force exiting if we don't exit gracefully (stuck)
go func() {
<-ctx.Done()
time.Sleep(3 * time.Second)

log.Print("Force exit")
os.Exit(1)
}()

app := &cli.App{
Name: "go-avahi-cname",
Usage: "A tool for publishing CNAME records with Avahi",
Expand Down
Loading