wakame-vdc-dcmgr 11.06.0 → 11.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +19 -31
- data/bin/collector +6 -1
- data/config/db/migrations/0001_v1110_origin.rb +446 -0
- data/config/dcmgr.conf.example +51 -0
- data/lib/dcmgr.rb +99 -22
- data/lib/dcmgr/cli/base.rb +34 -1
- data/lib/dcmgr/cli/host.rb +24 -20
- data/lib/dcmgr/cli/image.rb +38 -19
- data/lib/dcmgr/cli/keypair.rb +16 -12
- data/lib/dcmgr/cli/network.rb +189 -81
- data/lib/dcmgr/cli/quota.rb +2 -2
- data/lib/dcmgr/cli/security_group.rb +106 -0
- data/lib/dcmgr/cli/spec.rb +144 -39
- data/lib/dcmgr/cli/storage.rb +16 -15
- data/lib/dcmgr/cli/tag.rb +20 -14
- data/lib/dcmgr/cli/vlan.rb +5 -5
- data/lib/dcmgr/drivers/backing_store.rb +32 -0
- data/lib/dcmgr/drivers/comstar.rb +81 -0
- data/lib/dcmgr/drivers/iijgio_storage.rb +9 -19
- data/lib/dcmgr/drivers/iscsi_target.rb +41 -0
- data/lib/dcmgr/drivers/kvm.rb +161 -28
- data/lib/dcmgr/drivers/linux_iscsi.rb +60 -0
- data/lib/dcmgr/drivers/local_storage.rb +24 -0
- data/lib/dcmgr/drivers/lxc.rb +167 -125
- data/lib/dcmgr/drivers/raw.rb +74 -0
- data/lib/dcmgr/drivers/s3_storage.rb +7 -19
- data/lib/dcmgr/drivers/snapshot_storage.rb +18 -28
- data/lib/dcmgr/drivers/storage_initiator.rb +28 -0
- data/lib/dcmgr/drivers/sun_iscsi.rb +32 -0
- data/lib/dcmgr/drivers/zfs.rb +77 -0
- data/lib/dcmgr/endpoints/core_api.rb +315 -263
- data/lib/dcmgr/endpoints/errors.rb +21 -10
- data/lib/dcmgr/endpoints/metadata.rb +360 -23
- data/lib/dcmgr/helpers/cli_helper.rb +6 -3
- data/lib/dcmgr/helpers/ec2_metadata_helper.rb +9 -0
- data/lib/dcmgr/helpers/nic_helper.rb +11 -0
- data/lib/dcmgr/helpers/snapshot_storage_helper.rb +34 -0
- data/lib/dcmgr/models/account.rb +0 -6
- data/lib/dcmgr/models/account_resource.rb +0 -4
- data/lib/dcmgr/models/base_new.rb +14 -2
- data/lib/dcmgr/models/dhcp_range.rb +38 -0
- data/lib/dcmgr/models/frontend_system.rb +0 -6
- data/lib/dcmgr/models/history.rb +0 -11
- data/lib/dcmgr/models/host_node.rb +131 -0
- data/lib/dcmgr/models/hostname_lease.rb +0 -8
- data/lib/dcmgr/models/image.rb +31 -18
- data/lib/dcmgr/models/instance.rb +137 -143
- data/lib/dcmgr/models/instance_nic.rb +52 -29
- data/lib/dcmgr/models/instance_security_group.rb +9 -0
- data/lib/dcmgr/models/instance_spec.rb +163 -31
- data/lib/dcmgr/models/ip_lease.rb +10 -21
- data/lib/dcmgr/models/mac_lease.rb +30 -11
- data/lib/dcmgr/models/network.rb +148 -27
- data/lib/dcmgr/models/physical_network.rb +18 -0
- data/lib/dcmgr/models/quota.rb +0 -10
- data/lib/dcmgr/models/request_log.rb +3 -18
- data/lib/dcmgr/models/security_group.rb +66 -0
- data/lib/dcmgr/models/security_group_rule.rb +145 -0
- data/lib/dcmgr/models/ssh_key_pair.rb +16 -19
- data/lib/dcmgr/models/{storage_pool.rb → storage_node.rb} +35 -25
- data/lib/dcmgr/models/tag.rb +0 -14
- data/lib/dcmgr/models/tag_mapping.rb +1 -7
- data/lib/dcmgr/models/vlan_lease.rb +2 -8
- data/lib/dcmgr/models/volume.rb +49 -37
- data/lib/dcmgr/models/volume_snapshot.rb +15 -17
- data/lib/dcmgr/node_modules/hva_collector.rb +69 -28
- data/lib/dcmgr/node_modules/instance_ha.rb +23 -12
- data/lib/dcmgr/node_modules/instance_monitor.rb +16 -2
- data/lib/dcmgr/node_modules/openflow_controller.rb +784 -0
- data/lib/dcmgr/node_modules/scheduler.rb +189 -0
- data/lib/dcmgr/node_modules/service_netfilter.rb +452 -227
- data/lib/dcmgr/node_modules/service_openflow.rb +731 -0
- data/lib/dcmgr/node_modules/sta_collector.rb +20 -0
- data/lib/dcmgr/node_modules/sta_tgt_initializer.rb +35 -0
- data/lib/dcmgr/rack/request_logger.rb +11 -6
- data/lib/dcmgr/rpc/hva_handler.rb +256 -110
- data/lib/dcmgr/rpc/sta_handler.rb +244 -0
- data/lib/dcmgr/scheduler.rb +122 -8
- data/lib/dcmgr/scheduler/host_node/exclude_same.rb +24 -0
- data/lib/dcmgr/scheduler/host_node/find_first.rb +12 -0
- data/lib/dcmgr/scheduler/host_node/least_usage.rb +28 -0
- data/lib/dcmgr/scheduler/host_node/per_instance.rb +18 -0
- data/lib/dcmgr/scheduler/host_node/specify_node.rb +26 -0
- data/lib/dcmgr/scheduler/network/flat_single.rb +23 -0
- data/lib/dcmgr/scheduler/network/nat_one_to_one.rb +23 -0
- data/lib/dcmgr/scheduler/network/per_instance.rb +39 -0
- data/lib/dcmgr/scheduler/network/vif_template.rb +19 -0
- data/lib/dcmgr/scheduler/storage_node/find_first.rb +13 -0
- data/lib/dcmgr/scheduler/storage_node/least_usage.rb +23 -0
- data/lib/dcmgr/storage_service.rb +39 -40
- data/lib/dcmgr/tags.rb +3 -3
- data/lib/dcmgr/version.rb +1 -1
- data/lib/dcmgr/vnet.rb +105 -0
- data/lib/dcmgr/vnet/factories.rb +141 -0
- data/lib/dcmgr/vnet/isolators/by_securitygroup.rb +21 -0
- data/lib/dcmgr/vnet/isolators/dummy.rb +17 -0
- data/lib/dcmgr/vnet/netfilter/cache.rb +51 -0
- data/lib/dcmgr/vnet/netfilter/chain.rb +66 -0
- data/lib/dcmgr/vnet/netfilter/controller.rb +193 -0
- data/lib/dcmgr/vnet/netfilter/ebtables_rule.rb +53 -0
- data/lib/dcmgr/vnet/netfilter/iptables_rule.rb +45 -0
- data/lib/dcmgr/vnet/netfilter/task_manager.rb +459 -0
- data/lib/dcmgr/vnet/tasks/accept_all_dns.rb +19 -0
- data/lib/dcmgr/vnet/tasks/accept_arp_broadcast.rb +24 -0
- data/lib/dcmgr/vnet/tasks/accept_arp_from_friends.rb +34 -0
- data/lib/dcmgr/vnet/tasks/accept_arp_from_gateway.rb +21 -0
- data/lib/dcmgr/vnet/tasks/accept_arp_to_host.rb +30 -0
- data/lib/dcmgr/vnet/tasks/accept_ip_from_friends.rb +26 -0
- data/lib/dcmgr/vnet/tasks/accept_ip_from_gateway.rb +23 -0
- data/lib/dcmgr/vnet/tasks/accept_ip_to_anywhere.rb +18 -0
- data/lib/dcmgr/vnet/tasks/accept_related_established.rb +45 -0
- data/lib/dcmgr/vnet/tasks/accept_wakame_dhcp_only.rb +33 -0
- data/lib/dcmgr/vnet/tasks/accept_wakame_dns_only.rb +33 -0
- data/lib/dcmgr/vnet/tasks/debug_iptables.rb +21 -0
- data/lib/dcmgr/vnet/tasks/drop_arp_forwarding.rb +27 -0
- data/lib/dcmgr/vnet/tasks/drop_arp_to_host.rb +24 -0
- data/lib/dcmgr/vnet/tasks/drop_ip_from_anywhere.rb +18 -0
- data/lib/dcmgr/vnet/tasks/drop_ip_spoofing.rb +34 -0
- data/lib/dcmgr/vnet/tasks/drop_mac_spoofing.rb +33 -0
- data/lib/dcmgr/vnet/tasks/exclude_from_nat.rb +47 -0
- data/lib/dcmgr/vnet/tasks/security_group.rb +37 -0
- data/lib/dcmgr/vnet/tasks/static_nat.rb +54 -0
- data/lib/dcmgr/vnet/tasks/translate_metadata_address.rb +32 -0
- data/web/metadata/config.ru +1 -1
- metadata +174 -89
- data/lib/dcmgr/cli/group.rb +0 -101
- data/lib/dcmgr/endpoints/core_api_mock.rb +0 -865
- data/lib/dcmgr/models/host_pool.rb +0 -122
- data/lib/dcmgr/models/instance_netfilter_group.rb +0 -16
- data/lib/dcmgr/models/netfilter_group.rb +0 -89
- data/lib/dcmgr/models/netfilter_rule.rb +0 -21
- data/lib/dcmgr/scheduler/find_last.rb +0 -16
- data/lib/dcmgr/scheduler/find_random.rb +0 -16
- data/lib/dcmgr/stm/instance.rb +0 -25
- data/lib/dcmgr/stm/snapshot_context.rb +0 -33
- data/lib/dcmgr/stm/volume_context.rb +0 -65
@@ -0,0 +1,74 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr
|
4
|
+
module Drivers
|
5
|
+
class Raw < BackingStore
|
6
|
+
include Dcmgr::Logger
|
7
|
+
include Dcmgr::Helpers::CliHelper
|
8
|
+
|
9
|
+
def create_volume(ctx, snap_file = nil)
|
10
|
+
@volume_id = ctx.volume_id
|
11
|
+
@volume = ctx.volume
|
12
|
+
@snapshot = ctx.snapshot
|
13
|
+
|
14
|
+
logger.info("creating new volume: #{@volume_id}")
|
15
|
+
|
16
|
+
if @snapshot
|
17
|
+
cp_sparse(snap_file, vol_path)
|
18
|
+
if $?.exitstatus != 0
|
19
|
+
raise "failed copy snapshot: #{snap_file}"
|
20
|
+
end
|
21
|
+
else
|
22
|
+
unless File.exist?(vol_path)
|
23
|
+
logger.info("creating parent filesystem(size:#{@volume[:size]}): #{vol_path}")
|
24
|
+
|
25
|
+
sh("/bin/mkdir -p #{File.dirname(vol_path)}") unless File.directory?(File.dirname(vol_path))
|
26
|
+
sh("/bin/dd if=/dev/zero of=#{vol_path} bs=1 count=0 seek=#{@volume[:size] * 1024 * 1024}")
|
27
|
+
du_hs(vol_path)
|
28
|
+
|
29
|
+
logger.info("create parent filesystem(size:#{@volume[:size]}): #{vol_path}")
|
30
|
+
else
|
31
|
+
raise "volume already exists: #{@volume_id}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
logger.info("created new volume: #{@volume_id}")
|
36
|
+
end
|
37
|
+
|
38
|
+
def delete_volume(ctx)
|
39
|
+
@volume = ctx.volume
|
40
|
+
sh("/bin/rm %s", [vol_path]) if File.exists?(vol_path)
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_snapshot(ctx, snap_file)
|
44
|
+
@volume = ctx.volume
|
45
|
+
|
46
|
+
logger.info("creating new snapshot: #{snap_file}")
|
47
|
+
cp_sparse(vol_path, snap_file)
|
48
|
+
if $?.exitstatus != 0
|
49
|
+
raise "failed snapshot file : #{snap_file}"
|
50
|
+
end
|
51
|
+
du_hs(snap_file)
|
52
|
+
|
53
|
+
logger.info("created new snapshot: #{snap_file}")
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def vol_path
|
58
|
+
vol_base_path = @volume[:storage_node][:export_path]
|
59
|
+
vol_account_path = "#{vol_base_path}/#{@volume[:account_id]}"
|
60
|
+
"#{vol_account_path}/#{@volume[:uuid]}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def cp_sparse(src, dst)
|
64
|
+
sh("/bin/cp -p --sparse=always %s %s",[src, dst])
|
65
|
+
end
|
66
|
+
|
67
|
+
def du_hs(path)
|
68
|
+
sh("du -hs %s", [path])
|
69
|
+
sh("du -hs --apparent-size %s", [path])
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -3,36 +3,24 @@
|
|
3
3
|
module Dcmgr::Drivers
|
4
4
|
|
5
5
|
class S3Storage < SnapshotStorage
|
6
|
-
|
7
6
|
include Dcmgr::Logger
|
7
|
+
include Dcmgr::Helpers::SnapshotStorageHelper
|
8
8
|
|
9
|
-
def download(
|
9
|
+
def download(filename)
|
10
10
|
cmd = "get %s %s %s"
|
11
|
-
args = [@bucket,
|
11
|
+
args = [@bucket, key(filename), self.snapshot(filename)]
|
12
12
|
execute(cmd, args)
|
13
13
|
end
|
14
14
|
|
15
|
-
def upload(
|
15
|
+
def upload(filename)
|
16
16
|
cmd = "put %s %s %s"
|
17
|
-
args = [@bucket,
|
17
|
+
args = [@bucket, key(filename), self.snapshot(filename)]
|
18
18
|
execute(cmd, args)
|
19
19
|
end
|
20
20
|
|
21
|
-
def delete(
|
21
|
+
def delete(filename)
|
22
22
|
cmd = "rm %s %s"
|
23
|
-
args = [@bucket,
|
24
|
-
execute(cmd, args)
|
25
|
-
end
|
26
|
-
|
27
|
-
def check(keyname)
|
28
|
-
cmd = "test %s %s"
|
29
|
-
args = [@bucket, keyname]
|
30
|
-
execute(cmd, args)
|
31
|
-
end
|
32
|
-
|
33
|
-
def list
|
34
|
-
cmd = "ls %s"
|
35
|
-
args = [@bucket]
|
23
|
+
args = [@bucket, key(filename)]
|
36
24
|
execute(cmd, args)
|
37
25
|
end
|
38
26
|
end
|
@@ -1,51 +1,41 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
require 'rexml/document'
|
4
|
-
|
5
3
|
module Dcmgr::Drivers
|
6
4
|
class SnapshotStorage
|
7
5
|
include Dcmgr::Helpers::CliHelper
|
8
|
-
|
9
|
-
|
6
|
+
attr_reader :volume_snaphost_path
|
7
|
+
|
8
|
+
def initialize(account_id, bucket, volume_snaphost_path, options = {})
|
9
|
+
@account_id = account_id
|
10
10
|
@env = []
|
11
|
+
@volume_snaphost_path = volume_snaphost_path
|
11
12
|
@bucket = bucket
|
13
|
+
@tmp_dir = options[:tmp_dir] || '/var/tmp'
|
12
14
|
end
|
13
15
|
|
14
16
|
def setenv(key, value)
|
15
17
|
@env.push("#{key}=#{value}")
|
16
18
|
end
|
19
|
+
|
20
|
+
def clear
|
21
|
+
sh("/bin/rm #{@temporary_file}") if File.exists?(@temporary_file)
|
22
|
+
end
|
17
23
|
|
18
|
-
def
|
24
|
+
def snapshot(filename)
|
25
|
+
raise 'filename is empty' if filename == ''
|
26
|
+
@temporary_file = File.join(@tmp_dir, filename)
|
19
27
|
end
|
20
28
|
|
21
|
-
def
|
29
|
+
def download(filename)
|
22
30
|
end
|
23
31
|
|
24
|
-
def
|
32
|
+
def upload(filename)
|
25
33
|
end
|
26
34
|
|
27
|
-
def
|
35
|
+
def delete(filename)
|
28
36
|
end
|
29
|
-
|
30
|
-
def
|
31
|
-
script_root_path = File.join(File.expand_path('../../../../',__FILE__), 'script')
|
32
|
-
script = File.join(script_root_path, 'storage_service')
|
33
|
-
cmd = "/usr/bin/env #{@env.join(' ')} %s " + cmd
|
34
|
-
args = [script] + args
|
35
|
-
res = sh(cmd, args)
|
36
|
-
|
37
|
-
if res[:stdout] != ''
|
38
|
-
doc = REXML::Document.new res[:stdout]
|
39
|
-
code = REXML::XPath.match( doc, "//Error/Code/text()" ).to_s
|
40
|
-
message = REXML::XPath.match( doc, "//Error/Message/text()" ).to_s
|
41
|
-
bucket_name = REXML::XPath.match( doc, "//Error/BucketName/text()" ).to_s
|
42
|
-
request_id = REXML::XPath.match( doc, "//Error/RequestId/text()" ).to_s
|
43
|
-
host_id = REXML::XPath.match( doc, "//Error/HostId/text()" ).to_s
|
44
|
-
error_message = ["Snapshot execute error: ",cmd, code, message, bucket_name, request_id, host_id].join(',')
|
45
|
-
raise error_message
|
46
|
-
else
|
47
|
-
res
|
48
|
-
end
|
37
|
+
|
38
|
+
def check(filename)
|
49
39
|
end
|
50
40
|
end
|
51
41
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr
|
4
|
+
module Drivers
|
5
|
+
# Base class for remote storage initiators: NFS, ISCSI...
|
6
|
+
class StorageInitiator
|
7
|
+
|
8
|
+
def mount(hva_ctx)
|
9
|
+
raise NotImplementedError
|
10
|
+
end
|
11
|
+
|
12
|
+
def umount(hva_ctx)
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
class LinuxIscsiInitiator < StorageInitiator
|
20
|
+
def mount(hva_ctx)
|
21
|
+
end
|
22
|
+
|
23
|
+
def umount(hva_ctx, volume)
|
24
|
+
sh("iscsiadm -m node -T '%s' --logout", [volume[:transport_information][:iqn]])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dcmgr
|
4
|
+
module Drivers
|
5
|
+
class SunIscsi < IscsiTarget
|
6
|
+
include Dcmgr::Logger
|
7
|
+
include Dcmgr::Helpers::CliHelper
|
8
|
+
|
9
|
+
def create(ctx)
|
10
|
+
@volume = ctx.volume
|
11
|
+
@volume_id = ctx.volume_id
|
12
|
+
sh("/usr/sbin/zfs shareiscsi=on %s/%s", [@volume[:storage_node][:export_path], @volume[:uuid]])
|
13
|
+
|
14
|
+
if $?.exitstatus != 0
|
15
|
+
raise "failed iscsi target request: #{@volume_id}"
|
16
|
+
end
|
17
|
+
il = sh("iscsitadm list target -v %s", ["#{@volume[:storage_node][:export_path]}/#{@volume[:uuid]}"])
|
18
|
+
if $?.exitstatus != 0
|
19
|
+
raise "iscsi target has not be created #{@volume_id}"
|
20
|
+
end
|
21
|
+
il = il[:stdout].downcase.split("\n").select {|row| row.strip!}
|
22
|
+
# :transport_information => {:iqn => "iqn.1986-03.com.sun:02:787bca42-9639-44e4-f115-f5b06ed31817", :lun => 0}
|
23
|
+
opt = {:iqn => il[0].split(": ").last, :lun=>il[6].split(": ").last.to_i}
|
24
|
+
end
|
25
|
+
|
26
|
+
def delete(ctx)
|
27
|
+
@volume = ctx.volume
|
28
|
+
sh("/usr/sbin/zfs shareiscsi=off %s/%s", [@volume[:storage_node][:export_path], @volume[:uuid]])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Dcmgr
|
5
|
+
module Drivers
|
6
|
+
class Zfs < BackingStore
|
7
|
+
include Dcmgr::Logger
|
8
|
+
include Dcmgr::Helpers::CliHelper
|
9
|
+
|
10
|
+
def create_volume(ctx, zsnap_file)
|
11
|
+
@volume_id = ctx.volume_id
|
12
|
+
@volume = ctx.volume
|
13
|
+
@snapshot = ctx.snapshot
|
14
|
+
@destination = ctx.destination
|
15
|
+
|
16
|
+
### sta_handler :create_volume
|
17
|
+
vol_path = "#{@volume[:storage_node][:export_path]}/#{@volume[:uuid]}"
|
18
|
+
sh("/usr/sbin/zfs list %s", [File.dirname(vol_path)])
|
19
|
+
if $?.exitstatus != 0
|
20
|
+
# create parent filesystem
|
21
|
+
sh("/usr/sbin/zfs create -p %s", [File.dirname(vol_path)])
|
22
|
+
logger.info("create parent filesystem: #{File.dirname(vol_path)}")
|
23
|
+
end
|
24
|
+
|
25
|
+
if @snapshot
|
26
|
+
# create volume from snapshot
|
27
|
+
if File.exists?(zsnap_file)
|
28
|
+
sh("/usr/sbin/zfs receive %s < %s", [vol_path, zsnap_file])
|
29
|
+
if $?.exitstatus != 0
|
30
|
+
raise "volume already exists: #{@volume_id}"
|
31
|
+
end
|
32
|
+
else
|
33
|
+
raise "snapshot file isn't exists: #{zsnap_file}"
|
34
|
+
end
|
35
|
+
|
36
|
+
sh("/usr/sbin/zfs destroy %s@%s", [vol_path, @snapshot[:uuid]])
|
37
|
+
if $?.exitstatus != 0
|
38
|
+
raise "volume snapshot has not deleted: #{@volume_id}@#{@snapshot[:uuid]}"
|
39
|
+
end
|
40
|
+
else
|
41
|
+
# create volume
|
42
|
+
#sh("/usr/sbin/zfs create -p -V %s %s", ["#{@volume[:size]}m", vol_path])
|
43
|
+
# thin provisioning
|
44
|
+
sh("/usr/sbin/zfs create -p -s -V %s %s", ["#{@volume[:size]}m", vol_path])
|
45
|
+
if $?.exitstatus != 0
|
46
|
+
raise "volume already exists: #{@volume_id}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
sh("/usr/sbin/zfs list %s", [vol_path])
|
51
|
+
if $?.exitstatus != 0
|
52
|
+
raise "volume has not be created: #{@volume_id}"
|
53
|
+
end
|
54
|
+
|
55
|
+
logger.info("created new volume: #{@volume_id}")
|
56
|
+
### sta_handler :create_volume
|
57
|
+
end
|
58
|
+
|
59
|
+
def delete_volume(ctx)
|
60
|
+
@volume = ctx.volume
|
61
|
+
sh("/usr/sbin/zfs destroy %s", ["#{@volume[:storage_node][:export_path]}/#{@volume[:uuid]}"])
|
62
|
+
end
|
63
|
+
|
64
|
+
def create_snapshot(ctx, zsnap_file)
|
65
|
+
@snapshot_id = ctx.snapshot_id
|
66
|
+
@destination = ctx.destination
|
67
|
+
@snapshot = ctx.snapshot
|
68
|
+
@volume = ctx.volume
|
69
|
+
|
70
|
+
vol_path = "#{@volume[:storage_node][:export_path]}/#{@volume[:uuid]}"
|
71
|
+
sh("/usr/sbin/zfs snapshot %s@%s", [vol_path, @snapshot[:uuid]])
|
72
|
+
sh("/usr/sbin/zfs send %s@%s > %s", [vol_path, @snapshot[:uuid], zsnap_file])
|
73
|
+
sh("/usr/sbin/zfs destroy %s@%s", [vol_path, @snapshot[:uuid]])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -16,7 +16,7 @@ module Dcmgr
|
|
16
16
|
HTTP_X_VDC_ACCOUNT_UUID='HTTP_X_VDC_ACCOUNT_UUID'.freeze
|
17
17
|
|
18
18
|
RACK_FRONTEND_SYSTEM_ID='dcmgr.frotend_system.id'
|
19
|
-
|
19
|
+
|
20
20
|
class CoreAPI < Sinatra::Base
|
21
21
|
include Dcmgr::Logger
|
22
22
|
register Sinatra::Rabbit
|
@@ -42,7 +42,7 @@ module Dcmgr
|
|
42
42
|
end
|
43
43
|
raise InvalidRequestCredentials if @account.nil?
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
@requester_token = request.env[HTTP_X_VDC_REQUESTER_TOKEN]
|
47
47
|
#@frontend = Models::FrontendSystem[request.env[RACK_FRONTEND_SYSTEM_ID]]
|
48
48
|
|
@@ -79,6 +79,7 @@ module Dcmgr
|
|
79
79
|
hash = {:dummy=>@params}
|
80
80
|
else
|
81
81
|
mime = @mime_types.first
|
82
|
+
begin
|
82
83
|
case mime.to_s
|
83
84
|
when 'application/json', 'text/json'
|
84
85
|
require 'json'
|
@@ -91,6 +92,10 @@ module Dcmgr
|
|
91
92
|
else
|
92
93
|
raise "Unsupported body document type: #{mime.to_s}"
|
93
94
|
end
|
95
|
+
rescue => e
|
96
|
+
# fall back to query string params
|
97
|
+
hash = {:dummy=>@params}
|
98
|
+
end
|
94
99
|
end
|
95
100
|
return hash.values.first
|
96
101
|
end
|
@@ -105,7 +110,7 @@ module Dcmgr
|
|
105
110
|
raise NotImplementedError
|
106
111
|
else
|
107
112
|
content_type 'json'
|
108
|
-
body res.to_json
|
113
|
+
body res.to_json(JSON::PRETTY_STATE_PROTOTYPE)
|
109
114
|
end
|
110
115
|
end
|
111
116
|
|
@@ -113,6 +118,14 @@ module Dcmgr
|
|
113
118
|
# when matches the Exception class exactly. I expect to match
|
114
119
|
# whole subclasses of APIError so that override handle_exception!().
|
115
120
|
def handle_exception!(boom)
|
121
|
+
# Translate common non-APIError to APIError
|
122
|
+
boom = case boom
|
123
|
+
when Sequel::DatabaseError
|
124
|
+
DatabaseError.new
|
125
|
+
else
|
126
|
+
boom
|
127
|
+
end
|
128
|
+
|
116
129
|
if boom.kind_of?(APIError)
|
117
130
|
@env['sinatra.error'] = boom
|
118
131
|
Dcmgr::Logger.create('API Error').error("#{request.path_info} -> #{boom.class.to_s}: #{boom.message} (#{boom.backtrace.first})")
|
@@ -123,14 +136,13 @@ module Dcmgr
|
|
123
136
|
end
|
124
137
|
end
|
125
138
|
|
126
|
-
def
|
127
|
-
vs =
|
139
|
+
def find_volume_snapshot(snapshot_id)
|
140
|
+
vs = Models::VolumeSnapshot[snapshot_id]
|
128
141
|
raise UnknownVolumeSnapshot if vs.nil?
|
129
142
|
raise InvalidVolumeState unless vs.state.to_s == 'available'
|
130
|
-
|
131
|
-
vs.create_volume(account_id)
|
143
|
+
vs
|
132
144
|
end
|
133
|
-
|
145
|
+
|
134
146
|
def examine_owner(account_resource)
|
135
147
|
if @account.canonical_uuid == account_resource.account_id ||
|
136
148
|
@account.canonical_uuid == 'a-00000000'
|
@@ -157,7 +169,7 @@ module Dcmgr
|
|
157
169
|
else
|
158
170
|
total_ds = model_class.where(:account_id=>@account.canonical_uuid)
|
159
171
|
end
|
160
|
-
|
172
|
+
|
161
173
|
if %w(Dcmgr::Models::Instance Dcmgr::Models::Volume Dcmgr::Models::VolumeSnapshot).member?(model_class.to_s)
|
162
174
|
total_ds = total_ds.alives_and_recent_termed
|
163
175
|
end
|
@@ -201,83 +213,36 @@ module Dcmgr
|
|
201
213
|
description 'Runs a new VM instance'
|
202
214
|
# param :image_id, string, :required
|
203
215
|
# param :instance_spec_id, string, :required
|
204
|
-
# param :
|
205
|
-
# param :
|
216
|
+
# param :host_node_id, string, :optional
|
217
|
+
# param :hostname, string, :optional
|
206
218
|
# param :user_data, string, :optional
|
207
|
-
# param :
|
208
|
-
# param :
|
219
|
+
# param :security_groups, array, :optional
|
220
|
+
# param :ssh_key_id, string, :optional
|
209
221
|
# param :network_id, string, :optional
|
210
222
|
# param :ha_enabled, string, :optional
|
211
223
|
control do
|
212
224
|
Models::Instance.lock!
|
213
|
-
|
225
|
+
|
214
226
|
wmi = Models::Image[params[:image_id]] || raise(InvalidImageID)
|
215
227
|
spec = Models::InstanceSpec[params[:instance_spec_id]] || raise(InvalidInstanceSpec)
|
216
228
|
|
217
|
-
|
218
|
-
|
219
|
-
# 2. assume hp-xxxxx or tag-xxxxx style uuid
|
220
|
-
# 3. assign default shared host pool.
|
221
|
-
params[:host_id] ||= params[:host_pool_id]
|
222
|
-
hostnode = pool = nil
|
223
|
-
if params[:host_id]
|
224
|
-
# TODO: smart way to preload model libs.
|
225
|
-
Models::HostPool; Tags::HostPool;
|
226
|
-
if pool = Tags::HostPool.find(:account_id=>@account.canonical_uuid,
|
227
|
-
:name=>params[:host_id])
|
228
|
-
# Pattern 1st
|
229
|
-
elsif hostnode = Models::Taggable.find(params[:host_id])
|
230
|
-
# Pattern 2nd
|
231
|
-
case hostnode
|
232
|
-
when Models::HostPool
|
233
|
-
when Tags::HostPool
|
234
|
-
hostnode = hostnode.pick(spec)
|
235
|
-
else
|
236
|
-
raise UnknownHostPool, "Could not find the host: #{params[:host_id]}"
|
237
|
-
end
|
238
|
-
end
|
239
|
-
else
|
240
|
-
# Pattern 3rd
|
241
|
-
pool = Tags::HostPool[Dcmgr.conf.default_shared_host_pool]
|
242
|
-
hostnode = pool.pick(spec)
|
229
|
+
if !Models::HostNode.check_domain_capacity?(spec.cpu_cores, spec.memory_size)
|
230
|
+
raise OutOfHostCapacity
|
243
231
|
end
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
#
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
if params[:network_id]
|
254
|
-
# TODO: smart way to preload model libs.
|
255
|
-
Models::Network; Tags::NetworkPool;
|
256
|
-
if pool = Tags::NetworkPool.find(:account_id=>@account.canonical_uuid,
|
257
|
-
:name=>params[:network_id])
|
258
|
-
# Pattern 1st
|
259
|
-
network = pool.pick
|
260
|
-
elsif network = Models::Taggable.find(params[:network_id])
|
261
|
-
# Pattern 2nd
|
262
|
-
case network
|
263
|
-
when Models::Network
|
264
|
-
when Tags::NetworkPool
|
265
|
-
network = network.pick
|
266
|
-
else
|
267
|
-
raise "Unknown network uuid: #{params[:network_id]}"
|
268
|
-
end
|
269
|
-
end
|
270
|
-
else
|
271
|
-
# Pattern 3rd
|
272
|
-
pool = Tags::NetworkPool[Dcmgr.conf.default_shared_network_pool]
|
273
|
-
network = pool.pick
|
232
|
+
|
233
|
+
# TODO:
|
234
|
+
# "host_id" and "host_pool_id" will be obsolete.
|
235
|
+
# They are used in lib/dcmgr/scheduler/host_node/specify_node.rb.
|
236
|
+
if params[:host_id] || params[:host_pool_id] || params[:host_node_id]
|
237
|
+
host_node_id = params[:host_id] || params[:host_pool_id] || params[:host_node_id]
|
238
|
+
host_node = Models::HostNode[host_node_id]
|
239
|
+
raise UnknownHostNode, "#{host_node_id}" if host_node.nil?
|
240
|
+
raise InvalidHostNodeID, "#{host_node_id}" if host_node.status != 'online'
|
274
241
|
end
|
275
|
-
raise "Can not find the network" if network.nil?
|
276
|
-
raise "Out of IP addresses in the network" unless network.available_ip_nums > 0
|
277
242
|
|
278
|
-
|
279
|
-
|
280
|
-
|
243
|
+
# params is a Mash object. so coverts to raw Hash object.
|
244
|
+
instance = Models::Instance.entry_new(@account, wmi, spec, params.to_hash) do |i|
|
245
|
+
# Set common parameters from user's request.
|
281
246
|
i.user_data = params[:user_data] || ''
|
282
247
|
# set only when not nil as the table column has not null
|
283
248
|
# condition.
|
@@ -290,11 +255,11 @@ module Dcmgr
|
|
290
255
|
end
|
291
256
|
end
|
292
257
|
|
293
|
-
if params[:
|
294
|
-
ssh_key_pair = Models::SshKeyPair
|
295
|
-
|
258
|
+
if params[:ssh_key_id]
|
259
|
+
ssh_key_pair = Models::SshKeyPair[params[:ssh_key_id]]
|
260
|
+
|
296
261
|
if ssh_key_pair.nil?
|
297
|
-
raise UnknownSshKeyPair, "#{params[:
|
262
|
+
raise UnknownSshKeyPair, "#{params[:ssh_key_id]}"
|
298
263
|
else
|
299
264
|
i.set_ssh_key_pair(ssh_key_pair)
|
300
265
|
end
|
@@ -304,31 +269,52 @@ module Dcmgr
|
|
304
269
|
i.ha_enabled = 1
|
305
270
|
end
|
306
271
|
end
|
272
|
+
instance.save
|
307
273
|
|
308
|
-
|
309
|
-
params[:nf_group]
|
274
|
+
if params[:nf_group].is_a?(Array) || params[:nf_group].is_a?(String)
|
275
|
+
instance.join_security_group(params[:nf_group])
|
276
|
+
elsif params[:security_groups].is_a?(Array) || params[:security_groups].is_a?(String)
|
277
|
+
instance.join_security_group(params[:security_groups])
|
310
278
|
end
|
311
|
-
|
279
|
+
|
280
|
+
instance.state = :scheduling
|
281
|
+
instance.save
|
312
282
|
|
313
283
|
case wmi.boot_dev_type
|
314
284
|
when Models::Image::BOOT_DEV_SAN
|
315
285
|
# create new volume from snapshot.
|
316
286
|
snapshot_id = wmi.source[:snapshot_id]
|
317
|
-
|
287
|
+
vs = find_volume_snapshot(snapshot_id)
|
318
288
|
|
319
|
-
|
320
|
-
|
289
|
+
if !Models::StorageNode.check_domain_capacity?(vs.size)
|
290
|
+
raise OutOfDiskSpace
|
291
|
+
end
|
292
|
+
|
293
|
+
vol = Models::Volume.entry_new(@account, vs.size, params.to_hash) do |v|
|
294
|
+
if vs
|
295
|
+
v.snapshot_id = vs.canonical_uuid
|
296
|
+
end
|
297
|
+
v.boot_dev = 1
|
298
|
+
end
|
299
|
+
# assign instance -> volume
|
300
|
+
vol.instance = instance
|
301
|
+
vol.state = :scheduling
|
321
302
|
vol.save
|
322
|
-
|
323
|
-
res = Dcmgr.messaging.submit("kvm-handle.#{hostnode.node_id}", 'run_vol_store', inst.canonical_uuid, vol.canonical_uuid)
|
303
|
+
|
324
304
|
when Models::Image::BOOT_DEV_LOCAL
|
325
|
-
commit_transaction
|
326
|
-
res = Dcmgr.messaging.submit("kvm-handle.#{hostnode.node_id}", 'run_local_store', inst.canonical_uuid)
|
327
305
|
else
|
328
306
|
raise "Unknown boot type"
|
329
307
|
end
|
330
|
-
|
331
|
-
|
308
|
+
|
309
|
+
commit_transaction
|
310
|
+
Dcmgr.messaging.submit("scheduler",
|
311
|
+
'schedule_instance', instance.canonical_uuid)
|
312
|
+
|
313
|
+
# retrieve latest instance data.
|
314
|
+
# if not, security_groups value is empty.
|
315
|
+
instance = find_by_uuid(:Instance, instance.canonical_uuid)
|
316
|
+
|
317
|
+
response_to(instance.to_api_document)
|
332
318
|
end
|
333
319
|
end
|
334
320
|
|
@@ -337,7 +323,7 @@ module Dcmgr
|
|
337
323
|
control do
|
338
324
|
i = find_by_uuid(:Instance, params[:id])
|
339
325
|
raise UnknownInstance if i.nil?
|
340
|
-
|
326
|
+
|
341
327
|
response_to(i.to_api_document)
|
342
328
|
end
|
343
329
|
end
|
@@ -350,7 +336,16 @@ module Dcmgr
|
|
350
336
|
else
|
351
337
|
raise OperationNotPermitted
|
352
338
|
end
|
353
|
-
|
339
|
+
|
340
|
+
case i.state
|
341
|
+
when 'stopped'
|
342
|
+
# just destroy the record.
|
343
|
+
i.destroy
|
344
|
+
when 'terminated', 'scheduling'
|
345
|
+
raise InvalidInstanceState, i.state
|
346
|
+
else
|
347
|
+
res = Dcmgr.messaging.submit("hva-handle.#{i.host_node.node_id}", 'terminate', i.canonical_uuid)
|
348
|
+
end
|
354
349
|
response_to([i.canonical_uuid])
|
355
350
|
end
|
356
351
|
end
|
@@ -359,10 +354,42 @@ module Dcmgr
|
|
359
354
|
description 'Reboots the instance'
|
360
355
|
control do
|
361
356
|
i = find_by_uuid(:Instance, params[:id])
|
362
|
-
|
357
|
+
raise InvalidInstanceState, i.state if i.state != 'running'
|
358
|
+
Dcmgr.messaging.submit("hva-handle.#{i.host_node.node_id}", 'reboot', i.canonical_uuid)
|
363
359
|
response_to({})
|
364
360
|
end
|
365
361
|
end
|
362
|
+
|
363
|
+
operation :stop, :method=>:put, :member=>true do
|
364
|
+
description 'Stop the instance'
|
365
|
+
control do
|
366
|
+
i = find_by_uuid(:Instance, params[:id])
|
367
|
+
raise InvalidInstanceState, i.state if i.state != 'running'
|
368
|
+
|
369
|
+
# relase IpLease from nic.
|
370
|
+
i.nic.each { |nic|
|
371
|
+
nic.release_ip_lease
|
372
|
+
}
|
373
|
+
|
374
|
+
Dcmgr.messaging.submit("hva-handle.#{i.host_node.node_id}", 'stop', i.canonical_uuid)
|
375
|
+
response_to([i.canonical_uuid])
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
operation :start, :method=>:put, :member=>true do
|
380
|
+
description 'Restart the instance'
|
381
|
+
control do
|
382
|
+
instance = find_by_uuid(:Instance, params[:id])
|
383
|
+
raise InvalidInstanceState, instance.state if instance.state != 'stopped'
|
384
|
+
instance.state = :scheduling
|
385
|
+
instance.save
|
386
|
+
|
387
|
+
commit_transaction
|
388
|
+
Dcmgr.messaging.submit("scheduler", 'schedule_start_instance', instance.canonical_uuid)
|
389
|
+
response_to([instance.canonical_uuid])
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
366
393
|
end
|
367
394
|
|
368
395
|
collection :images do
|
@@ -400,7 +427,7 @@ module Dcmgr
|
|
400
427
|
Models::Image.lock!
|
401
428
|
i = find_by_uuid(:Image, params[:id])
|
402
429
|
if examine_owner(i)
|
403
|
-
i.
|
430
|
+
i.destroy
|
404
431
|
else
|
405
432
|
raise OperationNotPermitted
|
406
433
|
end
|
@@ -408,25 +435,28 @@ module Dcmgr
|
|
408
435
|
end
|
409
436
|
end
|
410
437
|
end
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
438
|
+
|
439
|
+
# obsolute path: "/host_pools"
|
440
|
+
[ :host_pools, :host_nodes ].each do |path|
|
441
|
+
collection path do
|
442
|
+
operation :index do
|
443
|
+
description 'Show list of host pools'
|
444
|
+
control do
|
445
|
+
res = select_index(:HostNode, {:start => params[:start],
|
446
|
+
:limit => params[:limit]})
|
447
|
+
response_to(res)
|
448
|
+
end
|
419
449
|
end
|
420
|
-
end
|
421
450
|
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
451
|
+
operation :show do
|
452
|
+
description 'Show status of the host'
|
453
|
+
#param :account_id, :string, :optional
|
454
|
+
control do
|
455
|
+
hp = find_by_uuid(:HostNode, params[:id])
|
456
|
+
raise OperationNotPermitted unless examine_owner(hp)
|
457
|
+
|
458
|
+
response_to(hp.to_api_document)
|
459
|
+
end
|
430
460
|
end
|
431
461
|
end
|
432
462
|
end
|
@@ -434,7 +464,7 @@ module Dcmgr
|
|
434
464
|
collection :volumes do
|
435
465
|
operation :index do
|
436
466
|
description 'Show lists of the volume'
|
437
|
-
# params start, fixnum, optional
|
467
|
+
# params start, fixnum, optional
|
438
468
|
# params limit, fixnum, optional
|
439
469
|
control do
|
440
470
|
res = select_index(:Volume, {:start => params[:start],
|
@@ -461,39 +491,69 @@ module Dcmgr
|
|
461
491
|
# params storage_pool_id, string, optional
|
462
492
|
control do
|
463
493
|
Models::Volume.lock!
|
494
|
+
sp = vs = vol = nil
|
495
|
+
# input parameter validation
|
464
496
|
if params[:snapshot_id]
|
465
|
-
|
466
|
-
sp = v.storage_pool
|
467
|
-
vs = find_by_uuid(:VolumeSnapshot, params[:snapshot_id])
|
468
|
-
repository_address = Dcmgr::StorageService.repository_address(vs.destination_key)
|
497
|
+
vs = find_volume_snapshot(params[:snapshot_id])
|
469
498
|
elsif params[:volume_size]
|
470
|
-
if Dcmgr.conf.
|
471
|
-
|
472
|
-
|
473
|
-
if Dcmgr.conf.create_volume_max_size.to_i < params[:volume_size].to_i
|
474
|
-
raise InvalidVolumeSize, "Requested Size is(<#{Dcmgr.conf.create_volume_max_size.to_i})"
|
499
|
+
if !(Dcmgr.conf.create_volume_max_size.to_i >= params[:volume_size].to_i) ||
|
500
|
+
!(params[:volume_size].to_i >= Dcmgr.conf.create_volume_min_size.to_i)
|
501
|
+
raise InvalidVolumeSize
|
475
502
|
end
|
476
503
|
if params[:storage_pool_id]
|
477
|
-
sp = find_by_uuid(:
|
478
|
-
raise
|
504
|
+
sp = find_by_uuid(:StorageNode, params[:storage_pool_id])
|
505
|
+
raise UnknownStorageNode if sp.nil?
|
506
|
+
raise StorageNodeNotPermitted if sp.account_id != @account.canonical_uuid
|
479
507
|
end
|
480
|
-
|
508
|
+
else
|
509
|
+
raise UndefinedRequiredParameter
|
510
|
+
end
|
511
|
+
|
512
|
+
volume_size = (vs ? vs.size : params[:volume_size].to_i)
|
513
|
+
|
514
|
+
if !Models::StorageNode.check_domain_capacity?(volume_size)
|
515
|
+
raise OutOfDiskSpace
|
516
|
+
end
|
517
|
+
|
518
|
+
# params is a Mash object. so coverts to raw Hash object.
|
519
|
+
vol = Models::Volume.entry_new(@account, volume_size, params.to_hash) do |v|
|
520
|
+
if vs
|
521
|
+
v.snapshot_id = vs.canonical_uuid
|
522
|
+
end
|
523
|
+
end
|
524
|
+
vol.save
|
525
|
+
|
526
|
+
if sp.nil?
|
527
|
+
# going to storage node scheduling mode.
|
528
|
+
vol.state = :scheduling
|
529
|
+
vol.save
|
530
|
+
|
531
|
+
commit_transaction
|
532
|
+
|
533
|
+
Dcmgr.messaging.submit("scheduler", 'schedule_volume', vol.canonical_uuid)
|
534
|
+
else
|
481
535
|
begin
|
482
|
-
|
483
|
-
|
536
|
+
vol.storage_node = sp
|
537
|
+
vol.save
|
538
|
+
rescue Models::Volume::CapacityError => e
|
484
539
|
logger.error(e)
|
485
540
|
raise OutOfDiskSpace
|
486
|
-
rescue Sequel::DatabaseError => e
|
487
|
-
logger.error(e)
|
488
|
-
raise DatabaseError
|
489
541
|
end
|
490
|
-
|
491
|
-
|
542
|
+
|
543
|
+
vol.state = :pending
|
544
|
+
vol.save
|
545
|
+
|
546
|
+
commit_transaction
|
547
|
+
|
548
|
+
repository_address = nil
|
549
|
+
if vol.snapshot
|
550
|
+
repository_address = Dcmgr::StorageService.repository_address(vol.snapshot.destination_key)
|
551
|
+
end
|
552
|
+
|
553
|
+
res = Dcmgr.messaging.submit("sta-handle.#{vol.storage_node.node_id}", 'create_volume', vol.canonical_uuid, repository_address)
|
492
554
|
end
|
493
555
|
|
494
|
-
|
495
|
-
res = Dcmgr.messaging.submit("zfs-handle.#{sp.values[:node_id]}", 'create_volume', v.canonical_uuid, repository_address)
|
496
|
-
response_to(v.to_api_document)
|
556
|
+
response_to(vol.to_api_document)
|
497
557
|
end
|
498
558
|
end
|
499
559
|
|
@@ -503,10 +563,11 @@ module Dcmgr
|
|
503
563
|
control do
|
504
564
|
volume_id = params[:id]
|
505
565
|
raise UndefinedVolumeID if volume_id.nil?
|
506
|
-
|
566
|
+
|
507
567
|
vol = find_by_uuid(:Volume, volume_id)
|
508
568
|
raise UnknownVolume if vol.nil?
|
509
|
-
raise InvalidVolumeState unless vol.state == "available"
|
569
|
+
raise InvalidVolumeState, "#{vol.state}" unless vol.state == "available"
|
570
|
+
|
510
571
|
|
511
572
|
begin
|
512
573
|
v = Models::Volume.delete_volume(@account.canonical_uuid, volume_id)
|
@@ -515,10 +576,9 @@ module Dcmgr
|
|
515
576
|
raise InvalidDeleteRequest
|
516
577
|
end
|
517
578
|
raise UnknownVolume if v.nil?
|
518
|
-
sp = v.storage_pool
|
519
579
|
|
520
580
|
commit_transaction
|
521
|
-
res = Dcmgr.messaging.submit("
|
581
|
+
res = Dcmgr.messaging.submit("sta-handle.#{v.storage_node.node_id}", 'delete_volume', v.canonical_uuid)
|
522
582
|
response_to([v.canonical_uuid])
|
523
583
|
end
|
524
584
|
end
|
@@ -530,7 +590,7 @@ module Dcmgr
|
|
530
590
|
control do
|
531
591
|
raise UndefinedInstanceID if params[:instance_id].nil?
|
532
592
|
raise UndefinedVolumeID if params[:id].nil?
|
533
|
-
|
593
|
+
|
534
594
|
i = find_by_uuid(:Instance, params[:instance_id])
|
535
595
|
raise UnknownInstance if i.nil?
|
536
596
|
raise InvalidInstanceState unless i.live? && i.state == 'running'
|
@@ -542,7 +602,7 @@ module Dcmgr
|
|
542
602
|
v.instance = i
|
543
603
|
v.save
|
544
604
|
commit_transaction
|
545
|
-
res = Dcmgr.messaging.submit("
|
605
|
+
res = Dcmgr.messaging.submit("hva-handle.#{i.host_node.node_id}", 'attach', i.canonical_uuid, v.canonical_uuid)
|
546
606
|
|
547
607
|
response_to(v.to_api_document)
|
548
608
|
end
|
@@ -562,13 +622,13 @@ module Dcmgr
|
|
562
622
|
i = v.instance
|
563
623
|
raise InvalidInstanceState unless i.live? && i.state == 'running'
|
564
624
|
commit_transaction
|
565
|
-
res = Dcmgr.messaging.submit("
|
625
|
+
res = Dcmgr.messaging.submit("hva-handle.#{i.host_node.node_id}", 'detach', i.canonical_uuid, v.canonical_uuid)
|
566
626
|
response_to(v.to_api_document)
|
567
627
|
end
|
568
628
|
end
|
569
629
|
|
570
630
|
end
|
571
|
-
|
631
|
+
|
572
632
|
get '/api/volume_snapshots/upload_destination' do
|
573
633
|
c = StorageService::snapshot_repository_config.dup
|
574
634
|
tmp = c['local']
|
@@ -580,16 +640,16 @@ module Dcmgr
|
|
580
640
|
}
|
581
641
|
}
|
582
642
|
results.unshift({
|
583
|
-
:destination_id => 'local',
|
643
|
+
:destination_id => 'local',
|
584
644
|
:destination_name => tmp['display_name']
|
585
645
|
})
|
586
646
|
response_to([{:results => results}])
|
587
647
|
end
|
588
|
-
|
648
|
+
|
589
649
|
collection :volume_snapshots do
|
590
650
|
operation :index do
|
591
651
|
description 'Show lists of the volume_snapshots'
|
592
|
-
# params start, fixnum, optional
|
652
|
+
# params start, fixnum, optional
|
593
653
|
# params limit, fixnum, optional
|
594
654
|
control do
|
595
655
|
res = select_index(:VolumeSnapshot, {:start => params[:start],
|
@@ -612,6 +672,7 @@ module Dcmgr
|
|
612
672
|
operation :create do
|
613
673
|
description 'Create a new volume snapshot'
|
614
674
|
# params volume_id, string, required
|
675
|
+
# params detination, string, required
|
615
676
|
# params storage_pool_id, string, optional
|
616
677
|
control do
|
617
678
|
Models::Volume.lock!
|
@@ -621,13 +682,13 @@ module Dcmgr
|
|
621
682
|
raise UnknownVolume if v.nil?
|
622
683
|
raise InvalidVolumeState unless v.ready_to_take_snapshot?
|
623
684
|
vs = v.create_snapshot(@account.canonical_uuid)
|
624
|
-
sp = vs.
|
685
|
+
sp = vs.storage_node
|
625
686
|
destination_key = Dcmgr::StorageService.destination_key(@account.canonical_uuid, params[:destination], sp.snapshot_base_path, vs.snapshot_filename)
|
626
687
|
vs.update_destination_key(@account.canonical_uuid, destination_key)
|
627
688
|
commit_transaction
|
628
|
-
|
689
|
+
|
629
690
|
repository_address = Dcmgr::StorageService.repository_address(destination_key)
|
630
|
-
res = Dcmgr.messaging.submit("
|
691
|
+
res = Dcmgr.messaging.submit("sta-handle.#{sp.node_id}", 'create_snapshot', vs.canonical_uuid, repository_address)
|
631
692
|
response_to(vs.to_api_document)
|
632
693
|
end
|
633
694
|
end
|
@@ -639,13 +700,13 @@ module Dcmgr
|
|
639
700
|
Models::VolumeSnapshot.lock!
|
640
701
|
snapshot_id = params[:id]
|
641
702
|
raise UndefindVolumeSnapshotID if snapshot_id.nil?
|
642
|
-
|
703
|
+
|
643
704
|
v = find_by_uuid(:VolumeSnapshot, snapshot_id)
|
644
705
|
raise UnknownVolumeSnapshot if v.nil?
|
645
706
|
raise InvalidVolumeState unless v.state == "available"
|
646
|
-
|
707
|
+
|
647
708
|
destination_key = v.destination_key
|
648
|
-
|
709
|
+
|
649
710
|
begin
|
650
711
|
vs = Models::VolumeSnapshot.delete_snapshot(@account.canonical_uuid, snapshot_id)
|
651
712
|
rescue Models::VolumeSnapshot::RequestError => e
|
@@ -653,32 +714,32 @@ module Dcmgr
|
|
653
714
|
raise InvalidDeleteRequest
|
654
715
|
end
|
655
716
|
raise UnknownVolumeSnapshot if vs.nil?
|
656
|
-
sp = vs.
|
717
|
+
sp = vs.storage_node
|
657
718
|
|
658
719
|
commit_transaction
|
659
|
-
|
720
|
+
|
660
721
|
repository_address = Dcmgr::StorageService.repository_address(destination_key)
|
661
|
-
res = Dcmgr.messaging.submit("
|
722
|
+
res = Dcmgr.messaging.submit("sta-handle.#{sp.node_id}", 'delete_snapshot', vs.canonical_uuid, repository_address)
|
662
723
|
response_to([vs.canonical_uuid])
|
663
724
|
end
|
664
725
|
end
|
665
726
|
|
666
727
|
end
|
667
728
|
|
668
|
-
collection :
|
669
|
-
description 'Show lists of the
|
729
|
+
collection :security_groups do
|
730
|
+
description 'Show lists of the security groups'
|
670
731
|
operation :index do
|
671
732
|
control do
|
672
|
-
res = select_index(:
|
733
|
+
res = select_index(:SecurityGroup, {:start => params[:start],
|
673
734
|
:limit => params[:limit]})
|
674
735
|
response_to(res)
|
675
736
|
end
|
676
737
|
end
|
677
738
|
|
678
739
|
operation :show do
|
679
|
-
description 'Show the
|
740
|
+
description 'Show the security group'
|
680
741
|
control do
|
681
|
-
g = find_by_uuid(:
|
742
|
+
g = find_by_uuid(:SecurityGroup, params[:id])
|
682
743
|
raise OperationNotPermitted unless examine_owner(g)
|
683
744
|
|
684
745
|
response_to(g.to_api_document)
|
@@ -686,34 +747,28 @@ module Dcmgr
|
|
686
747
|
end
|
687
748
|
|
688
749
|
operation :create do
|
689
|
-
description 'Register a new
|
690
|
-
# params name, string
|
750
|
+
description 'Register a new security group'
|
691
751
|
# params description, string
|
692
752
|
# params rule, string
|
693
753
|
control do
|
694
|
-
Models::
|
695
|
-
raise UndefinedNetfilterGroup if params[:name].nil?
|
696
|
-
|
697
|
-
@name = params[:name]
|
698
|
-
# TODO: validate @name. @name can use [a-z] [A-Z] '_' '-'
|
699
|
-
# - invalidate? -> raise InvalidCharacterOfNetfilterGroupName
|
700
|
-
|
701
|
-
g = Models::NetfilterGroup.filter(:name => @name, :account_id => @account.canonical_uuid).first
|
702
|
-
raise DuplicatedNetfilterGroup unless g.nil?
|
754
|
+
Models::SecurityGroup.lock!
|
703
755
|
|
704
|
-
g = Models::
|
756
|
+
g = Models::SecurityGroup.create(:account_id=>@account.canonical_uuid,
|
757
|
+
:description=>params[:description],
|
758
|
+
:rule=>params[:rule])
|
705
759
|
response_to(g.to_api_document)
|
706
760
|
end
|
707
761
|
end
|
708
762
|
|
709
763
|
operation :update do
|
710
|
-
description "Update parameters for the
|
764
|
+
description "Update parameters for the security group"
|
711
765
|
# params description, string
|
712
766
|
# params rule, string
|
713
767
|
control do
|
714
|
-
g = find_by_uuid(:
|
768
|
+
g = find_by_uuid(:SecurityGroup, params[:id])
|
715
769
|
|
716
|
-
raise
|
770
|
+
raise UnknownSecurityGroup if g.nil?
|
771
|
+
raise OperationNotPermitted unless examine_owner(g)
|
717
772
|
|
718
773
|
if params[:description]
|
719
774
|
g.description = params[:description]
|
@@ -723,25 +778,22 @@ module Dcmgr
|
|
723
778
|
end
|
724
779
|
|
725
780
|
g.save
|
726
|
-
g.rebuild_rule
|
727
781
|
|
728
782
|
commit_transaction
|
729
|
-
# refresh
|
730
|
-
Dcmgr.messaging.event_publish('hva/
|
783
|
+
# refresh security group rules on host nodes.
|
784
|
+
Dcmgr.messaging.event_publish('hva/security_group_updated', :args=>[g.canonical_uuid])
|
731
785
|
|
732
786
|
response_to(g.to_api_document)
|
733
787
|
end
|
734
788
|
end
|
735
789
|
|
736
790
|
operation :destroy do
|
737
|
-
|
738
|
-
description "Delete the netfilter group"
|
739
|
-
|
791
|
+
description "Delete the security group"
|
740
792
|
control do
|
741
|
-
Models::
|
742
|
-
g = find_by_uuid(:
|
793
|
+
Models::SecurityGroup.lock!
|
794
|
+
g = find_by_uuid(:SecurityGroup, params[:id])
|
743
795
|
|
744
|
-
raise
|
796
|
+
raise UnknownSecurityGroup if g.nil?
|
745
797
|
raise OperationNotPermitted unless examine_owner(g)
|
746
798
|
|
747
799
|
# raise OperationNotPermitted if g.instances.size > 0
|
@@ -758,52 +810,30 @@ module Dcmgr
|
|
758
810
|
|
759
811
|
end
|
760
812
|
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
@name = params[:id]
|
773
|
-
g = Models::NetfilterGroup.filter(:name => @name, :account_id => @account.canonical_uuid).first
|
774
|
-
raise UnknownNetfilterGroup if g.nil?
|
775
|
-
|
776
|
-
g.netfilter_rules.each { |rule|
|
777
|
-
rules << rule.values
|
778
|
-
}
|
813
|
+
# obsolute path: "/storage_pools"
|
814
|
+
[ :storage_pools, :storage_nodes ].each do |path|
|
815
|
+
collection path do
|
816
|
+
operation :index do
|
817
|
+
description 'Show lists of the storage_pools'
|
818
|
+
# params start, fixnum, optional
|
819
|
+
# params limit, fixnum, optional
|
820
|
+
control do
|
821
|
+
res = select_index(:StorageNode, {:start => params[:start],
|
822
|
+
:limit => params[:limit]})
|
823
|
+
response_to(res)
|
779
824
|
end
|
780
|
-
|
781
|
-
response_to(rules)
|
782
825
|
end
|
783
|
-
end
|
784
|
-
end
|
785
826
|
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
end
|
797
|
-
|
798
|
-
operation :show do
|
799
|
-
description 'Show the storage_pool status'
|
800
|
-
# params id, string, required
|
801
|
-
control do
|
802
|
-
pool_id = params[:id]
|
803
|
-
raise UndefinedStoragePoolID if pool_id.nil?
|
804
|
-
vs = find_by_uuid(:StoragePool, pool_id)
|
805
|
-
raise UnknownStoragePool if vs.nil?
|
806
|
-
response_to(vs.to_api_document)
|
827
|
+
operation :show do
|
828
|
+
description 'Show the storage_pool status'
|
829
|
+
# params id, string, required
|
830
|
+
control do
|
831
|
+
pool_id = params[:id]
|
832
|
+
raise UndefinedStorageNodeID if pool_id.nil?
|
833
|
+
vs = find_by_uuid(:StorageNode, pool_id)
|
834
|
+
raise UnknownStorageNode if vs.nil?
|
835
|
+
response_to(vs.to_api_document)
|
836
|
+
end
|
807
837
|
end
|
808
838
|
end
|
809
839
|
end
|
@@ -811,7 +841,7 @@ module Dcmgr
|
|
811
841
|
collection :ssh_key_pairs do
|
812
842
|
description "List ssh key pairs in account"
|
813
843
|
operation :index do
|
814
|
-
# params start, fixnum, optional
|
844
|
+
# params start, fixnum, optional
|
815
845
|
# params limit, fixnum, optional
|
816
846
|
control do
|
817
847
|
res = select_index(:SshKeyPair, {:start => params[:start],
|
@@ -819,53 +849,52 @@ module Dcmgr
|
|
819
849
|
response_to(res)
|
820
850
|
end
|
821
851
|
end
|
822
|
-
|
852
|
+
|
823
853
|
operation :show do
|
824
854
|
description "Retrieve details about ssh key pair"
|
825
855
|
# params :id required
|
826
856
|
# params :format optional [openssh,putty]
|
827
857
|
control do
|
828
858
|
ssh = find_by_uuid(:SshKeyPair, params[:id])
|
829
|
-
|
859
|
+
|
830
860
|
response_to(ssh.to_api_document)
|
831
861
|
end
|
832
862
|
end
|
833
|
-
|
863
|
+
|
834
864
|
operation :create do
|
835
865
|
description "Create ssh key pair information"
|
836
|
-
# params :name required key name (<100 chars)
|
837
866
|
# params :download_once optional set true if you do not want
|
838
867
|
# to save private key info on database.
|
839
868
|
control do
|
840
869
|
Models::SshKeyPair.lock!
|
841
|
-
keydata =
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
870
|
+
keydata = nil
|
871
|
+
|
872
|
+
ssh = Models::SshKeyPair.entry_new(@account) do |s|
|
873
|
+
keydata = Models::SshKeyPair.generate_key_pair(s.uuid)
|
874
|
+
s.public_key = keydata[:public_key]
|
875
|
+
s.finger_print = keydata[:finger_print]
|
876
|
+
|
877
|
+
if params[:download_once] != 'true'
|
878
|
+
s.private_key = keydata[:private_key]
|
879
|
+
end
|
880
|
+
|
881
|
+
if params[:description]
|
882
|
+
s.description = params[:description]
|
883
|
+
end
|
855
884
|
end
|
856
|
-
|
885
|
+
|
857
886
|
begin
|
858
|
-
ssh
|
887
|
+
ssh.save
|
859
888
|
rescue => e
|
860
889
|
raise DatabaseError, e.message
|
861
890
|
end
|
862
|
-
|
891
|
+
|
863
892
|
# include private_key data in response even if
|
864
893
|
# it's not going to be stored on DB.
|
865
894
|
response_to(ssh.to_api_document.merge(:private_key=>keydata[:private_key]))
|
866
895
|
end
|
867
896
|
end
|
868
|
-
|
897
|
+
|
869
898
|
operation :destroy do
|
870
899
|
description "Remove ssh key pair information"
|
871
900
|
# params :id required
|
@@ -877,18 +906,33 @@ module Dcmgr
|
|
877
906
|
else
|
878
907
|
raise OperationNotPermitted
|
879
908
|
end
|
880
|
-
|
909
|
+
|
881
910
|
response_to([ssh.canonical_uuid])
|
882
911
|
end
|
883
912
|
end
|
884
913
|
|
914
|
+
operation :update do
|
915
|
+
description "Update ssh key pair information"
|
916
|
+
control do
|
917
|
+
Models::SshKeyPair.lock!
|
918
|
+
ssh = find_by_uuid(:SshKeyPair, params[:id])
|
919
|
+
if examine_owner(ssh)
|
920
|
+
ssh.description = params[:description]
|
921
|
+
ssh.save_changes
|
922
|
+
else
|
923
|
+
raise OperationNotPermitted
|
924
|
+
end
|
925
|
+
|
926
|
+
response_to([ssh.canonical_uuid])
|
927
|
+
end
|
928
|
+
end
|
885
929
|
end
|
886
930
|
|
887
931
|
collection :networks do
|
888
932
|
description "Networks for account"
|
889
933
|
operation :index do
|
890
934
|
description "List networks in account"
|
891
|
-
# params start, fixnum, optional
|
935
|
+
# params start, fixnum, optional
|
892
936
|
# params limit, fixnum, optional
|
893
937
|
control do
|
894
938
|
res = select_index(:Network, {:start => params[:start],
|
@@ -896,18 +940,18 @@ module Dcmgr
|
|
896
940
|
response_to(res)
|
897
941
|
end
|
898
942
|
end
|
899
|
-
|
943
|
+
|
900
944
|
operation :show do
|
901
945
|
description "Retrieve details about a network"
|
902
946
|
# params :id required
|
903
947
|
control do
|
904
948
|
nw = find_by_uuid(:Network, params[:id])
|
905
949
|
examine_owner(nw) || raise(OperationNotPermitted)
|
906
|
-
|
950
|
+
|
907
951
|
response_to(nw.to_api_document)
|
908
952
|
end
|
909
953
|
end
|
910
|
-
|
954
|
+
|
911
955
|
operation :create do
|
912
956
|
description "Create new network"
|
913
957
|
# params :gw required default gateway address of the network
|
@@ -923,11 +967,11 @@ module Dcmgr
|
|
923
967
|
:description => params[:description],
|
924
968
|
}
|
925
969
|
nw = Models::Network.create(savedata)
|
926
|
-
|
970
|
+
|
927
971
|
response_to(nw.to_api_document)
|
928
972
|
end
|
929
973
|
end
|
930
|
-
|
974
|
+
|
931
975
|
operation :destroy do
|
932
976
|
description "Remove network information"
|
933
977
|
# params :id required
|
@@ -936,7 +980,7 @@ module Dcmgr
|
|
936
980
|
nw = find_by_uuid(:Network, params[:id])
|
937
981
|
examine_owner(nw) || raise(OperationNotPermitted)
|
938
982
|
nw.destroy
|
939
|
-
|
983
|
+
|
940
984
|
response_to([nw.canonical_uuid])
|
941
985
|
end
|
942
986
|
end
|
@@ -984,7 +1028,7 @@ module Dcmgr
|
|
984
1028
|
response_to({})
|
985
1029
|
end
|
986
1030
|
end
|
987
|
-
|
1031
|
+
|
988
1032
|
operation :del_pool, :method=>:put, :member=>true do
|
989
1033
|
description 'Unlabel network pool name'
|
990
1034
|
# param :name required
|
@@ -992,12 +1036,12 @@ module Dcmgr
|
|
992
1036
|
Models::Tag.lock!
|
993
1037
|
nw = find_by_uuid(:Network, params[:id])
|
994
1038
|
examine_owner(nw) || raise(OperationNotPermitted)
|
995
|
-
|
1039
|
+
|
996
1040
|
nw.unlabel_tag(:NetworkPool, params[:name], @account.canonical_uuid)
|
997
1041
|
response_to({})
|
998
1042
|
end
|
999
1043
|
end
|
1000
|
-
|
1044
|
+
|
1001
1045
|
operation :get_pool, :method=>:get, :member=>true do
|
1002
1046
|
description 'List network pool name'
|
1003
1047
|
# param :name required
|
@@ -1015,7 +1059,7 @@ module Dcmgr
|
|
1015
1059
|
collection :instance_specs do
|
1016
1060
|
operation :index do
|
1017
1061
|
description 'Show list of instance template'
|
1018
|
-
# params start, fixnum, optional
|
1062
|
+
# params start, fixnum, optional
|
1019
1063
|
# params limit, fixnum, optional
|
1020
1064
|
control do
|
1021
1065
|
res = select_index(:InstanceSpec, {:start => params[:start],
|
@@ -1023,8 +1067,16 @@ module Dcmgr
|
|
1023
1067
|
response_to(res)
|
1024
1068
|
end
|
1025
1069
|
end
|
1070
|
+
|
1071
|
+
operation :show do
|
1072
|
+
description "Show the instance template"
|
1073
|
+
# params :id required
|
1074
|
+
control do
|
1075
|
+
inst_spec = find_by_uuid(:InstanceSpec, params[:id])
|
1076
|
+
response_to(inst_spec.to_api_document)
|
1077
|
+
end
|
1078
|
+
end
|
1026
1079
|
end
|
1027
|
-
|
1028
1080
|
end
|
1029
1081
|
end
|
1030
1082
|
end
|