wakame-vdc-agents 10.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +202 -0
- data/NOTICE +1 -0
- data/Rakefile +142 -0
- data/bin/hva +972 -0
- data/bin/nsa +147 -0
- data/bin/sta +182 -0
- data/config/hva.conf.example +10 -0
- data/config/initializers/isono.rb +43 -0
- data/config/initializers/passenger.rb +6 -0
- data/config/initializers/sequel.rb +21 -0
- data/config/nsa.conf.example +9 -0
- data/config/path_resolver.rb +12 -0
- data/lib/dcmgr.rb +115 -0
- data/lib/dcmgr/endpoints/core_api.rb +1004 -0
- data/lib/dcmgr/endpoints/core_api_mock.rb +816 -0
- data/lib/dcmgr/endpoints/errors.rb +55 -0
- data/lib/dcmgr/endpoints/metadata.rb +129 -0
- data/lib/dcmgr/logger.rb +44 -0
- data/lib/dcmgr/models/account.rb +104 -0
- data/lib/dcmgr/models/account_resource.rb +16 -0
- data/lib/dcmgr/models/base.rb +69 -0
- data/lib/dcmgr/models/base_new.rb +371 -0
- data/lib/dcmgr/models/frontend_system.rb +38 -0
- data/lib/dcmgr/models/host_pool.rb +102 -0
- data/lib/dcmgr/models/image.rb +46 -0
- data/lib/dcmgr/models/instance.rb +255 -0
- data/lib/dcmgr/models/instance_netfilter_group.rb +16 -0
- data/lib/dcmgr/models/instance_nic.rb +68 -0
- data/lib/dcmgr/models/instance_spec.rb +21 -0
- data/lib/dcmgr/models/ip_lease.rb +42 -0
- data/lib/dcmgr/models/netfilter_group.rb +88 -0
- data/lib/dcmgr/models/netfilter_rule.rb +21 -0
- data/lib/dcmgr/models/network.rb +32 -0
- data/lib/dcmgr/models/physical_host.rb +67 -0
- data/lib/dcmgr/models/request_log.rb +25 -0
- data/lib/dcmgr/models/ssh_key_pair.rb +55 -0
- data/lib/dcmgr/models/storage_pool.rb +134 -0
- data/lib/dcmgr/models/tag.rb +126 -0
- data/lib/dcmgr/models/tag_mapping.rb +28 -0
- data/lib/dcmgr/models/volume.rb +130 -0
- data/lib/dcmgr/models/volume_snapshot.rb +47 -0
- data/lib/dcmgr/node_modules/hva_collector.rb +134 -0
- data/lib/dcmgr/node_modules/sta_collector.rb +72 -0
- data/lib/dcmgr/scheduler.rb +12 -0
- data/lib/dcmgr/scheduler/find_last.rb +16 -0
- data/lib/dcmgr/scheduler/find_random.rb +16 -0
- data/lib/dcmgr/stm/instance.rb +25 -0
- data/lib/dcmgr/stm/snapshot_context.rb +33 -0
- data/lib/dcmgr/stm/volume_context.rb +65 -0
- data/lib/dcmgr/web/base.rb +21 -0
- data/lib/sinatra/accept_media_types.rb +128 -0
- data/lib/sinatra/lazy_auth.rb +56 -0
- data/lib/sinatra/rabbit.rb +278 -0
- data/lib/sinatra/respond_to.rb +272 -0
- data/lib/sinatra/sequel_transaction.rb +27 -0
- data/lib/sinatra/static_assets.rb +83 -0
- data/lib/sinatra/url_for.rb +44 -0
- metadata +270 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr::Models
|
4
|
+
# Network interface for running instance.
|
5
|
+
class InstanceNic < BaseNew
|
6
|
+
taggable 'nic'
|
7
|
+
|
8
|
+
inheritable_schema do
|
9
|
+
Fixnum :instance_id, :null=>false
|
10
|
+
String :vif, :null=>false, :size=>50
|
11
|
+
String :mac_addr, :null=>false, :size=>12
|
12
|
+
|
13
|
+
index :mac_addr, {:unique=>true}
|
14
|
+
end
|
15
|
+
with_timestamps
|
16
|
+
|
17
|
+
many_to_one :instance
|
18
|
+
one_to_one :ip, :class=>IpLease
|
19
|
+
|
20
|
+
def to_hash
|
21
|
+
h = values.dup.merge(super)
|
22
|
+
h.delete(:instance_id)
|
23
|
+
h
|
24
|
+
end
|
25
|
+
|
26
|
+
def before_validation
|
27
|
+
super
|
28
|
+
m = normalize_mac_addr(self[:mac_addr])
|
29
|
+
if m.size == 6
|
30
|
+
# mac_addr looks like to only have vendor ID part so that
|
31
|
+
# generate unique value for node ID part.
|
32
|
+
mvendor = m
|
33
|
+
begin
|
34
|
+
m = mvendor + ("%02x%02x%02x" % [rand(0xff),rand(0xff),rand(0xff)])
|
35
|
+
end while self.class.find(:mac_addr=> m)
|
36
|
+
self[:mac_addr] = m
|
37
|
+
end
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def validate
|
42
|
+
super
|
43
|
+
|
44
|
+
unless self.mac_addr.size == 12
|
45
|
+
errors.add(:mac_addr, "Invalid mac address length: #{self.mac_addr}")
|
46
|
+
end
|
47
|
+
|
48
|
+
unless self.mac_addr =~ /^[0-9a-f]{12}$/
|
49
|
+
errors.add(:mac_addr, "Invalid mac address syntax: #{self.mac_addr}")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def pretty_mac_addr(delim=':')
|
54
|
+
self.mac_addr.unpack('A2'*6).join(delim)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def normalize_mac_addr(str)
|
59
|
+
str = str.downcase.gsub(/[^0-9a-f]/, '')
|
60
|
+
raise "invalid mac address data: #{str}" if str.size > 12
|
61
|
+
# TODO: put more checks on the mac address.
|
62
|
+
# i.e. single 0 to double 00
|
63
|
+
str
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr::Models
|
4
|
+
class InstanceSpec < AccountResource
|
5
|
+
taggable 'is'
|
6
|
+
|
7
|
+
inheritable_schema do
|
8
|
+
String :hypervisor, :null=>false
|
9
|
+
String :arch, :null=>false
|
10
|
+
|
11
|
+
Fixnum :cpu_cores, :null=>false, :unsigned=>true
|
12
|
+
Fixnum :memory_size, :null=>false, :unsigned=>true
|
13
|
+
Text :config, :null=>false, :default=>''
|
14
|
+
end
|
15
|
+
with_timestamps
|
16
|
+
|
17
|
+
def to_hash
|
18
|
+
super.merge({:config=>config.to_s})
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'ipaddress'
|
4
|
+
|
5
|
+
module Dcmgr::Models
|
6
|
+
# IP address lease information
|
7
|
+
class IpLease < BaseNew
|
8
|
+
|
9
|
+
inheritable_schema do
|
10
|
+
Fixnum :instance_nic_id, :null=>false
|
11
|
+
Fixnum :network_id, :null=>false
|
12
|
+
String :ipv4, :size=>50
|
13
|
+
|
14
|
+
index :ipv4, {:unique=>true}
|
15
|
+
end
|
16
|
+
with_timestamps
|
17
|
+
|
18
|
+
many_to_one :instance_nic
|
19
|
+
many_to_one :network
|
20
|
+
|
21
|
+
def self.lease(instance_nic)
|
22
|
+
raise TypeError unless instance_nic.is_a?(InstanceNic)
|
23
|
+
# TODO: consider the case of multiple nics on multiple network.
|
24
|
+
network = instance_nic.instance.host_pool.network
|
25
|
+
gwaddr = IPAddress::IPv4.new("#{network.ipv4_gw}/#{network.prefix}")
|
26
|
+
reserved = [gwaddr]
|
27
|
+
reserved << IPAddress::IPv4.new(network.dhcp_server)
|
28
|
+
reserved << IPAddress::IPv4.new(network.dns_server)
|
29
|
+
if network.metadata_server
|
30
|
+
reserved << IPAddress::IPv4.new(network.metadata_server)
|
31
|
+
end
|
32
|
+
reserved = reserved.map {|i| i.to_u32 }
|
33
|
+
# use SELECT FOR UPDATE to lock rows within same network.
|
34
|
+
addrs = (gwaddr.first.to_u32 .. gwaddr.last.to_u32).to_a -
|
35
|
+
reserved - network.ip_lease_dataset.for_update.all.map {|i| IPAddress::IPv4.new(i.ipv4).to_u32 }
|
36
|
+
raise "Out of IP address in this network segment: #{gwaddr.network.to_s}/#{gwaddr.prefix}" if addrs.empty?
|
37
|
+
|
38
|
+
leaseaddr = IPAddress::IPv4.parse_u32(addrs[rand(addrs.size).to_i])
|
39
|
+
create(:ipv4=>leaseaddr.to_s, :network_id=>network.id, :instance_nic_id=>instance_nic.id)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr::Models
|
4
|
+
class NetfilterGroup < AccountResource
|
5
|
+
taggable 'ng'
|
6
|
+
with_timestamps
|
7
|
+
|
8
|
+
inheritable_schema do
|
9
|
+
String :name, :null=>false
|
10
|
+
String :description
|
11
|
+
Text :rule
|
12
|
+
index [:account_id, :name], {:unique=>true}
|
13
|
+
end
|
14
|
+
|
15
|
+
one_to_many :netfilter_rules
|
16
|
+
one_to_many :instance_netfilter_groups
|
17
|
+
|
18
|
+
def to_hash
|
19
|
+
h = super
|
20
|
+
h = h.merge({
|
21
|
+
:rule => rule.to_s,
|
22
|
+
:rules => netfilter_rules.map { |rule| rule.to_hash },
|
23
|
+
})
|
24
|
+
#{
|
25
|
+
#:id => self.canonical_uuid,
|
26
|
+
#:name => name,
|
27
|
+
#:description => description,
|
28
|
+
#:rules => netfilter_rules.map { |rule| rule.to_hash },
|
29
|
+
#}
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_tiny_hash
|
33
|
+
{
|
34
|
+
:name => self.name,
|
35
|
+
:uuid => self.canonical_uuid,
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.create_group(account_id, params)
|
40
|
+
grp = self.create(:account_id => account_id,
|
41
|
+
:name => params[:name],
|
42
|
+
:rule => params[:rule],
|
43
|
+
:description => params[:description])
|
44
|
+
grp.build_rule
|
45
|
+
grp
|
46
|
+
end
|
47
|
+
|
48
|
+
def flush_rule
|
49
|
+
NetfilterRule.filter(:netfilter_group_id => self.id).destroy
|
50
|
+
end
|
51
|
+
|
52
|
+
def destroy_group
|
53
|
+
self.flush_rule
|
54
|
+
self.destroy
|
55
|
+
end
|
56
|
+
|
57
|
+
def rebuild_rule
|
58
|
+
self.flush_rule
|
59
|
+
self.build_rule
|
60
|
+
end
|
61
|
+
|
62
|
+
def build_rule
|
63
|
+
return if self.rule.nil?
|
64
|
+
|
65
|
+
self.rule.split("\n").each { |permission|
|
66
|
+
# [ToDo]
|
67
|
+
# to make strong parser
|
68
|
+
next if permission =~ /\A#/
|
69
|
+
next if permission.length == 0
|
70
|
+
|
71
|
+
# [format] protocol,source,destination
|
72
|
+
# - protocol: tcp|udp|icmp
|
73
|
+
# - source: IPAddr|CIDR|Owner:Group
|
74
|
+
# - destination: port|icmp-type
|
75
|
+
NetfilterRule.create(:netfilter_group_id => self.id,
|
76
|
+
:permission => permission)
|
77
|
+
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
def instances
|
82
|
+
self.instance_netfilter_groups.map { |instance_netfilter_group|
|
83
|
+
instance_netfilter_group.instance
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr::Models
|
4
|
+
class NetfilterRule < BaseNew
|
5
|
+
with_timestamps
|
6
|
+
|
7
|
+
inheritable_schema do
|
8
|
+
Fixnum :netfilter_group_id, :null=>false
|
9
|
+
String :permission, :null=>false
|
10
|
+
end
|
11
|
+
|
12
|
+
many_to_one :netfilter_group
|
13
|
+
|
14
|
+
def to_hash
|
15
|
+
{
|
16
|
+
:permission => permission,
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr::Models
|
4
|
+
# Network definitions in the DC.
|
5
|
+
class Network < BaseNew
|
6
|
+
|
7
|
+
inheritable_schema do
|
8
|
+
String :name, :null=>false
|
9
|
+
String :ipv4_gw, :null=>false
|
10
|
+
Fixnum :prefix, :null=>false, :default=>24, :unsigned=>true
|
11
|
+
String :domain_name, :null=>false
|
12
|
+
String :dns_server, :null=>false
|
13
|
+
String :dhcp_server, :null=>false
|
14
|
+
String :metadata_server
|
15
|
+
Text :description
|
16
|
+
index :name, {:unique=>true}
|
17
|
+
end
|
18
|
+
with_timestamps
|
19
|
+
|
20
|
+
many_to_one :host_pool
|
21
|
+
one_to_many :ip_lease
|
22
|
+
|
23
|
+
def validate
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_hash
|
28
|
+
values.dup.merge({:description=>description.to_s})
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Dcmgr
|
2
|
+
module Models
|
3
|
+
class PhysicalHost < Base
|
4
|
+
set_dataset :physical_hosts
|
5
|
+
set_prefix_uuid 'PH'
|
6
|
+
|
7
|
+
one_to_many :hv_agents
|
8
|
+
|
9
|
+
many_to_many :tags, :join_table=>:tag_mappings, :left_key=>:target_id, :conditions=>{:target_type=>TagMapping::TYPE_PHYSICAL_HOST}
|
10
|
+
many_to_many :location_tags, :class=>:Tag, :right_key=>:tag_id, :join_table=>:tag_mappings, :left_key=>:target_id, :conditions=>{:target_type=>TagMapping::TYPE_PHYSICAL_HOST_LOCATION}
|
11
|
+
|
12
|
+
many_to_one :relate_user, :class=>:User
|
13
|
+
|
14
|
+
def self.enable_hosts
|
15
|
+
filter(~:id => TagMapping.filter(:target_type=>TagMapping::TYPE_PHYSICAL_HOST).select(:target_id)).order_by(:id).all
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.assign(instance)
|
19
|
+
Dcmgr::scheduler.assign_to_instance(enable_hosts, instance)
|
20
|
+
end
|
21
|
+
|
22
|
+
def before_create
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
def after_create
|
27
|
+
super
|
28
|
+
TagMapping.create(:tag_id=>Tag.system_tag(:STANDBY_INSTANCE).id,
|
29
|
+
:target_type=>TagMapping::TYPE_PHYSICAL_HOST,
|
30
|
+
:target_id=>self.id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def instances
|
34
|
+
self.hv_agents.map{|hva| hva.instances}.flatten
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_location_tag(name, account)
|
38
|
+
TagMapping.create(:tag_id=>Tag.create(:name=>name, :account=>account).id,
|
39
|
+
:target_type=>TagMapping::TYPE_PHYSICAL_HOST_LOCATION,
|
40
|
+
:target_id=>self.id)
|
41
|
+
end
|
42
|
+
|
43
|
+
def space_cpu_mhz
|
44
|
+
setup_space unless @space_cpu_mhz
|
45
|
+
@space_cpu_mhz
|
46
|
+
end
|
47
|
+
|
48
|
+
def setup_space
|
49
|
+
|
50
|
+
need_cpu_mhz = instances.inject(0) {|v, ins| v + ins.need_cpu_mhz}
|
51
|
+
space_cpu_mhz = cpu_mhz - need_cpu_mhz
|
52
|
+
# 10 % down
|
53
|
+
@space_cpu_mhz = space_cpu_mhz * 0.9
|
54
|
+
|
55
|
+
need_memory = instances.inject(0) {|v, ins| v + ins.need_memory}
|
56
|
+
space_memory = memory - need_memory
|
57
|
+
# 10 % down
|
58
|
+
@space_memory = space_memory * 0.9
|
59
|
+
end
|
60
|
+
|
61
|
+
def space_memory
|
62
|
+
setup_space unless @space_memory
|
63
|
+
@space_memory
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr::Models
|
4
|
+
class RequestLog < BaseNew
|
5
|
+
|
6
|
+
inheritable_schema do
|
7
|
+
String :request_id, :null=>false, :size=>40, :unique=>true
|
8
|
+
Fixnum :frontend_system_id, :null=>false
|
9
|
+
Fixnum :account_id, :null=>false
|
10
|
+
String :requester_symbol, :null=>false, :size=>100
|
11
|
+
# HTTP Response Code
|
12
|
+
Fixnum :response_status, :null=>false
|
13
|
+
String :response_msg
|
14
|
+
String :api_path, :null=>false
|
15
|
+
String :params, :null=>false
|
16
|
+
Time :requested_at
|
17
|
+
Time :responsed_at
|
18
|
+
end
|
19
|
+
|
20
|
+
def after_initialize
|
21
|
+
self[:request_id] #
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'tmpdir'
|
4
|
+
|
5
|
+
module Dcmgr::Models
|
6
|
+
# SSH Key database for account.
|
7
|
+
class SshKeyPair < AccountResource
|
8
|
+
taggable 'ssh'
|
9
|
+
|
10
|
+
inheritable_schema do
|
11
|
+
String :name, :size=>100, :null=>false
|
12
|
+
Text :public_key, :null=>false
|
13
|
+
Text :private_key, :null=>true
|
14
|
+
|
15
|
+
index [:account_id, :name], {:unique=>true}
|
16
|
+
end
|
17
|
+
with_timestamps
|
18
|
+
|
19
|
+
def validate
|
20
|
+
end
|
21
|
+
|
22
|
+
def before_destroy
|
23
|
+
# TODO: check running instances which are associated to ssh key
|
24
|
+
# pairs. reject deletion if exist.
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# @return [Hash] {:private_key=>'pkey string',
|
29
|
+
# :public_key=>'pubkey string'}
|
30
|
+
def self.generate_key_pair()
|
31
|
+
pkey = File.expand_path(randstr, Dir.tmpdir)
|
32
|
+
pubkey = pkey + '.pub'
|
33
|
+
begin
|
34
|
+
system("ssh-keygen -q -t rsa -C '' -N '' -f %s >/dev/null" % [pkey])
|
35
|
+
unless $?.exitstatus == 0
|
36
|
+
raise "Failed to run ssh-keygen: exitcode=#{$?.exitstatus}"
|
37
|
+
end
|
38
|
+
|
39
|
+
{:private_key=>IO.read(pkey),
|
40
|
+
:public_key=>IO.read(pubkey)}
|
41
|
+
rescue
|
42
|
+
# clean up tmp key files
|
43
|
+
[pkey, pubkey].each { |i|
|
44
|
+
File.unlink(i) if File.exist?(i)
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def self.randstr
|
51
|
+
Array.new(10) { (('a'..'z').to_a + (0..9).to_a)[rand(36)] }.join
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'statemachine'
|
3
|
+
|
4
|
+
module Dcmgr::Models
|
5
|
+
class StoragePool < AccountResource
|
6
|
+
taggable 'sp'
|
7
|
+
with_timestamps
|
8
|
+
|
9
|
+
STATAS_TYPE_REGISTERING = "registering"
|
10
|
+
STATAS_TYPE_ONLINE = "online"
|
11
|
+
STATAS_TYPE_DEGRADE = "degrade"
|
12
|
+
STATAS_TYPE_FAILED = "failed"
|
13
|
+
STATAS_TYPE_DEREGISTERED = "deregistered"
|
14
|
+
|
15
|
+
STATUS_MSGS = {
|
16
|
+
STATAS_TYPE_REGISTERING => :registering,
|
17
|
+
STATAS_TYPE_ONLINE => :online,
|
18
|
+
STATAS_TYPE_DEGRADE => :degrade,
|
19
|
+
STATAS_TYPE_FAILED => :failed,
|
20
|
+
STATAS_TYPE_DEREGISTERED => :deregistered
|
21
|
+
}
|
22
|
+
|
23
|
+
inheritable_schema do
|
24
|
+
String :node_id, :null=>false
|
25
|
+
String :export_path, :null=>false
|
26
|
+
String :status, :null=>false, :default=>STATAS_TYPE_REGISTERING
|
27
|
+
Fixnum :offerring_disk_space, :null=>false, :unsigned=>true
|
28
|
+
String :transport_type, :null=>false
|
29
|
+
String :storage_type, :null=>false
|
30
|
+
String :ipaddr, :null=>false
|
31
|
+
String :snapshot_base_path, :null=>false
|
32
|
+
end
|
33
|
+
|
34
|
+
one_to_many :volumes
|
35
|
+
one_to_many :volume_snapshots
|
36
|
+
|
37
|
+
many_to_one :storage_agents
|
38
|
+
|
39
|
+
def before_validation
|
40
|
+
export_path = self.export_path
|
41
|
+
if export_path =~ /^(\/[a-z0-9]+)+$/
|
42
|
+
export_path = export_path.split('/')
|
43
|
+
export_path.shift
|
44
|
+
self.export_path = export_path.join('/')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_hash_document
|
49
|
+
h = self.values.dup
|
50
|
+
h[:id] = h[:uuid] = self.canonical_uuid
|
51
|
+
h
|
52
|
+
end
|
53
|
+
|
54
|
+
def state_machine
|
55
|
+
model = self
|
56
|
+
st = Statemachine.build do
|
57
|
+
superstate :storage_condition do
|
58
|
+
trans :registering, :on_success, :online
|
59
|
+
trans :registering, :on_error, :degrade
|
60
|
+
trans :online, :on_success, :online
|
61
|
+
trans :online, :on_error, :degrade
|
62
|
+
trans :degrade, :on_success, :online
|
63
|
+
trans :degrade, :on_error, :degrade
|
64
|
+
|
65
|
+
event :on_fail, :failed
|
66
|
+
event :on_deregistered, :deregistered
|
67
|
+
end
|
68
|
+
|
69
|
+
trans :failed, :on_success, :online
|
70
|
+
trans :failed, :on_error, :degrade
|
71
|
+
trans :failed, :on_deregistered, :deregistered
|
72
|
+
|
73
|
+
on_entry_of :registering, proc {
|
74
|
+
model.status = STATAS_TYPE_REGISTERING
|
75
|
+
}
|
76
|
+
|
77
|
+
on_entry_of :online, proc {
|
78
|
+
model.status = STATAS_TYPE_ONLINE
|
79
|
+
}
|
80
|
+
|
81
|
+
on_entry_of :degrade, proc {
|
82
|
+
model.status = STATAS_TYPE_DEGRADE
|
83
|
+
}
|
84
|
+
|
85
|
+
on_entry_of :failed, proc {
|
86
|
+
model.status = STATAS_TYPE_FAILED
|
87
|
+
}
|
88
|
+
|
89
|
+
on_entry_of :deregistered, proc {
|
90
|
+
model.status = STATAS_TYPE_DEREGISTERED
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
if self[:status]
|
95
|
+
if st.has_state(STATUS_MSGS[self[:status]].to_sym)
|
96
|
+
st.state = STATUS_MSGS[self[:status]].to_sym
|
97
|
+
else
|
98
|
+
raise "Unknown state: #{self[:status]}"
|
99
|
+
end
|
100
|
+
else
|
101
|
+
st.reset
|
102
|
+
end
|
103
|
+
st
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.create_pool(params)
|
107
|
+
self.create(:account_id => params[:account_id],
|
108
|
+
:node_id => params[:node_id],
|
109
|
+
:offerring_disk_space => params[:offerring_disk_space],
|
110
|
+
:transport_type => params[:transport_type],
|
111
|
+
:storage_type => params[:storage_type],
|
112
|
+
:export_path => params[:export_path],
|
113
|
+
:ipaddr => params[:ipaddr],
|
114
|
+
:snapshot_base_path => params[:snapshot_base_path])
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.get_lists(uuid)
|
118
|
+
self.dataset.where(:account_id => uuid).all.map{|row|
|
119
|
+
row.values
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
# def find_private_pool(account_id, uuid)
|
124
|
+
# sp = self.dataset.where(:account_id=>account_id).where(:uuid=>uuid)
|
125
|
+
# end
|
126
|
+
|
127
|
+
def create_volume(account_id, size, snapshot_id=nil)
|
128
|
+
v = Volume.create(:account_id => account_id,
|
129
|
+
:storage_pool_id => self.id,
|
130
|
+
:snapshot_id => snapshot_id,
|
131
|
+
:size =>size)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|