wakame-vdc-agents 10.11.0 → 10.12.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/nsa CHANGED
@@ -14,7 +14,7 @@ end
14
14
 
15
15
  require File.expand_path('../../config/path_resolver', __FILE__)
16
16
 
17
-
17
+ require 'erb'
18
18
  require 'eventmachine'
19
19
 
20
20
  class SuperviseDnsmasq < Isono::NodeModules::Base
@@ -29,8 +29,22 @@ class SuperviseDnsmasq < Isono::NodeModules::Base
29
29
  if manifest.config.network_name.nil?
30
30
  abort("network_name is not set yet in nsa.conf")
31
31
  end
32
+
33
+ # check the dnsmasq binary version
34
+ @conf_ver_253 = false
35
+ if `#{manifest.config.dnsmasq_bin_path} -version`.split("\n").first =~ /Dnsmasq version ([\d\.]+)/
36
+ verstr = $1.split('.')
37
+ if verstr[0].to_i == 2 && verstr[1].to_i >= 53
38
+ @conf_ver_253 = true
39
+ end
40
+ logger.info("Using dnsmasq v#{verstr}: configuration version #{@conf_ver_253 ? '>= 2.53' : '< 2.53'}")
41
+ else
42
+ logger.warn("Failed to detect dnsmasq binary version")
43
+ end
44
+
32
45
 
