diff --git a/kt/KT.md b/kt/KT.md index 9a66386..87b24eb 100644 --- a/kt/KT.md +++ b/kt/KT.md @@ -197,7 +197,7 @@ before creating it from scratch again. #### Example: ``` -$ kt checkout lts9_4 +$ kt checkout lts-9.4 ``` For this configuration @@ -212,7 +212,7 @@ For this configuration ``` This is the working directory for this kernel: -`~/ciq/kernels/lts9_4`. +`~/ciq/kernels/lts-9.4`. 2 git worktrees are created: @@ -247,7 +247,7 @@ $ sudo usermod -a -G libvirt $(whoami) #### Example: ``` -$ kt vm lts9_4 +$ kt vm lts-9.4 ``` For this configuration @@ -261,10 +261,10 @@ For this configuration } ``` -Here is the qcow2 vm image used as source for other vms as well: +Here is the qcow2 vm image used as source for other vms for 9.4 kernels as well: ``` -~/ciq/default_test_images/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2 +~/ciq/default_test_images/Rocky-9.4-GenericCloud.latest.x86_64.qcow2 ``` And here are the actual vm configuration and image files: diff --git a/kt/commands/checkout/command.py b/kt/commands/checkout/command.py index f29e39f..d0d6a85 100644 --- a/kt/commands/checkout/command.py +++ b/kt/commands/checkout/command.py @@ -25,16 +25,16 @@ Examples: \b -$ kt checkout lts9_4 +$ kt checkout lts-9.4 \b -$ kt checkout lts9_4 --cleanup +$ kt checkout lts-9.4 --cleanup \b -$ kt checkout lts9_4 --cleanup -c +$ kt checkout lts-9.4 --cleanup -c \b -$ kt checkout lts9_4 --cleanup --change-dir +$ kt checkout lts-9.4 --cleanup --change-dir \b -$ kt checkout lts9_4 -e CVE-2022-49909 -Will create folder lts9_4_CVE-2022-49909 instead of lts9_4. +$ kt checkout lts-9.4 -e CVE-2022-49909 +Will create folder lts-9.4_CVE-2022-49909 instead of lts-9.4. """ diff --git a/kt/commands/git_push/command.py b/kt/commands/git_push/command.py index a5c3107..deecdf9 100644 --- a/kt/commands/git_push/command.py +++ b/kt/commands/git_push/command.py @@ -15,17 +15,17 @@ Examples: \b -$ kt git-push lts9_4 -k -Will push the branch {USER}_ciqlts9_4 from kernel-src-tree from lts9_4 kernel +$ kt git-push lts-9.4 -k +Will push the branch {USER}_ciqlts-9.4 from kernel-src-tree from lts-9.4 kernel workspace. \b -$ kt git-push lts9_4 -k -f +$ kt git-push lts-9.4 -k -f Same as above but it will force push \b -$ kt git-push lts9_4 -d -Will push the branch {USER}_lts94-9 from kernel-dist-tree from lts9_4 kernel +$ kt git-push lts-9.4 -d +Will push the branch {USER}_lts94-9 from kernel-dist-tree from lts-9.4 kernel workspace. """ diff --git a/kt/commands/vm/command.py b/kt/commands/vm/command.py index 8ba2eff..206050b 100644 --- a/kt/commands/vm/command.py +++ b/kt/commands/vm/command.py @@ -17,19 +17,26 @@ cloud-init.yaml configuration is taken from kt/data and modified accordingly for each user and then put in the same folder. +If the base image exists at , it will be reused +forever, unless parameter --override-base is used to download the +base image and replace it. Note, this won't interfere with existing +vms that share the same base because their own image is copied in their +own / folder. + Examples: \b -$ kt vm lts9_4 +$ kt vm lts-9.4 \b -$ kt vm lts9_4 --console +$ kt vm lts-9.4 --console \b -$ kt vm lts9_4 -c +$ kt vm lts-9.4 -c \b -$ kt vm lts9_4 --destroy +$ kt vm lts-9.4 --destroy \b -$ kt vm lts9_4 -c --override - +$ kt vm lts-9.4 -c --override +\b +$ kt vm lts-9.4 -c --override-base """ @@ -51,6 +58,11 @@ is_flag=True, help="It destroys the vm if it exists and creates a new one", ) +@click.option( + "--override-base", + is_flag=True, + help="It destroys the vm if it exists and creates a new one, but it will also override the base qcow image", +) @click.option( "--list-all", is_flag=True, @@ -60,7 +72,7 @@ @click.option("--vcpus", type=int, default=12, help="Number of virtual CPUs (default: 12)") @click.option("--memory", type=int, default=32768, help="Memory in MiB (default: 32768)") @click.argument("kernel_workspace", required=False, shell_complete=ShellCompletion.show_kernel_workspaces) -def vm(kernel_workspace, console, destroy, override, list_all, test, vcpus, memory): +def vm(kernel_workspace, console, destroy, override, override_base, list_all, test, vcpus, memory): if not list_all and not kernel_workspace: raise click.UsageError("kernel_workspace is required unless --list-all is specified") @@ -69,6 +81,7 @@ def vm(kernel_workspace, console, destroy, override, list_all, test, vcpus, memo console=console, destroy=destroy, override=override, + override_base=override_base, list_all=list_all, test=test, vcpus=vcpus, diff --git a/kt/commands/vm/impl.py b/kt/commands/vm/impl.py index 3eec174..2c125fc 100644 --- a/kt/commands/vm/impl.py +++ b/kt/commands/vm/impl.py @@ -11,6 +11,7 @@ def main( console: bool, destroy: bool, override: bool, + override_base: bool, list_all: bool, test: bool = False, vcpus: int = 12, @@ -29,7 +30,9 @@ def main( vm.destroy() return - vm_instance = Vm.setup_and_spinup(kernel_workspace_name=name, override=override, vcpus=vcpus, memory=memory) + vm_instance = Vm.setup_and_spinup( + kernel_workspace_name=name, override=override, override_base=override_base, vcpus=vcpus, memory=memory + ) config = Config.load() if test: diff --git a/kt/ktlib/util.py b/kt/ktlib/util.py index 784271e..8284970 100644 --- a/kt/ktlib/util.py +++ b/kt/ktlib/util.py @@ -7,8 +7,8 @@ class Constants: COMMON_REPOS = "common_repos" KERNELS = "kernels" - BASE_URL = "https://download.rockylinux.org/pub/rocky" - QCOW2_TRAIL = "GenericCloud-Base.latest.x86_64.qcow2" + BASE_URL = "https://dl.rockylinux.org/vault/rocky" + QCOW2_TRAIL = "GenericCloud.latest.x86_64.qcow2" DEFAULT_VM_BASE = "Rocky" CLOUD_INIT = "cloud_init.yaml" diff --git a/kt/ktlib/vm.py b/kt/ktlib/vm.py index b6d7c84..e09de8d 100644 --- a/kt/ktlib/vm.py +++ b/kt/ktlib/vm.py @@ -31,12 +31,14 @@ class Vm: qcow2_source_path: qcow2 path to the vm image used as source vm_major_version: major vm version (9 for Rocky 9) + vm_major_version: major.minor vm version (9.2 for Rocky 9.2) qcow2_path: the qcow2 path of the vm image copied from qcow2_source_path cloud_init_path: cloud_init.yaml config, adapted from data/cloud_init.yaml """ qcow2_source_path: Path vm_major_version: str + vm_major_minor_version: str qcow2_path: Path cloud_init_path: Path name: str @@ -47,9 +49,12 @@ def load(cls, config: Config, kernel_workspace: KernelWorkspace): kernel_workspace_str = kernel_workspace.folder.name kernel_name = cls._extract_kernel_name(kernel_workspace_str) vm_major_version = cls._extract_major(kernel_name) + vm_major_minor_version = cls._extract_major_minor(kernel_name) # Image source paths construction - qcow2_source_path = config.images_source_dir / Path(cls._qcow2_name(vm_major_version=vm_major_version)) + qcow2_source_path = config.images_source_dir / Path( + cls._qcow2_name(vm_major_minor_version=vm_major_minor_version) + ) # Actual current image paths construction work_dir = config.images_dir / Path(kernel_workspace_str) @@ -59,6 +64,7 @@ def load(cls, config: Config, kernel_workspace: KernelWorkspace): return cls( qcow2_source_path=qcow2_source_path, vm_major_version=vm_major_version, + vm_major_minor_version=vm_major_minor_version, qcow2_path=qcow2_path, cloud_init_path=cloud_init_path, name=kernel_workspace_str, @@ -76,8 +82,13 @@ def _extract_major(cls, full_version): return full_version.split("-")[-1].split(".")[0] @classmethod - def _qcow2_name(cls, vm_major_version: str): - return f"{Constants.DEFAULT_VM_BASE}-{vm_major_version}-{Constants.QCOW2_TRAIL}" + def _extract_major_minor(cls, full_version): + # lts-9.4 -> return 9.4 + return full_version.split("-")[-1] + + @classmethod + def _qcow2_name(cls, vm_major_minor_version: str): + return f"{Constants.DEFAULT_VM_BASE}-{vm_major_minor_version}-{Constants.QCOW2_TRAIL}" @classmethod def load_from_workspace(cls, kernel_workspace_name: str): @@ -96,13 +107,21 @@ def load_from_workspace(cls, kernel_workspace_name: str): return cls.load(config=config, kernel_workspace=kernel_workspace) @classmethod - def setup_and_spinup(cls, kernel_workspace_name: str, override: bool = False, vcpus: int = 12, memory: int = 32768): + def setup_and_spinup( + cls, + kernel_workspace_name: str, + override: bool = False, + override_base: bool = False, + vcpus: int = 12, + memory: int = 32768, + ): """ Setup and spin up a VM from a kernel workspace name. Args: kernel_workspace_name: The name of the kernel workspace override: If True, destroy and recreate the VM + override_base: If True, destroy and recreate the VM but override the base image as well vcpus: Number of virtual CPUs memory: Memory in MiB @@ -112,27 +131,30 @@ def setup_and_spinup(cls, kernel_workspace_name: str, override: bool = False, vc vm = cls.load_from_workspace(kernel_workspace_name) config = Config.load() - if override: + if override or override_base: vm.destroy() - vm.setup(config=config) + vm.setup(override_base=override_base) vm_instance = vm.spin_up(config=config, vcpus=vcpus, memory=memory) return vm_instance def _get_vm_url(self): - return f"{Constants.BASE_URL}/{self.vm_major_version}/images/x86_64/{self.qcow2_source_path.name}" + return f"{Constants.BASE_URL}/{self.vm_major_minor_version}/images/x86_64/{Constants.DEFAULT_VM_BASE}-{self.vm_major_version}-{Constants.QCOW2_TRAIL}" - def _download_source_image(self): - if self.qcow2_source_path.exists(): + def _download_source_image(self, override_base: bool = False): + if self.qcow2_source_path.exists() and not override_base: logging.info(f"Image {self.qcow2_source_path} already exists, nothing to do") return # Make sure the folder exists self.qcow2_source_path.parent.mkdir(parents=True, exist_ok=True) - logging.info("Downloading image") - wget.download(self._get_vm_url(), out=str(self.qcow2_source_path.parent)) + # Delete existing image if it exists + self.qcow2_source_path.unlink(missing_ok=True) + + logging.info(f"Downloading image from {self._get_vm_url()}") + wget.download(self._get_vm_url(), out=str(self.qcow2_source_path)) def _setup_cloud_init(self, config: Config): data = None @@ -203,8 +225,8 @@ def _resize_disk(self): except RuntimeError as e: raise RuntimeError(f"Failed to resize disk image: {e}") - def setup(self, config: Config): - self._download_source_image() + def setup(self, override_base: bool = False): + self._download_source_image(override_base=override_base) def spin_up(self, config: Config, vcpus: int = 12, memory: int = 32768) -> VmInstance: if not VirtHelper.exists(vm_name=self.name):