Add shell commands to start a VM or check it is running
I'd really like a way to start a vm from the shell or via apple script as well as commands that allow me to check a vm is running.
I'm using a utm vm to sandbox a Cisco AnyConnect VPN that I really don't want to install / execute on my machine, because it forces all traffic to go through the vpn instead of allowing me a split tunnel setup.
What I'd like to do is have a shell script that starts the vm, waits for it to start successfully, then connects to it via ssh, starts the vpn.
Everything besides starting the vm if it is not running is already working - so there is one last bit to automate. Are you guys interested in supporting such use cases?
I would guess that a good way to do this would be to add command line argument support to the UTM binary, but of course many ways are possible.
Have you try vtool??, you could find it on GitHub its a command-line tool to open VM on macOS. And make a ping to VM before you use ssh.
So my understand you do not need UTM to do something like that.
On the other hand AppleScript do support GUI scripting.
@gustaf71 No idea what vtool is, and GitHub search brings up lots or results that all seem unrelated. Do you have a link?
As far as I know I need to use UTM for this, as I'm on an AppleSilicon machine, but the vpn is only available for x86.
Sure...
https://github.com/evansm7/vftool
You could compile it with XCode...
@gustaf71 am I missing something? vftool only seems to be able to emulate VMs of the same architecture as the base system? (As it seems to be a pure Virtualization.framework wrapper).
Now I understand your message you need a x86 emulation. You could use a compiled QEMU for Apple Silicon, and do a script... later call that script from AppleScript If I understand correct Apple will provide rosetta support in ARM based Linux with Ventura. In other words its possible to run x86 binary in Linux.
Yeah, this documentation suggests that this should be possible soon. However for now I am likely restricted to UTM, as I don't really want to compile my own QEMU. Especially since the setup already works as I need it, and I think it would be a nice extension of UTM to support starting and querying vm state from the shell.
(Before I got my Apple Silicon machine, I had the same setup running with expect and VirtualBox with scripts like this:
#!/usr/bin/expect -f
proc is_vm_on {} {
spawn zsh
send "ssh nathan /usr/local/bin/VBoxManage showvminfo VPN-VM | grep '^State:'\r"
expect {
"powered off" {
send "exit\r"
return 0
}
"running" {
send "exit\r"
return 1
}
}
return 0
}
proc is_vm_ssh_reachable {} {
spawn ssh dosis-vpn-vm
expect {
"Connection refused" {
return 0
}
"dwt@dosis" {
send "exit\r"
return 1
}
}
return 0
}
if { ! [is_vm_on] } {
spawn ssh nathan /usr/local/bin/VBoxManage startvm VPN-VM --type headless
expect "successfully started"
while { ! [is_vm_ssh_reachable] } {
sleep 1
}
}
...
Lets say you have a solution to start a VM on remote machine You could use ping -o <your_server_ip> | $? when the return is 0 you call ssh
There are plans to introduce a separate CLI but not until after 4.0.
@osy Can you provide a link to where this is discussed / planned? I'd love to contribute my use case to help this along. As far as 4.0 goes, that seems self evident, you seem to be pretty near to the release already with alphas / betas released.
I don’t think anything is in writing yet. There were some plans to support vagrant which would depend on it.
Well, I'm open to using this bug to discuss this.
While we're on the topic, something that would be extremely powerful for me would be the ability to connect to a VMs console via a shell command. Use Case: Cisco-Annyconnect VPN that insists on preventing any local connections. That would allow me to encapsulate the VPN in the VM and then use the console connection from the outside to tunnel ssh connections through it.
@osy it would be really helpful to have some links and issues tracking this and thoughts on vagrant so that those more familiar working with vagrant plugins can help. There aren't many avenues for people with spare time wanting to push this forward to take. I'm a restless dog, where's my bone!
I think it's a big premature to do that right now. At the minimum it would depend on the CLI tool which hasn't even been started yet. Right now the focus is getting UTM v4 out the door which has a LOT of backend changes which means lots of bugs to iron out.
Let's maybe try and get a list of what's expected of a Vagrant provider, and we can see what's missing, and how simple/difficult it will be to add it.
I personally haven't used Vagrant, but here's what I think is needed:
| Ability to start/stop, maybe pause/resume/restart a VM. | This is possible with the URL Scheme currently. It references by name, though, and I think in UTM 4.0, multiple VMs can share the same name (@osy can you please clarify?) so that could have problems. Does Vagrant reference a VM by its name, or by its box file, or some ID? |
| Ability to get the VM's IP address | Since the serial configuration allows exposing the QEMU Monitor as a TCP Server, this should be possible. |
| Ability to clone a VM, and maybe change its MAC address | There's no clone command. Changing the MAC address can be done by modifying the PLIST |
| Ability to create new VMs? | I'm not sure if this is possible, especially now that there's some VM "registry" (haven't read the code for what that is). Maybe the CLI tool would take a generated .utm file and import it? Edit: silly me for not reading the release notes. Looks like the registry is just for storing the equivalent of view.plist for multiple host devices, and is stored inside the .utm file. |
Also, I'm not really sure how including a CLI tool in a sandboxed app works.
Which of these would be best to interact with UTM?
- Adding more commands to the URL Scheme
- Making a CLI tool (potentially complicated)
- Some simple TCP/HTTP/telnet server
Once we decide on what's needed, and after UTM 4.0 is out of beta, I can start on implementing the changes to the UTM side. I also don't mind writing the Vagrant parts (for the fun of it). The vagrant-go stuff looks interesting, when will it be usable for provider plugins (saw on the Tart vagrant issue that it's not usable yet)?
Creating a standalone CLI tool interface/API is pretty straight forward, but it's talking from that app with UTM programmatically to do the work that has all the complexity and unknowns.
As for vagrant go, anything built at the moment will probably need rewriting, better to wait for vagrant 2.4 to start using the go api, and that'll put a hard minimum version requirement on things. Vagrant go also switches to the XDG folder format which may mean significant compatibility breaks for those who were hoping to switch over to UTM for continuity purposes
+1 for a CLI to start/stop VMs and getting their status, maybe even IP addresses. Would be extra nice if we can run headless Linux VMs without any host side GUI at all (apart from initial creation).