Guest User

Untitled

a guest
Jan 23rd, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.90 KB | None | 0 0
  1. include Opscode::Aws::Ec2
  2.  
  3.  
  4. # Auto locates and attached ebs devices based on the data bag they reside in. The following test cases need to be performed. Currently limited to 15 drives for the raid due to the drive mount point seek iteration logic. This could be fixed to include more than 15 mount points.
  5. # Create multiple resources with new node: PASS
  6. #
  7. # Re-attach multiple resources after a reboot: PASS
  8. #
  9. # Create resources across 2 runs. First run creates first raid set, second run re-attaches then creates: PASS
  10. #
  11. # Re-attach a different nodes data after terminating the original creator: PASS
  12.  
  13. # Installation:
  14. # Copy into the providers directory of your cookbook. In this example, I have chosen "brisk" as the cookbook
  15. #
  16. # Usage:
  17. # Creates a 1 TB raid 0 drive with 10 drives at 100 GB each
  18. # brisk_ebs_raid "create data dir /mnt/cassdata" do
  19. # mount_point /mnt/cassdata
  20. # disk_count 10
  21. # disk_size 100
  22. # action [:auto_attach]
  23. # notifies :restart, resources(:service => "cassandra")
  24. # end
  25. #
  26. # Author: Todd Nine
  27. #
  28. action :auto_attach do
  29.  
  30. Chef::Log.info("Executing the autolocate task")
  31.  
  32. #Make sure the mdadm package is installed
  33. package "mdadm" do
  34. action :install
  35. end
  36.  
  37. package "xfsprogs" do
  38. action :install
  39. end
  40.  
  41.  
  42.  
  43. #we're done we successfully located what we needed
  44. if !locate_and_mount(@new_resource.mount_point)
  45.  
  46. #If we get here, we couldn't auto attach, nor re-allocate an existing set of disks to ourselves. Auto create the md devices
  47. #Find our first raid device
  48. number=0
  49.  
  50. dir = "/dev/md#{number}"
  51.  
  52. #TODO, this won't work with more than 10 md devices
  53. begin
  54. dir = "/dev/md#{number}"
  55. Chef::Log.info("md pre trim #{dir}")
  56. number +=1
  57. end while ::File.exists?(dir)
  58.  
  59.  
  60. dir = dir[5, dir.length]
  61.  
  62. Chef::Log.debug("raid device is #{dir}")
  63.  
  64.  
  65. sd_dev = "sdh"
  66.  
  67. begin
  68. sd_dev = sd_dev.next
  69. base_device = "/dev/#{sd_dev}1"
  70. Chef::Log.info("dev pre trim #{base_device}")
  71. end while ::File.exists?(base_device)
  72.  
  73. Chef::Log.debug("sd device is #{sd_dev}")
  74.  
  75. create_raid_disks(@new_resource.mount_point, dir, sd_dev, @new_resource.disk_count, @new_resource.disk_size)
  76.  
  77. @new_resource.updated_by_last_action(true)
  78.  
  79. end
  80.  
  81.  
  82.  
  83.  
  84.  
  85. end
  86.  
  87.  
  88. private
  89.  
  90. #Attempt to find an unused data bag and mount all the EBS volumes to our system
  91. def locate_and_mount(mount_path )
  92.  
  93. if node[:aws].nil? || node[:aws][:raid].nil? || node[:aws][:raid][mount_path].nil?
  94. Chef::Log.info("No mount point found '#{mount_path}' for node")
  95. return false;
  96. end
  97.  
  98. raid_dev = node[:aws][:raid][mount_path][:raid_dev]
  99.  
  100. raid_dev = "/dev/#{raid_dev}"
  101.  
  102. Chef::Log.info("Raid device is #{raid_dev} and mount path is #{mount_path}")
  103.  
  104. assemble_raid(raid_dev, mount_path)
  105.  
  106. #Now mount the drive
  107. mount_device(raid_dev, mount_path)
  108.  
  109.  
  110.  
  111. return true
  112.  
  113. end
  114.  
  115. ##
  116. #Assembles the raid if it doesn't already exist
  117. ##
  118. def assemble_raid(raid_dev, mount_path)
  119. #D
  120. if ::File.exists?(raid_dev)
  121. Chef::Log.info("Device #{raid_dev} exists skipping")
  122. return
  123. end
  124.  
  125. Chef::Log.info("Raid device #{raid_dev} does not exist re-assembling")
  126.  
  127. device_vol_map = node[:aws][:raid][mount_path][:devices]
  128.  
  129. Chef::Log.debug("Devices for mount #{mount_path} are #{device_vol_map.pretty_inspect}")
  130.  
  131. device_string = ""
  132.  
  133. device_vol_map.keys.sort.each do |dev_device|
  134. attach_volume(dev_device, device_vol_map[dev_device])
  135. device_string += "/dev/#{dev_device} "
  136. end
  137.  
  138. #Wait until all volumes are mounted
  139. ruby_block "wait" do
  140. block do
  141. true
  142. end
  143. end
  144.  
  145. #Wait until all volumes are mounted
  146. ruby_block "wait" do
  147. block do
  148. Chef::Log.info("sleeping 10 seconds until EBS volumes have re-attached")
  149. sleep 10
  150. end
  151. end
  152.  
  153. #Now that attach is done we re-build the md device
  154. execute "re-attaching raid device" do
  155. command "mdadm --assemble #{raid_dev} #{device_string}"
  156. creates raid_dev
  157. not_if "test -d #{raid_dev}"
  158. # notifies :run, "ruby_block[setchanged]", :immediately
  159. end
  160. end
  161.  
  162.  
  163. def mount_device(raid_dev, mnt_point)
  164. #Create the mount point
  165. directory mnt_point do
  166. owner "root"
  167. group "nogroup"
  168. mode 0755
  169. recursive true
  170. action :create
  171. not_if "test -d #{mnt_point}"
  172. # notifies :run, "ruby_block[setchanged]", :immediately
  173. end
  174.  
  175.  
  176.  
  177. #Mount the device
  178. mount mnt_point do
  179. device raid_dev
  180. fstype "xfs"
  181. options "rw,noatime,inode64"
  182. action :mount
  183. # notifies :run, "ruby_block[setchanged]", :immediately
  184. end
  185.  
  186. end
  187.  
  188.  
  189.  
  190.  
  191. #Attach all existing ami instances if they exist on this node, if not, we want an error to occur Detects disk from node information
  192. def attach_volume(disk_dev, volume_id)
  193.  
  194. disk_dev_path = "/dev/#{disk_dev}"
  195.  
  196. aws = data_bag_item("deployment", "aws")
  197.  
  198. Chef::Log.info("Attaching existing ebs volume id #{volume_id} for device #{disk_dev_path}")
  199.  
  200. aws_ebs_volume "#{disk_dev_path}" do
  201. aws_access_key aws['accesskey']
  202. aws_secret_access_key aws['secretkey']
  203. device disk_dev_path
  204. name disk_dev
  205. volume_id volume_id
  206. action [:attach]
  207. provider "aws_ebs_volume"
  208. end
  209.  
  210.  
  211.  
  212.  
  213. end
  214.  
  215.  
  216. #Mount point for where to mount I.E /mnt/filesystem
  217. #Raid dev. I.E. md0
  218. #Diskset I.E sdi (which creates sdi1-sdi<n>
  219. #Raid size. The total size of the array
  220. def create_raid_disks(mnt_point, raid_dev, disk_dev, num_disks, disk_size)
  221.  
  222. #Create the mount point data bag
  223. devices = {}
  224.  
  225.  
  226. #For each volume add information to the mount metadata
  227. (1..num_disks).each do |i|
  228.  
  229. disk_dev_path = "#{disk_dev}#{i}"
  230.  
  231. aws = data_bag_item("deployment", "aws")
  232.  
  233. aws_ebs_volume "#{disk_dev_path}" do
  234. aws_access_key aws['accesskey']
  235. aws_secret_access_key aws['secretkey']
  236. size disk_size
  237. device "/dev/#{disk_dev_path}"
  238. name disk_dev_path
  239. action [:create, :attach]
  240. provider "aws_ebs_volume"
  241.  
  242. #set up our data bag info
  243. devices[disk_dev_path] = "pending"
  244. Chef::Log.info("creating ebs volume for device #{disk_dev_path} with size #{disk_size}")
  245. end
  246.  
  247. end
  248.  
  249. devices_string = ""
  250.  
  251. #Blocking task
  252.  
  253. devices.keys.sort.each do |k|
  254. devices_string += "/dev/#{k} "
  255. end
  256.  
  257. Chef::Log.debug("finsihed sorting devices #{devices_string}")
  258.  
  259. Chef::Log.debug("sleeping 10 seconds to let drives attach")
  260.  
  261. sleep 10
  262.  
  263. #Create the raid device on our system
  264. execute "creating raid device" do
  265. Chef::Log.info("creating raid device /dev/#{raid_dev} with raid devices #{devices_string}")
  266. command "mdadm --create /dev/#{raid_dev} --level=0 --raid-devices=#{devices.size} #{devices_string}"
  267. creates "/dev/#{raid_dev}"
  268. end
  269.  
  270. #Format the device
  271. execute "formatting device" do
  272. command "mkfs.xfs /dev/#{raid_dev}"
  273. only_if "xfs_admin -l /dev/#{raid_dev} 2>&1 | grep -qx 'xfs_admin: /dev/#{raid_dev} is not a valid XFS filesystem (unexpected SB magic number 0x00000000)'"
  274. end
  275.  
  276. #Mount the device
  277. mount_device("/dev/#{raid_dev}", mnt_point)
  278.  
  279. #Not invoked until the volumes have been successfully created and attached
  280. ruby_block "databagsetup" do
  281.  
  282. block do
  283. Chef::Log.info("finished creating disks")
  284.  
  285.  
  286. devices.each_pair do |key, value|
  287. value = node[:aws][:ebs_volume][key][:volume_id]
  288. devices[key] = value
  289. Chef::Log.info("value is #{value}")
  290. end
  291.  
  292. #Assemble all the data bag meta data
  293. mount_meta = {
  294. "raid_dev" => raid_dev,
  295. "devices" => devices
  296. }
  297.  
  298. raid_map = node[:aws][:raid]
  299.  
  300. if raid_map.nil?
  301. node[:aws][:raid] = {}
  302. end
  303.  
  304. node[:aws][:raid][mnt_point] = mount_meta
  305. node.save
  306.  
  307. end
  308. end
  309.  
  310. #Now format and create the device
  311.  
  312. end
Add Comment
Please, Sign In to add comment