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

Help getting Oracle Linux guest running #4969

Open
jackdouglas opened this issue Dec 24, 2024 · 2 comments
Open

Help getting Oracle Linux guest running #4969

jackdouglas opened this issue Dec 24, 2024 · 2 comments

Comments

@jackdouglas
Copy link

I use firecracker for many of the database backends on db<>fiddle, which has been working fine for years. I can run Debian and even Alpine guests but I've always had trouble with RHEL clones like Oracle Linux.

They boot ok but don't let me log in - with this dockerfile I get stuck without a tty:

FROM mysql:8.4-oraclelinux9
RUN microdnf install -y systemd
RUN echo '[Service]' > /etc/systemd/system/fiddle.service \
  && echo 'ExecStart=/fiddle.sh' >> /etc/systemd/system/fiddle.service \
  && echo '[Install]' >> /etc/systemd/system/fiddle.service \
  && echo 'WantedBy=default.target' >> /etc/systemd/system/fiddle.service \
  && systemctl enable fiddle
RUN echo '[Service]' > /etc/systemd/system/mysqld.service \
  && echo 'ExecStart=/usr/sbin/mysqld --user=root --skip-networking --daemonize' >> /etc/systemd/system/mysqld.service \
  && echo '[Install]' >> /etc/systemd/system/mysqld.service \
  && echo 'RequiredBy=fiddle.service' >> /etc/systemd/system/mysqld.service \
  && systemctl enable mysqld
RUN echo ttyS0 > /etc/securetty
RUN microdnf clean all
RUN echo "root:Docker!" | chpasswd
ENTRYPOINT ["bash"]

and today I finally got a login prompt for the first time, but logging in a 'no login shell' error with this dockerfile:

FROM mysql:8.4-oraclelinux9
RUN microdnf install -y systemd
RUN echo '[Service]' > /etc/systemd/system/fiddle.service \
  && echo 'ExecStart=/fiddle.sh' >> /etc/systemd/system/fiddle.service \
  && echo '[Install]' >> /etc/systemd/system/fiddle.service \
  && echo 'WantedBy=default.target' >> /etc/systemd/system/fiddle.service \
  && systemctl enable fiddle
RUN echo '[Service]' > /etc/systemd/system/mysqld.service \
  && echo 'ExecStart=/usr/sbin/mysqld --user=root --skip-networking --daemonize' >> /etc/systemd/system/mysqld.service \
  && echo '[Install]' >> /etc/systemd/system/mysqld.service \
  && echo 'RequiredBy=fiddle.service' >> /etc/systemd/system/mysqld.service \
  && systemctl enable mysqld
RUN echo ttyS0 > /etc/securetty \
  && echo '[Service]' > /etc/systemd/system/mygetty.service \
  && echo 'ExecStart=/usr/sbin/agetty -L 9600 ttyS0 vt102' >> /etc/systemd/system/mygetty.service \
  && echo '[Install]' >> /etc/systemd/system/mygetty.service \
  && echo 'RequiredBy=fiddle.service' >> /etc/systemd/system/mygetty.service \
  && systemctl enable mygetty
RUN microdnf clean all
RUN echo "root:Docker!" | chpasswd
ENTRYPOINT ["bash"]

in both cases I'm building the rootfs like this:

DOCKER_BUILDKIT=1 docker build -t dummy - < DOCKERFILE
dd if=/dev/zero bs=1M count=1000 > rootfs.ext4
mkfs.ext4 rootfs.ext4
mount -o loop rootfs.ext4 mnt
docker run --rm -ti -v mnt:/my-rootfs dummy
for d in bin etc home lib lib64 opt root sbin usr dev run var; do tar c "/$d" | tar x -C /my-rootfs; done
for dir in proc sys; do mkdir /my-rootfs/${dir}; done
exit

Is there something obvious I'm doing wrong? I'm really keen to add later versions of MySQL to dbfiddle but the official docker images are all Oracle Linux based since 8.0.

@hackeroneulevel
Copy link

Issue Overview
I use Firecracker to power many database backends on db<>fiddle, and while it has worked reliably for years with Debian and Alpine guests, RHEL-based distributions like Oracle Linux present challenges. The guests boot successfully but don't allow me to log in.

For example, using the following Dockerfile, I am unable to get a TTY:

FROM mysql:8.4-oraclelinux9
RUN microdnf install -y systemd
RUN echo '[Service]' > /etc/systemd/system/fiddle.service \
  && echo 'ExecStart=/fiddle.sh' >> /etc/systemd/system/fiddle.service \
  && echo '[Install]' >> /etc/systemd/system/fiddle.service \
  && echo 'WantedBy=default.target' >> /etc/systemd/system/fiddle.service \
  && systemctl enable fiddle
RUN echo '[Service]' > /etc/systemd/system/mysqld.service \
  && echo 'ExecStart=/usr/sbin/mysqld --user=root --skip-networking --daemonize' >> /etc/systemd/system/mysqld.service \
  && echo '[Install]' >> /etc/systemd/system/mysqld.service \
  && echo 'RequiredBy=fiddle.service' >> /etc/systemd/system/mysqld.service \
  && systemctl enable mysqld
RUN echo ttyS0 > /etc/securetty
RUN microdnf clean all
RUN echo "root:Docker!" | chpasswd
ENTRYPOINT ["bash"]

With modifications, I managed to get a login prompt, but encountered a "no login shell" error. Here's the updated Dockerfile:

FROM mysql:8.4-oraclelinux9
RUN microdnf install -y systemd
RUN echo '[Service]' > /etc/systemd/system/fiddle.service \
  && echo 'ExecStart=/fiddle.sh' >> /etc/systemd/system/fiddle.service \
  && echo '[Install]' >> /etc/systemd/system/fiddle.service \
  && echo 'WantedBy=default.target' >> /etc/systemd/system/fiddle.service \
  && systemctl enable fiddle
