Class: RightScale::Platform::VolumeManager
- Inherits:
-
PlatformHelperBase
- Object
- PlatformHelperBase
- RightScale::Platform::VolumeManager
- Defined in:
- lib/right_agent/platform.rb,
lib/right_agent/platform/unix/platform.rb,
lib/right_agent/platform/windows/platform.rb,
lib/right_agent/platform/unix/linux/platform.rb,
lib/right_agent/platform/unix/darwin/platform.rb
Overview
Provides utilities for managing volumes (disks).
Defined Under Namespace
Classes: ParserError, VolumeError
Constant Summary
Constants inherited from PlatformHelperBase
PlatformHelperBase::API_FALSE, PlatformHelperBase::API_NULL, PlatformHelperBase::API_TRUE, PlatformHelperBase::SIZEOF_DWORD, PlatformHelperBase::SIZEOF_QWORD, PlatformHelperBase::WIDE
Instance Method Summary collapse
-
#assign_device(volume_device_or_index, device, options = {}) ⇒ TrueClass
Assigns the given device name to the volume given by index and clears the readonly attribute, if necessary.
-
#disks(conditions = nil) ⇒ Array
Gets a list of physical or virtual disks in the form: [:status, :total_size, :free_size, :dynamic, :gpt*].
-
#format_disk(disk_index, device) ⇒ TrueClass
Formats a disk given by disk index and the device (e.g. “D:”) for the volume on the primary NTFS partition which will be created.
-
#initialize ⇒ VolumeManager
constructor
A new instance of VolumeManager.
-
#is_attachable_volume_path?(path) ⇒ TrueClass|FalseClass
Determines if the given path is valid for a Windows volume attachemnt (excluding the reserved A: B: C: drives).
-
#mount_volume(volume, mountpoint) ⇒ Object
Overrides base VolumeManager#mount_volume.
-
#offline_disk(disk_index) ⇒ TrueClass
Brings the disk given by index offline.
-
#online_disk(disk_index, options = {}) ⇒ TrueClass
Brings the disk given by index online and clears the readonly attribute, if necessary.
-
#partitions(disk_index, conditions = nil) ⇒ Array
Gets a list of partitions for the disk given by index in the form: :type, :size, :offset.
-
#volumes(conditions = nil) ⇒ Object
Overrides base VolumeManager#volumes.
Methods inherited from PlatformHelperBase
#copy_to_string_buffer, #with_unicode_buffer
Constructor Details
#initialize ⇒ VolumeManager
Returns a new instance of VolumeManager.
576 577 578 579 |
# File 'lib/right_agent/platform/windows/platform.rb', line 576 def initialize @assignable_disk_regex = /^[D-Zd-z]:[\/\\]?$/ @assignable_path_regex = /^[A-Za-z]:[\/\\][\/\\\w\s\d\-_\.~]+$/ end |
Instance Method Details
#assign_device(volume_device_or_index, device, options = {}) ⇒ TrueClass
Assigns the given device name to the volume given by index and clears the readonly attribute, if necessary. The device must not currently be in use.
823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 |
# File 'lib/right_agent/platform/windows/platform.rb', line 823 def assign_device(volume_device_or_index, device, = {}) # Set some defaults for backward compatibility, allow user specified options to override defaults = { :clear_readonly => true, :remove_all => false, :idempotent => false }.merge() if device.match(@assignable_path_regex) && os_version.major < 6 raise ArgumentError.new('Mount path assignment is not supported in this version of windows') end # Volume selector for drive letter assignments volume_selector_match = volume_device_or_index.to_s.match(/^([D-Zd-z]|\d+):?$/) # Volume selector for mount path assignments volume_selector_match = volume_device_or_index.to_s.match(@assignable_path_regex) unless volume_selector_match raise ArgumentError.new("Invalid volume_device_or_index = #{volume_device_or_index}") unless volume_selector_match volume_selector = volume_selector_match[1] raise ArgumentError.new("Invalid device = #{device}") unless is_attachable_volume_path?(device) if [:idempotent] # Device already assigned? already_assigned = volumes.any? do |volume| volume[:device] == device && (volume[:index] == volume_device_or_index.to_s || volume[:device] == volume_device_or_index.to_s) end return true if already_assigned end # Validation ends here, and real stuff starts to happen script = <<EOF rescan list volume select volume "#{volume_selector}" #{get_clear_readonly_command('volume') if [:clear_readonly]} #{'remove all noerr' if [:remove_all]} #{get_assign_command_for_device(device)} EOF run_diskpart_script(script, 'assign device') true end |
#disks(conditions = nil) ⇒ Array
Gets a list of physical or virtual disks in the form:
[{:index, :status, :total_size, :free_size, :dynamic, :gpt}*]
where
:index >= 0
:status = 'Online' | 'Offline'
:total_size = bytes used by partitions
:free_size = bytes not used by partitions
:dynamic = true | false
:gpt = true | false
GPT = GUID partition table
608 609 610 611 612 613 614 615 |
# File 'lib/right_agent/platform/windows/platform.rb', line 608 def disks(conditions = nil) script = <<EOF rescan list disk EOF output_text = run_diskpart_script(script, 'list disks') return parse_disks(output_text, conditions) end |
#format_disk(disk_index, device) ⇒ TrueClass
Formats a disk given by disk index and the device (e.g. “D:”) for the volume on the primary NTFS partition which will be created.
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 |
# File 'lib/right_agent/platform/windows/platform.rb', line 692 def format_disk(disk_index, device) if device.match(@assignable_path_regex) && os_version.major < 6 raise ArgumentError.new("Mount path assignment is not supported in this version of windows") end # note that creating the primary partition automatically creates and # selects a new volume, which can be assigned a letter before the # partition has actually been formatted. raise ArgumentError.new("Invalid index = #{disk_index}") unless disk_index >= 0 raise ArgumentError.new("Invalid device = #{device}") unless is_attachable_volume_path?(device) # note that Windows 2003 server version of diskpart doesn't support # format so that has to be done separately. format_command = (os_version.major < 6) ? '' : 'format FS=NTFS quick' script = <<EOF rescan list disk select disk #{disk_index} #{get_clear_readonly_command('disk')} #{get_online_disk_command} clean create partition primary #{get_assign_command_for_device(device)} #{format_command} EOF run_diskpart_script(script, 'format disk') # must format using command shell's FORMAT command before 2008 server. if os_version.major < 6 command = "echo Y | format #{device[0,1]}: /Q /V: /FS:NTFS" begin execute(command) rescue ::RightScale::Platform::CommandError => e raise VolumeError, "Failed to format disk #{disk_index} for device #{device}: #{e.}\n#{e.output_text}" end end true end |
#is_attachable_volume_path?(path) ⇒ TrueClass|FalseClass
Determines if the given path is valid for a Windows volume attachemnt (excluding the reserved A: B: C: drives).
585 586 587 |
# File 'lib/right_agent/platform/windows/platform.rb', line 585 def is_attachable_volume_path?(path) return (nil != (path =~ @assignable_disk_regex) || nil != (path =~ @assignable_path_regex)) end |
#mount_volume(volume, mountpoint) ⇒ Object
Overrides base VolumeManager#mount_volume
146 147 148 |
# File 'lib/right_agent/platform/unix/platform.rb', line 146 def mount_volume(volume, mountpoint) must_be_overridden end |
#offline_disk(disk_index) ⇒ TrueClass
Brings the disk given by index offline
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 |
# File 'lib/right_agent/platform/windows/platform.rb', line 779 def offline_disk(disk_index) raise ArgumentError.new("Invalid disk_index = #{disk_index}") unless disk_index >= 0 if os_version.major < 6 raise ::RightScale::Exceptions::PlatformError, 'Offline disk is not supported by this platform' end # Set some defaults for backward compatibility, allow user specified options to override defaults script = <<EOF rescan list disk select disk #{disk_index} offline disk noerr EOF run_diskpart_script(script, 'offline disk') true end |
#online_disk(disk_index, options = {}) ⇒ TrueClass
Brings the disk given by index online and clears the readonly attribute, if necessary. The latter is required for some kinds of disks to online successfully and SAN volumes may be readonly when initially attached. As this change may bring additional volumes online the updated volumes list is returned.
748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 |
# File 'lib/right_agent/platform/windows/platform.rb', line 748 def online_disk(disk_index, = {}) raise ArgumentError.new("Invalid disk_index = #{disk_index}") unless disk_index >= 0 # Set some defaults for backward compatibility, allow user specified options to override defaults = { :idempotent => false }.merge() script = <<EOF rescan list disk select disk #{disk_index} #{get_clear_readonly_command('disk')} #{get_online_disk_command} EOF if [:idempotent] disk = disks(:index => disk_index).first return true if disk && disk[:status] == 'Online' end run_diskpart_script(script, 'online disk') true end |
#partitions(disk_index, conditions = nil) ⇒ Array
Gets a list of partitions for the disk given by index in the form:
{:index, :type, :size, :offset}
where
:index >= 0
:type = 'OEM' | 'Primary' | <undocumented>
:size = size in bytes used by partition on disk
:offset = offset of partition in bytes from head of disk
672 673 674 675 676 677 678 679 680 |
# File 'lib/right_agent/platform/windows/platform.rb', line 672 def partitions(disk_index, conditions = nil) script = <<EOF rescan select disk #{disk_index} list partition EOF output_text = run_diskpart_script(script, 'list partitions') return parse_partitions(output_text, conditions) end |
#volumes(conditions = nil) ⇒ Object
Overrides base VolumeManager#volumes
440 441 442 |
# File 'lib/right_agent/platform.rb', line 440 def volumes(conditions = nil) must_be_overridden end |