diff --git a/src/answer.sh b/src/answer.sh index adb51d4f..4cf865f1 100644 --- a/src/answer.sh +++ b/src/answer.sh @@ -1423,42 +1423,90 @@ getXMLArchitecture() { setConfigurationXML() { local asset="$1" - local section + local setup='/*[local-name()="unattend"]/*[local-name()="settings" and @pass="windowsPE"]/*[local-name()="component" and @name="Microsoft-Windows-Setup"]' + local config="$setup/*[local-name()=\"UseConfigurationSet\"]" + local userdata="$setup/*[local-name()=\"UserData\"]" + local setup_count config_count userdata_count tmp [ -s "$asset" ] || return 1 - section=$(sed -n -E ' - /]*pass="windowsPE"[^>]*>/,/<\/settings>/ { - /]*name="Microsoft-Windows-Setup"[^>]*>/,/<\/component>/p - } - ' "$asset") || return 1 + setup_count=$(xmlstarlet sel -t -v "count($setup)" "$asset") || return 1 - [ -n "$section" ] || return 1 - - if grep -Fq '' <<< "$section"; then - - sed -i -E ' - /]*pass="windowsPE"[^>]*>/,/<\/settings>/ { - /]*name="Microsoft-Windows-Setup"[^>]*>/,/<\/component>/ { - s#[^<]*#true#g - } - } - ' "$asset" || return 1 - - return 0 - fi - - if ! grep -Fq '' <<< "$section"; then + if [ "$setup_count" != "1" ]; then + error "Failed to find a unique Microsoft-Windows-Setup component: $asset" return 1 fi - sed -i -E ' - /]*pass="windowsPE"[^>]*>/,/<\/settings>/ { - /]*name="Microsoft-Windows-Setup"[^>]*>/,/<\/component>/ { - s#^([[:space:]]*)#\1true\n\1# - } + config_count=$(xmlstarlet sel -t -v "count($config)" "$asset") || return 1 + + if [ "$config_count" -gt 1 ]; then + error "Multiple UseConfigurationSet entries found in answer file: $asset" + return 1 + fi + + if ! tmp=$(mktemp "${asset}.XXXXXX"); then + error "Failed to create a temporary answer file!" + return 1 + fi + + if [ "$config_count" -eq 1 ]; then + + if ! xmlstarlet ed \ + -u "$config" \ + -v "true" \ + "$asset" > "$tmp"; then + + rm -f "$tmp" + error "Failed to enable the Windows configuration set!" + return 1 + fi + + else + + userdata_count=$(xmlstarlet sel -t -v "count($userdata)" "$asset") || { + rm -f "$tmp" + return 1 } - ' "$asset" || return 1 + + if [ "$userdata_count" -gt 0 ]; then + + if ! xmlstarlet ed \ + -i "$userdata[1]" \ + -t elem \ + -n "UseConfigurationSet" \ + -v "true" \ + "$asset" > "$tmp"; then + + rm -f "$tmp" + error "Failed to insert UseConfigurationSet into answer file!" + return 1 + fi + + else + + if ! xmlstarlet ed \ + -s "$setup" \ + -t elem \ + -n "UseConfigurationSet" \ + -v "true" \ + "$asset" > "$tmp"; then + + rm -f "$tmp" + error "Failed to append UseConfigurationSet to answer file!" + return 1 + fi + + fi + + fi + + if ! chmod --reference="$asset" "$tmp" || + ! mv -f "$tmp" "$asset"; then + + rm -f "$tmp" + error "Failed to replace the updated answer file!" + return 1 + fi return 0 }