33
- opts = sprintf("-k --no-hosts --no-resolv --addn-hosts=%s --dhcp-hostsfile=%s --conf-file=%s",
46
+ opts = sprintf("-k --no-hosts --no-resolv --leasefile-ro --dhcp-leasefile=/dev/null " +
47
+ "--addn-hosts=%s --dhcp-hostsfile=%s --conf-file=%s",
34
48
  config_section.dhcp_hosts_conf + ".hosts",
35
49
  config_section.dhcp_hosts_conf + ".dhcp",
36
50
  config_section.dhcp_hosts_conf
@@ -85,42 +99,58 @@ class SuperviseDnsmasq < Isono::NodeModules::Base
85
99
  # load entier macaddr,ipaddr pairs for all instances from collector.
86
100
  confdata = rpc.request('hva-collector', 'get_dhcp_conf', manifest.config.network_name)
87
101
 
88
- require 'erb'
89
-
90
- File.open(config_section.dhcp_hosts_conf, 'w') { |f|
91
- f << ERB.new(<<'_EOS_', nil, '-').result(binding)
92
- #interface=eth0
102
+ render_conf(config_section.dhcp_hosts_conf, binding, <<'_EOS_')
93
103
  server=8.8.8.8
94
- dhcp-range=<%= confdata[:ipv4_gw] %>,static,<%= confdata[:netmask] %>
95
- dhcp-option=option:netmask,<%= confdata[:netmask] %>
96
- dhcp-option=option:router,<%= confdata[:ipv4_gw] %>
97
- dhcp-option=option:dns-server,<%= confdata[:dns_server] %>
98
- dhcp-option=option:domain-name,<%= confdata[:domain_name] %>
99
- #dhcp-option=option:domain-search,<%= confdata[:domain_name] %>
100
- <%- confdata[:mac2addr].each { |i| -%>
101
- #dhcp-host=<%= i[:mac_addr] %>,<%= i[:ipaddr] %>
104
+ log-facility=/var/log/dnsmasq.log
105
+ #log-queries
106
+ log-dhcp
107
+ <%- confdata.each { |nwid, v| -%>
108
+ <%- if @conf_ver_253 -%>
109
+ dhcp-range=set:<%= nwid %>,<%= v[:ipv4_first] %>,static,<%= v[:netmask] %>
110
+ dhcp-option=tag:<%= nwid %>,option:netmask,<%= v[:netmask] %>
111
+ dhcp-option=tag:<%= nwid %>,option:router,<%= v[:ipv4_gw] %>
112
+ dhcp-option=tag:<%= nwid %>,option:dns-server,<%= v[:dns_server] %>
113
+ dhcp-option=tag:<%= nwid %>,option:domain-name,<%= v[:domain_name] %>
114
+ #dhcp-option=tag:<%= nwid %>,option:domain-search,<%= v[:domain_name] %>
115
+ <%- else # if @conf_ver_253 -%>
116
+ dhcp-range=net:<%= nwid %>,<%= v[:ipv4_first] %>,static,<%= v[:netmask] %>
117
+ dhcp-option=<%= nwid %>,option:netmask,<%= v[:netmask] %>
118
+ dhcp-option=<%= nwid %>,option:router,<%= v[:ipv4_gw] %>
119
+ dhcp-option=<%= nwid %>,option:dns-server,<%= v[:dns_server] %>
120
+ dhcp-option=<%= nwid %>,option:domain-name,<%= v[:domain_name] %>
121
+ #dhcp-option=<%= nwid %>,option:domain-search,<%= v[:domain_name] %>
122
+ <%- end # if @conf_ver_253 -%>
123
+ <%- v[:mac2addr].each { |i| -%>
124
+ #dhcp-host=<%= i[:mac_addr] %>,net:<%= nwid %>,<%= i[:ipaddr] %>
102
125
  <%- } -%>
103
- <%- confdata[:addr2host].each { |i| -%>
126
+ <%- v[:addr2host].each { |i| -%>
104
127
  #address=/<%= i[:hostname] %>/<%= i[:ipaddr] %>
105
128
  <%- } -%>
129
+ <%- } -%>
106
130
  _EOS_
107
- }
108
131
 
109
- File.open(config_section.dhcp_hosts_conf + ".dhcp", 'w') { |f|
110
- f << ERB.new(<<'_EOS_', nil, '-').result(binding)
111
- <%- confdata[:mac2addr].each { |i| -%>
112
- <%= i[:mac_addr] %>,<%= i[:ipaddr] %>
132
+ render_conf(config_section.dhcp_hosts_conf + ".dhcp", binding, <<'_EOS_')
133
+ <%- confdata.each { |nwid, v| -%>
134
+ <%- v[:mac2addr].each { |i| -%>
135
+ <%= i[:mac_addr] %>,net:<%= nwid %>,<%= i[:ipaddr] %>,infinite
136
+ <%- } -%>
113
137
  <%- } -%>
114
138
  _EOS_
115
- }
116
139
 
117
- File.open(config_section.dhcp_hosts_conf + ".hosts", 'w') { |f|
118
- f << ERB.new(<<'_EOS_', nil, '-').result(binding)
119
- <%- confdata[:addr2host].each { |i| -%>
140
+ render_conf(config_section.dhcp_hosts_conf + ".hosts", binding, <<'_EOS_')
141
+ <%- confdata.each { |nwid, v| -%>
142
+ <%- v[:addr2host].each { |i| -%>
120
143
  <%= i[:ipaddr] %> <%= i[:hostname] %>
144
+ <%- } -%>
121
145
  <%- } -%>
122
146
  _EOS_
123
- }
147
+ end
148
+
149
+ private
150
+ def render_conf(file, bind, templ)
151
+ File.open(file, 'w') { |f|
152
+ f << ERB.new(templ, nil, '-').result(bind)
153
+ }
124
154
  end
125
155
  end
126
156
 
data/bin/sta CHANGED
@@ -19,9 +19,13 @@ class ZfsHandler < EndpointBuilder
19
19
  volume_id = request.args[0]
20
20
  job = Dcmgr::Stm::VolumeContext.new(volume_id)
21
21
  data = rpc.request('sta-collector', 'get_volume', volume_id)
22
- sdata = rpc.request('sta-collector', 'get_snapshot', data[:snapshot_id]) unless data[:snapshot_id].nil?
23
- logger.info("creating new volume #{volume_id}")
24
22
  raise "Invalid volume state: #{data[:state]}" unless data[:state].to_s == 'registering'
23
+
24
+ unless data[:snapshot_id].nil?
25
+ sdata = rpc.request('sta-collector', 'get_snapshot', data[:snapshot_id])
26
+ raise "Invalid snapshot state: #{sdata[:state]}" unless sdata[:state].to_s == 'available'
27
+ end
28
+ logger.info("creating new volume #{volume_id}")
25
29
  job.stm.state=data[:state].to_sym
26
30
  job.stm.on_create
27
31
 
@@ -119,6 +123,7 @@ class ZfsHandler < EndpointBuilder
119
123
  sdata = rpc.request('sta-collector', 'get_snapshot', snapshot_id) unless snapshot_id.nil?
120
124
  data = rpc.request('sta-collector', 'get_volume', sdata[:origin_volume_id])
121
125
  logger.info("create new snapshot: #{snapshot_id}")
126
+ raise "Invalid volume state: #{data[:state]}" unless data[:state].to_s == 'available'
122
127
  job.stm.state=sdata[:state].to_sym
123
128
  job.stm.on_create
124
129
 
@@ -144,14 +149,16 @@ class ZfsHandler < EndpointBuilder
144
149
  job :delete_snapshot do
145
150
  snapshot_id = request.args[0]
146
151
  job = Dcmgr::Stm::SnapshotContext.new(snapshot_id)
147
- sdata = rpc.request('sta-collector', 'get_snapshot', snapshot_id) unless snapshot_id.nil?
152
+ sdata = rpc.request('sta-collector', 'get_snapshot', snapshot_id)
148
153
  data = rpc.request('sta-collector', 'get_volume', sdata[:origin_volume_id])
149
154
  logger.info("deleting snapshot: #{snapshot_id}")
150
155
  raise "Invalid snapshot state: #{sdata[:state]}" unless sdata[:state].to_s == 'deleting'
151
156
  job.stm.state=sdata[:state].to_sym
152
157
  job.stm.on_delete
153
158
 
154
- snap_delete = `rm -rf #{data[:storage_pool][:snapshot_base_path]}/#{sdata[:account_id]}/#{sdata[:uuid]}.zsnap`
159
+ system("rm -rf #{data[:storage_pool][:snapshot_base_path]}/#{sdata[:account_id]}/#{sdata[:uuid]}.zsnap")
160
+ raise "snapshot has not be deleted" if $?.exitstatus != 0
161
+
155
162
  rpc.request('sta-collector', 'update_snapshot', job.to_hash)
156
163
  logger.info("deleted snapshot: #{snapshot_id}")
157
164
  end
@@ -8,3 +8,12 @@ config.vm_data_dir = "/home/demo/vm"
8
8
  # netfilter
9
9
  config.enable_ebtables = true
10
10
  config.enable_iptables = true
11
+
12
+ # physical nic index
13
+ config.hv_ifindex = 2 # ex. /sys/class/net/eth0/ifindex => 2
14
+
15
+ # bridge device name prefix
16
+ config.bridge_prefix = 'br'
17
+
18
+ # bridge device name novlan
19
+ config.bridge_novlan = 'br0'
@@ -5,5 +5,5 @@
5
5
  # path for dnsmaq binary
6
6
  config.dnsmasq_bin_path='/usr/sbin/dnsmasq'
7
7
 
8
- # network name to distribute dhcp/dns managed by this nsa
9
- config.network_name='network1'
8
+ # UUID of Network or NetworkPool to be delivered DHCP.
9
+ config.network_name='tag-xxxxxx'
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module Dcmgr
4
- VERSION='10.11.0'
4
+ VERSION='10.12.0'
5
5
 
6
6
  class << self
7
7
  def conf
@@ -73,7 +73,9 @@ module Dcmgr
73
73
  :StoragePool,:Volume,:VolumeSnapshot,
74
74
  :InstanceNetfilterGroup,
75
75
  :InstanceSpec, :InstanceNic, :Network, :IpLease,
76
- :SshKeyPair].freeze
76
+ :SshKeyPair, :History, :HostnameLease, :MacLease,
77
+ :VlanLease,
78
+ ].freeze
77
79
  autoload :BaseNew, 'dcmgr/models/base_new'
78
80
  autoload :Account, 'dcmgr/models/account'
79
81
  autoload :Tag, 'dcmgr/models/tag'
@@ -95,6 +97,10 @@ module Dcmgr
95
97
  autoload :IpLease, 'dcmgr/models/ip_lease'
96
98
  autoload :InstanceNetfilterGroup, 'dcmgr/models/instance_netfilter_group'
97
99
  autoload :SshKeyPair, 'dcmgr/models/ssh_key_pair'
100
+ autoload :History, 'dcmgr/models/history'
101
+ autoload :HostnameLease, 'dcmgr/models/hostname_lease'
102
+ autoload :MacLease, 'dcmgr/models/mac_lease'
103
+ autoload :VlanLease, 'dcmgr/models/vlan_lease'
98
104
  end
99
105
 
100
106
  module Endpoints
@@ -105,6 +111,7 @@ module Dcmgr
105
111
  module NodeModules
106
112
  autoload :StaCollector, 'dcmgr/node_modules/sta_collector'
107
113
  autoload :HvaCollector, 'dcmgr/node_modules/hva_collector'
114
+ autoload :InstanceHA, 'dcmgr/node_modules/instance_ha'
108
115
  end
109
116
 
110
117
  module Stm
@@ -112,4 +119,10 @@ module Dcmgr
112
119
  autoload :SnapshotContext, 'dcmgr/stm/snapshot_context'
113
120
  autoload :Instance, 'dcmgr/stm/instance'
114
121
  end
122
+
123
+ module Helpers
124
+ autoload :CliHelper, 'dcmgr/helpers/cli_helper'
125
+ end
126
+
127
+ autoload :Tags, 'dcmgr/tags'
115
128
  end
@@ -110,6 +110,7 @@ module Dcmgr
110
110
  def create_volume_from_snapshot(account_id, snapshot_id)
111
111
  vs = find_by_uuid(:VolumeSnapshot, snapshot_id)
112
112
  raise UnknownVolumeSnapshot if vs.nil?
113
+ raise InvalidRequestCredentials unless vs.state.to_s == 'available'
113
114
  vs.create_volume(account_id)
114
115
  end
115
116
 
@@ -131,9 +132,7 @@ module Dcmgr
131
132
  operation :show do
132
133
  control do
133
134
  a = find_account(params[:id])
134
- respond_to { |f|
135
- f.json { a.to_hash_document.to_json }
136
- }
135
+ response_to(a.to_hash)
137
136
  end
138
137
  end
139
138
 
@@ -141,9 +140,7 @@ module Dcmgr
141
140
  description 'Register a new account'
142
141
  control do
143
142
  a = Models::Account.create()
144
- respond_to { |f|
145
- f.json { a.to_hash_document.to_json }
146
- }
143
+ response_to(a.to_hash)
147
144
  end
148
145
  end
149
146
 
@@ -156,9 +153,7 @@ module Dcmgr
156
153
  a = find_account(params[:id])
157
154
  a.destroy
158
155
 
159
- respond_to { |f|
160
- f.json { {} }
161
- }
156
+ response_to([a.canonical_uuid])
162
157
  end
163
158
  end
164
159
 
@@ -271,9 +266,7 @@ module Dcmgr
271
266
  :results=> partial_ds.all.map {|i| i.to_api_document }
272
267
  }]
273
268
 
274
- respond_to { |f|
275
- f.json {res.to_json}
276
- }
269
+ response_to(res)
277
270
  end
278
271
  end
279
272
 
@@ -281,30 +274,94 @@ module Dcmgr
281
274
  description 'Runs a new VM instance'
282
275
  # param :image_id, string, :required
283
276
  # param :instance_spec_id, string, :required
284
- # param :host_pool_id, string, :optional
277
+ # param :host_id, string, :optional
285
278
  # param :host_name, string, :optional
286
279
  # param :user_data, string, :optional
287
280
  # param :nf_group, array, :optional
288
281
  # param :ssh_key, string, :optional
282
+ # param :network_id, string, :optional
283
+ # param :ha_enabled, string, :optional
289
284
  control do
290
285
  Models::Instance.lock!
291
286
 
292
287
  wmi = find_by_uuid(:Image, params[:image_id])
293
288
  spec = find_by_uuid(:InstanceSpec, (params[:instance_spec_id] || 'is-kpf0pasc'))
294
289
 
295
- if params[:host_pool_id]
296
- hp = Models::HostPool[params[:host_pool_id]]
297
- raise OutOfHostCapacity unless hp.check_capacity(spec)
290
+ # look up params[:host_id] in following order:
291
+ # 1. assume the host pool name.
292
+ # 2. assume hp-xxxxx or tag-xxxxx style uuid
293
+ # 3. assign default shared host pool.
294
+ params[:host_id] ||= params[:host_pool_id]
295
+ hostnode = pool = nil
296
+ if params[:host_id]
297
+ # TODO: smart way to preload model libs.
298
+ Models::HostPool; Tags::HostPool;
299
+ if pool = Tags::HostPool.find(:account_id=>@account.canonical_uuid,
300
+ :name=>params[:host_id])
301
+ # Pattern 1st
302
+ elsif hostnode = Models::Taggable.find(params[:host_id])
303
+ # Pattern 2nd
304
+ case hostnode
305
+ when Models::HostPool
306
+ when Tags::HostPool
307
+ hostnode = hostnode.pick(spec)
308
+ else
309
+ raise UnknownHostPool, "Could not find the host: #{params[:host_id]}"
310
+ end
311
+ end
298
312
  else
299
- # TODO: schedule a host pool owned by SharedPool account.
313
+ # Pattern 3rd
314
+ pool = Tags::HostPool[Dcmgr.conf.default_shared_host_pool]
315
+ hostnode = pool.pick(spec)
300
316
  end
301
-
302
- raise UnknownHostPool, "Could not find host pool: #{params[:host_pool_id]}" if hp.nil?
317
+ raise UnknownHostPool, "Could not find host pool: #{params[:host_id]}" if hostnode.nil?
318
+ raise OutOfHostCapacity unless hostnode.check_capacity(spec)
319
+
320
+ # look up params[:network_id] in following order:
321
+ # 1. assume the network pool name.
322
+ # 2. assume nw-xxxxx or tag-xxxxx style uuid
323
+ # 3. assign default shared network pool.
324
+ # then randomly choose one network from the pool object.
325
+ network = pool = nil
326
+ if params[:network_id]
327
+ # TODO: smart way to preload model libs.
328
+ Models::Network; Tags::NetworkPool;
329
+ if pool = Tags::NetworkPool.find(:account_id=>@account.canonical_uuid,
330
+ :name=>params[:network_id])
331
+ # Pattern 1st
332
+ network = pool.pick
333
+ elsif network = Models::Taggable.find(params[:network_id])
334
+ # Pattern 2nd
335
+ case network
336
+ when Models::Network
337
+ when Tags::NetworkPool
338
+ network = network.pick
339
+ else
340
+ raise "Unknown network uuid: #{params[:network_id]}"
341
+ end
342
+ end
343
+ else
344
+ # Pattern 3rd
345
+ pool = Tags::NetworkPool[Dcmgr.conf.default_shared_network_pool]
346
+ network = pool.pick
347
+ end
348
+ raise "Can not find the network" if network.nil?
349
+ raise "Out of IP addresses in the network" unless network.available_ip_nums > 0
303
350
 
304
- inst = hp.create_instance(@account, wmi, spec) do |i|
351
+ inst = hostnode.create_instance(@account, wmi, spec, network) do |i|
305
352
  # TODO: do not use rand() to decide vnc port.
306
353
  i.runtime_config = {:vnc_port=>rand(2000), :telnet_port=> (rand(2000) + 2000)}
307
354
  i.user_data = params[:user_data] || ''
355
+ # set only when not nil as the table column has not null
356
+ # condition.
357
+ if params[:hostname]
358
+ if Models::Instance::ValidationMethods.hostname_uniqueness(@account.canonical_uuid,
359
+ params[:hostname])
360
+ i.hostname = params[:hostname]
361
+ else
362
+ raise DuplicateHostname
363
+ end
364
+ end
308
365
 
309
366
  if params[:ssh_key]
310
367
  ssh_key_pair = Models::SshKeyPair.find(:account_id=>@account.canonical_uuid,
@@ -315,6 +372,10 @@ module Dcmgr
315
372
  i.ssh_key_pair_id = ssh_key_pair.canonical_uuid
316
373
  end
317
374
  end
375
+
376
+ if params[:ha_enabled] == 'true'
377
+ i.ha_enabled = 1
378
+ end
318
379
  end
319
380
 
320
381
  unless params[:nf_group].is_a?(Array)
@@ -328,17 +389,17 @@ module Dcmgr
328
389
  snapshot_id = wmi.source[:snapshot_id]
329
390
  vol = create_volume_from_snapshot(@account.canonical_uuid, snapshot_id)
330
391
 
392
+ vol.boot_dev = 1
331
393
  vol.instance = inst
332
394
  vol.save
333
- res = Dcmgr.messaging.submit("kvm-handle.#{hp.node_id}", 'run_vol_store', inst.canonical_uuid, vol.canonical_uuid)
395
+ res = Dcmgr.messaging.submit("kvm-handle.#{hostnode.node_id}", 'run_vol_store', inst.canonical_uuid, vol.canonical_uuid)
334
396
  when Models::Image::BOOT_DEV_LOCAL
335
- res = Dcmgr.messaging.submit("kvm-handle.#{hp.node_id}", 'run_local_store', inst.canonical_uuid)
397
+ res = Dcmgr.messaging.submit("kvm-handle.#{hostnode.node_id}", 'run_local_store', inst.canonical_uuid)
336
398
  else
337
399
  raise "Unknown boot type"
338
400
  end
339
- respond_to { |f|
340
- f.json { inst.to_api_document.to_json }
341
- }
401
+
402
+ response_to(inst.to_api_document)
342
403
  end
343
404
  end
344
405
 
@@ -348,9 +409,7 @@ module Dcmgr
348
409
  i = find_by_uuid(:Instance, params[:id])
349
410
  raise UnknownInstance if i.nil?
350
411
 
351
- respond_to { |f|
352
- f.json { i.to_api_document.to_json }
353
- }
412
+ response_to(i.to_api_document)
354
413
  end
355
414
  end
356
415
 
@@ -364,9 +423,7 @@ module Dcmgr
364
423
  raise OperationNotPermitted
365
424
  end
366
425
  res = Dcmgr.messaging.submit("kvm-handle.#{i.host_pool.node_id}", 'terminate', i.canonical_uuid)
367
- respond_to { |f|
368
- f.json { i.canonical_uuid }
369
- }
426
+ response_to([i.canonical_uuid])
370
427
  end
371
428
  end
372
429
 
@@ -407,9 +464,7 @@ module Dcmgr
407
464
  :results=> partial_ds.all.map {|i| i.to_hash }
408
465
  }]
409
466
 
410
- respond_to { |f|
411
- f.json {res.to_json}
412
- }
467
+ response_to(res)
413
468
  end
414
469
  end
415
470
 
@@ -421,9 +476,7 @@ module Dcmgr
421
476
  unless examine_owner(i)
422
477
  raise OperationNotPermitted
423
478
  end
424
- respond_to { |f|
425
- f.json { i.to_hash.to_json }
426
- }
479
+ response_to(i.to_hash)
427
480
  end
428
481
  end
429
482
 
@@ -437,6 +490,7 @@ module Dcmgr
437
490
  else
438
491
  raise OperationNotPermitted
439
492
  end
493
+ response_to([i.canonical_uuid])
440
494
  end
441
495
  end
442
496
  end
@@ -461,9 +515,7 @@ module Dcmgr
461
515
  :results=> partial_ds.all.map {|i| i.to_hash }
462
516
  }]
