#!/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 < "${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