From 82d9f888640a82f71dfefe44d557c593fc34f0f0 Mon Sep 17 00:00:00 2001 From: Kubilay Kocak Date: Fri, 2 Dec 2022 22:49:41 +0000 Subject: [PATCH 7/7] coderd/tz: Add FreeBSD tz support `./scripts/build_go.sh --os freebsd` fails to build with the following (unique) errors: cli/schedule.go:223:19: undefined: tz.TimezoneIANA cli/util.go:116:17: undefined: tz.TimezoneIANA coderd/util/tz currently contains per-OS implementions (one file per supported OS), but is missing a tz_freebsd.go. Follow the existing pattern by creating a tz_freebsd.go from tz_linux.go. FreeBSD supports standard IANA zoneinfo (and /etc/localtime), so no other changes are required. Fixes: #4516 --- coderd/util/tz/tz_freebsd.go | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 coderd/util/tz/tz_freebsd.go diff --git a/coderd/util/tz/tz_freebsd.go b/coderd/util/tz/tz_freebsd.go new file mode 100644 index 00000000..1008edca --- /dev/null +++ b/coderd/util/tz/tz_freebsd.go @@ -0,0 +1,43 @@ +//go:build freebsd + +package tz + +import ( + "path/filepath" + "strings" + "time" + + "golang.org/x/xerrors" +) + +const etcLocaltime = "/etc/localtime" +const zoneInfoPath = "/usr/share/zoneinfo" + +// TimezoneIANA attempts to determine the local timezone in IANA format. +// If the TZ environment variable is set, this is used. +// Otherwise, /etc/localtime is used to determine the timezone. +// Reference: https://stackoverflow.com/a/63805394 +// On Windows platforms, instead of reading /etc/localtime, powershell +// is used instead to get the current time location in IANA format. +// Reference: https://superuser.com/a/1584968 +func TimezoneIANA() (*time.Location, error) { + loc, err := locationFromEnv() + if err == nil { + return loc, nil + } + if !xerrors.Is(err, errNoEnvSet) { + return nil, xerrors.Errorf("lookup timezone from env: %w", err) + } + + lp, err := filepath.EvalSymlinks(etcLocaltime) + if err != nil { + return nil, xerrors.Errorf("read location of %s: %w", etcLocaltime, err) + } + stripped := strings.Replace(lp, zoneInfoPath, "", -1) + stripped = strings.TrimPrefix(stripped, string(filepath.Separator)) + loc, err = time.LoadLocation(stripped) + if err != nil { + return nil, xerrors.Errorf("invalid location %q guessed from %s: %w", stripped, lp, err) + } + return loc, nil +} -- 2.38.1