463
517
 
464
- respond_to { |f|
465
- f.json {res.to_json}
466
- }
518
+ response_to(res)
467
519
  end
468
520
  end
469
521
 
@@ -474,9 +526,7 @@ module Dcmgr
474
526
  hp = find_by_uuid(:HostPool, params[:id])
475
527
  raise OperationNotPermitted unless examine_owner(hp)
476
528
 
477
- respond_to { |f|
478
- f.json { hp.to_hash.to_json }
479
- }
529
+ response_to(hp.to_hash)
480
530
  end
481
531
  end
482
532
  end
@@ -499,11 +549,9 @@ module Dcmgr
499
549
  :owner_total => total_v.count,
500
550
  :start => start,
501
551
  :limit => limit,
502
- :results => partial_v.all.map { |v| v.to_hash_document}
552
+ :results => partial_v.all.map { |v| v.to_api_document}
503
553
  }]
504
- respond_to { |f|
505
- f.json { res.to_json}
506
- }
554
+ response_to(res)
507
555
  end
508
556
  end
509
557
 
@@ -514,9 +562,7 @@ module Dcmgr
514
562
  volume_id = params[:id]
515
563
  raise UndefinedVolumeID if volume_id.nil?
516
564
  v = find_by_uuid(:Volume, volume_id)
