Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kvm-test: add the option to "overwrite" an existing installation without recreating the disk from scratch #2093

Merged
merged 2 commits into from
Oct 17, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 49 additions & 11 deletions scripts/kvm-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

'''kvm-test - boot a kvm with a test iso, possibly building that test iso first

kvm-test -q --install -o --boot
kvm-test -q --install --recreate-target --boot
slimy build, install, overwrite existing image if it exists,
and boot the result after install

Expand All @@ -14,6 +14,7 @@
import copy
import crypt
import dataclasses
import enum
import os
import pathlib
import shlex
Expand Down Expand Up @@ -52,6 +53,15 @@
'''


class TargetOverwrite(enum.Enum):
# Abort if the target already exists
PRESERVE = enum.auto()
# Recreate the target if it already exists
RECREATE = enum.auto()
# Reuse the target if it already exists
REUSE = enum.auto()


@dataclasses.dataclass
class Profile:
name: str
Expand Down Expand Up @@ -156,7 +166,7 @@ def load_config(self):
Test isos and images written to /tmp/kvm-test

Sample usage:
kvm-test --build -q --install -o -a --boot
kvm-test --build -q --install --recreate-target -a --boot
slimy build, run install, overwrite existing image, use autoinstall,
boot final resulting image

Expand Down Expand Up @@ -204,8 +214,20 @@ def load_config(self):
metavar="argument",
help='pass custom -nic argument to QEMU'
' - overrides --nets')
parser.add_argument('-o', '--overwrite', default=False, action='store_true',
help='allow overwrite of the target image')
target_overwrite_group = parser.add_mutually_exclusive_group()
target_overwrite_group.add_argument('--preserve-target',
dest='target_overwrite',
action='store_const', const=TargetOverwrite.PRESERVE,
help='reuse the target image if it exists')
target_overwrite_group.add_argument('-o', '--overwrite', '--recreate-target',
dest='target_overwrite',
action='store_const', const=TargetOverwrite.RECREATE,
help='recreate the target disk if it already exists')
target_overwrite_group.add_argument('--reuse-target',
dest='target_overwrite',
action='store_const', const=TargetOverwrite.REUSE,
help='reuse the target image if it exists')
target_overwrite_group.set_defaults(target_overwrite=TargetOverwrite.PRESERVE)
parser.add_argument('-q', '--quick', default=False, action='store_true',
help='build iso with quick-test-this-branch')
parser.add_argument('-r', '--release', action='store', help='target release')
Expand Down Expand Up @@ -542,12 +564,28 @@ def get_initrd(mntdir):


def install(ctx):
boot_opts = ["order=d"]
if os.path.exists(ctx.target):
if ctx.args.overwrite:
os.remove(ctx.target)
else:
raise Exception('refusing to overwrite existing image, use the ' +
'-o option to allow overwriting')
match ctx.args.target_overwrite:
case TargetOverwrite.RECREATE:
os.remove(ctx.target)
case TargetOverwrite.PRESERVE:
raise Exception('refusing to overwrite existing image, use the ' +
'--reuse-target or --recreate-target option to ' +
'allow overwriting')
case TargetOverwrite.REUSE:
if not ctx.args.bios:
boot_opts.append("menu=on")
note = """
NOTE:
----
The option -boot order=d only works in legacy BIOS mode.
When reusing a target image in UEFI mode, QEMU will try to boot from the disk \
first; rather than from the installation media. To workaround the issue, mash \
the ESC button when the QEMU window opens. Then select "Device Manager" and \
"UEFI QEMU DVD-ROM".
----"""
print(note, file=sys.stderr)

# Only copy the files with secureboot, always overwrite on install
if ctx.args.secureboot:
Expand All @@ -571,7 +609,7 @@ def install(ctx):
else:
iso = ctx.iso

kvm.extend(('-cdrom', iso))
kvm.extend(('-cdrom', iso, '-boot', ','.join(boot_opts)))

if ctx.args.serial:
kvm.append('-nographic')
Expand All @@ -589,7 +627,7 @@ def install(ctx):
kvm.extend(('-device', 'nvme,drive=localdisk0,serial=deadbeef'))
case interface:
raise ValueError('unsupported disk interface', interface)
if not os.path.exists(ctx.target) or ctx.args.overwrite:
if not os.path.exists(ctx.target):
disksize = ctx.args.disksize or ctx.default_disk_size
run(f'qemu-img create -f qcow2 {ctx.target} {disksize}')

Expand Down
Loading