Checkpoint
[pwan.org.git] / content / hints / pm-utils-ubuntu-vagrant-fun.rst
1 Using pm-utils to save/restore VMs on workstation suspend/restore
2 #################################################################
3
4 :date: 2017-09-16
5 :tags: hints,ubuntu,vagrant,pm
6 :category: hints
7 :author: Jude N
8
9 I use Ubuntu (16.04 for now) and Vagrant (1.9.0 for now) on a bunch of my projects, and I've been running into somethinng like this
10 `power management bug` for a while now, where after restoring from suspension, my vagrant sessions would be dead and I'd have to
11 'vagrant halt' and 'vagrant up' before another 'vagrant ssh' would succeed.
12
13 To work around this, I came up with some /etc/pm/sleep.d scripts which would save any running vagrant boxes when suspending the
14 workstation and then resume the VMs when resuming the workstation.
15
16 Now if I'm in a 'vagrant ssh' session and Ubuntu suspends/resumes, instead of coming back to a frozen session, I'll see I've been
17 disconnected from the ssh session, and I can do another 'vagrant ssh' without having to halt/re-up the VM. That's better than nothing,
18 but the next step here is to start using something like screen or tmux in my vagrant sessions so I can restore right back to where I left
19 off.
20
21 So why bother with two scripts when you could have 1 script with a single case statement ? I wanted saving the running vagrant boxes to
22 happen when all the usual services and userspace infrastructure was still running, so I wanted that script in the 00 -49 range from as
23 per the 'Sleep Hook Ordering Convention' portion of 'man 8 pm-action`. However I don't restoration to happen until all the services
24 restarted, so I pushed to the end of the service handling hook range. I may want to revisit this, and rename it to 75_vagrant.
25
26 Note in the resume script, the command is pushed into the background since I didn't want want to wait for the VMs to be restored before
27 resuming Ubuntu. I'm usually checking email or the web for a bit before going back to my VMs so I'm OK if that's ready immediately.
28
29 Here are some other lessons I learned from these scripts:
30
31 - I didn't know `vagrant global-status`_ existed !
32 - vagrant commands have to be run as the user started the VM. I had to use runuser to run the vagrant commands as my dev user.
33 - I learned the '-I %' approach of `getting xargs to insert it's argument in the middle of a command`_.
34
35 The first script is /etc/pm/sleep.d/01_vagrant:
36
37 .. code-block:: bash
38
39 #!/bin/bash
40
41 YOURNAME="your normal nonroot user name"
42
43 case "$1" in
44 suspend)
45 timestamp=`date --rfc-3339=seconds`
46 echo "${timestamp}: $0 output" >> /var/log/pm-suspend-vagrant.log
47 (/sbin/runuser -u ${YOURNAME} /usr/bin/vagrant global-status | grep running | awk '{ print $1; }' | xargs -L1 -I % runuser -u ${YOURNAME} vagrant suspend % ) >> /var/log/pm-suspend-vagrant.log
48 ;;
49 *)
50 ;;
51 esac
52
53 # Don't let errors above stop suspension
54 true
55
56 The second script is /etc/pm/sleep.d/74_vagrant.sh
57
58 .. code-block:: bash
59
60 #!/bin/bash
61
62 YOURNAME="your normal nonroot user name"
63
64 case "$1" in
65 resume)
66 # Push the restoration into the background so it doesn't slow down
67 timestamp=`date --rfc-3339=seconds`
68 ((/sbin/runuser -u ${YOURNAME} /usr/bin/vagrant global-status | grep saved | awk '{ print $1; }' | xargs -L1 -I % runuser -u ${YOURNAME} vagrant resume % ) >> /var/log/pm-resume-vagrant.log) &
69 ;;
70 *)
71 ;;
72 esac
73
74 # Don't let errors above stop restoration
75 true
76
77 Sources:
78 - http://manpages.ubuntu.com/manpages/xenial/man8/pm-action.8.html
79
80 .. _power management bug: https://www.virtualbox.org/ticket/15378
81 .. _vagrant global-status: https://www.vagrantup.com/docs/cli/global-status.html
82 .. _getting xargs to insert it's argument in the middle of a command: https://stackoverflow.com/a/40355248/496127