wakame-vdc-dcmgr 10.12.0 → 11.06.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +164 -201
- data/Rakefile +6 -11
- data/bin/collector +10 -24
- data/config/dcmgr.conf.example +18 -6
- data/config/initializers/isono.rb +7 -23
- data/config/initializers/sequel.rb +11 -2
- data/lib/dcmgr.rb +70 -11
- data/lib/dcmgr/cli/base.rb +74 -0
- data/lib/dcmgr/cli/errors.rb +59 -0
- data/lib/dcmgr/cli/group.rb +101 -0
- data/lib/dcmgr/cli/host.rb +101 -0
- data/lib/dcmgr/cli/image.rb +108 -0
- data/lib/dcmgr/cli/keypair.rb +72 -0
- data/lib/dcmgr/cli/network.rb +198 -0
- data/lib/dcmgr/cli/quota.rb +28 -0
- data/lib/dcmgr/cli/spec.rb +82 -0
- data/lib/dcmgr/cli/storage.rb +88 -0
- data/lib/dcmgr/cli/tag.rb +81 -0
- data/lib/dcmgr/cli/vlan.rb +53 -0
- data/lib/dcmgr/drivers/hypervisor.rb +33 -0
- data/lib/dcmgr/drivers/iijgio_storage.rb +37 -0
- data/lib/dcmgr/drivers/kvm.rb +118 -0
- data/lib/dcmgr/drivers/lxc.rb +167 -0
- data/lib/dcmgr/drivers/s3_storage.rb +39 -0
- data/lib/dcmgr/drivers/snapshot_storage.rb +51 -0
- data/lib/dcmgr/endpoints/core_api.rb +188 -324
- data/lib/dcmgr/endpoints/core_api_mock.rb +52 -3
- data/lib/dcmgr/endpoints/errors.rb +73 -32
- data/lib/dcmgr/endpoints/metadata.rb +163 -16
- data/lib/dcmgr/helpers/cli_helper.rb +1 -1
- data/lib/dcmgr/helpers/nic_helper.rb +35 -0
- data/lib/dcmgr/logger.rb +5 -1
- data/lib/dcmgr/messaging_client.rb +117 -0
- data/lib/dcmgr/models/account.rb +27 -3
- data/lib/dcmgr/models/base_new.rb +21 -7
- data/lib/dcmgr/models/host_pool.rb +27 -7
- data/lib/dcmgr/models/image.rb +31 -3
- data/lib/dcmgr/models/instance.rb +72 -23
- data/lib/dcmgr/models/instance_nic.rb +12 -2
- data/lib/dcmgr/models/instance_spec.rb +16 -0
- data/lib/dcmgr/models/ip_lease.rb +37 -1
- data/lib/dcmgr/models/netfilter_group.rb +7 -7
- data/lib/dcmgr/models/network.rb +42 -3
- data/lib/dcmgr/models/quota.rb +25 -0
- data/lib/dcmgr/models/request_log.rb +26 -11
- data/lib/dcmgr/models/ssh_key_pair.rb +14 -1
- data/lib/dcmgr/models/storage_pool.rb +19 -72
- data/lib/dcmgr/models/tag.rb +5 -0
- data/lib/dcmgr/models/vlan_lease.rb +8 -0
- data/lib/dcmgr/models/volume.rb +26 -8
- data/lib/dcmgr/models/volume_snapshot.rb +37 -0
- data/lib/dcmgr/node_modules/hva_collector.rb +56 -36
- data/lib/dcmgr/node_modules/instance_ha.rb +1 -1
- data/lib/dcmgr/node_modules/instance_monitor.rb +70 -0
- data/lib/dcmgr/node_modules/service_netfilter.rb +914 -0
- data/lib/dcmgr/node_modules/sta_collector.rb +7 -30
- data/lib/dcmgr/rack/request_logger.rb +60 -0
- data/lib/dcmgr/rack/run_initializer.rb +42 -0
- data/lib/dcmgr/rpc/hva_handler.rb +388 -0
- data/lib/dcmgr/rubygems.rb +7 -0
- data/lib/dcmgr/storage_service.rb +98 -0
- data/lib/dcmgr/tags.rb +2 -2
- data/lib/dcmgr/version.rb +8 -0
- data/lib/ext/time.rb +8 -0
- data/lib/sinatra/respond_to.rb +3 -0
- data/lib/sinatra/sequel_transaction.rb +20 -5
- data/web/api/config.ru +9 -13
- data/web/metadata/config.ru +10 -13
- metadata +162 -120
- data/lib/dcmgr/models/physical_host.rb +0 -67
- data/lib/dcmgr/web/base.rb +0 -21
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr::Cli
|
4
|
+
class Quota < Base
|
5
|
+
namespace :quota
|
6
|
+
M = Dcmgr::Models
|
7
|
+
|
8
|
+
desc "modify ACCOUNT_UUID [options]", "Modify the quota settings for an account"
|
9
|
+
method_option :weight, :type => :numeric, :aliases => "-w", :desc => "The instance total weight for this account's quota"
|
10
|
+
method_option :size, :type => :numeric, :aliases => "-s", :desc => "The volume total size for this account's quota"
|
11
|
+
def modify(account_uuid)
|
12
|
+
acc = M::Account[account_uuid] || UnknownUUIDError.raise(account_uuid)
|
13
|
+
super(M::Quota,acc.quota.canonical_uuid,{:instance_total_weight => options[:weight], :volume_total_size => options[:size]})
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "show ACCOUNT_UUID", "Show the quota settings for an account"
|
17
|
+
def show(account_uuid)
|
18
|
+
acc = M::Account[account_uuid] || raise(Thor::Error, "Unknown Account UUID: #{account_uuid}")
|
19
|
+
puts ERB.new(<<__END, nil, '-').result(binding)
|
20
|
+
Instance total weight:
|
21
|
+
<%= acc.quota.instance_total_weight %>
|
22
|
+
Volume total size:
|
23
|
+
<%= acc.quota.volume_total_size %>
|
24
|
+
__END
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr::Cli
|
4
|
+
class Spec < Base
|
5
|
+
namespace :spec
|
6
|
+
M = Dcmgr::Models
|
7
|
+
|
8
|
+
desc "add [options]", "Register a new machine spec"
|
9
|
+
method_option :uuid, :type => :string, :aliases => "-u", :desc => "The UUID for the new machine spec"
|
10
|
+
method_option :account_id, :type => :string, :aliases => "-a", :required => true, :desc => "The UUID of the account that this machine spec belongs to"
|
11
|
+
method_option :arch, :type => :string, :default => 'x86_64', :aliases => "-r", :desc => "The architecture for the new machine image. [#{M::HostPool::SUPPORTED_ARCH.join(', ')}]"
|
12
|
+
method_option(:hypervisor, :type => :string, :aliases => "-p", :default => M::HostPool::HYPERVISOR_KVM.to_s,
|
13
|
+
:desc => "The hypervisor type for the new instance. [#{M::HostPool::SUPPORTED_HYPERVISOR.join(', ')}]")
|
14
|
+
method_option :cpu_cores, :type => :numeric, :aliases => "-c", :default => 1, :desc => "The initial cpu cores for the new instance"
|
15
|
+
method_option :memory_size, :type => :numeric, :aliases => "-m", :default => 1024, :desc => "The memory size for the new instance"
|
16
|
+
method_option :quota_weight, :type => :numeric, :aliases => "-w", :default => 1.0, :desc => "The cost weight factor for the new instance"
|
17
|
+
#method_option :is_public, :type => :boolean, :aliases => "-p", :default => false, :desc => "A flag that determines whether the new machine image is public or not."
|
18
|
+
def add
|
19
|
+
UnknownUUIDError.raise(options[:account_id]) if M::Account[options[:account_id]].nil?
|
20
|
+
UnsupportedArchError.raise(options[:arch]) unless M::HostPool::SUPPORTED_ARCH.member?(options[:arch])
|
21
|
+
UnsupportedHypervisorError.raise(options[:hypervisor]) unless M::HostPool::SUPPORTED_HYPERVISOR.member?(options[:hypervisor])
|
22
|
+
fields = options.dup
|
23
|
+
fields[:config] = {
|
24
|
+
}
|
25
|
+
puts super(M::InstanceSpec, fields)
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "modify UUID [options]", "Modify an existing machine spec"
|
29
|
+
method_option :account_id, :type => :string, :aliases => "-a", :desc => "The UUID of the account that this machine spec belongs to"
|
30
|
+
method_option :arch, :type => :string, :aliases => "-r", :desc => "The architecture for the new machine image. [#{M::HostPool::SUPPORTED_ARCH.join(', ')}]"
|
31
|
+
method_option(:hypervisor, :type => :string, :aliases => "-p",
|
32
|
+
:desc => "The hypervisor type for the new instance. [#{M::HostPool::SUPPORTED_HYPERVISOR.join(', ')}]")
|
33
|
+
method_option :cpu_cores, :type => :numeric, :aliases => "-c", :desc => "The initial cpu cores for the new instance"
|
34
|
+
method_option :memory_size, :type => :numeric, :aliases => "-m", :desc => "The memory size for the new instance"
|
35
|
+
method_option :quota_weight, :type => :numeric, :aliases => "-w", :desc => "The cost weight factor for the new instance"
|
36
|
+
def modify(uuid)
|
37
|
+
UnknownUUIDError.raise(options[:account_id]) if options[:account_id] && M::Account[options[:account_id]].nil?
|
38
|
+
UnsupportedArchError.raise(options[:arch]) unless options[:arch].nil? || M::HostPool::SUPPORTED_ARCH.member?(options[:arch])
|
39
|
+
UnsupportedHypervisorError.raise(options[:hypervisor]) unless options[:hypervisor].nil? || M::HostPool::SUPPORTED_HYPERVISOR.member?(options[:hypervisor])
|
40
|
+
super(M::InstanceSpec,uuid,options)
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "del UUID", "Delete registered machine spec"
|
44
|
+
def del(uuid)
|
45
|
+
UnknownUUIDError.raise(uuid) if M::InstanceSpec[uuid].nil?
|
46
|
+
super(M::InstanceSpec, uuid)
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "show [UUID]", "Show list of machine spec and details"
|
50
|
+
def show(uuid=nil)
|
51
|
+
if uuid
|
52
|
+
spec = M::InstanceSpec[uuid]
|
53
|
+
print ERB.new(<<__END, nil, '-').result(binding)
|
54
|
+
UUID:
|
55
|
+
<%= spec.canonical_uuid %>
|
56
|
+
Account ID:
|
57
|
+
<%= spec.account_id %>
|
58
|
+
Hypervisor:
|
59
|
+
<%= spec.hypervisor %>
|
60
|
+
Arch:
|
61
|
+
<%= spec.arch %>
|
62
|
+
CPU Cores:
|
63
|
+
<%= spec.cpu_cores %>
|
64
|
+
Memory Size:
|
65
|
+
<%= spec.memory_size %>
|
66
|
+
Quota Weight:
|
67
|
+
<%= spec.quota_weight %>
|
68
|
+
Hypervisor Configuration:
|
69
|
+
<%= spec.config.inspect %>
|
70
|
+
__END
|
71
|
+
else
|
72
|
+
cond = {}
|
73
|
+
specs = M::InstanceSpec.filter(cond).all
|
74
|
+
print ERB.new(<<__END, nil, '-').result(binding)
|
75
|
+
<%- specs.each { |row| -%>
|
76
|
+
<%= "%-20s %-15s %-15s" % [row.canonical_uuid, row.account_id, row.arch] %>
|
77
|
+
<%- } -%>
|
78
|
+
__END
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require 'isono'
|
5
|
+
|
6
|
+
module Dcmgr::Cli
|
7
|
+
class Storage < Base
|
8
|
+
namespace :storage
|
9
|
+
include Dcmgr::Models
|
10
|
+
|
11
|
+
desc "add NODE_ID [options]", "Register a new storage node"
|
12
|
+
method_option :uuid, :type => :string, :aliases => "-u", :desc => "The uuid for the new storage pool."
|
13
|
+
method_option :base_path, :type => :string, :aliases => "-b", :required => true, :desc => "Base path to store volume files"
|
14
|
+
method_option :snapshot_base_path, :type => :string, :aliases => "-n", :required => true, :desc => "Base path to store snapshot files"
|
15
|
+
method_option :disk_space, :type => :numeric, :aliases => "-s", :required => true, :desc => "Amount of disk size to be exported (in MB)."
|
16
|
+
method_option :transport_type, :type => :string, :aliases => "-t", :default=>'iscsi', :desc => "Transport type [iscsi]"
|
17
|
+
method_option :ipaddr, :type => :string, :aliases => "-i", :required=>true, :desc => "IP address of transport target"
|
18
|
+
method_option :storage_type, :type => :string, :aliases => "-o", :default=>'zfs', :desc => "Storage type [zfs]"
|
19
|
+
method_option :account_id, :type => :string, :default=>'a-shpool', :aliases => "-a", :desc => "The account ID to own this."
|
20
|
+
def add(node_id)
|
21
|
+
unless (options[:force] == false && Isono::Models::NodeState.exists?(:node_id=>options[:node_id]))
|
22
|
+
abort("Node ID is not registered yet: #{options[:node_id]}")
|
23
|
+
end
|
24
|
+
|
25
|
+
fields = {:node_id=>options[:node_id],
|
26
|
+
:offering_disk_space=>options[:disk_space],
|
27
|
+
:transport_type=>options[:transport_type],
|
28
|
+
:storage_type=>options[:storage_type],
|
29
|
+
:export_path=>options[:base_path],
|
30
|
+
:snapshot_base_path => options[:snapshot_base_path],
|
31
|
+
:ipaddr=>options[:ipaddr],
|
32
|
+
:account_id=>options[:account_id],
|
33
|
+
}
|
34
|
+
fields.merge!({:uuid => options[:uuid]}) unless options[:uuid].nil?
|
35
|
+
|
36
|
+
puts super(StoragePool,fields)
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "del UUID", "Deregister a storage node"
|
40
|
+
def del(uuid)
|
41
|
+
super(StoragePool,uuid)
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "show [UUID]", "Show list of storage nodes and details"
|
45
|
+
def show(uuid=nil)
|
46
|
+
if uuid
|
47
|
+
st = StoragePool[uuid]
|
48
|
+
puts ERB.new(<<__END, nil, '-').result(binding)
|
49
|
+
UUID:
|
50
|
+
<%= st.canonical_uuid %>
|
51
|
+
Node ID:
|
52
|
+
<%= st.node_id %>
|
53
|
+
Disk space (offerring):
|
54
|
+
<%= st.offering_disk_space %>MB
|
55
|
+
Storage:
|
56
|
+
<%= st.storage_type %>
|
57
|
+
Transport:
|
58
|
+
<%= st.transport_type %>
|
59
|
+
IP Address:
|
60
|
+
<%= st.ipaddr %>
|
61
|
+
Export path:
|
62
|
+
<%= st.export_path %>
|
63
|
+
Snapshot base path:
|
64
|
+
<%= st.snapshot_base_path %>
|
65
|
+
__END
|
66
|
+
else
|
67
|
+
cond = {}
|
68
|
+
all = StoragePool.filter(cond).all
|
69
|
+
puts ERB.new(<<__END, nil, '-').result(binding)
|
70
|
+
<%- all.each { |row| -%>
|
71
|
+
<%= "%-15s %-20s %-10s" % [row.canonical_uuid, row.node_id, row.status] %>
|
72
|
+
<%- } -%>
|
73
|
+
__END
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
desc "shownodes", "Show node (agents)"
|
78
|
+
def shownodes
|
79
|
+
nodes = Isono::Models::NodeState.filter.all
|
80
|
+
|
81
|
+
puts ERB.new(<<__END, nil, '-').result(binding)
|
82
|
+
<%- nodes.each { |row| -%>
|
83
|
+
<%= "%-20s %-10s" % [row.node_id, row.state] %>
|
84
|
+
<%- } -%>
|
85
|
+
__END
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr::Cli
|
4
|
+
class Tag < Base
|
5
|
+
namespace :tag
|
6
|
+
M = Dcmgr::Models
|
7
|
+
|
8
|
+
desc "add [options]", "Create a new tag"
|
9
|
+
method_option :uuid, :type => :string, :aliases => "-u", :desc => "The UUID for the new tag"
|
10
|
+
method_option :account_id, :type => :string, :aliases => "-a", :desc => "The UUID of the account that this tag belongs to", :required => true
|
11
|
+
method_option :type_id, :type => :numeric, :aliases => "-t", :desc => "The type for the new tag. Valid types are '#{Dcmgr::Tags::KEY_MAP.keys.join(", ")}'", :required => true
|
12
|
+
method_option :name, :type => :string, :aliases => "-n", :desc => "The name for the new tag", :required => true
|
13
|
+
method_option :attributes, :type => :string, :aliases => "-b", :desc => "The attributes for the new tag"
|
14
|
+
def add
|
15
|
+
UnknownUUIDError.raise(options[:account_id]) if M::Account[options[:account_id]].nil?
|
16
|
+
Error.raise("Invalid type_id: '#{options[:type_id]}'. Valid types are '#{Dcmgr::Tags::KEY_MAP.keys.join(", ")}'.",100) unless Dcmgr::Tags::KEY_MAP.member? options[:type_id]
|
17
|
+
|
18
|
+
puts super(M::Tag,options)
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "modify UUID [options]", "Modify an existing tag"
|
22
|
+
method_option :account_id, :type => :string, :aliases => "-a", :desc => "The UUID of the account that this tag belongs to"
|
23
|
+
method_option :type_id, :type => :numeric, :aliases => "-t", :desc => "The type for the new tag. Valid types are '#{Dcmgr::Tags::KEY_MAP.keys.join(", ")}'"
|
24
|
+
method_option :name, :type => :string, :aliases => "-n", :desc => "The name for the new tag"
|
25
|
+
method_option :attributes, :type => :string, :aliases => "-b", :desc => "The attributes for the new tag"
|
26
|
+
def modify(uuid)
|
27
|
+
UnknownUUIDError.raise(options[:account_id]) if options[:account_id] && M::Account[options[:account_id]].nil?
|
28
|
+
Error.raise("Invalid type_id: '#{options[:type_id]}'. Valid types are '#{Dcmgr::Tags::KEY_MAP.keys.join(", ")}'.",100) unless options[:type_id].nil? || Dcmgr::Tags::KEY_MAP.member?(options[:type_id])
|
29
|
+
super(M::Tag,uuid,options)
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "show [UUID]", "Show the existing tag(s)"
|
33
|
+
def show(uuid=nil)
|
34
|
+
if uuid
|
35
|
+
tag = M::Tag[uuid] || UnknownUUIDError.raise(uuid)
|
36
|
+
puts ERB.new(<<__END, nil, '-').result(binding)
|
37
|
+
Tag UUID:
|
38
|
+
<%= tag.canonical_uuid %>
|
39
|
+
Account id:
|
40
|
+
<%= tag.account_id %>
|
41
|
+
Name:
|
42
|
+
<%= tag.name %>
|
43
|
+
Type id:
|
44
|
+
<%= tag.type_id %>
|
45
|
+
Attributes:
|
46
|
+
<%= tag.attributes %>
|
47
|
+
__END
|
48
|
+
else
|
49
|
+
puts ERB.new(<<__END, nil, '-').result(binding)
|
50
|
+
<%- M::Tag.each { |row| -%>
|
51
|
+
<%= row.canonical_uuid %>\t<%= row.account_id %>\t<%= row.type_id %>\t<%= row.name%>
|
52
|
+
<%- } -%>
|
53
|
+
__END
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "del UUID", "Delete an existing tag"
|
58
|
+
def del(uuid)
|
59
|
+
super(M::Tag,uuid)
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "map UUID [options]", "Map a tag to a taggable object"
|
63
|
+
method_option :object_id, :type => :string, :aliases => "-o", :desc => "The canonical UUID for the object to map this tag to.", :required => true
|
64
|
+
def map(uuid)
|
65
|
+
#Quick hack to get all models in Dcmgr::Models loaded in Taggable.uuid_prefix_collection
|
66
|
+
#This is so the Taggable.find method can be used to determine the Model class based on canonical uuid
|
67
|
+
M.constants.each {|c| eval("M::#{c}")}
|
68
|
+
|
69
|
+
object = M::Taggable.find(options[:object_id])
|
70
|
+
|
71
|
+
UnknownUUIDError.raise(uuid) if M::Tag[uuid].nil?
|
72
|
+
UnknownUUIDError.raise(options[:object_id]) if object.nil?
|
73
|
+
Error.raise("Tag '#{uuid}' can not be mapped to a '#{object.class}'.",100) unless M::Tag[uuid].accept_mapping?(object)
|
74
|
+
|
75
|
+
M::TagMapping.create(
|
76
|
+
:tag_id => M::Tag[uuid].id,
|
77
|
+
:uuid => object.canonical_uuid
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr::Cli
|
4
|
+
class Vlan < Base
|
5
|
+
namespace :vlan
|
6
|
+
M = Dcmgr::Models
|
7
|
+
|
8
|
+
desc "add [options]", "Create a new vlan lease"
|
9
|
+
method_option :uuid, :type => :string, :aliases => "-u", :desc => "The UUID for the new vlan lease"
|
10
|
+
method_option :account_id, :type => :string, :aliases => "-a", :desc => "The UUID of the account for this vlan lease"
|
11
|
+
method_option :tag_id, :type => :numeric, :aliases => "-t", :desc => "The ethernet tag for this vlan lease"
|
12
|
+
def add
|
13
|
+
UnknownUUIDError.raise(options[:account_id]) if M::Account[options[:account_id]].nil?
|
14
|
+
Error.raise("Tag_id already exists",100) unless M::VlanLease.find(:tag_id => options[:tag_id]).nil?
|
15
|
+
|
16
|
+
puts super(M::VlanLease,options)
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "del UUID", "Delete an existing vlan lease"
|
20
|
+
def del(uuid)
|
21
|
+
super(M::VlanLease,uuid)
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "modify UUID [options]", "Modify an existing vlan lease"
|
25
|
+
method_option :account_id, :type => :string, :aliases => "-a", :desc => "The UUID of the account for this vlan lease"
|
26
|
+
method_option :tag_id, :type => :numeric, :aliases => "-t", :desc => "The ethernet tag for this vlan lease"
|
27
|
+
def modify(uuid)
|
28
|
+
UnknownUUIDError.raise(options[:account_id]) if options[:account_id] && M::Account[options[:account_id]].nil?
|
29
|
+
super(M::VlanLease,uuid,options)
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "show [UUID]", "Show existing vlan lease(s)"
|
33
|
+
def show(uuid=nil)
|
34
|
+
if uuid
|
35
|
+
lease = M::VlanLease[uuid] || UnknownUUIDError.raise(uuid)
|
36
|
+
puts ERB.new(<<__END, nil, '-').result(binding)
|
37
|
+
Vlan Lease UUID:
|
38
|
+
<%= lease.canonical_uuid %>
|
39
|
+
Account id:
|
40
|
+
<%= lease.account_id %>
|
41
|
+
Tag id:
|
42
|
+
<%= lease.tag_id %>
|
43
|
+
__END
|
44
|
+
else
|
45
|
+
puts ERB.new(<<__END, nil, '-').result(binding)
|
46
|
+
<%- M::VlanLease.each { |row| -%>
|
47
|
+
<%= row.canonical_uuid %>\t<%= row.account_id %>\t<%= row.tag_id %>
|
48
|
+
<%- } -%>
|
49
|
+
__END
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Dcmgr
|
2
|
+
module Drivers
|
3
|
+
class Hypervisor
|
4
|
+
|
5
|
+
def run_instance(hc)
|
6
|
+
end
|
7
|
+
|
8
|
+
def terminate_instance(hc)
|
9
|
+
end
|
10
|
+
|
11
|
+
def reboot_instance(hc)
|
12
|
+
end
|
13
|
+
|
14
|
+
def attach_volume_to_guest(hc)
|
15
|
+
end
|
16
|
+
|
17
|
+
def detach_volume_from_guest(hc)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.select_hypervisor(hypervisor)
|
21
|
+
case hypervisor
|
22
|
+
when "kvm"
|
23
|
+
hv = Dcmgr::Drivers::Kvm.new
|
24
|
+
when "lxc"
|
25
|
+
hv = Dcmgr::Drivers::Lxc.new
|
26
|
+
else
|
27
|
+
raise "Unknown hypervisor type: #{hypervisor}"
|
28
|
+
end
|
29
|
+
hv
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr::Drivers
|
4
|
+
|
5
|
+
class IIJGIOStorage < SnapshotStorage
|
6
|
+
|
7
|
+
def download(keyname, filename, path)
|
8
|
+
cmd = "get %s %s %s"
|
9
|
+
args = [@bucket, keyname, File.join(path, filename)]
|
10
|
+
execute(cmd, args)
|
11
|
+
end
|
12
|
+
|
13
|
+
def upload(keyname, file)
|
14
|
+
cmd = "put %s %s %s"
|
15
|
+
args = [@bucket, keyname, file]
|
16
|
+
execute(cmd, args)
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete(keyname)
|
20
|
+
cmd = "rm %s %s"
|
21
|
+
args = [@bucket, keyname]
|
22
|
+
execute(cmd, args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def check(keyname)
|
26
|
+
cmd = "test %s %s"
|
27
|
+
args = [@bucket, keyname]
|
28
|
+
execute(cmd, args)
|
29
|
+
end
|
30
|
+
|
31
|
+
def list
|
32
|
+
cmd = "ls %s"
|
33
|
+
args = [@bucket]
|
34
|
+
execute(cmd, args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Dcmgr
|
2
|
+
module Drivers
|
3
|
+
class Kvm < Hypervisor
|
4
|
+
include Dcmgr::Logger
|
5
|
+
include Dcmgr::Helpers::CliHelper
|
6
|
+
include Dcmgr::Rpc::KvmHelper
|
7
|
+
include Dcmgr::Helpers::NicHelper
|
8
|
+
|
9
|
+
def run_instance(hc)
|
10
|
+
# run vm
|
11
|
+
inst = hc.inst
|
12
|
+
cmd = "kvm -m %d -smp %d -name vdc-%s -vnc :%d -drive file=%s -pidfile %s -daemonize -monitor telnet::%d,server,nowait"
|
13
|
+
args=[inst[:instance_spec][:memory_size],
|
14
|
+
inst[:instance_spec][:cpu_cores],
|
15
|
+
inst[:uuid],
|
16
|
+
inst[:runtime_config][:vnc_port],
|
17
|
+
hc.os_devpath,
|
18
|
+
File.expand_path('kvm.pid', hc.inst_data_dir),
|
19
|
+
inst[:runtime_config][:telnet_port]
|
20
|
+
]
|
21
|
+
if vnic = inst[:instance_nics].first
|
22
|
+
cmd += " -net nic,macaddr=%s -net tap,ifname=%s,script=,downscript="
|
23
|
+
args << vnic[:mac_addr].unpack('A2'*6).join(':')
|
24
|
+
args << vnic[:uuid]
|
25
|
+
end
|
26
|
+
sh(cmd, args)
|
27
|
+
|
28
|
+
unless vnic.nil?
|
29
|
+
sh("/sbin/ifconfig %s 0.0.0.0 up", [vnic[:uuid]])
|
30
|
+
sh("/usr/sbin/brctl addif %s %s", [hc.bridge_if, vnic[:uuid]])
|
31
|
+
end
|
32
|
+
|
33
|
+
sleep 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def terminate_instance(hc)
|
37
|
+
kvm_pid=`pgrep -u root -f vdc-#{hc.inst_id}`
|
38
|
+
if $?.exitstatus == 0 && kvm_pid.to_s =~ /^\d+$/
|
39
|
+
sh("/bin/kill #{kvm_pid}")
|
40
|
+
else
|
41
|
+
logger.error("Can not find the KVM process. Skipping: kvm -name vdc-#{hc.inst_id}")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def reboot_instance(hc)
|
46
|
+
inst = hc.inst
|
47
|
+
connect_monitor(inst[:runtime_config][:telnet_port]) { |t|
|
48
|
+
t.cmd("system_reset")
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def attach_volume_to_guest(hc)
|
53
|
+
# pci_devddr consists of three hex numbers with colon separator.
|
54
|
+
# dom <= 0xffff && bus <= 0xff && val <= 0x1f
|
55
|
+
# see: qemu-0.12.5/hw/pci.c
|
56
|
+
# /*
|
57
|
+
# * Parse [[<domain>:]<bus>:]<slot>, return -1 on error
|
58
|
+
# */
|
59
|
+
# static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
|
60
|
+
pci_devaddr = nil
|
61
|
+
inst = hc.inst
|
62
|
+
|
63
|
+
sddev = File.expand_path(File.readlink(hc.os_devpath), '/dev/disk/by-path')
|
64
|
+
connect_monitor(inst[:runtime_config][:telnet_port]) { |t|
|
65
|
+
# success message:
|
66
|
+
# OK domain 0, bus 0, slot 4, function 0
|
67
|
+
# error message:
|
68
|
+
# failed to add file=/dev/xxxx,if=virtio
|
69
|
+
c = t.cmd("pci_add auto storage file=#{sddev},if=scsi")
|
70
|
+
# Note: pci_parse_devaddr() called in "pci_add" uses strtoul()
|
71
|
+
# with base 16 so that the input is expected in hex. however
|
72
|
+
# at the result display, void pci_device_hot_add_print() uses
|
73
|
+
# %d for showing bus and slot addresses. use hex to preserve
|
74
|
+
# those values to keep consistent.
|
75
|
+
if c =~ /\nOK domain ([0-9a-fA-F]+), bus ([0-9a-fA-F]+), slot ([0-9a-fA-F]+), function/m
|
76
|
+
# numbers in OK result is decimal. convert them to hex.
|
77
|
+
pci_devaddr = [$1, $2, $3].map{|i| i.to_i.to_s(16) }
|
78
|
+
else
|
79
|
+
raise "Error in qemu console: #{c}"
|
80
|
+
end
|
81
|
+
|
82
|
+
# double check the pci address.
|
83
|
+
c = t.cmd("info pci")
|
84
|
+
|
85
|
+
# static void pci_info_device(PCIBus *bus, PCIDevice *d)
|
86
|
+
# called in "info pci" gets back PCI bus info with %d.
|
87
|
+
if c.split(/\n/).grep(/^\s+Bus\s+#{pci_devaddr[1].to_i(16)}, device\s+#{pci_devaddr[2].to_i(16)}, function/).empty?
|
88
|
+
raise "Could not find new disk device attached to qemu-kvm: #{pci_devaddr.join(':')}"
|
89
|
+
end
|
90
|
+
}
|
91
|
+
pci_devaddr.join(':')
|
92
|
+
end
|
93
|
+
|
94
|
+
def detach_volume_from_guest(hc)
|
95
|
+
inst = hc.inst
|
96
|
+
vol = hc.vol
|
97
|
+
pci_devaddr = vol[:guest_device_name]
|
98
|
+
|
99
|
+
connect_monitor(inst[:runtime_config][:telnet_port]) { |t|
|
100
|
+
t.cmd("pci_del #{pci_devaddr}")
|
101
|
+
#
|
102
|
+
# Bus 0, device 4, function 0:
|
103
|
+
# SCSI controller: PCI device 1af4:1001
|
104
|
+
# IRQ 0.
|
105
|
+
# BAR0: I/O at 0x1000 [0x103f].
|
106
|
+
# BAR1: 32 bit memory at 0x08000000 [0x08000fff].
|
107
|
+
# id ""
|
108
|
+
c = t.cmd("info pci")
|
109
|
+
pci_devaddr = pci_devaddr.split(':')
|
110
|
+
unless c.split(/\n/).grep(/\s+Bus\s+#{pci_devaddr[1].to_i(16)}, device\s+#{pci_devaddr[2].to_i(16)}, function/).empty?
|
111
|
+
raise "Detached disk device still be attached in qemu-kvm: #{pci_devaddr.join(':')}"
|
112
|
+
end
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|