wolfcw / libfaketime

libfaketime modifies the system time for a single application
https://github.com/wolfcw/libfaketime
GNU General Public License v2.0
2.64k stars 321 forks source link

Compile issue on timescaledb docker image: Alpine Linux v3.16 #405

Closed sc-atompower closed 2 years ago

sc-atompower commented 2 years ago

trying to configure my container to trick the database into always thinking now() is a certain time. possibly related to https://github.com/wolfcw/libfaketime/issues/369

bash-5.1# make
cc -o libfaketime.o -c -std=gnu99 -Wall -Wextra -Werror -Wno-nonnull-compare -DFAKE_PTHREAD -DFAKE_STAT -DFAKE_UTIME -DFAKE_SLEEP -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -fPIC -DPREFIX='"'/usr/local'"' -DLIBDIRNAME='"'/lib/faketime'"'    libfaketime.c
make: cc: No such file or directory
make: *** [Makefile:145: libfaketime.o] Error 127

Operating system

bash-5.1# cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.16.0
PRETTY_NAME="Alpine Linux v3.16"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"

Make

bash-5.1# make -v
GNU Make 4.3
Built for x86_64-alpine-linux-musl
Copyright (C) 1988-2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

I know its a bit of a docker issue but this is the setup

FROM timescale/timescaledb:latest-pg13
RUN apk update
RUN apk add git
RUN apk add make
WORKDIR /
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime/src
RUN make install
wolfcw commented 2 years ago

make: cc: No such file or directory

Indicates that there is no C compiler on your system/container. You probably need to install one before compiling libfaketime from the source (similar to how you install git and make).

sc-atompower commented 2 years ago

@wolfcw yep. one of those days. I added

FROM timescale/timescaledb:latest-pg13
RUN apk update
RUN apk add git
RUN apk add make
RUN apk add gcc
RUN apk add libc-dev

and that solved the issue. Now its on to

libfaketime: In ft_shm_init(), sem_open failed and recreation attempts failed: Permission denied
2022-07-28T17:52:01.978832300Z libfaketime: sem_name was /faketime_sem_1, created locally: false

It seems this has come up a few time but none of the solutions are working for me; yet.

wolfcw commented 2 years ago

Can be a wide range of causes.

Usually, you might not want to run libfaketime for all of the container, but just for the process/application you really need the faked time for.

The error means that libfaketime cannot read the shared memory segment / semaphore created by a parent process, here with process id 1 (classically "init" or something comparable for Docker containers). This might be caused by the process with PID 1 running as "root" while your target application does not run as root. Or there could be restrictions for the whole container / containerized OS regarding the use of shared memory. I don't know.

The solution is typically to use the faketime command (or LD_PRELOADing the library manually) as late as possible in the entrypoint script, just before the application process is started. Never preload it from the Dockerfile unless there's a good reason.

sc-atompower commented 2 years ago

So it this not something we can use with prebuilt images that are not open source? I have no control over the entry point script of this image. I've exported it to my desktop, modified it to set faketime at the very end and injected it at build time and I'm still getting the semaphore issue. I'll head to the timescale repo and see if they can tell me the exact file that starts up postgres and try to modify that and overwrite it.

wolfcw commented 2 years ago

libfaketime works by LD_PRELOADing it to the target application. If your environment (e.g., prebuilt something) does not give you that level of control, it's usually not the best precondition. Sure, you can try to LD_PRELOAD libfaketime to that whole environment (and everything inside), but that's like flooding a whole city just to wash some dishes.

Again, the error means that libfaketime does not have access to a shared memory segment within your container. It's a simply file system permissions problem, likely caused by a root vs. non-root thing or general container security settings. You might even want to have a look at #379.

sc-atompower commented 2 years ago

@wolfcw thank you for helping me along the way. For anyone who runs across this issue, more specifically working with timescaledb, swap to the builting postgres user before executing faketime. The following solved my issue.

FROM timescale/timescaledb:latest-pg13
RUN apk update
RUN apk add make
RUN apk add gcc
RUN apk add git
RUN apk add libc-dev

WORKDIR /
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime/src
RUN make install

ENV POSTGRES_USER whatever
ENV POSTGRES_PASSWORD apassword

USER postgres
ENV FAKETIME 2020-01-01 00:00:00
ENV LD_PRELOAD /usr/local/lib/faketime/libfaketime.so.1

The game changer here was USER postgres