已合并
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
已合并
Hyunbin创建于 9月15日
共 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=$1736 local active_paths=$1
737 local baseline_paths=$2737 local baseline_paths=$2
738+ local output=$3
738 local path739 local path
739 740 
741+ : > "${output}"
740 while IFS= read -r path; do742 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+ 
746verify_checksums()783verify_checksums()
747{784{
748 local root=$1785 local root=$1
@@ -1205,6 +1242,7 @@ install_patch()
1205 local package_paths1242 local package_paths
1206 local baseline_paths1243 local baseline_paths
1207 local active_paths1244 local active_paths
1245+ local missing_baseline_paths
1208 local touched_paths1246 local touched_paths
1209 local package_directories1247 local package_directories
1210 local touched_directories1248 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}" ]]; then1273 if [[ -d "${STATE_DIR}" ]]; then
1234 validate_state_format1274 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"; then1281 if ! verify_checksums "${CANN_ROOT}" "${STATE_DIR}/active.manifest.sha256"; then
1240 if [[ "${FORCE}" == true ]]; then1282 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_paths1369 local baseline_paths
1327 local active_paths1370 local active_paths
1371+ local missing_baseline_paths
1328 local touched_paths1372 local touched_paths
1329 local touched_directories1373 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"; then1391 if ! verify_checksums "${CANN_ROOT}" "${STATE_DIR}/active.manifest.sha256"; then
1345 if [[ "${FORCE}" == true ]]; then1392 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" ]]; then1419 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.
79expect_failure env ASCEND_HOME_PATH="${TEST_ROOT}/missing-cann" \90expect_failure env ASCEND_HOME_PATH="${TEST_ROOT}/missing-cann" \
80 bash "${PROJECT_ROOT}/build.sh" --pkg91 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.
264chmod 750 "${FAKE_CANN}/asc/include/comm_api/aicore"295chmod 750 "${FAKE_CANN}/asc/include/comm_api/aicore"
265rm -f -- "${FAKE_CANN}/asc/include/comm_api/aicore/hcomm"296rm -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.
282run_package --full --install-path="${FAKE_CANN}"313run_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 
285while read -r _ path; do318while read -r _ path; do
286 cmp "${BASELINE_DIR}/${path}" "${FAKE_CANN}/${path}"319 cmp "${BASELINE_DIR}/${path}" "${FAKE_CANN}/${path}"