wakame-vdc-dcmgr 10.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +202 -0
- data/NOTICE +1 -0
- data/Rakefile +142 -0
- data/bin/collector +46 -0
- data/config/dcmgr.conf.example +9 -0
- data/config/initializers/isono.rb +43 -0
- data/config/initializers/passenger.rb +6 -0
- data/config/initializers/sequel.rb +21 -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
- data/web/api/config.ru +20 -0
- data/web/api/public/index.html +0 -0
- data/web/metadata/config.ru +20 -0
- data/web/metadata/public/index.html +0 -0
- metadata +326 -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
|