517
- respond_to { |f|
518
- f.json { v.to_hash_document.to_json}
519
- }
565
+ response_to(v.to_api_document)
520
566
  end
521
567
  end
522
568
 
@@ -531,8 +577,10 @@ module Dcmgr
531
577
  v = create_volume_from_snapshot(@account.canonical_uuid, params[:snapshot_id])
532
578
  sp = v.storage_pool
533
579
  elsif params[:volume_size]
534
- raise InvalidVolumeSize if !(Dcmgr.conf.create_volume_max_size.to_i >= params[:volume_size].to_i) || !(params[:volume_size\
535
- ].to_i >= Dcmgr.conf.create_volume_min_size.to_i)
580
+ if !(Dcmgr.conf.create_volume_max_size.to_i >= params[:volume_size].to_i) ||
581
+ !(params[:volume_size].to_i >= Dcmgr.conf.create_volume_min_size.to_i)
582
+ raise InvalidVolumeSize
583
+ end
536
584
  if params[:storage_pool_id]
537
585
  sp = find_by_uuid(:StoragePool, params[:storage_pool_id])
538
586
  raise StoragePoolNotPermitted if sp.account_id != @account.canonical_uuid
@@ -552,9 +600,7 @@ module Dcmgr
552
600
  end
553
601
 
554
602
  res = Dcmgr.messaging.submit("zfs-handle.#{sp.values[:node_id]}", 'create_volume', v.canonical_uuid)
555
- respond_to { |f|
556
- f.json { v.to_hash_document.to_json}
557
- }
603
+ response_to(v.to_api_document)
558
604
  end
559
605
  end
560
606
 
@@ -576,9 +622,7 @@ module Dcmgr
576
622
  sp = v.storage_pool
577
623
 
578
624
  res = Dcmgr.messaging.submit("zfs-handle.#{sp.values[:node_id]}", 'delete_volume', v.canonical_uuid)
579
- respond_to { |f|
580
- f.json { v.to_hash_document.to_json}
581
- }
625
+ response_to([v.canonical_uuid])
582
626
  end
583
627
  end
584
628
 
@@ -592,17 +636,17 @@ module Dcmgr
592
636
 
593
637
  i = find_by_uuid(:Instance, params[:instance_id])
594
638
  raise UnknownInstance if i.nil?
639
+ raise InvalidInstanceState unless i.live? && i.state == 'running'
595
640
 
596
641
  v = find_by_uuid(:Volume, params[:id])
597
642
  raise UnknownVolume if v.nil?
643
+ raise AttachVolumeFailure, "Volume is attached to running instance." if v.instance
598
644
 
599
645
  v.instance = i
600
646
  v.save
601
647
  res = Dcmgr.messaging.submit("kvm-handle.#{i.host_pool.node_id}", 'attach', i.canonical_uuid, v.canonical_uuid)
602
648
 
603
- respond_to { |f|
604
- f.json { v.to_hash_document.to_json}
605
- }
649
+ response_to(v.to_api_document)
606
650
  end
607
651
  end
608
652
 
@@ -614,11 +658,13 @@ module Dcmgr
614
658
 
615
659
  v = find_by_uuid(:Volume, params[:id])
616
660
  raise UnknownVolume if v.nil?
661
+ raise DetachVolumeFailure, "Volume is not attached to any instance." if v.instance.nil?
662
+ # the volume as the boot device can not be detached.
663
+ raise DetachVolumeFailure, "boot device can not be detached" if v.boot_dev == 1
617
664
  i = v.instance
665
+ raise InvalidInstanceState unless i.live? && i.state == 'running'
618
666
  res = Dcmgr.messaging.submit("kvm-handle.#{i.host_pool.node_id}", 'detach', i.canonical_uuid, v.canonical_uuid)
619
- respond_to { |f|
620
- f.json {v.to_hash_document.to_json}
621
- }
667
+ response_to(v.to_api_document)
622
668
  end
623
669
  end
624
670
 
@@ -655,11 +701,9 @@ module Dcmgr
655
701
  :owner_total => total_vs.count,
656
702
  :start => start,
657
703
  :limit => limit,
658
- :results => partial_vs.all.map { |vs| vs.to_hash_document}
704
+ :results => partial_vs.all.map { |vs| vs.to_api_document}
659
705
  }]
660
- respond_to { |f|
661
- f.json { res.to_json}
662
- }
706
+ response_to(res)
663
707
  end
664
708
  end
665
709
 
@@ -670,9 +714,7 @@ module Dcmgr
670
714
  snapshot_id = params[:id]
671
715
  raise UndefinedVolumeSnapshotID if snapshot_id.nil?
672
716
  vs = find_by_uuid(:VolumeSnapshot, snapshot_id)
673
- respond_to { |f|
674
- f.json { vs.to_hash_document.to_json}
675
- }
717
+ response_to(vs.to_api_document)
676
718
  end
677
719
  end
678
720
 
@@ -686,14 +728,13 @@ module Dcmgr
686
728
 
687
729
  v = find_by_uuid(:Volume, params[:volume_id])
688
730
  raise UnknownVolume if v.nil?
731
+ raise InvalidRequestCredentials unless v.state == "available"
689
732
 
690
733
  vs = v.create_snapshot(@account.canonical_uuid)
691
734
  sp = vs.storage_pool
692
735
 
693
736
  res = Dcmgr.messaging.submit("zfs-handle.#{sp.node_id}", 'create_snapshot', vs.canonical_uuid)
694
- respond_to { |f|
695
- f.json { vs.to_hash_document.to_json}
696
- }
737
+ response_to(vs.to_api_document)
697
738
  end
698
739
  end
699
740
 
@@ -705,15 +746,17 @@ module Dcmgr
705
746
  snapshot_id = params[:id]
706
747
  raise UndefindVolumeSnapshotID if snapshot_id.nil?
707
748
 
708
- vs = find_by_uuid(:VolumeSnapshot, snapshot_id)
749
+ begin
750
+ vs = Models::VolumeSnapshot.delete_snapshot(@account.canonical_uuid, snapshot_id)
751
+ rescue Models::VolumeSnapshot::RequestError => e
752
+ logger.error(e)
753
+ raise InvalidDeleteRequest
754
+ end
709
755
  raise UnknownVolumeSnapshot if vs.nil?
710
- vs = vs.delete_snapshot
711
756
  sp = vs.storage_pool
712
757
 
713
758
  res = Dcmgr.messaging.submit("zfs-handle.#{sp.node_id}", 'delete_snapshot', vs.canonical_uuid)
714
- respond_to { |f|
715
- f.json { vs.to_hash_document.to_json }
716
- }
759
+ response_to([vs.canonical_uuid])
717
760
  end
718
761
  end
719
762
 
@@ -752,9 +795,7 @@ module Dcmgr
752
795
  :results=> partial_ds.all.map {|i| i.to_hash }
753
796
  }]
754
797
 
755
- respond_to { |f|
756
- f.json {res.to_json}
757
- }
798
+ response_to(res)
758
799
  end
759
800
  end
760
801
 
@@ -762,12 +803,9 @@ module Dcmgr
762
803
  description 'Show the netfilter_groups'
763
804
  control do
764
805
  g = find_by_uuid(:NetfilterGroup, params[:id])
765
- p params[:id]
766
806
  raise OperationNotPermitted unless examine_owner(g)
767
807
 
768
- respond_to { |f|
769
- f.json { g.to_hash.to_json }
770
- }
808
+ response_to(g.to_hash)
771
809
  end
772
810
  end
773
811
 
@@ -788,9 +826,7 @@ module Dcmgr
788
826
  raise DuplicatedNetfilterGroup unless g.nil?
789
827
 
790
828
  g = Models::NetfilterGroup.create_group(@account.canonical_uuid, params)
791
- respond_to { |f|
792
- f.json { g.to_hash.to_json }
793
- }
829
+ response_to(g.to_hash)
794
830
  end
795
831
  end
796
832
 
@@ -816,9 +852,7 @@ module Dcmgr
816
852
  # refresh netfilter_rules
817
853
  Dcmgr.messaging.event_publish('hva/netfilter_updated', :args=>[g.canonical_uuid])
818
854
 
819
- respond_to { |f|
820
- f.json { g.to_hash.to_json }
821
- }
855
+ response_to(g.to_hash)
822
856
  end
823
857
  end
824
858
 
@@ -833,9 +867,8 @@ module Dcmgr
833
867
  raise UnknownNetfilterGroup if g.nil?
834
868
  raise NetfilterGroupNotPermitted if g.account_id != @account.canonical_uuid
835
869
 
836
- respond_to { |f|
837
- f.json { g.destroy_group.values.to_json }
838
- }
870
+ g.destroy
871
+ response_to([g.canonical_uuid])
839
872
  end
840
873
  end
841
874
 
@@ -861,9 +894,7 @@ module Dcmgr
861
894
  }
862
895
  end
863
896
 
864
- respond_to { |f|
865
- f.json { rules.to_json }
866
- }
897
+ response_to(rules)
867
898
  end
868
899
  end
869
900
  end
@@ -887,12 +918,10 @@ module Dcmgr
887
918
  :owner_total => total_ds.count,
888
919
  :start => start,
889
920
  :limit => limit,
890
- :results=> partial_ds.all.map {|sp| sp.to_hash_document }
921
+ :results=> partial_ds.all.map {|sp| sp.to_hash }
891
922
  }]
892
923
 
893
- respond_to { |f|
894
- f.json { res.to_json}
895
- }
924
+ response_to(res)
896
925
  end
897
926
  end
898
927
 
@@ -904,9 +933,7 @@ module Dcmgr
904
933
  raise UndefinedStoragePoolID if pool_id.nil?
905
934
  vs = find_by_uuid(:StoragePool, pool_id)
906
935
  raise UnknownStoragePool if vs.nil?
907
- respond_to { |f|
908
- f.json { vs.to_hash_document.to_json}
909
- }
936
+ response_to(vs.to_hash)
910
937
  end
911
938
  end
912
939
  end
@@ -934,9 +961,7 @@ module Dcmgr
934
961
  :results=> partial_ds.all.map {|i| i.to_hash }
935
962
  }]
936
963
 
937
- respond_to { |f|
938
- f.json {res.to_json}
939
- }
964
+ response_to(res)
940
965
  end
941
966
  end
942
967
 
@@ -947,9 +972,7 @@ module Dcmgr
947
972
  control do
948
973
  ssh = find_by_uuid(:SshKeyPair, params[:id])
949
974
 
950
- respond_to { |f|
951
- f.json {ssh.to_hash.to_json}
952
- }
975
+ response_to(ssh.to_hash)
953
976
  end
954
977
  end
955
978
 
@@ -971,11 +994,9 @@ module Dcmgr
971
994
  end
972
995
  ssh = Models::SshKeyPair.create(savedata)
973
996
 
974
- respond_to { |f|
975
- # include private_key data in response even if
976
- # it's not going to be stored on DB.
977
- f.json {ssh.to_hash.merge(:private_key=>keydata[:private_key]).to_json}
978
- }
997
+ # include private_key data in response even if
998
+ # it's not going to be stored on DB.
999
+ response_to(ssh.to_hash.merge(:private_key=>keydata[:private_key]))
979
1000
  end
980
1001
  end
981
1002
 
@@ -991,14 +1012,155 @@ module Dcmgr
991
1012
  raise OperationNotPermitted
992
1013
  end
993
1014
 
994
- respond_to { |f|
995
- f.json {ssh.to_hash.to_json}
996
- }
1015
+ response_to([ssh.canonical_uuid])
997
1016
  end
998
1017
  end
999
1018
 
1000
1019
  end
1001
1020
 
