mirror of
https://github.com/tailscale/tailscale.git
synced 2025-03-26 11:11:01 +00:00
logpolicy: add a temporary fixup for #247.
Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
parent
0dac03876a
commit
d4127db0fe
@ -18,6 +18,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -101,9 +102,9 @@ func (l logWriter) Write(buf []byte) (int, error) {
|
|||||||
// logsDir returns the directory to use for log configuration and
|
// logsDir returns the directory to use for log configuration and
|
||||||
// buffer storage.
|
// buffer storage.
|
||||||
func logsDir() string {
|
func logsDir() string {
|
||||||
systemdCacheDir := os.Getenv("CACHE_DIRECTORY")
|
systemdStateDir := os.Getenv("STATE_DIRECTORY")
|
||||||
if systemdCacheDir != "" {
|
if systemdStateDir != "" {
|
||||||
return systemdCacheDir
|
return systemdStateDir
|
||||||
}
|
}
|
||||||
|
|
||||||
cacheDir, err := os.UserCacheDir()
|
cacheDir, err := os.UserCacheDir()
|
||||||
@ -125,7 +126,6 @@ func logsDir() string {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic("no safe place found to store log state")
|
panic("no safe place found to store log state")
|
||||||
}
|
}
|
||||||
|
|
||||||
return tmp
|
return tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +138,155 @@ func runningUnderSystemd() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tryFixLogStateLocation is a temporary fixup for
|
||||||
|
// https://github.com/tailscale/tailscale/issues/247 . We accidentally
|
||||||
|
// wrote logging state files to /, and then later to $CACHE_DIRECTORY
|
||||||
|
// (which is incorrect because the log ID is not reconstructible if
|
||||||
|
// deleted - it's state, not cache data).
|
||||||
|
//
|
||||||
|
// If log state for cmdname exists in / or $CACHE_DIRECTORY, and no
|
||||||
|
// log state for that command exists in dir, then the log state is
|
||||||
|
// moved from whereever it does exist, into dir. Leftover logs state
|
||||||
|
// in / and $CACHE_DIRECTORY is deleted.
|
||||||
|
func tryFixLogStateLocation(dir, cmdname string) {
|
||||||
|
if cmdname == "" {
|
||||||
|
log.Printf("[unexpected] no cmdname given to tryFixLogStateLocation, please file a bug at https://github.com/tailscale/tailscale")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if dir == "/" {
|
||||||
|
// Trying to store things in / still. That's a bug, but don't
|
||||||
|
// abort hard.
|
||||||
|
log.Printf("[unexpected] storing logging config in /, please file a bug at https://github.com/tailscale/tailscale")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if os.Getuid() != 0 {
|
||||||
|
// Only root could have written log configs to weird places.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "linux", "freebsd", "openbsd":
|
||||||
|
// These are the OSes where we might have written stuff into
|
||||||
|
// root. Others use different logic to find the logs storage
|
||||||
|
// dir.
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// We stored logs in 2 incorrect places: either /, or CACHE_DIR
|
||||||
|
// (aka /var/cache/tailscale). We want to move files into the
|
||||||
|
// provided dir, preferring those in CACHE_DIR over those in / if
|
||||||
|
// both exist. If files already exist in dir, don't
|
||||||
|
// overwrite. Finally, once we've maybe moved files around, we
|
||||||
|
// want to delete leftovers in / and CACHE_DIR, to clean up after
|
||||||
|
// our past selves.
|
||||||
|
|
||||||
|
files := []string{
|
||||||
|
fmt.Sprintf("%s.log.conf", cmdname),
|
||||||
|
fmt.Sprintf("%s.log1.txt", cmdname),
|
||||||
|
fmt.Sprintf("%s.log2.txt", cmdname),
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks if any of the files above exist in d.
|
||||||
|
checkExists := func(d string) (bool, error) {
|
||||||
|
for _, file := range files {
|
||||||
|
p := filepath.Join(d, file)
|
||||||
|
_, err := os.Stat(p)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
continue
|
||||||
|
} else if err != nil {
|
||||||
|
return false, fmt.Errorf("stat %q: %w", p, err)
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
// move files from d into dir, if they exist.
|
||||||
|
moveFiles := func(d string) error {
|
||||||
|
for _, file := range files {
|
||||||
|
src := filepath.Join(d, file)
|
||||||
|
_, err := os.Stat(src)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
continue
|
||||||
|
} else if err != nil {
|
||||||
|
return fmt.Errorf("stat %q: %v", src, err)
|
||||||
|
}
|
||||||
|
dst := filepath.Join(dir, file)
|
||||||
|
bs, err := exec.Command("mv", src, dst).CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("mv %q %q: %v (%s)", src, dst, err, bs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
existsInRoot, err := checkExists("/")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("checking for configs in /: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
existsInCache := false
|
||||||
|
cacheDir := os.Getenv("CACHE_DIRECTORY")
|
||||||
|
if cacheDir != "" {
|
||||||
|
existsInCache, err = checkExists("/var/cache/tailscale")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("checking for configs in %s: %v", cacheDir, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
existsInDest, err := checkExists(dir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("checking for configs in %s: %v", dir, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case !existsInRoot && !existsInCache:
|
||||||
|
// No leftover files, nothing to do.
|
||||||
|
return
|
||||||
|
case existsInDest:
|
||||||
|
// Already have "canonical" configs, just delete any remnants
|
||||||
|
// (below).
|
||||||
|
case existsInCache:
|
||||||
|
// CACHE_DIRECTORY takes precedence over /, move files from
|
||||||
|
// there.
|
||||||
|
if err := moveFiles(cacheDir); err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case existsInRoot:
|
||||||
|
// Files from root is better than nothing.
|
||||||
|
if err := moveFiles("/"); err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If moving succeeded, or we didn't need to move files, try to
|
||||||
|
// delete any leftover files, but it's okay if we can't delete
|
||||||
|
// them for some reason.
|
||||||
|
dirs := []string{}
|
||||||
|
if existsInCache {
|
||||||
|
dirs = append(dirs, cacheDir)
|
||||||
|
}
|
||||||
|
if existsInRoot {
|
||||||
|
dirs = append(dirs, "/")
|
||||||
|
}
|
||||||
|
for _, d := range dirs {
|
||||||
|
for _, file := range files {
|
||||||
|
p := filepath.Join(d, file)
|
||||||
|
_, err := os.Stat(p)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
continue
|
||||||
|
} else if err != nil {
|
||||||
|
log.Printf("stat %q: %v", p, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := os.Remove(p); err != nil {
|
||||||
|
log.Printf("rm %q: %v", p, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// New returns a new log policy (a logger and its instance ID) for a
|
// New returns a new log policy (a logger and its instance ID) for a
|
||||||
// given collection name.
|
// given collection name.
|
||||||
func New(collection string) *Policy {
|
func New(collection string) *Policy {
|
||||||
@ -155,6 +304,9 @@ func New(collection string) *Policy {
|
|||||||
console := log.New(stderrWriter{}, "", lflags)
|
console := log.New(stderrWriter{}, "", lflags)
|
||||||
|
|
||||||
dir := logsDir()
|
dir := logsDir()
|
||||||
|
|
||||||
|
tryFixLogStateLocation(dir, version.CmdName())
|
||||||
|
|
||||||
cfgPath := filepath.Join(dir, fmt.Sprintf("%s.log.conf", version.CmdName()))
|
cfgPath := filepath.Join(dir, fmt.Sprintf("%s.log.conf", version.CmdName()))
|
||||||
var oldc *Config
|
var oldc *Config
|
||||||
data, err := ioutil.ReadFile(cfgPath)
|
data, err := ioutil.ReadFile(cfgPath)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user