diff --git a/build-tests/x86/tumbleweed/test-image-disk/appliance.kiwi b/build-tests/x86/tumbleweed/test-image-disk/appliance.kiwi
index c00882d6560..9f8abf2da1a 100644
--- a/build-tests/x86/tumbleweed/test-image-disk/appliance.kiwi
+++ b/build-tests/x86/tumbleweed/test-image-disk/appliance.kiwi
@@ -8,7 +8,8 @@
-
+
+
1.42.1
@@ -35,7 +36,7 @@
-
+
@@ -54,8 +55,27 @@
3
+
+
+
+
+ true
+ true
+ 512
+ false
+
+ false
+
+
+
+
+ 3
+
+
+
+
@@ -88,11 +108,13 @@
-
+
+
+
diff --git a/build-tests/x86/tumbleweed/test-image-disk/config.sh b/build-tests/x86/tumbleweed/test-image-disk/config.sh
index 3551376a6d8..c17447b3ae8 100644
--- a/build-tests/x86/tumbleweed/test-image-disk/config.sh
+++ b/build-tests/x86/tumbleweed/test-image-disk/config.sh
@@ -13,7 +13,7 @@ systemctl enable dracut_hostonly
# Just in case the kiwi resizer is disabled in the system and
# gets dropped from the initrd by the customer for some reason
for profile in ${kiwi_profiles//,/ }; do
- if [ "${profile}" = "Retain" ]; then
+ if [ "${profile}" = "RetainLast" ]; then
cat > /etc/fstab.script <<-EOF
sed -ie "s@/home ext4 defaults@/home ext4 x-systemd.growfs,defaults@" /etc/fstab
rm /etc/fstabe
diff --git a/dracut/modules.d/55kiwi-dump/kiwi-dump-image.sh b/dracut/modules.d/55kiwi-dump/kiwi-dump-image.sh
index c60e43b0a18..29c0120b8a7 100755
--- a/dracut/modules.d/55kiwi-dump/kiwi-dump-image.sh
+++ b/dracut/modules.d/55kiwi-dump/kiwi-dump-image.sh
@@ -346,8 +346,15 @@ function dump_image {
dump=dump_local_image
fi
+ # preserve pre-dump partition table
+ if getargbool 0 rd.kiwi.install.retain_past; then
+ fetch_local_partition_table "${image_target}" /tmp/parttable_pre
+ fi
+
# setup blocks and blocksize to retain last
- if getargbool 0 rd.kiwi.install.retain_last; then
+ if getargbool 0 rd.kiwi.install.retain_last || \
+ getargbool 0 rd.kiwi.install.retain_past
+ then
if [ -n "${image_from_remote}" ];then
image_size=$((blocks * blocksize))
parttable=$(
@@ -359,7 +366,15 @@ function dump_image {
)
fi
if compatible_to_retain "${parttable}" "${image_target}"; then
- count=$(get_disk_offset_retain_last_partition "${parttable}")
+ if getargbool 0 rd.kiwi.install.retain_last; then
+ count=$(get_disk_offset_retain_last_partition "${parttable}")
+ else
+ # retain_past always dumps the complete image
+ # the compatible_to_retain check for this image blob
+ # has been done and the deployment can happen for
+ # all blocks
+ count=0
+ fi
fi
if [ "${count}" -gt 0 ];then
block_size=$(get_sector_size_from_table_dump "${parttable}")
@@ -384,8 +399,7 @@ function dump_image {
# deploy
echo "${load_text} [${image_target}]..."
- if command -v pv &>/dev/null && [ "${kiwi_oemsilentinstall}" = "false" ]
- then
+ if with_progress && [ "${kiwi_oemsilentinstall}" = "false" ]; then
# dump with dialog based progress information
setup_progress_fifo ${progress}
eval \
@@ -409,15 +423,58 @@ function dump_image {
report_and_quit "Failed to install image"
fi
fi
+
+ # recreate last partition from pre-dump table
+ if getargbool 0 rd.kiwi.install.retain_past && \
+ [ ! -e /tmp/retain_not_applicable ]
+ then
+ recreate_last_partition "${image_target}"
+ fi
+}
+
+function with_progress {
+ if getargbool 0 rd.debug || ! command -v pv &>/dev/null; then
+ return 1
+ fi
+ return 0
}
function fetch_local_partition_table {
local image_source=$1
- local parttable=/tmp/parttable
+ local parttable=$2
+ if [ -z "${parttable}" ];then
+ parttable=/tmp/parttable
+ fi
sfdisk -d "${image_source}" > "${parttable}" 2>/dev/null
echo "${parttable}"
}
+function recreate_last_partition {
+ # recreate last partition as it existed prior dump
+ local image_target=$1
+ local table_type
+ table_type=$(get_partition_table_type "${image_target}")
+ if [ "${table_type}" = "gpt" ];then
+ relocate_gpt_at_end_of_disk "${image_target}"
+ fi
+ # parttable after image dump, the OS
+ sfdisk -d "${image_target}" > /tmp/parttable_1 2>/dev/null
+ # last partition of table as it existed prior dump
+ tail -n 1 /tmp/parttable_pre > /tmp/parttable_2
+ # combine table snippets. Please note there can now be a gap
+ # between the end of the OS table and the start of the last
+ # partition of the table prior dump. Please also note, if the
+ # table prior dump had more partitions than only the last
+ # one to retain, this table concat will not retain those.
+ # and the OS dump might have overwritten them. A more
+ # sophisticated concat procedure would be needed to support
+ # this case here in this code and also in the
+ # compatible_to_retain() method
+ cat /tmp/parttable_1 /tmp/parttable_2 > /tmp/parttable
+ set_device_lock "${image_target}" \
+ sfdisk -f "${image_target}" < /tmp/parttable
+}
+
function fetch_remote_partition_table {
local image_source=$1
local image_size=$2
@@ -452,8 +509,14 @@ function compatible_to_retain {
touch /tmp/retain_not_applicable
return 1
fi
- if [ ! "${source_start}" = "${target_start}" ];then
- report_and_quit "Cannot retain partition, start address mismatch"
+ if getargbool 0 rd.kiwi.install.retain_last; then
+ if [ ! "${source_start}" = "${target_start}" ];then
+ report_and_quit "Cannot retain partition, start address mismatch"
+ fi
+ elif getargbool 0 rd.kiwi.install.retain_past; then
+ if [ "${source_start}" -gt "${target_start}" ];then
+ report_and_quit "Cannot retain partition, image overlaps"
+ fi
fi
return 0
}
@@ -550,15 +613,18 @@ function check_image_integrity {
# no verification wanted
return
fi
- if getargbool 0 rd.kiwi.install.retain_last; then
+ if getargbool 0 rd.kiwi.install.retain_last || \
+ getargbool 0 rd.kiwi.install.retain_past
+ then
if [ ! -e /tmp/retain_not_applicable ];then
# no verification possible as only a portion of
- # the image got deployed intentionally
+ # the image got deployed intentionally (retain_last)
+ # or parts of the former partition table got
+ # restored (retain_past)
return
fi
fi
- if command -v pv &>/dev/null && [ "${kiwi_oemsilentverify}" = "false" ]
- then
+ if with_progress && [ "${kiwi_oemsilentverify}" = "false" ]; then
# verify with dialog based progress information
setup_progress_fifo ${progress}
(