已合并
fix(package): allow --force to recover from incomplete baseline manifest #184
Hyunbin创建于 9月15日
fix(package): allow --force to recover from incomplete baseline manifest #184
已合并
共 2 个文件变更+87-6
| @@ -731,18 +731,55 @@ collect_baseline_paths() | |||
| 731 | [[ $(sort -u "${output}" | wc -l) -eq ${count} ]] || fail "duplicate path in ${manifest}" | 731 | [[ $(sort -u "${output}" | wc -l) -eq ${count} ]] || fail "duplicate path in ${manifest}" |
| 732 | } | 732 | } |
| 733 | 733 | ||
| 734 | -validate_baseline_coverage() | 734 | +collect_missing_baseline_paths() |
| 735 | { | 735 | { |
| 736 | local active_paths=$1 | 736 | local active_paths=$1 |
| 737 | local baseline_paths=$2 | 737 | local baseline_paths=$2 |
| 738 | + local output=$3 | ||
| 738 | local path | 739 | local path |
| 739 | 740 | ||
| 741 | + : > "${output}" | ||
| 740 | while IFS= read -r path; do | 742 | while IFS= read -r path; do |
| 741 | - grep -Fqx -- "${path}" "${baseline_paths}" || \ | 743 | + grep -Fqx -- "${path}" "${baseline_paths}" || printf '%s\n' "${path}" >> "${output}" |
| 742 | - fail "baseline does not cover installed patch path: ${path}" | ||
| 743 | done < "${active_paths}" | 744 | done < "${active_paths}" |
| 744 | } | 745 | } |
| 745 | 746 | ||
| 747 | +validate_baseline_recovery() | ||
| 748 | +{ | ||
| 749 | + local missing_paths=$1 | ||
| 750 | + local path | ||
| 751 | + local backup | ||
| 752 | + local missing_count | ||
| 753 | + | ||
| 754 | + [[ -s "${missing_paths}" ]] || return 0 | ||
| 755 | + path=$(head -n 1 "${missing_paths}") | ||
| 756 | + [[ "${FORCE}" == true ]] || fail \ | ||
| 757 | + "baseline does not cover installed patch path: ${path}; use --force to recover from existing backups" | ||
| 758 | + | ||
| 759 | + while IFS= read -r path; do | ||
| 760 | + backup="${STATE_DIR}/baseline/files/${path}" | ||
| 761 | + [[ -f "${backup}" && ! -L "${backup}" ]] || fail \ | ||
| 762 | + "baseline does not cover installed patch path and its backup is unavailable: ${path}" | ||
| 763 | + done < "${missing_paths}" | ||
| 764 | + missing_count=$(wc -l < "${missing_paths}") | ||
| 765 | + log "WARNING" \ | ||
| 766 | + "baseline manifest is incomplete; --force will recover ${missing_count} entries from existing backups" | ||
| 767 | +} | ||
| 768 | + | ||
| 769 | +repair_baseline_manifest() | ||
| 770 | +{ | ||
| 771 | + local missing_paths=$1 | ||
| 772 | + local manifest="${STATE_DIR}/baseline/manifest.tsv" | ||
| 773 | + local path | ||
| 774 | + | ||
| 775 | + [[ -s "${missing_paths}" ]] || return 0 | ||
| 776 | + chmod 640 "${manifest}" | ||
| 777 | + while IFS= read -r path; do | ||
| 778 | + printf 'present\t%s\n' "${path}" >> "${manifest}" | ||
| 779 | + done < "${missing_paths}" | ||
| 780 | + chmod 440 "${manifest}" | ||
| 781 | +} | ||
| 782 | + | ||
| 746 | verify_checksums() | 783 | verify_checksums() |
| 747 | { | 784 | { |
| 748 | local root=$1 | 785 | local root=$1 |
| @@ -1205,6 +1242,7 @@ install_patch() | |||
| 1205 | local package_paths | 1242 | local package_paths |
| 1206 | local baseline_paths | 1243 | local baseline_paths |
| 1207 | local active_paths | 1244 | local active_paths |
| 1245 | + local missing_baseline_paths | ||
| 1208 | local touched_paths | 1246 | local touched_paths |
| 1209 | local package_directories | 1247 | local package_directories |
| 1210 | local touched_directories | 1248 | local touched_directories |
| @@ -1217,6 +1255,7 @@ install_patch() | |||
| 1217 | package_paths="${WORK_DIR}/package.paths" | 1255 | package_paths="${WORK_DIR}/package.paths" |
| 1218 | baseline_paths="${WORK_DIR}/baseline.paths" | 1256 | baseline_paths="${WORK_DIR}/baseline.paths" |
| 1219 | active_paths="${WORK_DIR}/active.paths" | 1257 | active_paths="${WORK_DIR}/active.paths" |
| 1258 | + missing_baseline_paths="${WORK_DIR}/missing-baseline.paths" | ||
| 1220 | touched_paths="${WORK_DIR}/touched.paths" | 1259 | touched_paths="${WORK_DIR}/touched.paths" |
| 1221 | package_directories="${WORK_DIR}/package.directories" | 1260 | package_directories="${WORK_DIR}/package.directories" |
| 1222 | touched_directories="${WORK_DIR}/touched.directories" | 1261 | touched_directories="${WORK_DIR}/touched.directories" |
| @@ -1229,13 +1268,16 @@ install_patch() | |||
| 1229 | verify_checksums "${PAYLOAD_DIR}" "${PACKAGE_MANIFEST}" || fail "package payload checksum verification failed" | 1268 | verify_checksums "${PAYLOAD_DIR}" "${PACKAGE_MANIFEST}" || fail "package payload checksum verification failed" |
| 1230 | : > "${baseline_paths}" | 1269 | : > "${baseline_paths}" |
| 1231 | : > "${active_paths}" | 1270 | : > "${active_paths}" |
| 1271 | + : > "${missing_baseline_paths}" | ||
| 1232 | 1272 | ||
| 1233 | if [[ -d "${STATE_DIR}" ]]; then | 1273 | if [[ -d "${STATE_DIR}" ]]; then |
| 1234 | validate_state_format | 1274 | validate_state_format |
| 1235 | collect_baseline_paths "${STATE_DIR}/baseline/manifest.tsv" "${baseline_paths}" | 1275 | collect_baseline_paths "${STATE_DIR}/baseline/manifest.tsv" "${baseline_paths}" |
| 1236 | collect_checksum_paths "${STATE_DIR}/active.manifest.sha256" "${active_paths}" | 1276 | collect_checksum_paths "${STATE_DIR}/active.manifest.sha256" "${active_paths}" |
| 1237 | validate_directory_mode_manifest "${directory_manifest}" | 1277 | validate_directory_mode_manifest "${directory_manifest}" |
| 1238 | - validate_baseline_coverage "${active_paths}" "${baseline_paths}" | 1278 | + collect_missing_baseline_paths \ |
| 1279 | + "${active_paths}" "${baseline_paths}" "${missing_baseline_paths}" | ||
| 1280 | + validate_baseline_recovery "${missing_baseline_paths}" | ||
| 1239 | if ! verify_checksums "${CANN_ROOT}" "${STATE_DIR}/active.manifest.sha256"; then | 1281 | if ! verify_checksums "${CANN_ROOT}" "${STATE_DIR}/active.manifest.sha256"; then |
| 1240 | if [[ "${FORCE}" == true ]]; then | 1282 | if [[ "${FORCE}" == true ]]; then |
| 1241 | log "WARNING" "installed patch files were changed; --force will overwrite them" | 1283 | log "WARNING" "installed patch files were changed; --force will overwrite them" |
| @@ -1265,6 +1307,7 @@ install_patch() | |||
| 1265 | collect_managed_directories "${touched_paths}" "${touched_directories}" | 1307 | collect_managed_directories "${touched_paths}" "${touched_directories}" |
| 1266 | validate_target_paths "${touched_paths}" | 1308 | validate_target_paths "${touched_paths}" |
| 1267 | snapshot_transaction "${touched_paths}" "${touched_directories}" | 1309 | snapshot_transaction "${touched_paths}" "${touched_directories}" |
| 1310 | + repair_baseline_manifest "${missing_baseline_paths}" | ||
| 1268 | build_baseline_directory_manifest \ | 1311 | build_baseline_directory_manifest \ |
| 1269 | "${package_directories}" \ | 1312 | "${package_directories}" \ |
| 1270 | "${TRANSACTION_DIR}/directories.tsv" \ | 1313 | "${TRANSACTION_DIR}/directories.tsv" \ |
| @@ -1325,6 +1368,7 @@ uninstall_patch() | |||
| 1325 | { | 1368 | { |
| 1326 | local baseline_paths | 1369 | local baseline_paths |
| 1327 | local active_paths | 1370 | local active_paths |
| 1371 | + local missing_baseline_paths | ||
| 1328 | local touched_paths | 1372 | local touched_paths |
| 1329 | local touched_directories | 1373 | local touched_directories |
| 1330 | local directory_manifest="${STATE_DIR}/baseline/directories.tsv" | 1374 | local directory_manifest="${STATE_DIR}/baseline/directories.tsv" |
| @@ -1333,6 +1377,7 @@ uninstall_patch() | |||
| 1333 | WORK_DIR=$(mktemp -d) | 1377 | WORK_DIR=$(mktemp -d) |
| 1334 | baseline_paths="${WORK_DIR}/baseline.paths" | 1378 | baseline_paths="${WORK_DIR}/baseline.paths" |
| 1335 | active_paths="${WORK_DIR}/active.paths" | 1379 | active_paths="${WORK_DIR}/active.paths" |
| 1380 | + missing_baseline_paths="${WORK_DIR}/missing-baseline.paths" | ||
| 1336 | touched_paths="${WORK_DIR}/touched.paths" | 1381 | touched_paths="${WORK_DIR}/touched.paths" |
| 1337 | touched_directories="${WORK_DIR}/touched.directories" | 1382 | touched_directories="${WORK_DIR}/touched.directories" |
| 1338 | 1383 | ||
| @@ -1340,7 +1385,9 @@ uninstall_patch() | |||
| 1340 | collect_baseline_paths "${STATE_DIR}/baseline/manifest.tsv" "${baseline_paths}" | 1385 | collect_baseline_paths "${STATE_DIR}/baseline/manifest.tsv" "${baseline_paths}" |
| 1341 | collect_checksum_paths "${STATE_DIR}/active.manifest.sha256" "${active_paths}" | 1386 | collect_checksum_paths "${STATE_DIR}/active.manifest.sha256" "${active_paths}" |
| 1342 | validate_directory_mode_manifest "${directory_manifest}" | 1387 | validate_directory_mode_manifest "${directory_manifest}" |
| 1343 | - validate_baseline_coverage "${active_paths}" "${baseline_paths}" | 1388 | + collect_missing_baseline_paths \ |
| 1389 | + "${active_paths}" "${baseline_paths}" "${missing_baseline_paths}" | ||
| 1390 | + validate_baseline_recovery "${missing_baseline_paths}" | ||
| 1344 | if ! verify_checksums "${CANN_ROOT}" "${STATE_DIR}/active.manifest.sha256"; then | 1391 | if ! verify_checksums "${CANN_ROOT}" "${STATE_DIR}/active.manifest.sha256"; then |
| 1345 | if [[ "${FORCE}" == true ]]; then | 1392 | if [[ "${FORCE}" == true ]]; then |
| 1346 | log "WARNING" "installed patch files were changed; --force will discard those changes" | 1393 | log "WARNING" "installed patch files were changed; --force will discard those changes" |
| @@ -1366,6 +1413,7 @@ uninstall_patch() | |||
| 1366 | collect_managed_directories "${touched_paths}" "${touched_directories}" | 1413 | collect_managed_directories "${touched_paths}" "${touched_directories}" |
| 1367 | validate_target_paths "${touched_paths}" | 1414 | validate_target_paths "${touched_paths}" |
| 1368 | snapshot_transaction "${touched_paths}" "${touched_directories}" | 1415 | snapshot_transaction "${touched_paths}" "${touched_directories}" |
| 1416 | + repair_baseline_manifest "${missing_baseline_paths}" | ||
| 1369 | prepare_directories_for_install "${touched_directories}" | 1417 | prepare_directories_for_install "${touched_directories}" |
| 1370 | restore_baseline "${active_paths}" | 1418 | restore_baseline "${active_paths}" |
| 1371 | if [[ "${STATE_FORMAT_VERSION}" == "3" ]]; then | 1419 | if [[ "${STATE_FORMAT_VERSION}" == "3" ]]; then |
| @@ -75,6 +75,17 @@ write_dependency_versions() | |||
| 75 | "${cann_root}/share/info/runtime/version.info" | 75 | "${cann_root}/share/info/runtime/version.info" |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | +remove_baseline_entry() | ||
| 79 | +{ | ||
| 80 | + local manifest=$1 | ||
| 81 | + local path=$2 | ||
| 82 | + | ||
| 83 | + chmod 640 "${manifest}" | ||
| 84 | + awk -F '\t' -v path="${path}" '$2 != path' "${manifest}" > "${manifest}.tmp" | ||
| 85 | + mv "${manifest}.tmp" "${manifest}" | ||
| 86 | + chmod 440 "${manifest}" | ||
| 87 | +} | ||
| 88 | + | ||
| 78 | # build.sh must propagate packaging failures to CI and other callers. | 89 | # build.sh must propagate packaging failures to CI and other callers. |
| 79 | expect_failure env ASCEND_HOME_PATH="${TEST_ROOT}/missing-cann" \ | 90 | expect_failure env ASCEND_HOME_PATH="${TEST_ROOT}/missing-cann" \ |
| 80 | bash "${PROJECT_ROOT}/build.sh" --pkg | 91 | bash "${PROJECT_ROOT}/build.sh" --pkg |
| @@ -260,6 +271,26 @@ grep -qx 'FormatVersion=3' "${FAKE_CANN}/var/asc-comm-dev-patch/state.info" | |||
| 260 | [[ -f "${FAKE_CANN}/var/asc-comm-dev-patch/baseline/directories.tsv" ]] | 271 | [[ -f "${FAKE_CANN}/var/asc-comm-dev-patch/baseline/directories.tsv" ]] |
| 261 | [[ -f "${FAKE_CANN}/var/asc-comm-dev-patch/baseline/links.tsv" ]] | 272 | [[ -f "${FAKE_CANN}/var/asc-comm-dev-patch/baseline/links.tsv" ]] |
| 262 | 273 | ||
| 274 | +# Recover an incomplete baseline manifest only when --force is used and the | ||
| 275 | +# original backup still provides an unambiguous baseline. | ||
| 276 | +INCOMPLETE_BASELINE_PATH="asc/impl/adv_api/detail/hcomm/common/hcomm_base.h" | ||
| 277 | +BASELINE_MANIFEST="${FAKE_CANN}/var/asc-comm-dev-patch/baseline/manifest.tsv" | ||
| 278 | +remove_baseline_entry "${BASELINE_MANIFEST}" "${INCOMPLETE_BASELINE_PATH}" | ||
| 279 | +expect_failure run_package --full --install-path="${FAKE_CANN}" | ||
| 280 | +grep -q 'use --force to recover from existing backups' "${ERROR_LOG}" | ||
| 281 | +run_package --full --force --install-path="${FAKE_CANN}" | ||
| 282 | +grep -Fqx $'present\t'"${INCOMPLETE_BASELINE_PATH}" "${BASELINE_MANIFEST}" | ||
| 283 | + | ||
| 284 | +UNRECOVERABLE_BASELINE_PATH="asc/impl/adv_api/detail/hcomm/common/hcomm_inner_def.h" | ||
| 285 | +UNRECOVERABLE_BACKUP="${FAKE_CANN}/var/asc-comm-dev-patch/baseline/files/${UNRECOVERABLE_BASELINE_PATH}" | ||
| 286 | +remove_baseline_entry "${BASELINE_MANIFEST}" "${UNRECOVERABLE_BASELINE_PATH}" | ||
| 287 | +rm -f -- "${UNRECOVERABLE_BACKUP}" | ||
| 288 | +expect_failure run_package --full --force --install-path="${FAKE_CANN}" | ||
| 289 | +grep -q 'backup is unavailable' "${ERROR_LOG}" | ||
| 290 | +mkdir -p "$(dirname -- "${UNRECOVERABLE_BACKUP}")" | ||
| 291 | +cp -a "${BASELINE_DIR}/${UNRECOVERABLE_BASELINE_PATH}" "${UNRECOVERABLE_BACKUP}" | ||
| 292 | +run_package --full --force --install-path="${FAKE_CANN}" | ||
| 293 | + | ||
| 263 | # Missing managed links are protected like modified managed files. | 294 | # Missing managed links are protected like modified managed files. |
| 264 | chmod 750 "${FAKE_CANN}/asc/include/comm_api/aicore" | 295 | chmod 750 "${FAKE_CANN}/asc/include/comm_api/aicore" |
| 265 | rm -f -- "${FAKE_CANN}/asc/include/comm_api/aicore/hcomm" | 296 | rm -f -- "${FAKE_CANN}/asc/include/comm_api/aicore/hcomm" |
| @@ -280,7 +311,9 @@ run_package --full --install-path="${FAKE_CANN}" --force | |||
| 280 | 311 | ||
| 281 | # Reinstalling must retain the original baseline rather than backing up patched files. | 312 | # Reinstalling must retain the original baseline rather than backing up patched files. |
| 282 | run_package --full --install-path="${FAKE_CANN}" | 313 | run_package --full --install-path="${FAKE_CANN}" |
| 283 | -run_package --uninstall --install-path="${FAKE_CANN}" | 314 | +remove_baseline_entry "${BASELINE_MANIFEST}" "${INCOMPLETE_BASELINE_PATH}" |
| 315 | +expect_failure run_package --uninstall --install-path="${FAKE_CANN}" | ||
| 316 | +run_package --uninstall --force --install-path="${FAKE_CANN}" | ||
| 284 | 317 | ||
| 285 | while read -r _ path; do | 318 | while read -r _ path; do |
| 286 | cmp "${BASELINE_DIR}/${path}" "${FAKE_CANN}/${path}" | 319 | cmp "${BASELINE_DIR}/${path}" "${FAKE_CANN}/${path}" |