const std = @import("std"); const process = std.process; const heap = std.heap; const mem = std.mem; const fs = std.fs; const libvirt = @import("libvirt.zig"); pub fn main() !void { var arena = heap.ArenaAllocator.init(heap.raw_c_allocator); defer arena.deinit(); const allocator = arena.allocator(); const connection = try libvirt.Connection.connect("qemu:///system", allocator); defer connection.close(); var flake_dir = try fs.cwd().openDir("flakes/windows/test", .{}); defer flake_dir.close(); var nix = process.Child.init(&[_][]const u8{ "nix", "build", ".#volume", "-o", "volume" }, allocator); nix.cwd_dir = flake_dir; _ = try nix.spawnAndWait(); nix.argv = &[_][]const u8{ "nix", "build", ".#beforeInstall", "-o", "beforeInstall" }; _ = try nix.spawnAndWait(); nix.argv = &[_][]const u8{ "nix", "build", ".#afterInstall", "-o", "afterInstall" }; // _ = try nix.spawnAndWait(); nix.argv = &[_][]const u8{ "nix", "build", ".#beforeBoot", "-o", "beforeBoot" }; // _ = try nix.spawnAndWait(); nix.argv = &[_][]const u8{ "nix", "build", ".#afterBoot", "-o", "afterBoot" }; // _ = try nix.spawnAndWait(); const volume_def = try flake_dir.openFile("volume", .{}); defer volume_def.close(); const volume_xml = try volume_def.readToEndAlloc(allocator, 1024 * 1024); defer allocator.free(volume_xml); const domain_beforeinstall_def = try flake_dir.openFile("beforeInstall", .{}); defer domain_beforeinstall_def.close(); const domain_beforeinstall_xml = try domain_beforeinstall_def.readToEndAlloc(allocator, 1024 * 1024 * 1024); defer allocator.free(domain_beforeinstall_xml); // -------------- const uri = try connection.getURI(); defer connection.freeURI(uri); // std.debug.print("uri: {s}\n", .{uri}); const num_active = try connection.numOfDomains(); const num_inactive = try connection.numOfDefinedDomains(); // std.debug.print("active: {d}, inactive: {d}\n", .{ num_active, num_inactive }); _ = .{ num_active, num_inactive }; var domain_iter = try connection.iterateDomains(&[_]libvirt.Domain.ListFlags{ libvirt.Domain.ListFlags.Active, libvirt.Domain.ListFlags.Inactive, }); defer domain_iter.deinit(); while (domain_iter.next()) |domain| { const active = domain.isActive(); const name = domain.getName(); // std.debug.print("name: {s}, active: {any}\n", .{ name, active }); _ = .{ name, active }; } var pool_iter = try connection.iteratePools(&[_]libvirt.Pool.ListFlags{ libvirt.Pool.ListFlags.Active, libvirt.Pool.ListFlags.Inactive, }); defer pool_iter.deinit(); while (pool_iter.next()) |pool| { const name = try pool.getName(); // std.debug.print("name: {s}\n", .{name}); if (mem.eql(u8, name, "default")) { const vol_str = try libvirt.String.init(allocator, volume_xml); defer vol_str.deinit(); const volume = pool.createVolume(vol_str, &[_]libvirt.Pool.Volume.CreateFlags{}) catch |err| blk: { if (err == libvirt.VirError.StorageVolExist) { break :blk try pool.lookupVolumeByName("wintest.qcow2"); } else return err; }; _ = volume; break; } } const dom_str = try libvirt.String.init(allocator, domain_beforeinstall_xml); defer dom_str.deinit(); const domain = try connection.createDomain(dom_str, &[_]libvirt.Domain.CreateFlags{}); _ = domain; } pub const DomainSpec = struct { os: Quad, preinstalledSoftware: []const []const u8, modules: []const []const u8, }; pub const Quad = struct { name: []const u8, version: []const u8, edition: []const u8, arch: []const u8, };