Set display

This commit is contained in:
f-trycua
2025-02-09 11:12:21 +01:00
parent 38446afa88
commit 5e44535723
10 changed files with 80 additions and 15 deletions

View File

@@ -70,9 +70,10 @@ Command Options:
--mount <path> For Linux VMs only, attach a read-only disk image
set:
--cpu <cores> New number of CPU cores
--memory <size> New memory size
--disk-size <size> New disk size
--cpu <cores> New number of CPU cores (e.g., 4)
--memory <size> New memory size (e.g., 8192MB or 8GB)
--disk-size <size> New disk size (e.g., 40960MB or 40GB)
--display <res> New display resolution in format WIDTHxHEIGHT (e.g., 1024x768)
delete:
--force Force deletion without confirmation

View File

@@ -18,6 +18,9 @@ struct Set: AsyncParsableCommand {
@Option(help: "New disk size, e.g., 20480MB or 20GB.", transform: { try parseSize($0) })
var diskSize: UInt64?
@Option(help: "New display resolution in format WIDTHxHEIGHT.")
var display: VMDisplayResolution?
init() {
}
@@ -28,7 +31,8 @@ struct Set: AsyncParsableCommand {
name: name,
cpu: cpu,
memory: memory,
diskSize: diskSize
diskSize: diskSize,
display: display?.string
)
}
}

View File

