Class: Dcmgr::Models::Volume

Inherits:
AccountResource show all
Defined in:
lib/dcmgr/models/volume.rb

Defined Under Namespace

Classes: CapacityError, RequestError

Constant Summary collapse

STATUS_TYPE_REGISTERING =
"registering"
STATUS_TYPE_ONLINE =
"online"
STATUS_TYPE_OFFLINE =
"offline"
STATUS_TYPE_FAILED =
"failed"
STATE_TYPE_REGISTERING =
"registering"
STATE_TYPE_CREATING =
"creating"
STATE_TYPE_AVAILABLE =
"available"
STATE_TYPE_ATTATING =
"attating"
STATE_TYPE_ATTACHED =
"attached"
STATE_TYPE_DETACHING =
"detaching"
STATE_TYPE_FAILED =
"failed"
STATE_TYPE_DEREGISTERING =
"deregistering"
STATE_TYPE_DELETING =
"deleting"
STATE_TYPE_DELETED =
"deleted"
RECENT_TERMED_PERIOD =
(60 * 15)

Constants inherited from BaseNew

BaseNew::LOCK_TABLES_KEY

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from AccountResource

#account

Methods inherited from BaseNew

Proxy, dataset, default_row_lock_mode=, install_data, install_data_hooks, lock!, unlock!, #with_timestamps?

Class Method Details

.delete_volume(account_id, uuid) ⇒ Object



104
105
106
107
108
109
110
111
112
# File 'lib/dcmgr/models/volume.rb', line 104

def self.delete_volume(, uuid)
  v = self.dataset.where(:account_id=>).where(:uuid=>uuid.split('-').last).first
  if v.state.to_sym != :available
    raise RequestError, "invalid delete request"
  end
  v.state = :deregistering
  v.save_changes
  v
end

.entry_new(account, size, params, &blk) ⇒ Object

Raises:

  • (ArgumentError)


166
167
168
169
170
171
172
173
174
# File 'lib/dcmgr/models/volume.rb', line 166

def self.entry_new(, size, params, &blk)
  # Mash is passed in some cases.
  raise ArgumentError unless params.class == ::Hash
  v = self.new &blk
  v. = .canonical_uuid
  v.size = size
  v.request_params = params
  v
end

.get_list(account_id, *args) ⇒ Object



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
# File 'lib/dcmgr/models/volume.rb', line 78

def self.get_list(, *args)
  data = args.first
  vl = self.dataset.where(:account_id=>)
  vl = vl.limit(data[:limit], data[:start]) if data[:start] && data[:limit]
  if data[:target] && data[:sort]
    vl = case data[:sort]
         when 'desc'
           vl.order(data[:target].to_sym.desc)
         when 'asc'
           vl.order(data[:target].to_sym.asc)
         end
  end
  if data[:target] && data[:filter]
    filter = case data[:target]
             when 'uuid'
               data[:filter].split('vol-').last
             else
               data[:filter]
             end
    vl = vl.grep(data[:target].to_sym, "%#{filter}%")
  end
  vl.all.map{|row|
    row.to_api_document
  }
end

Instance Method Details

#create_snapshot(account_id) ⇒ Object



146
147
148
149
150
151
# File 'lib/dcmgr/models/volume.rb', line 146

def create_snapshot()
  vs = VolumeSnapshot.create(:account_id=>,
                             :storage_node_id=>self.storage_node_id,
                             :origin_volume_id=>self.canonical_uuid,
                             :size=>self.size)
end

#deleteObject

override Sequel::Model#delete not to delete rows but to set delete flags.



155
156
157
158
159
160
# File 'lib/dcmgr/models/volume.rb', line 155

def delete
  self.deleted_at ||= Time.now
  self.state = :deleted if self.state != :deleted
  self.status = :offline if self.status != :offline
  self.save
end

#merge_pool_dataObject



114
115
116
117
# File 'lib/dcmgr/models/volume.rb', line 114

def merge_pool_data
  v = self.to_hash
  v.merge(:storage_node=>storage_node.to_hash)
end

#ready_to_take_snapshot?Boolean

Returns:

  • (Boolean)


142
143
144
# File 'lib/dcmgr/models/volume.rb', line 142

def ready_to_take_snapshot?
  %w(available attached).member?(self.state)
end

#snapshotObject



162
163
164
# File 'lib/dcmgr/models/volume.rb', line 162

def snapshot
  VolumeSnapshot[self.snapshot_id]
end

#to_api_documentObject

Hash data for API response.



127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/dcmgr/models/volume.rb', line 127

def to_api_document
  h = {
    :id => self.canonical_uuid,
    :uuid => self.canonical_uuid,
    :size => self.size,
    :snapshot_id => self.snapshot_id,
    :created_at => self.created_at,
    :attached_at => self.attached_at,
    :state => self.state,
    :instance_id => (self.instance && self.instance.canonical_uuid),
    :deleted_at => self.deleted_at,
    :detached_at => self.detached_at,
  }
end

#to_hashObject



119
120
121
122
123
124
# File 'lib/dcmgr/models/volume.rb', line 119

def to_hash
  h = super
  # yaml -> hash translation
  h[:transport_information]=self.transport_information
  h
end

#validateObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/dcmgr/models/volume.rb', line 61

def validate
  # do not run validation if the row is maked as deleted.
  return true if self.deleted_at

  if new?
    # TODO: Here may not be the right place for capacity validation.
     = self.class.filter(:account_id=>self.).lives.sum(:size).to_i
    if self..quota.volume_total_size <  + self.size.to_i
      raise CapacityError, "Allocation exceeds account's quota: #{self..quota.volume_total_size}, #{self.size.to_i}, #{}"
    end
  end

  errors.add(:size, "Invalid volume size.") if self.size == 0
  
  super
end

#validate_storage_node_assigned(sp) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/dcmgr/models/volume.rb', line 48

def validate_storage_node_assigned(sp)
  unless sp.is_a?(StorageNode)
    raise "unknown class: #{sp.class}"
  end
  volume_size = sp.volumes_dataset.lives.sum(:size).to_i
  # check if the sum of available volume and new volume is under
  # the limit of offering capacity.
  total_size = sp.offering_disk_space - volume_size.to_i
  if self.size > total_size
    raise CapacityError, "Allocation exceeds storage node blank size: #{}"
  end
end