wakame-vdc-agents 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/hva +11 -1351
- data/bin/nsa +5 -9
- data/bin/sta +124 -71
- data/config/hva.conf.example +12 -0
- 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
- metadata +133 -100
- data/lib/dcmgr/models/physical_host.rb +0 -67
- data/lib/dcmgr/web/base.rb +0 -21
@@ -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
|
@@ -0,0 +1,167 @@
|
|
1
|
+
module Dcmgr
|
2
|
+
module Drivers
|
3
|
+
class Lxc < Hypervisor
|
4
|
+
include Dcmgr::Logger
|
5
|
+
include Dcmgr::Helpers::CliHelper
|
6
|
+
|
7
|
+
def create_config
|
8
|
+
# create config file i-xxxxxxxx.log
|
9
|
+
inst_id = @inst[:uuid]
|
10
|
+
vnic = @inst[:instance_nics].first
|
11
|
+
mac_addr = vnic[:mac_addr].unpack('A2'*6).join(':')
|
12
|
+
|
13
|
+
config_name = "#{@inst_data_dir}/config.#{inst_id}"
|
14
|
+
# check config file
|
15
|
+
if File.exist?(config_name)
|
16
|
+
sh("rm #{config_name}")
|
17
|
+
end
|
18
|
+
|
19
|
+
config = File.open(config_name, 'w')
|
20
|
+
config.puts "lxc.utsname = #{inst_id}"
|
21
|
+
config.puts "lxc.tty = 4"
|
22
|
+
config.puts "lxc.pts = 1024"
|
23
|
+
config.puts "lxc.network.type = veth"
|
24
|
+
config.puts "lxc.network.veth.pair = #{vnic[:uuid]}"
|
25
|
+
config.puts "lxc.network.flags = up"
|
26
|
+
config.puts "lxc.network.link = #{@bridge_if}"
|
27
|
+
config.puts "lxc.network.hwaddr = #{mac_addr}"
|
28
|
+
config.puts "lxc.rootfs = #{@inst_data_dir}/rootfs"
|
29
|
+
config.puts "lxc.mount = #{@inst_data_dir}/fstab"
|
30
|
+
config.puts "lxc.cgroup.devices.deny = a"
|
31
|
+
config.puts "lxc.cgroup.devices.allow = c 1:3 rwm"
|
32
|
+
config.puts "lxc.cgroup.devices.allow = c 1:5 rwm"
|
33
|
+
config.puts "lxc.cgroup.devices.allow = c 5:1 rwm"
|
34
|
+
config.puts "lxc.cgroup.devices.allow = c 5:0 rwm"
|
35
|
+
config.puts "lxc.cgroup.devices.allow = c 4:0 rwm"
|
36
|
+
config.puts "lxc.cgroup.devices.allow = c 4:1 rwm"
|
37
|
+
config.puts "lxc.cgroup.devices.allow = c 1:9 rwm"
|
38
|
+
config.puts "lxc.cgroup.devices.allow = c 1:8 rwm"
|
39
|
+
config.puts "lxc.cgroup.devices.allow = c 136:* rwm"
|
40
|
+
config.puts "lxc.cgroup.devices.allow = c 5:2 rwm"
|
41
|
+
config.puts "lxc.cgroup.devices.allow = c 254:0 rwm"
|
42
|
+
config.puts "lxc.cgroup.devices.allow = c 10:232 rwm"
|
43
|
+
config.puts "lxc.cgroup.devices.allow = c 10:200 rwm"
|
44
|
+
unless @inst[:volume].nil?
|
45
|
+
@inst[:volume].each { |volid, v|
|
46
|
+
vol_id = volid
|
47
|
+
vol = v
|
48
|
+
unless v[:guest_device_name].nil?
|
49
|
+
config.puts "lxc.cgroup.devices.allow = b #{v[:guest_device_name]} rwm"
|
50
|
+
else
|
51
|
+
@os_devpath = v[:host_device_name] unless v[:host_device_name].nil?
|
52
|
+
sddev = File.expand_path(File.readlink(@os_devpath), '/dev/disk/by-path')
|
53
|
+
# find major number and minor number to device file
|
54
|
+
stat = File.stat(sddev)
|
55
|
+
config.puts "lxc.cgroup.devices.allow = b #{stat.rdev_major}:#{stat.rdev_minor} rwm"
|
56
|
+
end
|
57
|
+
}
|
58
|
+
end
|
59
|
+
config.close
|
60
|
+
config_name
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_fstab
|
64
|
+
config_name = "#{@inst_data_dir}/fstab"
|
65
|
+
config = File.open(config_name, "w")
|
66
|
+
config.puts "proc #{@inst_data_dir}/rootfs/proc proc nodev,noexec,nosuid 0 0"
|
67
|
+
config.puts "devpts #{@inst_data_dir}/rootfs/dev/pts devpts defaults 0 0"
|
68
|
+
config.puts "sysfs #{@inst_data_dir}/rootfs/sys sysfs defaults 0 0"
|
69
|
+
config.close
|
70
|
+
end
|
71
|
+
|
72
|
+
def setup_container
|
73
|
+
sh("echo \"127.0.0.1 localhost #{@inst_id}\" > #{@inst_data_dir}/rootfs/etc/hosts")
|
74
|
+
sh("echo \"#{@inst_id}\" > #{@inst_data_dir}/rootfs/etc/hostname")
|
75
|
+
end
|
76
|
+
|
77
|
+
def run_instance(hc)
|
78
|
+
# run lxc
|
79
|
+
@inst = hc.inst
|
80
|
+
@bridge_if = hc.bridge_if
|
81
|
+
@inst_data_dir = hc.inst_data_dir
|
82
|
+
@os_devpath = hc.os_devpath
|
83
|
+
if @os_devpath.nil?
|
84
|
+
if @inst[:image][:boot_dev_type] == 1
|
85
|
+
@inst[:volume].each{|volid, v|
|
86
|
+
@os_devpath = v[:host_device_name] if v[:boot_dev] == 1
|
87
|
+
}
|
88
|
+
else
|
89
|
+
@os_devpath = "#{@inst_data_dir}/#{hc.inst_id}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
# check mount point
|
93
|
+
mount_point = "#{@inst_data_dir}/rootfs"
|
94
|
+
unless File.exist?(mount_point)
|
95
|
+
sh("mkdir #{mount_point}")
|
96
|
+
end
|
97
|
+
|
98
|
+
cmd = "mount %s %s"
|
99
|
+
args = [@os_devpath, mount_point]
|
100
|
+
if @inst[:image][:boot_dev_type] == 2
|
101
|
+
cmd += " -o loop"
|
102
|
+
end
|
103
|
+
sh(cmd, args)
|
104
|
+
|
105
|
+
config_name = create_config
|
106
|
+
create_fstab
|
107
|
+
setup_container
|
108
|
+
|
109
|
+
sh("lxc-create -f %s -n %s", [config_name, @inst[:uuid]])
|
110
|
+
sh("sudo lxc-start -n %s -d -l DEBUG -o %s/%s.log", [@inst[:uuid], @inst_data_dir, @inst[:uuid]])
|
111
|
+
end
|
112
|
+
|
113
|
+
def terminate_instance(hc)
|
114
|
+
sh("lxc-stop -n #{hc.inst_id}")
|
115
|
+
sh("lxc-destroy -n #{hc.inst_id}")
|
116
|
+
sh("umount #{hc.inst_data_dir}/rootfs")
|
117
|
+
end
|
118
|
+
|
119
|
+
def reboot_instance(hc)
|
120
|
+
inst = hc.inst
|
121
|
+
terminate_instance(hc)
|
122
|
+
run_instance(hc)
|
123
|
+
end
|
124
|
+
|
125
|
+
def attach_volume_to_guest(hc)
|
126
|
+
inst_id = hc.inst_id
|
127
|
+
sddev = File.expand_path(File.readlink(hc.os_devpath), '/dev/disk/by-path')
|
128
|
+
|
129
|
+
# find major number and minor number to device file
|
130
|
+
stat = File.stat(sddev)
|
131
|
+
devnum = [stat.rdev_major,stat.rdev_minor].join(':')
|
132
|
+
|
133
|
+
sh("echo \"b #{devnum} rwm\" > /cgroup/#{inst_id}/devices.allow")
|
134
|
+
sh("mknod #{hc.inst_data_dir}/rootfs#{sddev} -m 660 b #{stat.rdev_major} #{stat.rdev_minor}")
|
135
|
+
|
136
|
+
config_name = "#{hc.inst_data_dir}/config.#{inst_id}"
|
137
|
+
config = File.open(config_name, 'r')
|
138
|
+
data = config.readlines
|
139
|
+
config.close
|
140
|
+
config = File.open(config_name, 'w')
|
141
|
+
config.write data
|
142
|
+
config.puts "lxc.cgroup.devices.allow = b #{devnum} rwm"
|
143
|
+
config.close
|
144
|
+
devnum
|
145
|
+
end
|
146
|
+
|
147
|
+
def detach_volume_from_guest(hc)
|
148
|
+
inst_id = hc.inst_id
|
149
|
+
vol = hc.vol
|
150
|
+
sddev = File.expand_path(File.readlink(vol[:host_device_name]), '/dev/disk/by-path')
|
151
|
+
devnum = vol[:guest_device_name]
|
152
|
+
|
153
|
+
sh("echo \"b #{devnum} rwm\" > /cgroup/#{inst_id}/devices.deny")
|
154
|
+
sh("rm -rf #{hc.inst_data_dir}/rootfs#{sddev}")
|
155
|
+
|
156
|
+
config_name = "#{hc.inst_data_dir}/config.#{inst_id}"
|
157
|
+
config = File.open(config_name, 'r')
|
158
|
+
data = config.readlines.select {|f| f != "lxc.cgroup.devices.allow = b #{devnum} rwm\n" }
|
159
|
+
config.close
|
160
|
+
config = File.open(config_name, 'w+')
|
161
|
+
config.write data
|
162
|
+
config.close
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|