#!/bin/sh
# Dynamically adds After=apparmor.service to open-vm-tools units ONLY on VMware hypervisors.
#
# WHY ConditionVirtualization ALONE IS INSUFFICIENT:
# Systemd constructs its transaction and ordering graph (processing Before= and After= directives)
# when building the boot sequence long BEFORE it evaluates ConditionVirtualization= at runtime.
#
# If open-vm-tools.service statically defines both "After=apparmor.service" and "Before=cloud-init-local.service",
# systemd builds a transitive dependency chain:
#   apparmor.service -> open-vm-tools.service -> cloud-init-local.service
#
# On non-VMware platforms, ConditionVirtualization=vmware evaluates to false and skips running open-vm-tools,
# but systemd STILL enforces the ordering chain. Consequently, cloud-init-local.service is blocked from
# starting until apparmor.service finishes loading.
#
# Moving "After=apparmor.service" into this early boot generator ensures the dependency edge is only added to
# the systemd graph when actually running inside a VMware virtual machine.

set -e

NORMAL_DIR="$1"

# $SYSTEMD_VIRTUALIZATION is set by systemd (v251+) to "type:implementation" (e.g., "vm:vmware").
# https://www.freedesktop.org/software/systemd/man/latest/systemd.generator.html?#%24SYSTEMD_VIRTUALIZATION
# Exit cleanly if not running in a VMware VM or if the variable is unset.
case "$SYSTEMD_VIRTUALIZATION" in
    *:vmware) ;;
    *) exit 0 ;;
esac

# Dynamically inject the ordering drop-in for VMware environments
for SVC in open-vm-tools.service vgauth.service; do
    DROPIN_DIR="${NORMAL_DIR}/${SVC}.d"
    mkdir -p "${DROPIN_DIR}"
    cat <<EOF > "${DROPIN_DIR}/10-open-vm-tools-apparmor-ordering-on-vmware.conf"
# Automatically generated by open-vm-tools-apparmor-generator
[Unit]
After=apparmor.service
EOF
done

exit 0
