From bbff1add94f98ad42a07a59640d515f9e8bdf538 Mon Sep 17 00:00:00 2001 From: Jeeves Date: Tue, 25 Jun 2024 12:46:03 -0600 Subject: [PATCH] zig libvirt: implement lotsa functions --- server/src/libvirt.zig | 349 +++++++++++++++++++++++++++-------------- 1 file changed, 228 insertions(+), 121 deletions(-) diff --git a/server/src/libvirt.zig b/server/src/libvirt.zig index 4803b24..02bdeb9 100644 --- a/server/src/libvirt.zig +++ b/server/src/libvirt.zig @@ -340,75 +340,75 @@ pub const Connection = struct { _ = c.virConnectClose(self.ptr); } - pub fn getURI(self: *const Connection) ![]u8 { - const uri = c.virConnectGetURI(self.ptr); - defer std.c.free(uri); - const str = string(uri); - return if (str.len == 0) handleError() else try self.allocator.dupe(u8, str); - } - pub fn freeURI(self: *const Connection, uri: []u8) void { - self.allocator.free(uri); - } + // pub fn getURI(self: *const Connection) ![]u8 { + // const uri = c.virConnectGetURI(self.ptr); + // defer std.c.free(uri); + // const str = string(uri); + // return if (str.len == 0) handleError() else try self.allocator.dupe(u8, str); + // } + // pub fn freeURI(self: *const Connection, uri: []u8) void { + // self.allocator.free(uri); + // } - pub fn numOfPools(self: *const Connection) !u32 { - return numOf(c.virConnectPtr, self.ptr, c.virConnectNumOfStoragePools); - } - pub fn numOfDefinedPools(self: *const Connection) !u32 { - return numOf(c.virConnectPtr, self.ptr, c.virConnectNumOfDefinedStoragePools); - } + // pub fn numOfPools(self: *const Connection) !u32 { + // return numOf(c.virConnectPtr, self.ptr, c.virConnectNumOfStoragePools); + // } + // pub fn numOfDefinedPools(self: *const Connection) !u32 { + // return numOf(c.virConnectPtr, self.ptr, c.virConnectNumOfDefinedStoragePools); + // } - pub fn iteratePools(self: *const Connection, flags: []const Pool.ListFlags) !Pool.PoolIterator { - return Pool.PoolIterator.init( - c.virConnect, - Connection, - Pool.ListFlags, - self, - flags, - self.allocator, - c.virConnectListAllStoragePools, - ); - } + // pub fn iteratePools(self: *const Connection, flags: []const Pool.ListFlags) !Pool.PoolIterator { + // return Pool.PoolIterator.init( + // c.virConnect, + // Connection, + // Pool.ListFlags, + // self, + // flags, + // self.allocator, + // c.virConnectListAllStoragePools, + // ); + // } - pub fn createPool(self: *const Connection, xml: String, flags: []const Pool.CreateFlags) !Pool { - const pool = c.virStoragePoolCreateXML(self.ptr, @ptrCast(xml.str), intFromFlags(Pool.CreateFlags, flags)); - return if (pool) |p| Pool.init(p, self.allocator) else handleError(); - } - pub fn definePoolFlags(self: *const Connection, xml: String, flags: []const Pool.DefineFlags) !Pool { - const pool = c.virStoragePoolCreateXML(self.ptr, @ptrCast(xml.str), intFromFlags(Pool.DefineFlags, flags)); - return if (pool) |p| Pool.init(p, self.allocator) else handleError(); - } + // pub fn createPool(self: *const Connection, xml: String, flags: []const Pool.CreateFlags) !Pool { + // const pool = c.virStoragePoolCreateXML(self.ptr, @ptrCast(xml.str), intFromFlags(Pool.CreateFlags, flags)); + // return if (pool) |p| Pool.init(p, self.allocator) else handleError(); + // } + // pub fn definePoolFlags(self: *const Connection, xml: String, flags: []const Pool.DefineFlags) !Pool { + // const pool = c.virStoragePoolCreateXML(self.ptr, @ptrCast(xml.str), intFromFlags(Pool.DefineFlags, flags)); + // return if (pool) |p| Pool.init(p, self.allocator) else handleError(); + // } - pub fn numOfDomains(self: *const Connection) !u32 { - return numOf(c.virConnectPtr, self.ptr, c.virConnectNumOfDomains); - } - pub fn numOfDefinedDomains(self: *const Connection) !u32 { - return numOf(c.virConnectPtr, self.ptr, c.virConnectNumOfDefinedDomains); - } + // pub fn numOfDomains(self: *const Connection) !u32 { + // return numOf(c.virConnectPtr, self.ptr, c.virConnectNumOfDomains); + // } + // pub fn numOfDefinedDomains(self: *const Connection) !u32 { + // return numOf(c.virConnectPtr, self.ptr, c.virConnectNumOfDefinedDomains); + // } - pub fn iterateDomains(self: *const Connection, flags: []const Domain.ListFlags) !Domain.DomainIterator { - return Domain.DomainIterator.init( - c.virConnect, - Connection, - Domain.ListFlags, - self, - flags, - self.allocator, - c.virConnectListAllDomains, - ); - } + // pub fn iterateDomains(self: *const Connection, flags: []const Domain.ListFlags) !Domain.DomainIterator { + // return Domain.DomainIterator.init( + // c.virConnect, + // Connection, + // Domain.ListFlags, + // self, + // flags, + // self.allocator, + // c.virConnectListAllDomains, + // ); + // } - pub fn createDomain(self: *const Connection, xml: String, flags: []const Domain.CreateFlags) !Domain { - const domain = c.virDomainCreateXML(self.ptr, @ptrCast(xml.str), intFromFlags(Domain.CreateFlags, flags)); - return if (domain) |d| Domain.init(d, self.allocator) else handleError(); - } - pub fn defineDomain(self: *const Connection, xml: String) !Domain { - const domain = c.virDomainDefineXML(self.ptr, @ptrCast(xml.str)); - return if (domain) |d| Domain.init(d, self.allocator) else handleError(); - } - pub fn defineDomainFlags(self: *const Connection, xml: String, flags: []const Domain.DefineFlags) !Domain { - const domain = c.virDomainDefineXMLFlags(self.ptr, @ptrCast(xml.str), intFromFlags(Domain.DefineFlags, flags)); - return if (domain) |d| Domain.init(d, self.allocator) else handleError(); - } + // pub fn createDomain(self: *const Connection, xml: String, flags: []const Domain.CreateFlags) !Domain { + // const domain = c.virDomainCreateXML(self.ptr, @ptrCast(xml.str), intFromFlags(Domain.CreateFlags, flags)); + // return if (domain) |d| Domain.init(d, self.allocator) else handleError(); + // } + // pub fn defineDomain(self: *const Connection, xml: String) !Domain { + // const domain = c.virDomainDefineXML(self.ptr, @ptrCast(xml.str)); + // return if (domain) |d| Domain.init(d, self.allocator) else handleError(); + // } + // pub fn defineDomainFlags(self: *const Connection, xml: String, flags: []const Domain.DefineFlags) !Domain { + // const domain = c.virDomainDefineXMLFlags(self.ptr, @ptrCast(xml.str), intFromFlags(Domain.DefineFlags, flags)); + // return if (domain) |d| Domain.init(d, self.allocator) else handleError(); + // } }; pub const Pool = struct { @@ -426,51 +426,104 @@ pub const Pool = struct { self.arena.deinit(); } - pub fn findStoragePoolSources() void {} - pub fn getStoragePoolCapabilities() void {} - pub fn listAllStoragePools() void {} - pub fn listDefinedStoragePools() void {} - pub fn listStoragePools() void {} - pub fn numOfDefinedStoragePools() void {} - pub fn numOfStoragePools() void {} + pub fn findStoragePoolSources( + conn: *const Connection, + type: []const u8, + srcSpec: []const u8, + flags: []const Flags, + ) VirError![]u8 {} // TODO + pub fn getStoragePoolCapabilities( + conn: *const Connection, + flags: []const Flags, + ) VirError![]u8 {} // TODO + pub fn listAllStoragePools( + conn: *const Connection, + pools: [*]c.virStoragePoolPtr, + flags: []const ListFlags, + ) VirError![]const c.virStoragePoolPtr { + const num = c.virConnectListAllStoragePools( + conn.ptr, + @ptrCast(&pools), + intFromFlags(ListFlags, flags), + ); + return if (num < 0) handleError() else pools[0..num]; + } + pub fn listDefinedStoragePools( + conn: *const Connection, + names: [*]const []const u8, + maxnames: u32, + ) VirError!u32 {} // TODO + pub fn listStoragePools( + conn: *const Connection, + names: [*]const []const u8, + maxnames: u32, + ) VirError!u32 {} // TODO + pub fn numOfDefinedStoragePools(conn: *const Connection) VirError!u32 {} + pub fn numOfStoragePools(conn: *const Connection) VirError!u32 {} // TODO event handling callbacks - pub fn build() void {} - pub fn create() void {} - pub fn createXML() void {} - pub fn defineXML() void {} - pub fn delete() void {} - pub fn destroy() void {} - pub fn free() void {} + pub fn build(self: *const Pool) VirError!void {} // TODO + pub fn create(conn: *const Connection) VirError!void {} // TODO + pub fn createXML(conn: *const Connection) VirError!void {} // TODO + pub fn defineXML(conn: *const Connection) VirError!void {} // TODO + pub fn delete(self: *const Pool) VirError!void {} // TODO + pub fn destroy(self: *const Pool) VirError!void {} // TODO + pub fn free(self: *const Pool) VirError!void { + if (c.virStoragePoolFree(self.ptr) < 0) return handleError(); + } - pub fn getAutostart() void {} - pub fn getConnect() void {} - pub fn getInfo() void {} + pub fn getAutostart(self: *const Pool, autostart: *c_int) VirError!void { + if (c.virStoragePoolGetAutostart(self.ptr, autostart) < 0) return handleError(); + } + pub fn getConnect(self: *const Pool) VirError!c.virConnectPtr { + return if (c.virStoragePoolGetConnect(self.ptr)) |ptr| ptr else handleError(); + } + pub fn getInfo(self: *const Pool, info: c.virStoragePoolInfoPtr) VirError!void { + if (c.virStoragePoolGetInfo(self.ptr, info) < 0) return handleError(); + } pub fn getName(self: *const Pool) VirError![]const u8 { const name = c.virStoragePoolGetName(self.ptr); const str = string(name); return if (str.len == 0) handleError() else str; } - pub fn getUUID() void {} - pub fn getUUIDString() void {} - pub fn getXMLDesc() void {} + pub fn getUUID(self: *const Pool) VirError!void {} // TODO + pub fn getUUIDString(self: *const Pool) VirError!void {} // TODO + pub fn getXMLDesc(self: *const Pool, flags: []const XMLFlags) VirError![]const u8 { + const desc = c.virStoragePoolGetXMLDesc(self.ptr, intFromFlags(XMLFlags, flags)); + const str = string(desc); + return if (str.len == 0) handleError() else str; + } - pub fn isActive() void {} - pub fn isPersistent() void {} - pub fn listAllVolumes() void {} - pub fn listVolumes() void {} + pub fn isActive(self: *const Pool) VirError!bool { + return switch (c.virStoragePoolIsActive(self.ptr)) { + 0 => false, + 1 => true, + else => handleError(), + }; + } + pub fn isPersistent(self: *const Pool) VirError!bool { + return switch (c.virStoragePoolIsPersistent(self.ptr)) { + 0 => false, + 1 => true, + else => handleError(), + }; + } + pub fn listAllVolumes(self: *const Pool) void {} // TODO + pub fn listVolumes(self: *const Pool) void {} // TODO - pub fn lookupByName() void {} - pub fn lookupByTargetPath() void {} - pub fn lookupByUUID() void {} - pub fn lookupByUUIDString() void {} - pub fn lookupByVolume() void {} + pub fn lookupByName() void {} // TODO + pub fn lookupByTargetPath() void {} // TODO + pub fn lookupByUUID() void {} // TODO + pub fn lookupByUUIDString() void {} // TODO + pub fn lookupByVolume() void {} // TODO - pub fn numOfVolumes() void {} - pub fn ref() void {} - pub fn refresh() void {} - pub fn setAutostart() void {} - pub fn undefine() void {} + pub fn numOfVolumes() void {} // TODO + pub fn ref(self: *const Pool) VirError!void { + if (c.virStoragePoolRef(self.ptr) < 0) return handleError(); + } + pub fn refresh() void {} // TODO + pub fn setAutostart() void {} // TODO + pub fn undefine() void {} // TODO // pub fn createVolume(self: *const Pool, xml: String, flags: []const Volume.CreateFlags) !Volume { // const volume = c.virStorageVolCreateXML(self.ptr, @ptrCast(xml.str), intFromFlags(Volume.CreateFlags, flags)); @@ -494,6 +547,19 @@ pub const Pool = struct { // ); // } + pub fn lookupVolumeByKey(self: *const Pool, key: []const u8) VirError!Volume { + const volume = Volume.lookupByKey(self, key); + return if (volume) |v| v else handleError(); + } + pub fn lookupVolumeByName(self: *const Pool, name: []const u8) VirError!Volume { + const volume = Volume.lookupByName(self, name); + return if (volume) |v| v else handleError(); + } + pub fn lookupVolumeByPath(self: *const Pool, path: []const u8) VirError!Volume { + const volume = Volume.lookupByPath(self, path); + return if (volume) |v| v else handleError(); + } + pub const ListFlags = enum(c_uint) { Inactive = c.VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE, Active = c.VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE, @@ -520,6 +586,9 @@ pub const Pool = struct { pub const CreateFlags = enum(c_uint) {}; pub const DefineFlags = enum(c_uint) {}; pub const DeleteFlags = enum(c_uint) {}; + pub const XMLFlags = enum(c_uint) { + Inactive = c.VIR_STORAGE_XML_INACTIVE, + }; pub const Info = struct { state: State, @@ -568,29 +637,59 @@ pub const Pool = struct { self.arena.deinit(); } - pub fn createXML() void {} - pub fn createXMLFrom() void {} - pub fn delete() void {} - pub fn download() void {} - pub fn free() void {} + pub fn createXML( + pool: *const Pool, + xml: String, + flags: []const CreateFlags, + ) void {} // TODO + pub fn createXMLFrom( + pool: *const Pool, + xml: String, + flags: []const CreateFlags, + ) void {} // TODO + pub fn delete(self: *const Volume, flags: []const DeleteFlags) VirError!void { + if (c.virStorageVolDelete(self.ptr, intFromFlags(DeleteFlags, flags)) < 0) + return handleError(); + } + pub fn download(self: *const Volume) VirError!void {} // TODO + pub fn free(self: *const Volume) VirError!void { + if (c.virStorageVolFree(self.ptr) < 0) return handleError(); + } - pub fn getConnect() void {} - pub fn getInfo() void {} - pub fn getInfoFlags() void {} - pub fn getKey() void {} - pub fn getName() void {} - pub fn getPath() void {} - pub fn getXMLDesc() void {} + pub fn getConnect(self: *const Volume) VirError!c.virConnectPtr { + return if (c.virStorageVolGetConnect(self.ptr)) |c| c else handleError(); + } + pub fn getInfo(self: *const Volume) void {} // TODO + pub fn getInfoFlags(self: *const Volume) void {} // TODO + pub fn getKey(self: *const Volume) VirError![]const u8 { + return if (c.virStorageVolGetKey(self.ptr)) |v| v else handleError(); + } + pub fn getName(self: *const Volume) VirError![]const u8 { + return if (c.virStorageVolGetName(self.ptr)) |v| v else handleError(); + } + pub fn getPath(self: *const Volume) VirError![]const u8 { + // TODO use String? + return if (c.virStorageVolGetPath(self.ptr)) |v| v else handleError(); + } + pub fn getXMLDesc(self: *const Volume) void {} // TODO - pub fn lookupByKey() void {} - pub fn lookupByName() void {} - pub fn lookupByPath() void {} + pub fn lookupByKey(conn: *const Connection, key: []const u8) VirError!Volume { + return if (c.virStorageVolLookupByKey(conn.ptr, key)) |v| v else handleError(); + } + pub fn lookupByName(conn: *const Connection, name: []const u8) VirError!Volume { + return if (c.virStorageVolLookupByName(conn.ptr, name)) |v| v else handleError(); + } + pub fn lookupByPath(conn: *const Connection, path: []const u8) VirError!Volume { + return if (c.virStorageVolLookupByPath(conn.ptr, path)) |v| v else handleError(); + } - pub fn ref() void {} - pub fn resize() void {} - pub fn upload() void {} - pub fn wipe() void {} - pub fn wipePattern() void {} + pub fn ref(self: *const Volume) VirError!void { + if (c.virStorageVolRef(self.ptr) < 0) return handleError(); + } + pub fn resize(self: *const Volume) void {} // TODO + pub fn upload(self: *const Volume) void {} // TODO + pub fn wipe(self: *const Volume) void {} // TODO + pub fn wipePattern(self: *const Volume) void {} // TODO pub const ListFlags = enum(c_uint) {}; pub const CreateFlags = enum(c_uint) { @@ -716,7 +815,9 @@ pub const Domain = struct { pub fn fsInfoFree() void {} pub fn fsThaw() void {} pub fn fsTrim() void {} - pub fn free() void {} + pub fn free(self: *const Domain) VirError!void { + if (c.virDomainFree(self.ptr) < 0) return handleError(); + } pub fn getAutostart() void {} pub fn getBlkioParameters() void {} @@ -806,7 +907,9 @@ pub const Domain = struct { pub fn pinVcpuFlags() void {} pub fn reboot() void {} - pub fn ref() void {} + pub fn ref(self: *const Domain) VirError!void { + if (c.virDomainRef(self.ptr) < 0) return handleError(); + } pub fn rename() void {} pub fn reset() void {} pub fn restore() void {} @@ -925,7 +1028,9 @@ pub const Domain = struct { pub fn current() void {} pub fn delete() void {} - pub fn free() void {} + pub fn free(self: *const Snapshot) VirError!void { + if (c.virDomainSnapshotFree(self.ptr) < 0) return handleError(); + } pub fn getConnect() void {} pub fn getDomain() void {} pub fn getName() void {} @@ -941,7 +1046,9 @@ pub const Domain = struct { pub fn lookupByName() void {} pub fn num() void {} pub fn numChildren() void {} - pub fn ref() void {} + pub fn ref(self: *const Snapshot) VirError!void { + if (c.virDomainSnapshotRef(self.ptr) < 0) return handleError(); + } pub const ListFlags = enum(c_uint) { Descendants = c.VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS,