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

Linux VM builder refactor #46

Merged
merged 35 commits into from
Jan 16, 2025
Merged

Linux VM builder refactor #46

merged 35 commits into from
Jan 16, 2025

Conversation

aleasims
Copy link
Collaborator

@aleasims aleasims commented Jan 7, 2025

This PR contains a big Linux VM builder refactor.

Motivation

  • Make the code more solid and extendable
  • Remove the need of sudo
  • Improve logging and error messaging
  • Calculate the size of VM automatically (no need to guess --size)
  • Remove the need of extlinux installed

Changes

Most of the code is located in src/builders_v2. Most of commits are representing a single entity addition to new builder.

Code structure

  • core.rs - implements pipeline and context logic for builder.
  • linux_vm/mod.rs - is the main entrypoint for Linux VM builder. Pipeline steps are configured there. Build options are also defined there.
  • linux_vm/*.rs - other modules. Each module contains helping data types (normally they will be stored in Context) and Step implementations. Most of the step implementations are dramatically reworked from older SkopeoSyslinuxBuilder.
  • linux_vm/data - contains some auxiliary data for builder, which will be baked into gvltctl executable.

Changes overview

  • Added option to specify container backend (podman or docker). But docker is still untested :)
  • Added FUSE support (no more sudo for mounting!). R.n. it is enabled with --fuse option, however in the future this should be the default behavior and this option will be replaced with --no-fuse.
  • Size of the VM is now calculated automatically by the size of all the artifacts to install into VM (see linux_vm/resize.rs). However --size option is still available to overwrite this behavior.
  • Instead of creating VM image from scratch, there is a base image, which contains:
    • MBR partitions
    • filesystem EXT4
    • EXTLINUX bootloader
      This doesn't boost performance a lot, however eliminates the need of EXTLINUX for user. To create an image from scratch added --from-scratch option. This will require root however, because EXTLINUX installation doesn't support FUSE filesystems. So using --from-scratch is almost the same as SkopeoSyslinuxBuilder.
  • Base image can be generated with --generate-base-image option.
  • Some ways to extend the code are left there: e.g. FileSystemHandler trait allows to add other filesystems (EXT3 or else). Same with MountHandler trait. The same is possible for partition table handling, but for now I use only MBR.
  • NVIDIA drivers now building and installing in separate steps (to retrieve their size on time)
  • MBR partitions are handled with mbrman crate. MBR limits our filesystem size and in the future we will probably need to change it. However I haven't find a nice read-write API for GPT in Rust.
  • Added CI workflow to test VM building. It takes quite a lot of time to run, so for now it is triggered only manually.

Notes

  • Since this builder is still considered unstable, all the changes to builder are gated with vm-builder-v2. To use new builder, compile gvltctl with this feature enabled. Without this feature everything is working as it was before.
  • When we will be happy with this builder, we can remove this feature and make this implementation a default one. By design it is including the previous version facilities.
  • MacOS is not implemented yet (sorry)
  • Something may not work, it's still rough, but since it is hidden under feature, we can even safely merge it.

Example

Simple VM test is added to tests/vm_builder/simple_vm. You can install required runtime dependencies (described in README) and run it:

cargo build --features vm-builder-v2
cd tests/vm_builder/simple_vm
../../../target/debug/gvltctl build -f ./Containerfile --fuse --no-gevulot-runtime
qemu-system-x86_64 -machine q35 -enable-kvm -nographic --hda disk.img

You should see "Hello world" printed by main application in the VM.

Future work

  • Implement everything left for MacOS support (basically filesystem/FUSE handling)
  • Test new builder intensively and figure out all the bugs
  • Run tests on CI
  • Work on proper NVIDIA drivers installation to allow running inside container (without podman-in-podman)
  • Improve caching for Linux kernel, MIA, NVIDIA drivers etc.
  • Consider switching to GPT from MBR.
  • All the TODOs left in the code

@aleasims aleasims self-assigned this Jan 7, 2025
@aleasims aleasims force-pushed the linux-vm-builder-v2 branch from bd49d34 to b9ba7b4 Compare January 7, 2025 14:34
@aleasims aleasims marked this pull request as ready for review January 8, 2025 18:08
@aleasims aleasims force-pushed the linux-vm-builder-v2 branch from f5de9a1 to f6adc73 Compare January 8, 2025 18:08
@aleasims aleasims requested review from tuommaki and trusch January 8, 2025 18:08
@@ -0,0 +1,187 @@
//! Core interfaces for builders.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

}

impl Mbr {
pub const DISK_SIGNATURE: [u8; 4] = [b'G', b'V', b'L', b'T'];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love it

@aleasims aleasims force-pushed the linux-vm-builder-v2 branch from cfa2432 to e8824e3 Compare January 14, 2025 15:55
@aleasims aleasims force-pushed the linux-vm-builder-v2 branch from e8824e3 to ffdd52f Compare January 14, 2025 16:01
@aleasims
Copy link
Collaborator Author

aleasims commented Jan 14, 2025

Update on CI

I've added a proper workflow for testing VM builder (works with --features vm-builder-v2).

  • First step simply builds gvltctl and should be used in the future as a replacement to existing workflow, because it has caching.
  • Second step builds test VM image (with precompiled HelloWorld and kernel) and runs it with QEMU

(Sorry for force-pushing, I messed up merging master somehow)

Copy link
Contributor

@tuommaki tuommaki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given we clear out the licensing question, otherwise this looks very good to me 🙌


- name: Update APT packages
run: |-
sudo apt-get update
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the intention here to only prepare for later package installations or actually upgrade all packages? apt-get update only updates the package index. apt-get upgrade upgrades packages themselves 🙂

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, just preparing for future installations.

Comment on lines 16 to 21
/// This boot code is copied from extlinux 6.04.
const BOOTCODE: &[u8; 440] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/src/builders_v2/linux_vm/data/extlinux/mbr.bin"
));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... This is slightly in grey area. After a quick peek, it seems that the syslinux/extlinux and it's mbr are under GPL. When embedding pre-compiled binary inside a binary, does it count as redistribution or linking (legally)? At least the copyright and license should probably be present somewhere.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tbh I have absolutely no idea what we should do here :) Does it mean that we have to include GPL to our repo?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This include is removed in the following commits.

@aleasims aleasims merged commit 259985b into main Jan 16, 2025
3 checks passed
@aleasims aleasims deleted the linux-vm-builder-v2 branch January 16, 2025 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants