@@ -424,6 +424,101 @@ configure_network() {
424424
425425}
426426
427+ configure_udev () {
428+ local rules_file=" ${T_FILE_UDEV_RULES:-/ etc/ udev/ rules.d/ 99-cuos.rules} "
429+ local rules_file_new=" ${T_FILE_UDEV_RULES_NEW:- " ${rules_file} .new" } "
430+
431+ local count
432+ count=" $( jq_config ' .udev | length' ) "
433+
434+ {
435+ echo " # Managed automatically"
436+ echo
437+
438+ for (( i= 0 ; i< count; i++ )) ; do
439+ local entry
440+ entry=" $( jq_config -c " .udev[$i ]" ) "
441+
442+ # --- unified field extraction (old + new schema) ---
443+ local subsystem vendor product serial mac symlink
444+
445+ subsystem=" $( echo " $entry " | jq -r ' .subsystem // .match.subsystem // empty' ) "
446+ symlink=" $( echo " $entry " | jq -r ' .symlink // empty' ) "
447+
448+ vendor=" $( echo " $entry " | jq -r ' .vendor // .match.vendor // empty' ) "
449+ product=" $( echo " $entry " | jq -r ' .product // .match.product // empty' ) "
450+ serial=" $( echo " $entry " | jq -r ' .serial // .match.serial // empty' ) "
451+ mac=" $( echo " $entry " | jq -r ' ."mac-address" // .match."mac-address" // empty' | tr ' [:upper:]' ' [:lower:]' ) "
452+
453+ mode=" $( echo " $entry " | jq -r ' .mode // empty' ) "
454+ tag=" $( echo " $entry " | jq -r ' .tag // empty' ) "
455+
456+ # skip invalid entries
457+ [[ -z " $subsystem " || -z " $symlink " ]] && continue
458+
459+ local rule=" "
460+ rule+=" SUBSYSTEM==\" ${subsystem} \" "
461+
462+ case " $subsystem " in
463+ tty)
464+ [[ -n " $serial " ]] && rule+=" , ATTRS{serial}==\" ${serial} \" "
465+ [[ -n " $vendor " ]] && rule+=" , ATTRS{idVendor}==\" ${vendor} \" "
466+ [[ -n " $product " ]] && rule+=" , ATTRS{idProduct}==\" ${product} \" "
467+ ;;
468+
469+ hidraw)
470+ [[ -n " $vendor " ]] && rule+=" , ATTRS{idVendor}==\" ${vendor} \" "
471+ [[ -n " $product " ]] && rule+=" , ATTRS{idProduct}==\" ${product} \" "
472+ [[ -n " $serial " ]] && rule+=" , ATTRS{serial}==\" ${serial} \" "
473+ ;;
474+
475+ sound)
476+ [[ -n " $vendor " ]] && rule+=" , ATTRS{idVendor}==\" ${vendor} \" "
477+ [[ -n " $product " ]] && rule+=" , ATTRS{idProduct}==\" ${product} \" "
478+ ;;
479+
480+ block)
481+ [[ -n " $serial " ]] && rule+=" , ATTRS{serial}==\" ${serial} \" "
482+ [[ -n " $vendor " ]] && rule+=" , ATTRS{idVendor}==\" ${vendor} \" "
483+ [[ -n " $product " ]] && rule+=" , ATTRS{idProduct}==\" ${product} \" "
484+ ;;
485+
486+ net)
487+ [[ -n " $mac " ]] && rule+=" , ATTR{address}==\" ${mac} \" "
488+ ;;
489+ esac
490+
491+ [[ -n " $mode " ]] && rule+=" , MODE=\" ${mode} \" "
492+ [[ -n " $tag " ]] && rule+=" , TAG+=\" ${tag} \" "
493+
494+ rule+=" , SYMLINK+=\" ${symlink} \" "
495+
496+ echo " $rule "
497+ done
498+ } > " ${rules_file_new} "
499+
500+ # --- atomic replace ---
501+ if [[ -n " ${TEST:- } " ]]; then
502+ return
503+ fi
504+
505+ local changed=1
506+
507+ if [[ -f " ${rules_file} " ]]; then
508+ if [[ " $( sha256sum " ${rules_file} " | cut -d ' ' -f1) " == \
509+ " $( sha256sum " ${rules_file_new} " | cut -d ' ' -f1) " ]]; then
510+ changed=0
511+ fi
512+ fi
513+
514+ mv " ${rules_file_new} " " ${rules_file} "
515+
516+ if (( changed )) ; then
517+ udevadm control --reload-rules
518+ udevadm trigger
519+ fi
520+ }
521+
427522configure_keyboard () {
428523 # For lxc we do not configure the keyboard
429524 if [[ " ${VIRT_TYPE} " == " lxc" || " ${VIRT_TYPE} " == " docker" ]]; then
@@ -762,6 +857,8 @@ main() {
762857
763858 ensure_system_config
764859
860+ configure_udev
861+
765862 set_hostname
766863
767864 configure_network
0 commit comments