Sho
Sho

Reputation: 353

How to correct system clock in vagrant automatically

How to Correct Timezone

Last time, I figured out how to adjust a system clock in vagrant server. However, when I halt the vagrant and start it again, the system clock is always 9 hours late. I can adjust by using ntp command manually, but I'd like to know how to adjust the system clock automatically.

I have tried the below, but it still doesn't work. Are there any suggestions?

How to sync time on host wake-up within VirtualBox?

Upvotes: 32

Views: 28556

Answers (9)

Benny K
Benny K

Reputation: 1247

Accepted answer is not robust enough, as it does not account for people who travel between timezones, and requires end users to modify Vagrantfile instead of just doing vagrant up.

Building up on Scott P.'s answer, here's a better more flexible solution that matches VM timezone to host's tz automatically. There's a typo/mistake in his snippet's Etc/GMT time zone selection, as per POSIX GMT+7 sets clock 7 hours behind (see Wiki explanation), hence we need to swap offsets:

Vagrant.configure("2") do |config|
  require 'time'
  offset = ((Time.zone_offset(Time.now.zone) / 60) / 60)
  timezone_suffix = offset >= 0 ? "-#{offset.to_s}" : "+#{offset.to_s}"
  timezone = 'Etc/GMT' + timezone_suffix
  config.vm.provision :shell, :inline => "sudo rm /etc/localtime && sudo ln -s /usr/share/zoneinfo/" + timezone + " /etc/localtime", run: "always"
end

Upvotes: 10

Priyank Gosalia
Priyank Gosalia

Reputation: 6660

The simplest way is to set the timezone automatically is to use the vagrant-timezone plugin.

Install it once with:

vagrant plugin install vagrant-timezone



After that, add the below to your Vagrantfile:

if Vagrant.has_plugin?("vagrant-timezone")
   config.timezone.value = "UTC"
end

You may replace "UTC" with any of the tz values listed here. For example: "Asia/Kolkata".



Or you can use your host's timezone with this entry in your Vagrantfile:

if Vagrant.has_plugin?("vagrant-timezone")
   config.timezone.value = :host
end

Upvotes: 19

The way is to set the timezone automatically same like host using the vagrant-timezone plugin.

Install the vagrant-timezone plugin with

vagrant plugin install vagrant-timezone

After that, add the below to your Vagrantfile

config.timezone.value = :host

Note that this functionality has only been tested with an OS X host and Linux guest.

Upvotes: 0

Lanti
Lanti

Reputation: 2339

@Benny K and @Scott P.'s solution giving me the negative value of a timezone, like in @rubo77's case. Worth to note that my host OS is Windows. If timedatectl is present on your guests (like Debian 9+), this is what I used to change timezone settings:

config.vm.provision "shell",
    inline: "timedatectl set-timezone Europe/Budapest",
    run: "always" 

This one returns the expected timezone, not the negative value:

# before timedatectl
vagrant@master:~$ timedatectl
               Local time: Fri 2020-07-03 11:52:31 -02
           Universal time: Fri 2020-07-03 13:52:31 UTC
                 RTC time: Fri 2020-07-03 13:52:31
                Time zone: Etc/GMT+2 (-02, -0200)
System clock synchronized: no
              NTP service: inactive
          RTC in local TZ: no

# after timedatectl
vagrant@master:~$ timedatectl
               Local time: Fri 2020-07-03 15:53:24 CEST
           Universal time: Fri 2020-07-03 13:53:24 UTC
                 RTC time: Fri 2020-07-03 13:53:24
                Time zone: Europe/Budapest (CEST, +0200)
System clock synchronized: no
              NTP service: inactive
          RTC in local TZ: no

Upvotes: 2

Based on @Benny K.'s answer (https://stackoverflow.com/a/46778032/3194807), with the daylight saving time taken into account:

require "time"
offset = ((Time.zone_offset(Time.now.zone) / 60) / 60) + (Time.now.dst? ? 1 : 0)
timezone_suffix = offset >= 0 ? "-#{offset.to_s}" : "+#{offset.to_s}"
timezone = 'Etc/GMT' + timezone_suffix

tzShellProvision = <<_SHELL_
    ln -fs /usr/share/zoneinfo/#{timezone} /etc/localtime
    dpkg-reconfigure -f noninteractive tzdata
_SHELL_

default.vm.provision :shell, inline: tzShellProvision, run: "always"

Upvotes: 1

Peter de Zwart
Peter de Zwart

Reputation: 71

I got:

[vagrant@ansiblecontrol ~]$ date -s \"$(curl -I google.com 2>&1 | grep Date: | cut -d' ' -f3-6)Z\"
date: extra operand ‘2018’
Try 'date --help' for more information.

This works for me:

sudo date -s "$(curl -I google.com 2>&1 | grep Date: | cut -d' ' -f3-6)Z"
Sun Apr  1 16:36:59 CEST 2018

So removed the "\" escape character.

Upvotes: 6

Joyce Babu
Joyce Babu

Reputation: 20694

My Vagrant Guest OS time was out of sync by 7 days. The above methods did not work for me, since Guest additions and ntp were not installed in my Guest machine.

I finally solved the issue by using the hack from https://askubuntu.com/a/683136/119371

cfg.vm.provision "shell", inline: "date -s \"$(wget -qSO- --max-redirect=0 google.com 2>&1 | grep Date: | cut -d' ' -f5-8)Z\"", run: "always", privileged: true, upload_path: "/home/vagrant/tmp/vagrant-shell"

The above method does not sync the Guest OS time with your host machine or any NTP server. It sends an HTTP request to google.com and updates the system time with the time in the HTTP response header field.

Hence, depending on your internet connection speed and latency, the updated time could be off by several milliseconds to a few seconds (usually < 100ms). But it shouldn't matter for most cases.

Following is the curl version, if you don't want to use wget for any reason

cfg.vm.provision "shell", inline: "date -s \"$(curl -I google.com 2>&1 | grep Date: | cut -d' ' -f3-6)Z\""

Upvotes: 3

Scott P.
Scott P.

Reputation: 1074

A slightly improved version that auto-detects timezone:

The auto-detect portion came from here.

Vagrant.configure("2") do |config|
  require 'time'
  offset = ((Time.zone_offset(Time.now.zone) / 60) / 60)
  timezone_suffix = offset >= 0 ? "+#{offset.to_s}" : "#{offset.to_s}"
  timezone = 'Etc/GMT' + timezone_suffix
  config.vm.provision :shell, :inline => "sudo rm /etc/localtime && sudo ln -s /usr/share/zoneinfo/" + timezone + " /etc/localtime", run: "always"
end

Upvotes: 4

Frederic Henri
Frederic Henri

Reputation: 53773

The method I use and it should not be provider specific is to add the following in my Vagrantfile

  config.vm.provision :shell, :inline => "sudo rm /etc/localtime && sudo ln -s /usr/share/zoneinfo/Europe/Paris /etc/localtime", run: "always"

you would need to replace '/Europe/Paris' with the timezone you want to set

Upvotes: 45

Related Questions