mirror of
https://github.com/cirruslabs/tart.git
synced 2026-10-18 11:55:36 +02:00
support ZVirtioConsoleDevice for linux vm (#364)
* support ZVirtioConsoleDevice for linux vm, user can control the vm via serial port with screen command * cleanup code, fix indent * add --serial option to tart * remove serial in vmconfig, fix Serial.swift --------- Co-authored-by: peternguyen93 <peternguyen9321@gmail.com> Co-authored-by: peter <peter@starlabs.sg>
This commit is contained in:
co-authored by
peternguyen93
peter
parent
4a454a3115
commit
d8ac36b3bd
@@ -20,6 +20,11 @@ struct Run: AsyncParsableCommand {
|
||||
discussion: "Useful for integrating Tart VMs into other tools.\nUse `tart ip` in order to get an IP for SSHing or VNCing into the VM."))
|
||||
var noGraphics: Bool = false
|
||||
|
||||
@Flag(help: ArgumentHelp(
|
||||
"Open serial console in /dev/ttySXX",
|
||||
discussion: "Useful for debugging Linux Kernel"))
|
||||
var serial: Bool = false
|
||||
|
||||
@Flag(help: "Force open a UI window, even when VNC is enabled.")
|
||||
var graphics: Bool = false
|
||||
|
||||
@@ -122,7 +127,8 @@ struct Run: AsyncParsableCommand {
|
||||
vmDir: vmDir,
|
||||
network: userSpecifiedNetwork(vmDir: vmDir) ?? NetworkShared(),
|
||||
additionalDiskAttachments: additionalDiskAttachments,
|
||||
directorySharingDevices: directoryShares() + rosettaDirectoryShare()
|
||||
directorySharingDevices: directoryShares() + rosettaDirectoryShare(),
|
||||
serial: serial
|
||||
)
|
||||
|
||||
let vncImpl: VNC? = try {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// File.swift
|
||||
//
|
||||
//
|
||||
// Created by Peter Nguyen on 19/12/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
func createPTY() -> Int32
|
||||
{
|
||||
var tty_fd: Int32 = -1
|
||||
var sfd: Int32 = -1
|
||||
var termios_ = termios()
|
||||
let tty_path = UnsafeMutablePointer<CChar>.allocate(capacity: 1024)
|
||||
|
||||
var res = openpty(&tty_fd, &sfd, tty_path, nil, nil);
|
||||
if(res < 0 ){
|
||||
perror("openpty error")
|
||||
return -1
|
||||
}
|
||||
|
||||
// close slave file descriptor
|
||||
close(sfd)
|
||||
|
||||
res = fcntl(tty_fd, F_GETFL)
|
||||
if(res < 0){
|
||||
perror("fcntl F_GETFL error")
|
||||
return res
|
||||
}
|
||||
|
||||
// set serial nonblocking
|
||||
res = fcntl(tty_fd, F_SETFL, res | O_NONBLOCK)
|
||||
if(res < 0){
|
||||
perror("fcntl F_SETFL O_NONBLOCK error")
|
||||
return res
|
||||
}
|
||||
|
||||
// set baudrate to 115200
|
||||
tcgetattr(tty_fd, &termios_)
|
||||
cfsetispeed(&termios_, speed_t(B115200))
|
||||
cfsetospeed(&termios_, speed_t(B115200))
|
||||
if(tcsetattr(tty_fd, TCSANOW, &termios_) != 0){
|
||||
perror("tcsetattr error")
|
||||
return -1
|
||||
}
|
||||
|
||||
print("Successfully open pty \(String(cString: tty_path))")
|
||||
|
||||
tty_path.deallocate()
|
||||
return tty_fd
|
||||
}
|
||||
+27
-5
@@ -40,7 +40,8 @@ class VM: NSObject, VZVirtualMachineDelegate, ObservableObject {
|
||||
init(vmDir: VMDirectory,
|
||||
network: Network = NetworkShared(),
|
||||
additionalDiskAttachments: [VZDiskImageStorageDeviceAttachment] = [],
|
||||
directorySharingDevices: [VZDirectorySharingDeviceConfiguration] = []
|
||||
directorySharingDevices: [VZDirectorySharingDeviceConfiguration] = [],
|
||||
serial: Bool = false
|
||||
) throws {
|
||||
name = vmDir.name
|
||||
config = try VMConfig.init(fromURL: vmDir.configURL)
|
||||
@@ -54,7 +55,8 @@ class VM: NSObject, VZVirtualMachineDelegate, ObservableObject {
|
||||
let configuration = try Self.craftConfiguration(diskURL: vmDir.diskURL,
|
||||
nvramURL: vmDir.nvramURL, vmConfig: config,
|
||||
network: network, additionalDiskAttachments: additionalDiskAttachments,
|
||||
directorySharingDevices: directorySharingDevices
|
||||
directorySharingDevices: directorySharingDevices,
|
||||
serial: serial
|
||||
)
|
||||
virtualMachine = VZVirtualMachine(configuration: configuration)
|
||||
|
||||
@@ -132,7 +134,8 @@ class VM: NSObject, VZVirtualMachineDelegate, ObservableObject {
|
||||
diskSizeGB: UInt16,
|
||||
network: Network = NetworkShared(),
|
||||
additionalDiskAttachments: [VZDiskImageStorageDeviceAttachment] = [],
|
||||
directorySharingDevices: [VZDirectorySharingDeviceConfiguration] = []
|
||||
directorySharingDevices: [VZDirectorySharingDeviceConfiguration] = [],
|
||||
serial: Bool = false
|
||||
) async throws {
|
||||
var ipswURL = ipswURL
|
||||
|
||||
@@ -179,7 +182,8 @@ class VM: NSObject, VZVirtualMachineDelegate, ObservableObject {
|
||||
let configuration = try Self.craftConfiguration(diskURL: vmDir.diskURL, nvramURL: vmDir.nvramURL,
|
||||
vmConfig: config, network: network,
|
||||
additionalDiskAttachments: additionalDiskAttachments,
|
||||
directorySharingDevices: directorySharingDevices
|
||||
directorySharingDevices: directorySharingDevices,
|
||||
serial: serial
|
||||
)
|
||||
virtualMachine = VZVirtualMachine(configuration: configuration)
|
||||
|
||||
@@ -261,7 +265,8 @@ class VM: NSObject, VZVirtualMachineDelegate, ObservableObject {
|
||||
vmConfig: VMConfig,
|
||||
network: Network = NetworkShared(),
|
||||
additionalDiskAttachments: [VZDiskImageStorageDeviceAttachment],
|
||||
directorySharingDevices: [VZDirectorySharingDeviceConfiguration]
|
||||
directorySharingDevices: [VZDirectorySharingDeviceConfiguration],
|
||||
serial: Bool
|
||||
) throws -> VZVirtualMachineConfiguration {
|
||||
let configuration = VZVirtualMachineConfiguration()
|
||||
|
||||
@@ -308,6 +313,23 @@ class VM: NSObject, VZVirtualMachineDelegate, ObservableObject {
|
||||
// Directory sharing devices
|
||||
configuration.directorySharingDevices = directorySharingDevices
|
||||
|
||||
// Serial Port
|
||||
if serial {
|
||||
let tty_fd = createPTY()
|
||||
if(tty_fd > -1){
|
||||
let tty_read = FileHandle.init(fileDescriptor: tty_fd)
|
||||
let tty_write = FileHandle.init(fileDescriptor: tty_fd)
|
||||
|
||||
|
||||
configuration.serialPorts = [VZVirtioConsoleDeviceSerialPortConfiguration()]
|
||||
let serialPortAttachment = VZFileHandleSerialPortAttachment(
|
||||
fileHandleForReading: tty_read,
|
||||
fileHandleForWriting: tty_write)
|
||||
|
||||
configuration.serialPorts[0].attachment = serialPortAttachment
|
||||
}
|
||||
}
|
||||
|
||||
try configuration.validate()
|
||||
|
||||
return configuration
|
||||
|
||||
Reference in New Issue
Block a user