1021
+ collection :networks do
1022
+ description "Networks for account"
1023
+ operation :index do
1024
+ description "List networks in account"
1025
+ # params start, fixnum, optional
1026
+ # params limit, fixnum, optional
1027
+ control do
1028
+ start = params[:start].to_i
1029
+ start = start < 1 ? 0 : start
1030
+ limit = params[:limit].to_i
1031
+ limit = limit < 1 ? nil : limit
1032
+
1033
+ total_ds = Models::Network.where(:account_id=>@account.canonical_uuid)
1034
+ partial_ds = total_ds.dup.order(:id)
1035
+ partial_ds = partial_ds.limit(limit, start) if limit.is_a?(Integer)
1036
+
1037
+ res = [{
1038
+ :owner_total => total_ds.count,
1039
+ :filter_total => total_ds.count,
1040
+ :start => start,
1041
+ :limit => limit,
1042
+ :results=> partial_ds.all.map {|i| i.to_hash }
1043
+ }]
1044
+
1045
+ response_to(res)
1046
+ end
1047
+ end
1048
+
1049
+ operation :show do
1050
+ description "Retrieve details about a network"
1051
+ # params :id required
1052
+ control do
1053
+ nw = find_by_uuid(:Network, params[:id])
1054
+ examine_owner(nw) || raise(OperationNotPermitted)
1055
+
1056
+ response_to(nw.to_hash)
1057
+ end
1058
+ end
1059
+
1060
+ operation :create do
1061
+ description "Create new network"
1062
+ # params :gw required default gateway address of the network
1063
+ # params :prefix optional netmask bit length. it will be
1064
+ # set 24 if none.
1065
+ # params :description optional description for the network
1066
+ control do
1067
+ Models::Network.lock!
1068
+ savedata = {
1069
+ :account_id=>@account.canonical_uuid,
1070
+ :ipv4_gw => params[:gw],
1071
+ :prefix => params[:prefix].to_i,
1072
+ :description => params[:description],
1073
+ }
1074
+ nw = Models::Network.create(savedata)
1075
+
1076
+ response_to(nw.to_hash)
1077
+ end
1078
+ end
1079
+
1080
+ operation :destroy do
1081
+ description "Remove network information"
1082
+ # params :id required
1083
+ control do
1084
+ Models::Network.lock!
1085
+ nw = find_by_uuid(:Network, params[:id])
1086
+ examine_owner(nw) || raise(OperationNotPermitted)
1087
+ nw.destroy
1088
+
1089
+ response_to([nw.canonical_uuid])
1090
+ end
1091
+ end
1092
+
1093
+ operation :reserve, :method =>:put, :member=>true do
1094
+ description 'Register reserved IP address to the network'
1095
+ # params id, string, required
1096
+ # params ipaddr, [String,Array], required
1097
+ control do
1098
+ Models::IpLease.lock!
1099
+ nw = find_by_uuid(:Network, params[:id])
1100
+ examine_owner(nw) || raise(OperationNotPermitted)
1101
+
1102
+ (ipaddr.is_a?(Array) ? params[:ipaddr] : Array(params[:ipaddr])).each { |ip|
1103
+ nw.add_reserved(ip)
1104
+ }
1105
+ response_to({})
1106
+ end
1107
+ end
1108
+
1109
+ operation :release, :method =>:put, :member=>true do
1110
+ description 'Unregister reserved IP address from the network'
1111
+ # params id, string, required
1112
+ # params ipaddr, [String,Array], required
1113
+ control do
1114
+ Models::IpLease.lock!
1115
+ nw = find_by_uuid(:Network, params[:id])
1116
+ examine_owner(nw) || raise(OperationNotPermitted)
1117
+
1118
+ (ipaddr.is_a?(Array) ? params[:ipaddr] : Array(params[:ipaddr])).each { |ip|
1119
+ nw.delete_reserved(ip)
1120
+ }
1121
+ response_to({})
1122
+ end
1123
+ end
1124
+
1125
+ operation :add_pool, :method=>:put, :member=>true do
1126
+ description 'Label network pool name'
1127
+ # param :name required
1128
+ control do
1129
+ Models::Tag.lock!
1130
+ nw = find_by_uuid(:Network, params[:id])
1131
+ examine_owner(nw) || raise(OperationNotPermitted)
1132
+ nw.label_tag(:NetworkPool, params[:name], @account.canonical_uuid)
1133
+ response_to({})
1134
+ end
1135
+ end
1136
+
1137
+ operation :del_pool, :method=>:put, :member=>true do
1138
+ description 'Unlabel network pool name'
1139
+ # param :name required
1140
+ control do
1141
+ Models::Tag.lock!
1142
+ nw = find_by_uuid(:Network, params[:id])
1143
+ examine_owner(nw) || raise(OperationNotPermitted)
1144
+
1145
+ nw.unlabel_tag(:NetworkPool, params[:name], @account.canonical_uuid)
1146
+ response_to({})
1147
+ end
1148
+ end
1149
+
1150
+ operation :get_pool, :method=>:get, :member=>true do
1151
+ description 'List network pool name'
1152
+ # param :name required
1153
+ control do
1154
+ Models::Tag.lock!
1155
+ nw = find_by_uuid(:Network, params[:id])
1156
+ examine_owner(nw) || raise(OperationNotPermitted)
1157
+
1158
+ res = nw.tags_dataset.filter(:type_id=>Tags.type_id(:NetworkPool)).all.map{|i| i.to_api_document }
1159
+ response_to(res)
1160
+ end
1161
+ end
1162
+ end
1163
+
1002
1164
  end
1003
1165
  end
1004
1166
  end