Refactored main and some error messages
This commit is contained in:
parent
ba9379dfb8
commit
7755300638
@ -36,7 +36,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// VERSION is the current version of the application.
|
// VERSION is the current version of the application.
|
||||||
var VERSION = "0.1.4"
|
var VERSION = "0.1.5"
|
||||||
|
|
||||||
// Domain is a single domain listed in the configuration file.
|
// Domain is a single domain listed in the configuration file.
|
||||||
type Domain struct {
|
type Domain struct {
|
||||||
@ -113,7 +113,7 @@ func getConfig(pathToJSON string) (Config, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Main is the main function for the cloud-dyndns-client command. It returns the OS exit code.
|
// Main is the main function for the cloud-dyndns-client command. It returns the OS exit code.
|
||||||
func Main() int {
|
func main() {
|
||||||
addr := flag.String("addr", ":8080", "Address to listen on for health checks.")
|
addr := flag.String("addr", ":8080", "Address to listen on for health checks.")
|
||||||
version := flag.Bool("version", false, "Print the version and exit.")
|
version := flag.Bool("version", false, "Print the version and exit.")
|
||||||
config := flag.String("config", "/etc/cloud-dyndns-client/config.json", "The path to the JSON config file.")
|
config := flag.String("config", "/etc/cloud-dyndns-client/config.json", "The path to the JSON config file.")
|
||||||
@ -122,12 +122,12 @@ func Main() int {
|
|||||||
|
|
||||||
if *version {
|
if *version {
|
||||||
fmt.Println(VERSION)
|
fmt.Println(VERSION)
|
||||||
return 0
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := getConfig(*config)
|
cfg, err := getConfig(*config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error reading config: %#v", err)
|
log.Fatalf("Error reading config: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert config to sync records
|
// Convert config to sync records
|
||||||
@ -160,6 +160,7 @@ func Main() int {
|
|||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
wg, ctx := errgroup.WithContext(ctx)
|
wg, ctx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
|
// TODO: Refactor and move this code to it's own package
|
||||||
wg.Go(func() error { return syncer.Run(ctx.Done()) })
|
wg.Go(func() error { return syncer.Run(ctx.Done()) })
|
||||||
wg.Go(func() error { return poller.Run(ctx.Done()) })
|
wg.Go(func() error { return poller.Run(ctx.Done()) })
|
||||||
wg.Go(func() error {
|
wg.Go(func() error {
|
||||||
@ -182,6 +183,7 @@ func Main() int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
// TODO: Refactor and move to it's own package
|
||||||
wg.Go(func() error {
|
wg.Go(func() error {
|
||||||
// This goroutine sets up health checks on an HTTP endpoint.
|
// This goroutine sets up health checks on an HTTP endpoint.
|
||||||
// It's a bit complicated as it is necessary to gracefully
|
// It's a bit complicated as it is necessary to gracefully
|
||||||
@ -221,19 +223,13 @@ func Main() int {
|
|||||||
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
|
||||||
select {
|
select {
|
||||||
case s := <-signals:
|
case s := <-signals:
|
||||||
log.Printf("Received signal %#v, exiting...", s)
|
log.Printf("Received signal %v, exiting...", s)
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
}
|
}
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
if err := wg.Wait(); err != nil {
|
if err := wg.Wait(); err != nil {
|
||||||
log.Printf("Unhandled error received. Exiting: %s %#v", err.Error(), err)
|
log.Fatalf("Unhandled error received. Exiting: %v", err)
|
||||||
return 1
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
os.Exit(Main())
|
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ func (p *IPAddressPoller) poll() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("Could not obtain IP address: %s %#v", lastErr.Error(), lastErr)
|
return fmt.Errorf("Could not obtain IP address: %v", lastErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// request() makes a request to a URL to get the internet IP address.
|
// request() makes a request to a URL to get the internet IP address.
|
||||||
@ -102,7 +102,7 @@ func request(url string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return "", fmt.Errorf("Got status code from %s: %s", url, resp.StatusCode)
|
return "", fmt.Errorf("Got status code from %q: %d", url, resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
z := html.NewTokenizer(resp.Body)
|
z := html.NewTokenizer(resp.Body)
|
||||||
@ -122,24 +122,21 @@ func request(url string) (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", fmt.Errorf("Could not obtain IP address from html body")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run() starts the main loop for the poller.
|
// Run() starts the main loop for the poller.
|
||||||
func (i *IPAddressPoller) Run(stopCh <-chan struct{}) error {
|
func (i *IPAddressPoller) Run(stopCh <-chan struct{}) error {
|
||||||
if err := i.poll(); err != nil {
|
if err := i.poll(); err != nil {
|
||||||
log.Printf("Error polling for IP: %s %#v", err.Error(), err)
|
log.Printf("Error polling for IP: %v", err)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-time.After(i.pollInterval):
|
case <-time.After(i.pollInterval):
|
||||||
if err := i.poll(); err != nil {
|
if err := i.poll(); err != nil {
|
||||||
log.Printf("Error polling for IP: %s %#v", err.Error(), err)
|
log.Printf("Error polling for IP: %v", err)
|
||||||
}
|
}
|
||||||
case <-stopCh:
|
case <-stopCh:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -112,10 +112,10 @@ func (s *Syncer) UpdateRecord(dnsName, dnsType string, ttl int64, data []string)
|
|||||||
return fmt.Errorf("Domain %s not registered.", dnsName)
|
return fmt.Errorf("Domain %s not registered.", dnsName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// needsUpdate() returns true if the first DNSRecord needs to be
|
// needsUpdate() compares the left/local DNSRecord against the right/remote
|
||||||
// updated with the remote backend as compared to the remote
|
// DNSRecord and returns true if the record needs to be updated in the remote
|
||||||
// version of the DNSRecord.
|
// backend.
|
||||||
func needsUpdate(l backend.DNSRecord, r backend.DNSRecord) bool {
|
func needsUpdate(l, r backend.DNSRecord) bool {
|
||||||
if l == nil {
|
if l == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -175,14 +175,16 @@ func (s *Syncer) pollSingle(d *domainObj) error {
|
|||||||
|
|
||||||
// poll() runs a loop to poll the backend and update the remote cache.
|
// poll() runs a loop to poll the backend and update the remote cache.
|
||||||
func (s *Syncer) poll(d *domainObj, stopCh <-chan struct{}) {
|
func (s *Syncer) poll(d *domainObj, stopCh <-chan struct{}) {
|
||||||
|
// Start by polling the domain to initialize the remote value and local cache
|
||||||
|
// TODO: Implement some exponential retry backoff logic in case poll interval is long
|
||||||
if err := s.pollSingle(d); err != nil {
|
if err := s.pollSingle(d); err != nil {
|
||||||
log.Printf("Error polling DNS record %s %#v %#v %s", err.Error(), d, err)
|
log.Printf("Error polling DNS record %q: %v", d.managed.Name(), err)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-time.After(s.pollInterval):
|
case <-time.After(s.pollInterval):
|
||||||
if err := s.pollSingle(d); err != nil {
|
if err := s.pollSingle(d); err != nil {
|
||||||
log.Printf("Error polling DNS record: %s %#v %#v", err.Error(), d, err)
|
log.Printf("Error polling DNS record %q: %v", d.managed.Name(), err)
|
||||||
}
|
}
|
||||||
case <-stopCh:
|
case <-stopCh:
|
||||||
return
|
return
|
||||||
@ -210,7 +212,7 @@ func (s *Syncer) syncSingle(d *domainObj) error {
|
|||||||
if d.remote != nil {
|
if d.remote != nil {
|
||||||
deletions = []backend.DNSRecord{d.remote}
|
deletions = []backend.DNSRecord{d.remote}
|
||||||
}
|
}
|
||||||
log.Printf("Updating record: %#v", d.managed)
|
log.Printf("Updating record %v", d.managed.Name())
|
||||||
err := d.backend.UpdateRecords(ctx, additions, deletions)
|
err := d.backend.UpdateRecords(ctx, additions, deletions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -246,6 +248,8 @@ func (s *Syncer) sync(d *domainObj, stopCh <-chan struct{}) {
|
|||||||
|
|
||||||
// Run() starts the sync and poll loops
|
// Run() starts the sync and poll loops
|
||||||
func (s *Syncer) Run(stopCh <-chan struct{}) error {
|
func (s *Syncer) Run(stopCh <-chan struct{}) error {
|
||||||
|
// Run a sync and poll loop for each domain. Sync and poll loops are
|
||||||
|
// separated so that polling and syncing do not block on each other.
|
||||||
for _, d := range s.domains {
|
for _, d := range s.domains {
|
||||||
go s.poll(d, stopCh)
|
go s.poll(d, stopCh)
|
||||||
go s.sync(d, stopCh)
|
go s.sync(d, stopCh)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user