Skip to content

Commit d52f29d

Browse files
committed
kt: Add vm command
This will create a vm for a kernel workspace created earlier with kt checkout. If the vm does not exists, it will create it. It includes options to get console access, to destroy the vm and list the running vms. The most relevant one is the --test option that builds the kernel from kernel-src-tree of the matching kernel workspace, boots it and then kselftests are run. TODOs: 1. autocompletion work fine, except if --destroy is used. Ideally when --destroy is used, only the running vms should be shown. For now, please check the existing vms with kt vm --list-all and then run kt vm --destroy <kernel_workspace> 2. The implementation replies a lot of waiting for the vm to boot up, install depedencies etc. Hence the time.sleep() calls. It would be improved in the future. IMPORTANT: The vm instance needs to have access to this repo because the scripts for building the kernel, running the kselftests and installing depedencies. We share <config.kernels_dir> with the vm, so please make sure this repo is there. That's what the implementation assumes. Note: Make sure your user is part of the libvirt group, otherwise you will need to type the root password multiple times, because kt calls virsh multiple times before getting access to a vm: for checking if it exists etc. Signed-off-by: Roxana Nicolescu <rnicolescu@ciq.com>
1 parent 298450e commit d52f29d

File tree

10 files changed

+665
-0
lines changed

10 files changed

+665
-0
lines changed

bin/kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ from kt.commands.checkout.command import checkout
88
from kt.commands.git_push.command import git_push
99
from kt.commands.list_kernels.command import list_kernels
1010
from kt.commands.setup.command import setup
11+
from kt.commands.vm.command import vm
1112

1213
epilog = """
1314
Base of all tooling used for kernel development.
@@ -28,6 +29,7 @@ def main():
2829
cli.add_command(setup)
2930
cli.add_command(checkout)
3031
cli.add_command(git_push)
32+
cli.add_command(vm)
3133
cli()
3234

3335

kt/KT.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,71 @@ This is the working directory for this kernel:
227227

228228
This representes branch `{<user>}/ciqlts9_4:origin/ciqlts9_4`
229229
The source repo is ~/ciq/kernel-src-tree
230+
231+
### kt vm
232+
233+
It spins up a virtual machine for the corresponding kernel.
234+
If the virtual machine does not exist, it gets created.
235+
236+
First, the vm image base (source) is downloaded if it does not exist
237+
in <config.images_source_dir>.
238+
To spin up the machine, a copy of this qcow2 image is put in
239+
<config.images_dir/<kernel>. Even if kernels may share the same image base,
240+
they will have their own configuration and image.
241+
cloud-init.yaml configuration is taken from kt/data and modified accordingly
242+
for each user and then put in the same folder.
243+
244+
Make sure your user is part of the libvirt group, otherwise you would need
245+
to type your root password multiple times when getting access to the vm:
246+
```
247+
$ sudo usermod -a -G libvirt $(whoami)
248+
```
249+
250+
#### Example:
251+
```
252+
$ kt vm lts9_4
253+
```
254+
255+
For this configuration
256+
```
257+
{
258+
"base_path": "~/ciq",
259+
"kernels_dir": "~/ciq/kernels",
260+
"images_source_dir": "~/ciq/default_test_images",
261+
"images_dir": "~/ciq/tmp/virt-images",
262+
"ssh_key": "~/.ssh/id_ed25519_generic.pub",
263+
}
264+
```
265+
266+
Here is the qcow2 vm image used as source for other vms as well:
267+
268+
```
269+
~/ciq/default_test_images/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2
270+
```
271+
272+
And here are the actual vm configuration and image files:
273+
```
274+
ciq/tmp/virt-images/lts-9.4/cloud-init.yaml
275+
ciq/tmp/virt-images/lts-9.4/lts-9.4.qcow2
276+
```
277+
278+
The cloud-init.yaml file is adapted from kt/data/cloud-init.yaml base file.
279+
280+
`virt-install` command is then used to create the vm.
281+
282+
If `--console` option is used, then `virsh --connect qemu://system console lts9-4`
283+
is run (indirectly).
284+
285+
286+
If `--test` option is used, then we connect to the vm via ssh and run
287+
288+
```
289+
<config.base_path>/kernel-src-tree-tools/kernel-build.sh -n
290+
```
291+
292+
reboot
293+
and then
294+
295+
```
296+
<config.base_path>/kernel-src-tree-tools/kernel-kselftest.sh
297+
```

kt/commands/vm/command.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import click
2+
3+
from kt.commands.vm.impl import main
4+
from kt.ktlib.shell_completion import ShellCompletion
5+
6+
epilog = """
7+
It spins up a virtual machine for the corresponding kernel.
8+
9+
If the virtual machine does not exist, it gets created.
10+
11+
First, the vm image base (source) is downloaded if it does not exist
12+
in <config.images_source_dir>.
13+
14+
To spin up the machine, a copy of this qcow2 image is put in
15+
<config.images_dir/<kernel>. Even if kernels may share the same image base,
16+
they will have their own configuration and image.
17+
cloud-init.yaml configuration is taken from kt/data and modified accordingly
18+
for each user and then put in the same folder.
19+
20+
Examples:
21+
22+
\b
23+
$ kt vm lts9_4
24+
\b
25+
$ kt vm lts9_4 --console
26+
\b
27+
$ kt vm lts9_4 -c
28+
\b
29+
$ kt vm lts9_4 --destroy
30+
\b
31+
$ kt vm lts9_4 -c --override
32+
33+
"""
34+
35+
36+
@click.command(epilog=epilog)
37+
@click.option(
38+
"-c",
39+
"--console",
40+
is_flag=True,
41+
help="It connects to the console of the vm",
42+
)
43+
@click.option(
44+
"-d",
45+
"--destroy",
46+
is_flag=True,
47+
help="It destroys the vm",
48+
)
49+
@click.option(
50+
"--override",
51+
is_flag=True,
52+
help="It destroys the vm if it exists and creates a new one",
53+
)
54+
@click.option(
55+
"--list-all",
56+
is_flag=True,
57+
help="Lists existings vms",
58+
)
59+
@click.option("--test", is_flag=True, help="Build the kernel and run kselftests")
60+
@click.argument("kernel_workspace", required=False, shell_complete=ShellCompletion.show_kernel_workspaces)
61+
def vm(kernel_workspace, console, destroy, override, list_all, test):
62+
main(name=kernel_workspace, console=console, destroy=destroy, override=override, list_all=list_all, test=test)

0 commit comments

Comments
 (0)