From 42552f43161a7545e56c60f5120e5a0e83c0cc51 Mon Sep 17 00:00:00 2001 From: Leo Antunes Date: Thu, 23 Aug 2018 00:25:12 +0200 Subject: [PATCH] add more error reporting and fallback mode for docker --- docker.go | 1 + etchosts.go | 44 ++++++++++++++++++++++++++++++++++++-------- main.go | 2 +- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/docker.go b/docker.go index da24cd1..e81abe8 100644 --- a/docker.go +++ b/docker.go @@ -132,6 +132,7 @@ func waitForConnection(client dockerClienter) { log.Info("retrying connection to docker") _, err := client.Ping(context.Background()) if err != nil { + log.Errorf("error pinging docker server: %s", err) return fmt.Errorf("error pinging docker server: %s", err) } return nil diff --git a/etchosts.go b/etchosts.go index 951c7bb..da412b1 100644 --- a/etchosts.go +++ b/etchosts.go @@ -17,8 +17,9 @@ const ( ) func writeToEtcHosts(ipsToNames ipsToNamesMap) error { - // this will fail if the file doesn't exist, which is probably ok - etcHosts, err := os.Open(config.EtcHostsPath) + // We do not want to create the hosts file; if it's not there, we probably have the wrong path. + // Open RW because we might have to write to it (see movePreservePerms) + etcHosts, err := os.OpenFile(config.EtcHostsPath, os.O_RDWR, 0644) if err != nil { return fmt.Errorf("could not open %s for reading: %s", config.EtcHostsPath, err) } @@ -55,7 +56,10 @@ func writeToEtcHosts(ipsToNames ipsToNamesMap) error { } ip := tokens[0] if names, ok := ipsToNames[ip]; ok { - writeEntryWithBanner(tmp, ip, names) + err = writeEntryWithBanner(tmp, ip, names) + if err != nil { + return err + } delete(ipsToNames, ip) // otherwise we'll append it again below } } else { @@ -63,10 +67,16 @@ func writeToEtcHosts(ipsToNames ipsToNamesMap) error { fmt.Fprintf(tmp, "%s\n", line) } } + if err := scanner.Err(); err != nil { + return fmt.Errorf("error reading %s: %s", config.EtcHostsPath, err) + } // append remaining entries to file for ip, names := range ipsToNames { - writeEntryWithBanner(tmp, ip, names) + err = writeEntryWithBanner(tmp, ip, names) + if err != nil { + return err + } } err = movePreservePerms(tmp, etcHosts) @@ -77,12 +87,17 @@ func writeToEtcHosts(ipsToNames ipsToNamesMap) error { return nil } -func writeEntryWithBanner(tmp io.Writer, ip string, names []string) { +func writeEntryWithBanner(tmp io.Writer, ip string, names []string) error { if len(names) > 0 { log.Debugf("writing entry for %s (%s)", ip, names) - fmt.Fprintf(tmp, "%s\n", banner) - fmt.Fprintf(tmp, "%s\t%s\n", ip, strings.Join(names, " ")) + if _, err := fmt.Fprintf(tmp, "%s\n", banner); err != nil { + return fmt.Errorf("error writing entry for %s: %s", ip, err) + } + if _, err := fmt.Fprintf(tmp, "%s\t%s\n", ip, strings.Join(names, " ")); err != nil { + return fmt.Errorf("error writing entry for %s: %s", ip, err) + } } + return nil } func movePreservePerms(src, dst *os.File) error { @@ -93,7 +108,20 @@ func movePreservePerms(src, dst *os.File) error { err = os.Rename(src.Name(), dst.Name()) if err != nil { - return fmt.Errorf("could not rename to %s: %s", config.EtcHostsPath, err) + log.Infof("could not rename to %s; falling back to less safe direct-write (%s)", config.EtcHostsPath, err) + + if _, err := src.Seek(0, io.SeekStart); err != nil { + return err + } + if _, err := dst.Seek(0, io.SeekStart); err != nil { + return err + } + if err := dst.Truncate(0); err != nil { + return err + } + + _, err = io.Copy(dst, src) + return err } // ensure we're not running with some umask that might break things diff --git a/main.go b/main.go index 9866cc3..b62b591 100644 --- a/main.go +++ b/main.go @@ -65,7 +65,7 @@ func main() { client, err := docker.NewEnvClient() if err != nil { - log.Fatalf("error starting docker client: %s", err) + log.Fatalf("error initializing docker client: %s", err) } defer client.Close()