在 Ubuntu 19.10 中,我尝试创建一个脚本,以便在系统关闭时正常关闭用户的虚拟机,例如以 root 身份运行时
runuser -l jamie -c "vboxmanage controlvm \"Windows 10" suspend"
我根据我能找到的每个示例尝试了多种技术systemctl
,但都不起作用:在我的脚本运行之前总会有一些东西杀死虚拟机,并且它在日志中显示:
runuser[11997]: pam_unix(runuser-l:session): session opened for user jamie by (uid=0)
Nov 12 23:51:48 media2 shutdown[11979]: VBoxManage: error: Machine 'Windows 10' is not currently running
至少我有理由相信这就是我收到此消息的原因——如果我不在正确的用户上下文中,它会说机器不存在。
有许多类似的问题,但这些问题对我都没有用,我几乎尝试了所有我能从类似问题中找到的变体这里,这里,这里,这里, 和这里, 例如:
[Unit]
Description=Run Scripts at Start and Stop
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/home/jamie/.scripts/shutdown
[Install]
WantedBy=multi-user.target
(以及涉及其他目标、选项等的许多其他变体)。这些在末尾运行脚本,multi-user.target
这似乎太晚了。使用reboot.target
etc 的结果相同 - 脚本显然运行得太晚了。
我尝试使用这种技术-- 创建在多用户目标之后运行的新自定义目标 -- 但我无法注册自定义目标;它只是让 gnome 崩溃了。我在其他地方找不到有关此方法的进一步讨论。
有什么想法我可以如何在正在运行的进程终止之前成功拦截重启/关机事件?
答案1
此解决方案分为两部分。第一部分是创建脚本,第二部分是创建 systemd 服务文件来运行该脚本。
第 1 部分:创建脚本:autovm.sh
注意:您可以通过以下方式找到虚拟机的 UUID:VBoxManage list vms
sudo nano /bin/autovm.sh
#!/bin/bash
VMUSER="username"
VMNAME="21b3afd8-8f71-4c31-9853-ce9aa2eb58fb"
case "$1" in
start)
echo "===Starting VirtualBox VM==="
sudo -H -u $VMUSER VBoxManage startvm "$VMNAME" --type headless
;;
stop)
echo "===Shutting down Virtualbox VM==="
sudo -H -u $VMUSER VBoxManage controlvm "$VMNAME" acpipowerbutton
sleep 20
;;
*)
echo "Usage: /bin/autovm.sh {start|stop}"
exit 1
;;
esac
exit 0
现在使autovm.sh
脚本可执行并将其放置到:/bin/
第 2 部分:创建autovm.service
文件/etc/systemd/system/
(不要使此文件可执行)
sudo nano /etc/systemd/system/autovm.service
[Unit]
Description=Autostart VM
[Service]
Type=oneshot
ExecStartPre=/bin/sleep 20
ExecStart=/bin/autovm.sh start
ExecStop=/bin/autovm.sh stop
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
现在通过以下方式启用该服务:
sudo systemctl enable autovm.service