When developing the next bot for the group in Telegram, I had the need to test it with different system time values. At the end of each day, this bot sends (or, depending on a number of conditions, does not send) a message to the chat and performs manipulations with some of its previous messages (or, again, does not produce).
Change system time globally oh how did not want. It’s a chore, plus I have so much to say in it, God forbid something will turn up (hardly, but you never know). I thought to launch VirtualBox, but it was too lazy to put a “clean” Ubuntu, to share folders, etc., especially since this option eating like a troglodyte seriously consumes engine resources.
But just recently, I started picking Docker. “It just has to have a system time control mechanism inside the container,” I thought. Consider what happened as a result.
So, create a container and climb into it:
docker run -it ubuntu bash
I’ll say right away that in the container I work as root
, so sudo
not required.
I try:
date --set='2017-04-20 23:59:50'
Displays date: cannot set date: Operation not permitted
I try:
hwclock --set --date='2017-04-20 23:59:50'
Gives hwclock: Cannot access the Hardware Clock via any known method.
Does not exceed. Googling a bit, stumble upon this answer . It seems that Docker does not produce virtualization as deeply as it seemed to me. He uses the system time, and there is no way to get out. Is it possible to play around with time zones, but in my case it is not good, I need full control over time.
Another option - in my program to intercept calls to the system time, but, again, a chore. But literally on the floor above there is a response pointing to some kind of libfaketime library . With it, you can substitute "fake time" for the process being started. So, install it in a container:
git clone https://github.com/wolfcw/libfaketime.git cd libfaketime make install
Next, following the instructions in the response, I launch the bot with the specified environment variables:
LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME_NO_CACHE=1 FAKETIME="2017-04-19 23:59:50" ./run.sh --debug#
Where in the LD_PRELOAD
substitute the newly installed library, and in FAKETIME
we write the time we want to set for the process being started. FAKETIME_NO_CACHE
used in the example and presumably disables the caching used to improve performance. Did not test, but I believe that this parameter is optional.
So, the program started, and really time was exposed as I wanted. Only with one problem - time stopped . Messages debug show constantly [2017-04-19 23:59:50]
. There is one non-intuitive feature in this library. A simple task of time really sets and fixes it. In FAKETIME='@2017-04-19 23:59:50'
for time exactly to start from this point, you need to set it as FAKETIME='@2017-04-19 23:59:50'
. And the time will go from this point.
It turns out that everything is even easier. A little later, I discovered that this library is in the standard Ubuntu repositories, and is quietly apt-get install faketime
via apt-get install faketime
. And it starts like this:
faketime -f '@2017-04-20 23:59:50' ./run.sh
Do not forget about @ before time, here is the same syntax, but in a rather brief man
it does not say. Only in the detailed description on Github.
This way, you can quickly and easily adjust the time perceived by the program being launched, whether it is in a Docker container or in a host system. The answer indicated that if you need to change the “fake time” from the program itself, then it is enough to change the global variable. For example, on Python:
os.environ["FAKETIME"] = "2020-01-01"
Perhaps there are other, more convenient ways to control the time for the process? Tell about them in the comments.
Source: https://habr.com/ru/post/326772/
All Articles