@@ -127,7 +127,7 @@ enum VMError: Error, LocalizedError {
case vncNotConfigured
case internalError(String)
case unsupportedOS(String)
case invalidDisplayResolution(String)
var errorDescription: String? {
switch self {
case .alreadyExists(let name):
@@ -152,6 +152,8 @@ enum VMError: Error, LocalizedError {
return "Internal error: \(message)"
case .unsupportedOS(let os):
return "Unsupported operating system: \(os)"
case .invalidDisplayResolution(let resolution):
return "Invalid display resolution: \(resolution)"
}
}
}

View File

@@ -22,7 +22,7 @@ struct VMConfig: Codable {
private var _memorySize: UInt64?
private var _diskSize: UInt64?
private var _macAddress: String?
let display: VMDisplayResolution
private var _display: VMDisplayResolution
private var _hardwareModel: Data?
private var _machineIdentifier: Data?
@@ -42,11 +42,16 @@ struct VMConfig: Codable {
self._memorySize = memorySize
self._diskSize = diskSize
self._macAddress = macAddress
self.display = VMDisplayResolution(string: display) ?? VMDisplayResolution(string: "1024x768")!
self._display = VMDisplayResolution(string: display) ?? VMDisplayResolution(string: "1024x768")!
self._hardwareModel = hardwareModel
self._machineIdentifier = machineIdentifier
}
var display: VMDisplayResolution {
get { _display }
set { _display = newValue }
}
var cpuCount: Int? {
get { _cpuCount }
set { _cpuCount = newValue }
@@ -97,10 +102,14 @@ struct VMConfig: Codable {
_machineIdentifier = machineIdentifier
}
mutating func setMacAddress(_ macAddress: String) {
_macAddress = macAddress
mutating func setMacAddress(_ newMacAddress: String) {
self._macAddress = newMacAddress
}
mutating func setDisplay(_ newDisplay: VMDisplayResolution) {
self._display = newDisplay
}
// MARK: - Codable
enum CodingKeys: String, CodingKey {
case _cpuCount = "cpuCount"
@@ -121,7 +130,7 @@ struct VMConfig: Codable {
_memorySize = try container.decodeIfPresent(UInt64.self, forKey: ._memorySize)
_diskSize = try container.decodeIfPresent(UInt64.self, forKey: ._diskSize)
_macAddress = try container.decodeIfPresent(String.self, forKey: .macAddress)
display = VMDisplayResolution(string: try container.decode(String.self, forKey: .display))!
_display = VMDisplayResolution(string: try container.decode(String.self, forKey: .display))!
_hardwareModel = try container.decodeIfPresent(Data.self, forKey: ._hardwareModel)
_machineIdentifier = try container.decodeIfPresent(Data.self, forKey: ._machineIdentifier)
}

View File

@@ -180,7 +180,8 @@ final class LumeController {
name: String,
cpu: Int? = nil,
memory: UInt64? = nil,
diskSize: UInt64? = nil
diskSize: UInt64? = nil,
display: String? = nil
) throws {
let normalizedName = normalizeVMName(name: name)
Logger.info(
@@ -190,6 +191,7 @@ final class LumeController {
"cpu": cpu.map { "\($0)" } ?? "unchanged",
"memory": memory.map { "\($0 / 1024 / 1024)MB" } ?? "unchanged",
"disk_size": diskSize.map { "\($0 / 1024 / 1024)MB" } ?? "unchanged",
"display": display ?? "unchanged",
])
do {
try self.validateVMExists(normalizedName)
@@ -206,6 +208,9 @@ final class LumeController {
if let diskSize = diskSize {
try vm.setDiskSize(diskSize)
}
if let display = display {
try vm.setDisplay(display)
}
Logger.info("VM settings updated successfully", metadata: ["name": normalizedName])
} catch {

View File

@@ -124,7 +124,8 @@ extension Server {
name: name,
cpu: request.cpu,
memory: sizes.memory,
diskSize: sizes.diskSize
diskSize: sizes.diskSize,
display: sizes.display?.string
)
return HTTPResponse(

View File

@@ -71,11 +71,18 @@ struct SetVMRequest: Codable {
let cpu: Int?
let memory: String?
let diskSize: String?
let display: String?
func parse() throws -> (memory: UInt64?, diskSize: UInt64?) {
func parse() throws -> (memory: UInt64?, diskSize: UInt64?, display: VMDisplayResolution?) {
return (
memory: try memory.map { try parseSize($0) },
diskSize: try diskSize.map { try parseSize($0) }
diskSize: try diskSize.map { try parseSize($0) },
display: try display.map {
guard let resolution = VMDisplayResolution(string: $0) else {
throw ValidationError("Invalid display resolution format: \($0). Expected format: WIDTHxHEIGHT")
}
return resolution
}
)
}
}

View File

@@ -79,6 +79,7 @@ class VM {
cpuCount: vmDirContext.config.cpuCount ?? 0,
memorySize: vmDirContext.config.memorySize ?? 0,
diskSize: try! getDiskSize(),
display: vmDirContext.config.display.string,
status: isRunning ? "running" : "stopped",
vncUrl: vncUrl,
ipAddress: isRunning ? DHCPLeaseParser.getIPAddress(forMAC: vmDirContext.config.macAddress!) : nil
@@ -295,6 +296,17 @@ class VM {
try vmDirContext.saveConfig()
}
func setDisplay(_ newDisplay: String) throws {
guard !isRunning else {
throw VMError.alreadyRunning(vmDirContext.name)
}
guard let display: VMDisplayResolution = VMDisplayResolution(string: newDisplay) else {
throw VMError.invalidDisplayResolution(newDisplay)
}
vmDirContext.config.setDisplay(display)
try vmDirContext.saveConfig()
}
func setHardwareModel(_ newHardwareModel: Data) throws {
guard !isRunning else {
throw VMError.alreadyRunning(vmDirContext.name)

View File

@@ -35,7 +35,30 @@ struct VMDetails: Codable {
let cpuCount: Int
let memorySize: UInt64
let diskSize: DiskSize
let display: String
let status: String
let vncUrl: String?
let ipAddress: String?
init(
name: String,
os: String,
cpuCount: Int,
memorySize: UInt64,
diskSize: DiskSize,
display: String,
status: String,
vncUrl: String?,
ipAddress: String?
) {
self.name = name
self.os = os
self.cpuCount = cpuCount
self.memorySize = memorySize
self.diskSize = diskSize
self.display = display
self.status = status
self.vncUrl = vncUrl
self.ipAddress = ipAddress
}
}

View File

@@ -20,6 +20,7 @@ enum VMDetailsPrinter {
Column(header: "disk", width: 16, getValue: {
"\($0.diskSize.formattedAllocated)/\($0.diskSize.formattedTotal)"
}),
Column(header: "display", width: 12, getValue: { $0.display }),
Column(header: "status", width: 16, getValue: {
$0.status
}),