How do you start/stop VMs from shell?

Joined
Jul 27, 2017
Messages
16
I've written a script that shuts down a VM, snapshots it, sends the snapshot to a file and backs that file up to an online backup. I find it better to snapshot backups while the VM is offline to prevent file system errors (starting up from a snapshot of when the VM was running is equivalent to a power failure).

I use ssh user@address 'sh' < poweroff.sh to power the machine off gracefully. I can't, however, find a way to power the machine back on. I've tried bhyvectl and iohyve with no luck.

This seems like it should be simple; like a feature you put in before anything else, but a ton of Google searching reveals nothing. I'd honestly rather not have to write some script to web scrape the UI, but I will have I have to.
 

ukos

Dabbler
Joined
Jul 22, 2018
Messages
12
It's been a while but I think you could observe the command for turning on your vm via

tail -f /var/log/middlewared.log

There should be a log entry containing the full bhyve command for powering on the vm:
Code:
[2018/09/17 11:52:42] (DEBUG) VMService.run():259 - Starting bhyve: bhyve -A -H -w -c 4 -m 4096 -s 0:0,hostbridge -s 31,lpc -l com1,/dev/nmdm40A -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd -s 3,virtio-net,tap3,mac=00:a0:98:5b:8b:34 -s 4:0,virtio-blk,/dev/zvol/hydra/vm/debian_ahab 40_ahab


I would be interested in your script, though. Can you make it available on gist?
 

KrisBee

Wizard
Joined
Mar 20, 2017
Messages
1,288
I've written a script that shuts down a VM, snapshots it, sends the snapshot to a file and backs that file up to an online backup. I find it better to snapshot backups while the VM is offline to prevent file system errors (starting up from a snapshot of when the VM was running is equivalent to a power failure).

I use ssh user@address 'sh' < poweroff.sh to power the machine off gracefully. I can't, however, find a way to power the machine back on. I've tried bhyvectl and iohyve with no luck.

This seems like it should be simple; like a feature you put in before anything else, but a ton of Google searching reveals nothing. I'd honestly rather not have to write some script to web scrape the UI, but I will have I have to.

You should monitor your /var/log/middlewared.log to see if your script actually results in the VM being both stopped and destroyed. Then it has to be booted using the appropriated bhyve command(s) as @ukos stated. Perhaps you could have made use of bhyvectl commands to stop and poweroff your VM. Supposedly there should no be difference in using a "poweroff" inside your (linux?) VM and using bhyvectl commands at the FreeNAS CLI.
 
Last edited:

qwerion

Dabbler
Joined
Jan 30, 2014
Messages
19
From my recent experience finding the command from /var/log/middlewared.log and using it from a script does start the VM, but networking in the guest is completely borked. So that doesn't work (unless you don't need networking in the guest). It also desyncs the FreeNAS VM GUI, in that it displays the guest as permanently running even after stopping it (via GUI or other means).

However, you are able to control the VM from the API (websocket or REST), which you can find the endpoints at http://freenas.url/api/docs/

e.g. in a python script
Code:
import requests

authdata = ('root', 'rootpasswordthing')
# get VM information (ID, name, devices, etc)
r = requests.get('http://freenas.url/api/v2.0/vm', auth=authdata)
r.json()
# get VM status (STOPPED or RUNNING)
vm_id = 1
r = requests.post('http://freenas.url/api/v2.0/vm/id/{}/status'.format(vm_id) , auth=authdata)
# start VM
r = requests.post('http://freenas.url/api/v2.0/vm/id/{}/start'.format(vm_id) , auth=authdata)

Then call the script from the shell. Or you can probably one-line from the shell using curl or wget
 
Last edited:

Tsaukpaetra

Patron
Joined
Jan 7, 2014
Messages
215
I've been pondering how to keep certain VMs alive that sometimes crash, so I dabbled with @querion's sample code to make this little script:
Code:
#!/usr/local/bin/python
import requests

authdata = ('root','superSecretPassword')

#get vm list
r = requests.get('http://localhost/api/v2.0/vm',auth=authdata)

for vm in r.json():
  if vm['autostart'] == True and vm['status']['state'] != 'RUNNING':
    print('Starting {}'.format(vm['name']))
    requests.post('http://localhost/api/v2.0/vm/id/{}/start'.format(vm['id']), auth=authdata)


I think it can be improved to save restart state information (i.e. if it's crashing too fast, stop trying to restart it), but for now this suits my needs.
 

glauco

Guru
Joined
Jan 30, 2017
Messages
526
I've been pondering how to keep certain VMs alive that sometimes crash, so I dabbled with @querion's sample code to make this little script:
Code:
#!/usr/local/bin/python
import requests

authdata = ('root','superSecretPassword')

#get vm list
r = requests.get('http://localhost/api/v2.0/vm',auth=authdata)

for vm in r.json():
  if vm['autostart'] == True and vm['status']['state'] != 'RUNNING':
    print('Starting {}'.format(vm['name']))
    requests.post('http://localhost/api/v2.0/vm/id/{}/start'.format(vm['id']), auth=authdata)


I think it can be improved to save restart state information (i.e. if it's crashing too fast, stop trying to restart it), but for now this suits my needs.
Thank you, are you running this as a cronjob?
 
Top