ansible/ansible

Wrong OS family fact reported for Flatcar

johananl opened this issue · 4 comments

Summary

Ansible may report the wrong ansible_os_family fact on Flatcar Container Linux. The correct value is Flatcar, however some users are seeing Flatcar Container Linux by Kinvolk for the same fact under certain circumstances, which leads to wrong playbook behavior given that Ansible fails to identify Flatcar as the running distro.

In #69627 we've contributed Ansible core logic which affects the value of ansible_os_family for Flatcar. Back then we've specified /etc/flatcar/update.conf as the file based on which to figure out the name of the distro (likely because that's how CoreOS - Flatcar's direct ancestor - used to do the same). This decision no longer makes sense to us given that this file isn't the authoritative place for the distro name. Moreover, /etc/flatcar/update.conf may sometimes be missing based on user-provided bootstrap configuration.

Issue Type

Bug Report

Component Name

Ansible core

Ansible Version

$ ansible --version
ansible [core 2.11.5]
  config file = None
  configured module search path = ['/home/me/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/me/.local/lib/python3.8/site-packages/ansible
  ansible collection location = /home/me/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/me/.local/bin/ansible
  python version = 3.8.10 (default, Nov 26 2021, 20:14:08) [GCC 9.3.0]
  jinja version = 3.1.1
  libyaml = True

Configuration

$ ansible-config dump --only-changed

OS / Environment

Flatcar Container Linux 3139.2.0 for example

Steps to Reproduce

Follow the official instructions to run Flatcar locally on QEMU:

mkdir flatcar; cd flatcar
wget https://stable.release.flatcar-linux.net/amd64-usr/3139.2.0/flatcar_production_qemu.sh
wget https://stable.release.flatcar-linux.net/amd64-usr/3139.2.0/flatcar_production_qemu.sh.sig
wget https://stable.release.flatcar-linux.net/amd64-usr/3139.2.0/flatcar_production_qemu_image.img.bz2
wget https://stable.release.flatcar-linux.net/amd64-usr/3139.2.0/flatcar_production_qemu_image.img.bz2.sig
bzip2 -d flatcar_production_qemu_image.img.bz2
chmod +x flatcar_production_qemu.sh

ssh-keygen -f key -q -N ""

./flatcar_production_qemu.sh -a ./key.pub -- -nographic

On another shell, SSH into the Flatcar VM:

cd flatcar
ssh -p 2222 -i key core@localhost

Install PyPy (Flatcar doesn't ship with a Python interpreter):

cd /opt
wget -O - https://downloads.python.org/pypy/pypy3.8-v7.3.9-linux64.tar.bz2 | sudo tar xjf -
sudo ln -s /opt/pypy3.8-v7.3.9-linux64/bin/pypy /opt/bin/python

Run Ansible against the VM and print the OS family:

cat <<EOF >playbook.yaml
- hosts: all
  user: core
  tasks:
  - name: Print distro
    debug:
      var: ansible_os_family
EOF

ansible-playbook playbook.yaml -i localhost:2222, --key-file ./key -e ansible_python_interpreter=/opt/bin/python -e ansible_port=2222

Output:

PLAY [all] *****************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************ok: [localhost]

TASK [Print distro] ********************************************************************************************************************************************************************************************************************************************ok: [localhost] => {
    "ansible_os_family": "Flatcar Container Linux by Kinvolk"
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************************************localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

SSH into the VM and populate /etc/flatcar/update.conf with dummy values:

printf "SERVER=foo\nGROUP=bar\n" | sudo tee /etc/flatcar/update.conf

Run the play book again:

ansible-playbook playbook.yaml -i localhost:2222, --key-file ./key -e ansible_python_interpreter=/opt/bin/python -e ansible_port=2222

Output:

PLAY [all] *****************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************************************************ok: [localhost]

TASK [Print distro] ********************************************************************************************************************************************************************************************************************************************ok: [localhost] => {
    "ansible_os_family": "Flatcar"
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************************************localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Expected Results

I expected to always see Flatcar as ansible_os_family on Flatcar Container Linux.

Actual Results

The value of `ansible_os_family` changes based on the existence of `/etc/flatcar/update.conf`.

Code of Conduct

  • I agree to follow the Ansible Code of Conduct

Relevant issue on Flatcar repo: flatcar/Flatcar#719

@johananl What file should be used instead of /etc/flatcar/update.conf?

@johananl What file should be used instead of /etc/flatcar/update.conf?

/etc/os-release makes the most sense.

Here an example for the /etc/os-release content:

NAME="Flatcar Container Linux by Kinvolk"
ID=flatcar
ID_LIKE=coreos
VERSION=3200.0.0
VERSION_ID=3200.0.0
BUILD_ID=2022-04-05-2013
SYSEXT_LEVEL=1.0
PRETTY_NAME="Flatcar Container Linux by Kinvolk 3200.0.0 (Oklo)"
ANSI_COLOR="38;5;75"
HOME_URL="https://flatcar-linux.org/"
BUG_REPORT_URL="https://issues.flatcar-linux.org"
FLATCAR_BOARD="amd64-usr"
CPE_NAME="cpe:2.3:o:flatcar-linux:flatcar_linux:3200.0.0:*:*:*:*:*:*:*"

The ID=flatcar field is perfect for identification, the VERSION= field can be used for additional release info.
Anything else is not interesting for Ansible. The update group ("channel", usually one of stable, beta, or alpha, lts-YEAR but can be totally custom, too) from /etc/flatcar/update.conf or /usr/share/flatcar/update.conf is not interesting for Ansible.