-
Notifications
You must be signed in to change notification settings - Fork 0
/
vagrant-rebox
executable file
·138 lines (108 loc) · 3.87 KB
/
vagrant-rebox
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/bin/sh
# vagrant-rebox - repackage a Vagrant box, to capture modifications
# Intended to make it possible to more quickly boot a vagrant VM that's
# been partially provisioned (or updated, or similar). One can then
# change (or have the script change) the config.vm.box line to the newly
# captured box, and you'll now have a VM with a starting point of where
# your provisioned/updated box was, thus avoiding long delays in startup
# of a vagrant instance, at least of a particularly avoidable kind.
# Copyright 2014 by David Lindes. All rights reserved.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This program is based loosely (and in part) on the instructions here,
# for which I am thankful:
# http://abhishek-tiwari.com/hacking/creating-a-new-vagrant-base-box-from-an-existing-vm
# default value for vmname:
vmname=default
usage() {
cat <<EOF >&2
usage: $0 [-f] [-u] [-v <vmname>] boxname
Mandatory argument:
boxname - specify the name for the new vagrant box
Options:
-f - force - clobber an existing vagrant box, if extant
-u - update - attempt to modify Vagrantfile to use the new box
-v <vmname> - specify the name (instead of "$vmname") of the vagrant VM
to use as a baseline.
EOF
}
run() {
echo "-- Running: $*"
"$@"
}
read_vbox_id() {
box="$1"
idfile=".vagrant/machines/$box/virtualbox/id"
if [ ! -f "$idfile" ]
then
echo "Sorry, Couldn't find VirtualBox id for $box: $idfile doesn't exist" >&2
exit 1
fi
cat "$idfile"
}
get_vbox_name() {
# this actually seems easier, in shell, than showvminfo --machinereadable
VBoxManage showvminfo "$1" | awk 'NR == 1 {print $2}'
}
force_arg=""
update=false
while getopts fuv: opt; do
case "$opt" in
f) force_arg="--force";;
u) update=true;;
v) vmname="$OPTARG";;
esac
done
shift $((OPTIND - 1))
output="$1"; shift
# make sure we have an output file specified:
# TODO: some sort of sanity check on the name?
if [ -z "$output" ]; then
usage
exit 1
fi
# we don't know what to do with extra arguments; bail:
if [ ! -z "$*" ]; then
echo "Extra arguments: $*" >&2
usage
exit 1
fi
tmpbox="/tmp/vrb-$output.box"
if [ -f "$tmpbox" ]; then
echo "Sorry, $tmpbox already exists. Please remove if you wish to overwrite."
exit 1
fi
id=$(read_vbox_id $vmname)
if [ $? != 0 ]; then exit $?; fi
echo "Looking for information on box $vmname ($id)..."
# this isn't strictly necessary (using --base $id would work), but it
# makes it more user-friendly in its output:
vboxname=$(get_vbox_name "$id")
echo "- Found vbox name: $vboxname"
# exit on errors:
set -e
echo "- Packaging $vboxname as $tmpbox:"
run vagrant package --base "$vboxname" --output "$tmpbox"
echo "- Adding $tmpbox as $output:"
run vagrant box add $force_arg "$output" "$tmpbox"
rm -f "$tmpbox"
if $update; then
echo "- Attempting to modify Vagrantfile to use $output:"
echo " Before: \c"
perl -ne 'print if /^\s*\w+\.vm.box\s*=\s*["'\''].*["'\'']/' Vagrantfile
# hmm, I think I won't do this under `run`... best with just
# before/after, it seems to me:
perl -pi.vagrant-rebox-backup -e 's/^(\s*\w+\.vm\.box\s*=\s*["'\'']).*["'\'']/$1'"$output"'"/' Vagrantfile
echo " After: \c"
perl -ne 'print if /^\s*\w+\.vm.box\s*=\s*["'\''].*["'\'']/' Vagrantfile
fi