Fusemount the first gluster volume on the nodes
[obnox/vagrant/vagrant-gluster-samba-cluster.git] / Vagrantfile
1 # -*- mode: ruby -*-
2 # vi: ft=ruby:et:ts=2:sts=2:sw=2
3
4 VAGRANTFILE_API_VERSION = 2
5
6
7 require 'yaml'
8
9 #
10 # Defaults for Configuration data.
11 # Will be overridden from the settings file
12 # and (possibly later) from commandline parameters.
13 #
14
15 net_default = {
16   :type   => 'veth',
17   :flags  => 'up',
18   :hwaddr => '',
19   :name   => '',
20   :ipv4   => '',
21   :ipv6   => '',
22 }
23
24 network_opts = [ :type, :link, :flags, :hwaddr, :name, :ipv4, :ipv6 ]
25
26 libvirt_network_parms = {
27   :hwaddr => :mac,
28   :ipv4   => :ip,
29   :ipv6   => '',
30   :link   => '',
31   :flags  => '',
32   :type   => '',
33 }
34
35 defaults = {
36   :provider => {
37     :libvirt => {
38       :prefix => 'vagrant',
39     },
40   },
41 }
42
43
44 vms = [
45   {
46     #:hostname => 'gluno1',
47     :hostname => 'node1',
48     #:box => 'local-fedora-rawhide-64',
49     #:box => 'purpleidea-fedora-21',
50     #:box => 'local-fedora-21.2',
51     :provider => {
52       :lxc => {
53         :container_name => 'gluno1',
54         #:container_name => 'node1',
55       },
56       :libvirt => {
57         :box => 'local-fedora-21.2',
58         :prefix => 'gluster',
59       }, 
60     },
61     :internal_if => 'virbr1',
62     :networks => [
63       {
64         :link => 'virbr1',
65         :ipv4 => '172.20.10.30',
66       },
67       #{
68       #  :link => 'virbr2',
69       #  #:ipv4 => '10.111.222.201',
70       #},
71     ],
72   },
73 ]
74
75 #
76 # Load the config, if it exists,
77 # possibly override with commandline args,
78 # (currently none supported yet)
79 # and then store the config.
80 #
81
82 projectdir = File.expand_path File.dirname(__FILE__)
83 f = File.join(projectdir, 'vagrant.yaml')
84 if File.exists?(f)
85   settings = YAML::load_file f
86
87   if settings[:vms].is_a?(Array)
88     vms = settings[:vms]
89   end
90   puts "Loaded settings from #{f}."
91 end
92
93 # TODO(?): ARGV-processing
94
95 settings = {
96   :vms  => vms,
97 }
98
99 File.open(f, 'w') do |file|
100   file.write settings.to_yaml
101 end
102 puts "Wrote settings to #{f}."
103
104
105 # apply defaults:
106
107 vms.each do |vm|
108   defaults.keys.each do |cat|
109     next if not vm.has_key?(cat)
110     defaults[cat].keys.each do |subcat|
111       next if not vm[cat].has_key?(subcat)
112       defaults[cat][subcat].keys.each do |key|
113         if not vm[cat][subcat].has_key?(key)
114           vm[cat][subcat][key] = defaults[cat][subcat][key]
115         end
116       end
117     end
118   end
119
120   #if not vm[:provider][:libvirt].has_key?(:prefix)
121   #  vm[:provider][:libvirt][:prefix] = default_libvirt_prefix
122   #end
123
124   vm[:networks].each do |net|
125     net_default.keys.each do |key|
126       if not net.has_key?(key)
127         net[key] = net_default[key]
128       end
129     end
130   end
131 end
132
133
134 # compose the list of cluster internal ips
135 #
136 cluster_internal_ips = vms.map do |vm|
137   net = nil
138   vm[:networks].each do |n|
139     if n[:link] == vm[:internal_if]
140       net = n
141       break
142     end
143   end
144   if net != nil
145     net[:ipv4]
146   end
147 end
148
149 #print "internal ips: "
150 #print cluster_internal_ips
151 #print "\n"
152
153 #PROVISION_SCRIPT = <<SCRIPT
154 #yum -y install make samba
155 #SCRIPT
156
157 NET_FIX_ALWAYS_SCRIPT = <<SCRIPT
158 set -e
159 # eth1 is not brought up automatically
160 # by 'vagrant up' of the existing vm
161 ifup eth1
162 SCRIPT
163
164 NET_FIX_INITIAL_SCRIPT = <<SCRIPT
165 set -e
166 # Fix dhclient running on private network IF
167 ifdown eth1
168 systemctl restart NetworkManager
169 ifup eth1
170 SCRIPT
171
172 INSTALL_SCRIPT = <<SCRIPT
173 set -e
174 yum -y install xfsprogs
175 yum -y install glusterfs{,-server,-fuse,-geo-replication}
176 yum -y install ctdb samba
177 SCRIPT
178
179 XFS_SCRIPT = <<SCRIPT
180 set -e
181
182 DEVICE=$1
183 PARTDEV=${DEVICE}1
184 DISKDEV="/dev/${DEVICE}"
185 DISKPARTDEV="/dev/${PARTDEV}"
186 ##MOUNTP=$2
187 MOUNTP=/export/${PARTDEV}
188 BRICKD=${MOUNTP}/brick
189
190 BACKUP_SUFFIX=".orig.$(date +%Y%m%d-%H%M%S)"
191
192 parted -s ${DISKDEV} mklabel msdos
193 parted -s ${DISKDEV} mkpart primary 1 100%
194 mkfs.xfs -f ${DISKPARTDEV}
195
196 mkdir -p ${MOUNTP}
197
198 FILE=/etc/fstab
199 test -f ${FILE} || touch ${FILE}
200 cp -f -a ${FILE} ${FILE}${BACKUP_SUFFIX}
201
202 cat <<EOF >> ${FILE}
203 ${DISKPARTDEV} ${MOUNTP} xfs defaults 0 0
204 EOF
205
206 mount ${MOUNTP}
207
208 mkdir ${BRICKD}
209 SCRIPT
210
211 GLUSTER_START_SCRIPT = <<SCRIPT
212 set -e
213 systemctl start glusterd.service
214 SCRIPT
215
216 #GLUSTER_PROBE_SCRIPT = <<SCRIPT
217 #set -e
218 #
219 #PEER_IP=$1
220 #
221 #gluster peer probe ${PEER_IP}
222 #SCRIPT
223
224 GLUSTER_PROBE_SCRIPT = <<SCRIPT
225 set -e
226
227 PEER_IPS="$@"
228
229 for PEER_IP in ${PEER_IPS}
230 do
231   gluster peer probe ${PEER_IP}
232 done
233 SCRIPT
234
235 GLUSTER_CREATEVOL_SCRIPT = <<SCRIPT
236 set -e
237 VOLNAME=$1
238 shift
239 REP=$1
240 shift
241
242 echo "gluster volume create $VOLNAME rep $REP transport tcp $@"
243 gluster volume create $VOLNAME rep $REP transport tcp $@
244
245 gluster volume start $VOLNAME
246 SCRIPT
247
248 GLUSTER_MOUNT_SCRIPT = <<SCRIPT
249 set -e
250 VOLNAME=$1
251 shift
252 MOUNTPT=$1
253 shift
254
255 MOUNTDEV="127.0.0.1:/${VOLNAME}"
256
257 mkdir -p ${MOUNTPT}
258
259 #mount -t glusterfs ${MOUNTDEV} ${MOUNTPT}
260
261 BACKUP_SUFFIX=".orig.$(date +%Y%m%d-%H%M%S)"
262
263 FILE=/etc/fstab
264
265 grep -q -s "${MOUNTPT}" || {
266   test -f ${FILE} || touch ${FILE}
267   cp -f -a ${FILE} ${FILE}${BACKUP_SUFFIX}
268
269   cat <<EOF >> ${FILE}
270 ${MOUNTDEV} ${MOUNTPT} glusterfs defaults,selinux 0 0
271 EOF
272 }
273
274 mount ${MOUNTPT}
275
276 SCRIPT
277
278 #
279 # The vagrant machine definitions
280 #
281
282 Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
283
284   if Vagrant.has_plugin?("vagrant-cachier")
285     config.cache.scope = :box
286   end
287
288   vms.each do |machine|
289     config.vm.define machine[:hostname] do |node|
290       node.vm.box = machine[:provider][:libvirt][:box]
291       node.vm.hostname = machine[:hostname]
292
293       node.vm.provider :libvirt do |libvirt|
294         libvirt.default_prefix = machine[:provider][:libvirt][:prefix]
295         libvirt.memory = 1024
296         libvirt.storage :file, :size => '64M', :device => 'vdb'
297         libvirt.storage :file, :size => '10G', :device => 'vdc'
298
299         machine[:networks].each do |net|
300           if not net[:ipv4] == ''
301             node.vm.network :private_network, :ip => net[:ipv4]
302           end
303         end
304       end
305
306       # There is some problem with the fedora base box:
307       # We need to up the interface on reboots.
308       # It does not come up automatically.
309       node.vm.provision "net_fix_always", type: "shell", run: "always" do |s|
310         s.inline = NET_FIX_ALWAYS_SCRIPT
311       end
312
313       # There is some problem with the fedora base box:
314       # Upon first boot, ifdown eth1 fails and the dhclient
315       # keep being active. Simply bringing down and up again
316       # the interface is not sufficient. We need to restart
317       # NetworkManager in order to teach it to not feel
318       # responsible for the interface any more.
319       node.vm.provision "net_fix_initial", type: "shell" do |s|
320         s.inline = NET_FIX_INITIAL_SCRIPT
321       end
322
323       node.vm.provision :shell do |s|
324         s.inline = INSTALL_SCRIPT
325       end
326
327       # multiple privisioners with same name possible?
328       node.vm.provision "xfs", type: "shell" do |s|
329         s.inline = XFS_SCRIPT
330         #s.args = [ "vdb", "/export/gluster/brick1" ]
331         s.args = [ "vdb" ]
332       end
333
334       node.vm.provision "xfs", type: "shell" do |s|
335         s.inline = XFS_SCRIPT
336         #s.args = [ "vdc" , "/export/gluster/brick2" ]
337         s.args = [ "vdc" ]
338       end
339
340       node.vm.provision "gluster_start", type: "shell" do |s|
341         s.inline = GLUSTER_START_SCRIPT
342       end
343
344       node.vm.provision "gluster_probe", type: "shell" do |s|
345         s.inline = GLUSTER_PROBE_SCRIPT
346         s.args = cluster_internal_ips
347       end
348
349       node.vm.provision "gluster_createvol", type: "shell" do |s|
350         mount_points = cluster_internal_ips.map do |ip|
351           "#{ip}:/export/vdb1/brick"
352         end
353         s.inline = GLUSTER_CREATEVOL_SCRIPT
354         s.args = [ "gv0", "3" ] + mount_points
355       end
356
357       node.vm.provision "gluster_mount", type: "shell" do |s|
358         s.inline = GLUSTER_MOUNT_SCRIPT
359         s.args = [ "gv0", "/gluster/gv0" ]
360       end
361     end
362   end
363
364 end