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

Set guest timezone from host setting #2097

Merged
merged 1 commit into from
Dec 25, 2023
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
5 changes: 5 additions & 0 deletions examples/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ rosetta:
# 🟢 Builtin default: false
binfmt: null

# Specify the timezone name (as used by the zoneinfo database). Specify the empty string
# to not set a timezone in the instance.
# 🟢 Builtin default: use name from /etc/timezone or deduce from symlink target of /etc/localtime
timezone: null

firmware:
# Use legacy BIOS instead of UEFI. Ignored for aarch64.
# 🟢 Builtin default: false
Expand Down
12 changes: 12 additions & 0 deletions pkg/cidata/cidata.TEMPLATE.d/boot/04-persistent-data-volume.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ if [ "$(awk '$2 == "/" {print $3}' /proc/mounts)" == "tmpfs" ]; then
# Update /etc files that might have changed during this boot
cp /etc/network/interfaces /mnt/data/etc/network/
cp /etc/resolv.conf /mnt/data/etc/
if [ -f /etc/localtime ]; then
# Preserve symlink
cp -d /etc/localtime /mnt/data/etc/
# setup-timezone copies the single zoneinfo file into /etc/zoneinfo and targets the symlink there
if [ -d /etc/zoneinfo ]; then
rm -rf /mnt/data/etc/zoneinfo
cp -r /etc/zoneinfo /mnt/data/etc
fi
fi
if [ -f /etc/timezone ]; then
cp /etc/timezone /mnt/data/etc/
fi
# TODO there are probably others that should be updated as well
else
# Find an unpartitioned disk and create data-volume
Expand Down
4 changes: 4 additions & 0 deletions pkg/cidata/cidata.TEMPLATE.d/user-data
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ mounts:
{{- end }}
{{- end }}

{{- if .TimeZone }}
timezone: {{.TimeZone}}
{{- end }}

users:
- name: "{{.User}}"
uid: "{{.UID}}"
Expand Down
1 change: 1 addition & 0 deletions pkg/cidata/cidata.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort
VMType: *y.VMType,
VSockPort: vsockPort,
Plain: *y.Plain,
TimeZone: *y.TimeZone,
}

firstUsernetIndex := limayaml.FirstUsernetIndex(y)
Expand Down
1 change: 1 addition & 0 deletions pkg/cidata/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ type TemplateArgs struct {
VMType string
VSockPort int
Plain bool
TimeZone string
}

func ValidateTemplateArgs(args TemplateArgs) error {
Expand Down
41 changes: 36 additions & 5 deletions pkg/limayaml/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ import (
"path/filepath"
"runtime"
"strconv"
"strings"
"text/template"

"github.com/docker/go-units"
"github.com/lima-vm/lima/pkg/networks"
"github.com/lima-vm/lima/pkg/ptr"
"github.com/pbnjay/memory"
"github.com/sirupsen/logrus"
"golang.org/x/sys/cpu"

"github.com/lima-vm/lima/pkg/guestagent/api"
"github.com/lima-vm/lima/pkg/networks"
"github.com/lima-vm/lima/pkg/osutil"
"github.com/lima-vm/lima/pkg/ptr"
"github.com/lima-vm/lima/pkg/store/dirnames"
"github.com/lima-vm/lima/pkg/store/filenames"
"github.com/sirupsen/logrus"

"golang.org/x/sys/cpu"
)

const (
Expand Down Expand Up @@ -83,6 +83,26 @@ func MACAddress(uniqueID string) string {
return hw.String()
}

func hostTimeZone() string {
// WSL2 will automatically set the timezone
if runtime.GOOS != "windows" {
tz, err := os.ReadFile("/etc/timezone")
if err == nil {
return strings.TrimSpace(string(tz))
}
zoneinfoFile, err := filepath.EvalSymlinks("/etc/localtime")
if err == nil {
for baseDir := filepath.Dir(zoneinfoFile); baseDir != "/"; baseDir = filepath.Dir(baseDir) {
if _, err = os.Stat(filepath.Join(baseDir, "Etc/UTC")); err == nil {
return strings.TrimPrefix(zoneinfoFile, baseDir+"/")
}
}
logrus.Warnf("could not locate zoneinfo directory from %q", zoneinfoFile)
}
}
return ""
}

func defaultCPUs() int {
const x = 4
if hostCPUs := runtime.NumCPU(); hostCPUs < x {
Expand Down Expand Up @@ -325,6 +345,16 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
}
}

if y.TimeZone == nil {
y.TimeZone = d.TimeZone
}
if o.TimeZone != nil {
y.TimeZone = o.TimeZone
}
if y.TimeZone == nil {
y.TimeZone = ptr.Of(hostTimeZone())
}

if y.SSH.LocalPort == nil {
y.SSH.LocalPort = d.SSH.LocalPort
}
Expand Down Expand Up @@ -731,6 +761,7 @@ func fixUpForPlainMode(y *LimaYAML) {
y.Containerd.User = ptr.Of(false)
y.Rosetta.BinFmt = ptr.Of(false)
y.Rosetta.Enabled = ptr.Of(false)
y.TimeZone = ptr.Of("")
}

func executeGuestTemplate(format string) (bytes.Buffer, error) {
Expand Down
5 changes: 5 additions & 0 deletions pkg/limayaml/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func TestFillDefault(t *testing.T) {
ForwardX11: ptr.Of(false),
ForwardX11Trusted: ptr.Of(false),
},
TimeZone: ptr.Of(hostTimeZone()),
Firmware: Firmware{
LegacyBIOS: ptr.Of(false),
},
Expand Down Expand Up @@ -181,6 +182,7 @@ func TestFillDefault(t *testing.T) {
"-----BEGIN CERTIFICATE-----\nYOUR-ORGS-TRUSTED-CA-CERT\n-----END CERTIFICATE-----\n",
},
},
TimeZone: ptr.Of("Antarctica/Troll"),
Firmware: Firmware{
LegacyBIOS: ptr.Of(false),
Images: []FileWithVMType{
Expand Down Expand Up @@ -273,6 +275,7 @@ func TestFillDefault(t *testing.T) {
},
}

expect.TimeZone = y.TimeZone
expect.Firmware = y.Firmware

expect.Rosetta = Rosetta{
Expand Down Expand Up @@ -320,6 +323,7 @@ func TestFillDefault(t *testing.T) {
ForwardX11: ptr.Of(false),
ForwardX11Trusted: ptr.Of(false),
},
TimeZone: ptr.Of("Zulu"),
Firmware: Firmware{
LegacyBIOS: ptr.Of(true),
Images: []FileWithVMType{
Expand Down Expand Up @@ -512,6 +516,7 @@ func TestFillDefault(t *testing.T) {
ForwardX11: ptr.Of(false),
ForwardX11Trusted: ptr.Of(false),
},
TimeZone: ptr.Of("Universal"),
Firmware: Firmware{
LegacyBIOS: ptr.Of(true),
},
Expand Down
1 change: 1 addition & 0 deletions pkg/limayaml/limayaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type LimaYAML struct {
CACertificates CACertificates `yaml:"caCerts,omitempty" json:"caCerts,omitempty"`
Rosetta Rosetta `yaml:"rosetta,omitempty" json:"rosetta,omitempty"`
Plain *bool `yaml:"plain,omitempty" json:"plain,omitempty"`
TimeZone *string `yaml:"timezone,omitempty" json:"timezone,omitempty"`
}

type (
Expand Down
Loading