Skip to content

Commit

Permalink
Create a virtual machine with virtio-gpu device
Browse files Browse the repository at this point in the history
Signed-off-by: Yuri Nesterov <yuriy.nesterov@unikie.com>
  • Loading branch information
nesteroff committed Apr 11, 2024
1 parent d616449 commit 25a09cb
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 0 deletions.
1 change: 1 addition & 0 deletions modules/microvm/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
./virtualization/microvm/appvm.nix
./virtualization/microvm/guivm.nix
./networking.nix
./virtualization/microvm/virtgpuvm.nix
];
}
156 changes: 156 additions & 0 deletions modules/microvm/virtualization/microvm/virtgpuvm.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
# SPDX-License-Identifier: Apache-2.0
{
config,
lib,
pkgs,
...
}: let
configHost = config;
vmName = "virtgpu-vm";
virtgpuvmBaseConfiguration = {
imports = [
(import ./common/vm-networking.nix {
inherit vmName;
macAddress = "02:00:00:03:05:01";
})
({
lib,
pkgs,
...
}: {
ghaf = {
users.accounts.enable = lib.mkDefault configHost.ghaf.users.accounts.enable;

development = {
ssh.daemon.enable = lib.mkDefault configHost.ghaf.development.ssh.daemon.enable;
debug.tools.enable = lib.mkDefault configHost.ghaf.development.debug.tools.enable;
nix-setup.enable = lib.mkDefault configHost.ghaf.development.nix-setup.enable;
};
};

# SSH is very picky about the file permissions and ownership and will
# accept neither direct path inside /nix/store or symlink that points
# there. Therefore we copy the file to /etc/ssh/get-auth-keys (by
# setting mode), instead of symlinking it.
environment.etc."ssh/get-auth-keys" = {
source = let
script = pkgs.writeShellScriptBin "get-auth-keys" ''
[[ "$1" != "ghaf" ]] && exit 0
${pkgs.coreutils}/bin/cat /run/waypipe-ssh-public-key/id_ed25519.pub
'';
in "${script}/bin/get-auth-keys";
mode = "0555";
};
services.openssh = {
authorizedKeysCommand = "/etc/ssh/get-auth-keys";
authorizedKeysCommandUser = "nobody";
};

system.stateVersion = lib.trivial.release;

nixpkgs.buildPlatform.system = configHost.nixpkgs.buildPlatform.system;
nixpkgs.hostPlatform.system = configHost.nixpkgs.hostPlatform.system;

environment.systemPackages = [
pkgs.sommelier
pkgs.wayland-proxy-virtwl
pkgs.waypipe
pkgs.zathura
pkgs.chromium
];

# DRM fbdev emulation is disabled to get rid of the popup console window that appears when running a VM with virtio-gpu device
boot.kernelParams = ["drm_kms_helper.fbdev_emulation=false"];

hardware.opengl.enable = true;

microvm = {
optimize.enable = false;
mem = 4096;
vcpu = 4;
hypervisor = "crosvm";
shares = [
{
tag = "waypipe-ssh-public-key";
source = "/run/waypipe-ssh-public-key";
mountPoint = "/run/waypipe-ssh-public-key";
proto = "virtiofs";
}
{
tag = "ro-store";
source = "/nix/store";
mountPoint = "/nix/.ro-store";
proto = "virtiofs";
}
];

# Adds run-sommelier, run-wayland-proxy and run-waypipe scripts as well as drm and virtio_gpu kernel modules
graphics.enable = true;

# VSOCK is required for waypipe, 3 is the first available CID
vsock.cid = 3;
};
fileSystems."/run/waypipe-ssh-public-key".options = ["ro"];

imports = [../../../common];
})
];
};
cfg = config.ghaf.virtualization.microvm.virtgpuvm;
in {
options.ghaf.virtualization.microvm.virtgpuvm = {
enable = lib.mkEnableOption "VirtgpuVM";

extraModules = lib.mkOption {
description = ''
List of additional modules to be imported and evaluated as part of
VirtgpuVM's NixOS configuration.
'';
default = [];
};
};

config = lib.mkIf cfg.enable {
microvm.vms."${vmName}" = {
autostart = false;
config = virtgpuvmBaseConfiguration // {imports = virtgpuvmBaseConfiguration.imports ++ cfg.extraModules;};
specialArgs = {inherit lib;};
};

# This directory needs to be created before any of the microvms start.
systemd.services."create-waypipe-ssh-public-key-directory" = let
script = pkgs.writeShellScriptBin "create-waypipe-ssh-public-key-directory" ''
mkdir -pv /run/waypipe-ssh-public-key
chown -v microvm /run/waypipe-ssh-public-key
'';
in {
enable = true;
description = "Create shared directory on host";
path = [];
wantedBy = ["microvms.target"];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
StandardOutput = "journal";
StandardError = "journal";
ExecStart = "${script}/bin/create-waypipe-ssh-public-key-directory";
};
};

# MicroVM.nix contains a run-waypipe script that expects Waypipe to be running on the host and listening on port 6000
systemd.user.services.waypipe = {
enable = true;
description = "waypipe";
after = ["weston.service" "labwc.service"];
serviceConfig = {
Type = "simple";
ExecStart = "${pkgs.waypipe}/bin/waypipe --vsock -s 6000 client";
Restart = "always";
RestartSec = "1";
};
startLimitIntervalSec = 0;
wantedBy = ["ghaf-session.target"];
};
};
}
27 changes: 27 additions & 0 deletions overlays/custom-packages/crosvm/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
# SPDX-License-Identifier: Apache-2.0
{
final,
prev,
}:
prev.crosvm.overrideAttrs (_final: prevAttrs: rec {
version = "122.1";
src = prev.fetchgit {
url = "https://chromium.googlesource.com/chromiumos/platform/crosvm";
rev = "562d81eb28a49ed6e0d771a430c21a458cdd33f9";
sha256 = "sha256-l5sIUInOhhkn3ernQLIEwEpRCyICDH/1k4C/aidy1/I=";
fetchSubmodules = true;
};

patches = [];

cargoBuildFeatures = final.lib.lists.remove "virgl_renderer_next" prevAttrs.cargoBuildFeatures;
cargoCheckFeatures = final.lib.lists.remove "virgl_renderer_next" prevAttrs.cargoCheckFeatures;
CROSVM_USE_SYSTEM_MINIGBM = true;

cargoDeps = prevAttrs.cargoDeps.overrideAttrs (prev.lib.const {
inherit src;
name = "crosvm-vendor.tar.gz";
outputHash = "sha256-yTdho6lW+XqB/iGf+bT2iwnAdjz3TrrI7YAaLoenR1U=";
});
})
2 changes: 2 additions & 0 deletions overlays/custom-packages/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@
# launcher overlays
networkmanagerapplet = import ./networkmanagerapplet {inherit prev;};
htop = import ./htop {inherit prev;};
sommelier = import ./sommelier {inherit final prev;};
crosvm = import ./crosvm {inherit final prev;};
})
20 changes: 20 additions & 0 deletions overlays/custom-packages/sommelier/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
# SPDX-License-Identifier: Apache-2.0
{
final,
prev,
}:
prev.sommelier.overrideAttrs (_final: prevAttrs: {
version = "122.0";
src = prev.fetchzip rec {
url = "https://chromium.googlesource.com/chromiumos/platform2/+archive/${passthru.rev}/vm_tools/sommelier.tar.gz";
passthru.rev = "2d4f46c679da7a4e8c447c8cf68c74b80f9de3fe";
stripRoot = false;
sha256 = "sha256-LNGA1r2IO3Ekh+dK6HUge001qC2TFvxwjhM0iaY0DbU=";
};

nativeBuildInputs = prevAttrs.nativeBuildInputs ++ [final.python3 final.python3.pkgs.jinja2];
postPatch = ''
patchShebangs gen-shim.py
'';
})
3 changes: 3 additions & 0 deletions targets/generic-x86_64/flake-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
#graphics.compositor = "labwc";
};
windows-launcher.enable = true;

# Uncomment this line to enable the virtgpu-vm with a virtio-gpu device:
#virtualization.microvm.virtgpuvm.enable = true;
};

#TODO: how to handle the majority of laptops that need a little
Expand Down

0 comments on commit 25a09cb

Please sign in to comment.