RUN echo '[Service]' > /etc/systemd/system/mysqld.service \
  && echo 'ExecStart=/usr/sbin/mysqld --user=root --skip-networking --daemonize' >> /etc/systemd/system/mysqld.service \
  && echo '[Install]' >> /etc/systemd/system/mysqld.service \
  && echo 'RequiredBy=fiddle.service' >> /etc/systemd/system/mysqld.service \
  && systemctl enable mysqld
RUN echo ttyS0 > /etc/securetty \
  && echo '[Service]' > /etc/systemd/system/mygetty.service \
  && echo 'ExecStart=/usr/sbin/agetty -L 9600 ttyS0 vt102' >> /etc/systemd/system/mygetty.service \
  && echo '[Install]' >> /etc/systemd/system/mygetty.service \
  && echo 'RequiredBy=fiddle.service' >> /etc/systemd/system/mygetty.service \
  && systemctl enable mygetty
RUN microdnf clean all
RUN echo "root:Docker!" | chpasswd
ENTRYPOINT ["bash"]

Steps to Build the Root Filesystem
I use the following process to build the root filesystem:

DOCKER_BUILDKIT=1 docker build -t dummy - < DOCKERFILE
dd if=/dev/zero bs=1M count=1000 > rootfs.ext4
mkfs.ext4 rootfs.ext4
mount -o loop rootfs.ext4 mnt
docker run --rm -ti -v mnt:/my-rootfs dummy
for d in bin etc home lib lib64 opt root sbin usr dev run var; do tar c "/$d" | tar x -C /my-rootfs; done
for dir in proc sys; do mkdir /my-rootfs/${dir}; done
exit

Current Status
Even with the updates, I am unable to get a working login shell. Is there something obvious I'm missing? I would appreciate any insights or solutions to enable me to incorporate the official Oracle Linux-based Docker images (used in MySQL 8.0 and later) into db<>fiddle.

@hackeroneulevel
Copy link

Your issue seems related to how the login shell is being set up and the configuration of agetty for Oracle Linux inside your Firecracker-based environment. Here's a breakdown of potential issues and their solutions:


1. No Login Shell

The no login shell error may occur due to missing or improperly configured getty services, bash not being properly set as the default shell, or environment configuration issues.

Fix:

Ensure agetty is set up correctly and bash is available and correctly configured. Update your [Dockerfile] as follows:

RUN echo 'root:x:0:0:root:/root:/bin/bash' > /etc/passwd
RUN echo 'ttyS0' > /etc/securetty

The passwd file explicitly ensures that root has /bin/bash as its shell.


2. agetty Service Configuration

Your mygetty.service configuration may not be linked correctly to systemd. Here's a cleaner version of the service file:

RUN echo '[Unit]' > /etc/systemd/system/mygetty.service \
  && echo 'Description=Serial Console Login' >> /etc/systemd/system/mygetty.service \
  && echo '[Service]' >> /etc/systemd/system/mygetty.service \
  && echo 'ExecStart=/usr/sbin/agetty -L 9600 ttyS0 vt102' >> /etc/systemd/system/mygetty.service \
  && echo '[Install]' >> /etc/systemd/system/mygetty.service \
  && echo 'WantedBy=multi-user.target' >> /etc/systemd/system/mygetty.service \
  && systemctl enable mygetty

Ensure multi-user.target is included as it aligns with the expected systemd runlevels.


3. Running Services

You need to ensure systemd is running properly in the root filesystem. Replace ENTRYPOINT ["bash"] with:

CMD ["/usr/sbin/init"]

This ensures that systemd starts and manages your agetty service.


4. Root Filesystem Construction

When creating the root filesystem, you might miss essential files or device nodes. Update your rootfs creation steps as follows:

# Create device nodes required for `systemd` and `agetty`
mknod -m 666 mnt/dev/null c 1 3
mknod -m 666 mnt/dev/zero c 1 5
mknod -m 666 mnt/dev/tty c 5 0
mknod -m 666 mnt/dev/ttyS0 c 4 64

Ensure all required /dev files exist in your rootfs.


5. Clean-Up

Clear unnecessary cache and ensure minimal clutter:

RUN microdnf clean all && rm -rf /var/cache/* /tmp/*

6. Testing the Environment

Run your image with a Firecracker-compatible VM to test the login prompt:

firecracker --config-file vm_config.json

Ensure vm_config.json maps the serial console output to ttyS0.


Full Dockerfile (Updated)

Here's the complete revised Dockerfile:

FROM mysql:8.4-oraclelinux9

RUN microdnf install -y systemd \
  && echo "root:Docker!" | chpasswd \
  && echo 'root:x:0:0:root:/root:/bin/bash' > /etc/passwd \
  && echo 'ttyS0' > /etc/securetty

RUN echo '[Unit]' > /etc/systemd/system/mygetty.service \
  && echo 'Description=Serial Console Login' >> /etc/systemd/system/mygetty.service \
  && echo '[Service]' >> /etc/systemd/system/mygetty.service \
  && echo 'ExecStart=/usr/sbin/agetty -L 9600 ttyS0 vt102' >> /etc/systemd/system/mygetty.service \
  && echo '[Install]' >> /etc/systemd/system/mygetty.service \
  && echo 'WantedBy=multi-user.target' >> /etc/systemd/system/mygetty.service \
  && systemctl enable mygetty

RUN microdnf clean all

CMD ["/usr/sbin/init"]

Let me know how it works!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants