1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-23 17:33:56 +03:00

Merge branch 'master' into f-3951

This commit is contained in:
Tino Vazquez 2021-01-21 10:42:59 +01:00
commit e08ad357f6
No known key found for this signature in database
GPG Key ID: 14201E424D02047E
22 changed files with 272 additions and 224 deletions

View File

@ -339,6 +339,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/im/kvm-probes.d/host/system \
$VAR_LOCATION/remotes/im/kvm-probes.d/vm/monitor \
$VAR_LOCATION/remotes/im/kvm-probes.d/vm/status \
$VAR_LOCATION/remotes/im/kvm-probes.d/vm/snapshot \
$VAR_LOCATION/remotes/im/dummy.d \
$VAR_LOCATION/remotes/im/dummy-probes.d/host/beacon \
$VAR_LOCATION/remotes/im/dummy-probes.d/host/monitor \
@ -571,6 +572,7 @@ INSTALL_FILES=(
IM_PROBES_KVM_HOST_SYSTEM_FILES:$VAR_LOCATION/remotes/im/kvm-probes.d/host/system
IM_PROBES_KVM_VM_MONITOR_FILES:$VAR_LOCATION/remotes/im/kvm-probes.d/vm/monitor
IM_PROBES_KVM_VM_STATUS_FILES:$VAR_LOCATION/remotes/im/kvm-probes.d/vm/status
IM_PROBES_KVM_VM_SNAPSHOT_FILES:$VAR_LOCATION/remotes/im/kvm-probes.d/vm/snapshot
IM_PROBES_ETC_KVM_PROBES_FILES:$VAR_LOCATION/remotes/etc/im/kvm-probes.d
IM_PROBES_DUMMY_HOST_BEACON_FILES:$VAR_LOCATION/remotes/im/dummy-probes.d/host/beacon
IM_PROBES_DUMMY_HOST_MONITOR_FILES:$VAR_LOCATION/remotes/im/dummy-probes.d/host/monitor
@ -1315,6 +1317,9 @@ IM_PROBES_KVM_VM_MONITOR_FILES="\
IM_PROBES_KVM_VM_STATUS_FILES="\
src/im_mad/remotes/kvm-probes.d/vm/status/state.rb"
IM_PROBES_KVM_VM_SNAPSHOT_FILES="\
src/im_mad/remotes/kvm-probes.d/vm/snapshot/recovery.rb"
IM_PROBES_ETC_KVM_PROBES_FILES="\
src/im_mad/remotes/kvm-probes.d/pci.conf \
src/im_mad/remotes/lib/probe_db.conf"

View File

@ -1071,6 +1071,9 @@ INHERIT_VNET_ATTR = "IP_LINK_CONF"
INHERIT_VNET_ATTR = "EXTERNAL"
INHERIT_VNET_ATTR = "AWS_ALLOCATION_ID"
INHERIT_VNET_ATTR = "GATEWAY"
INHERIT_VNET_ATTR = "VXLAN_MODE"
INHERIT_VNET_ATTR = "VXLAN_TEP"
INHERIT_VNET_ATTR = "VXLAN_MC"
INHERIT_VNET_ATTR = "VCENTER_NET_REF"
INHERIT_VNET_ATTR = "VCENTER_SWITCH_NAME"

View File

@ -19,6 +19,7 @@ networks:
- name: "${provision}-public"
vn_mad: 'elastic'
bridge: 'br0'
netrole: 'public'
provision:
count: "${input.number_public_ips}"
ar:
@ -32,4 +33,8 @@ vntemplates:
vn_mad: 'vxlan'
phydev: 'eth0'
automatic_vlan_id: 'yes'
netrole: 'private'
vxlan_mode: 'evpn'
vxlan_tep: 'dev'
ip_link_conf: 'nolearning='
cluster_ids: "${cluster.0.id}"

View File

@ -19,6 +19,7 @@ networks:
- name: "${provision}-public"
vn_mad: 'elastic'
bridge: 'br0'
netrole: 'public'
provision:
count: "${input.number_public_ips}"
ar:
@ -32,4 +33,8 @@ vntemplates:
vn_mad: 'vxlan'
phydev: 'bond0'
automatic_vlan_id: 'yes'
netrole: 'private'
vxlan_mode: 'evpn'
vxlan_tep: 'dev'
ip_link_conf: 'nolearning='
cluster_ids: "${cluster.0.id}"

View File

@ -19,20 +19,15 @@
ONE_LOCATION = ENV['ONE_LOCATION']
if !ONE_LOCATION
LIB_LOCATION = '/usr/lib/one'
RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
GEMS_LOCATION = '/usr/share/one/gems'
REMOTES_LOCATION = '/var/lib/one/remotes'
ANSIBLE_LOCATION = '/usr/share/one/oneprovision/ansible'
PROVIDERS_LOCATION = '/usr/lib/one/oneprovision/lib/terraform/providers'
LIB_LOCATION = '/usr/lib/one'
RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
GEMS_LOCATION = '/usr/share/one/gems'
REMOTES_LOCATION = '/var/lib/one/remotes'
else
LIB_LOCATION = ONE_LOCATION + '/lib'
RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
GEMS_LOCATION = ONE_LOCATION + '/share/gems'
REMOTES_LOCATION = ONE_LOCATION + '/var/remotes'
ANSIBLE_LOCATION = ONE_LOCATION + '/share/oneprovision/ansible'
PROVIDERS_LOCATION = ONE_LOCATION +
'/lib/oneprovision/lib/terraform/providers'
LIB_LOCATION = ONE_LOCATION + '/lib'
RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
GEMS_LOCATION = ONE_LOCATION + '/share/gems'
REMOTES_LOCATION = ONE_LOCATION + '/var/remotes'
end
if File.directory?(GEMS_LOCATION)

View File

@ -23,13 +23,11 @@ if !ONE_LOCATION
RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
GEMS_LOCATION = '/usr/share/one/gems'
REMOTES_LOCATION = '/var/lib/one/remotes'
ANSIBLE_LOCATION = '/usr/share/one/oneprovision/ansible'
else
LIB_LOCATION = ONE_LOCATION + '/lib'
RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
GEMS_LOCATION = ONE_LOCATION + '/share/gems'
REMOTES_LOCATION = ONE_LOCATION + '/var/remotes'
ANSIBLE_LOCATION = ONE_LOCATION + '/share/oneprovision/ansible'
end
if File.directory?(GEMS_LOCATION)

View File

@ -84,30 +84,38 @@ class HookManagerDriver < OpenNebulaDriver
end
def action_execute(_not_used, *arguments)
arg_xml = Nokogiri::XML(Base64.decode64(arguments.flatten[0]))
type = arg_xml.xpath('//HOOK_TYPE').text
begin
arg_xml = Nokogiri::XML(Base64.decode64(arguments.flatten[0]))
type = arg_xml.xpath('//HOOK_TYPE').text
key(type, arg_xml).each do |key|
m_key = "EVENT #{key}"
key(type, arg_xml).each do |key|
m_key = "EVENT #{key}"
# Using envelopes for splitting key/val
# http://zguide.zeromq.org/page:all#Pub-Sub-Message-Envelopes
@publisher.send_string m_key, ZMQ::SNDMORE
@publisher.send_string arguments.flatten[0]
# Using envelopes for splitting key/val
# http://zguide.zeromq.org/page:all#Pub-Sub-Message-Envelopes
send_string(@publisher, m_key, ZMQ::SNDMORE)
send_string(@publisher, arguments.flatten[0])
end
rescue StandardError => e
log(0, "ERROR: #{e.message}")
end
end
def action_retry(_not_used, *arguments)
arguments.flatten!
begin
arguments.flatten!
command = arguments[0]
params = arguments[1]
command = arguments[0]
params = arguments[1]
m_key = 'RETRY'
m_val = "#{command} #{params}"
m_key = 'RETRY'
m_val = "#{command} #{params}"
@publisher.send_string m_key, ZMQ::SNDMORE
@publisher.send_string m_val
send_string(@publisher, m_key, ZMQ::SNDMORE)
send_string(@publisher, m_val)
rescue StandardError => e
log(0, "ERROR: #{e.message}")
end
end
def receiver_thread
@ -133,8 +141,9 @@ class HookManagerDriver < OpenNebulaDriver
end
#---------------------------------------------------------------------------
# Helpers to build key and message values
# Helpers
#---------------------------------------------------------------------------
def key(type, xml)
case type.to_sym
when :API
@ -161,6 +170,22 @@ class HookManagerDriver < OpenNebulaDriver
end
end
def send_string(socket, content, flag = nil)
rc = 0
if flag.nil?
rc = socket.send_string(content)
else
rc = socket.send_string(content, flag)
end
return unless rc < 0
msg = "ERROR: failure sending string: #{ZMQ::Util.error_string}" \
" (#{ZMQ::Util.errno})"
log(0, msg)
end
end
#-------------------------------------------------------------------------------

View File

@ -213,6 +213,12 @@ begin
:path => 'vm/monitor'
},
:snapshot_vm_udp => {
:period => 60,
:elem_name => 'MONITOR_VM',
:path => 'vm/snapshot'
},
:beacon_host_udp => {
:period => config.elements['PROBES_PERIOD/BEACON_HOST'].text.to_s,
:path => 'host/beacon'

View File

@ -0,0 +1,99 @@
#!/usr/bin/env ruby
# -------------------------------------------------------------------------- #
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
require 'rexml/document'
require 'fileutils'
require 'open3'
require 'base64'
def xml_elem(xml, xpath)
rexml = REXML::Document.new(xml).root
rexml.elements[xpath].text.to_s
rescue StandardError
nil
end
ds_loc = xml_elem(STDIN.read, 'DATASTORE_LOCATION')
ds_loc ||= '/var/lib/one/datastores'
Dir.chdir ds_loc
datastores = Dir.glob('*').select do |f|
File.directory?(f) && f.match(/^\d+$/)
end
monitor_data = []
datastores.each do |ds|
# Skip if datastore is not ssh
mark = "#{ds_loc}/#{ds}/.monitor"
next unless File.exist? mark
driver = File.read mark
driver.chomp!
next unless driver == 'ssh'
# for all VMs
Dir.entries("#{ds_loc}/#{ds}").each do |vm_id|
vm_dir = "#{ds_loc}/#{ds}/#{vm_id}"
next if vm_id !~ /^\d+$/
next unless File.directory?(vm_dir)
disk_data = []
# for all disks
Dir.entries(vm_dir).each do |disk|
next if disk !~ /^disk.\d+$/
next unless File.file?("#{vm_dir}/#{disk}.snap/base.1")
next unless File.file?("#{vm_dir}/vm.xml")
next unless File.file?("#{vm_dir}/ds.xml")
disk_id = disk.split('.')[1]
replica = xml_elem(File.read("#{vm_dir}/ds.xml"),
'/DATASTORE/TEMPLATE/REPLICA_HOST')
freq = xml_elem(File.read("#{vm_dir}/vm.xml"),
"/VM/TEMPLATE/DISK[DISK_ID=#{disk_id}]/" <<
'RECOVERY_SNAPSHOT_FREQ')
rs_script = '/var/tmp/one/tm/ssh/recovery_snap_create_live'
next if freq.empty? || replica.empty? || !File.exist?(rs_script)
o, _e, s = Open3.capture3("#{rs_script} #{vm_id} " <<
"#{vm_dir}/#{disk} " <<
"#{freq} #{replica}")
o.chomp!
if s.exitstatus == 0
disk_data << \
'DISK_RECOVERY_SNAPSHOT = ' \
"[ ID=#{disk_id}, TIMESTAMP=#{o}]"
else
disk_data << \
'DISK_RECOVERY_SNAPSHOT = ' \
"[ ID=#{disk_id}, MSG=\"ERROR #{o}\"]"
end
end
next if disk_data.empty?
enc_data = Base64.strict_encode64(disk_data.join("\n"))
monitor_data << \
"VM = [ ID=\"#{vm_id}\" MONITOR = \"#{enc_data}\" ]"
end
end
puts monitor_data.join("\n")

View File

@ -16,4 +16,6 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
STDIN=`cat -`
exit 0

View File

@ -16,4 +16,6 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
STDIN=`cat -`
exit 0

View File

@ -16,4 +16,6 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
STDIN=`cat -`
exit 0

View File

@ -16,20 +16,6 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
###############################################################################
# This script is used to unregister a new IP network in the IPAM.
#
# STDIN input:
# - Base64 encoded XML with AR request
#
# XML format
# <IPAM_DRIVER_ACTION_DATA>
# <AR>
# <DEPLOY_ID>Packet AR ID</DEPLOY_ID>
# <PACKET_TOKEN>Packet auth token</PACKET_TOKEN>
# </AR>
# </IPAM_DRIVER_ACTION_DATA>
#
################################################################################
STDIN=`cat -`
exit 0

View File

@ -214,7 +214,12 @@ module OpenNebula::MarketPlaceAppExt
create_vm_template(options, disks)
end
rc[:vmtemplate] = [vmtmpl]
rc[:vmtemplate] = [vmtmpl[0]]
unless OpenNebula.is_error?(vmtmpl[0])
rc[:image] += vmtmpl[1]
rc[:vmtemplate] += vmtmpl[2]
end
rc
end
@ -235,7 +240,12 @@ module OpenNebula::MarketPlaceAppExt
create_service_template(options, roles)
end
rc[:service_template] = [stmpl]
rc[:service_template] = [stmpl[0]]
unless OpenNebula.is_error?(stmpl[0])
rc[:image] += stmpl[1]
rc[:vmtemplate] += stmpl[2]
end
rc
end
@ -371,6 +381,10 @@ module OpenNebula::MarketPlaceAppExt
exported = {}
idx = 0
# Store IDs of created resources
images = []
templates = []
# Iterate over all childs
rc = retrieve_xmlelements(xpath).each do |obj|
# Get name and app information
@ -407,6 +421,10 @@ module OpenNebula::MarketPlaceAppExt
# Update exported hash with information
exported[app] = rc
exported[app][:names] = [obj_name]
# Add IDs to return object
images << image
templates << vmtemplate
end
if block_given? && !OpenNebula.is_error?(rc)
@ -419,7 +437,7 @@ module OpenNebula::MarketPlaceAppExt
return rc_rbck if OpenNebula.is_error?(rc_rbck)
end
rc
[rc, images, templates]
end
# Delete templates/images in case something went wrong
@ -438,18 +456,22 @@ module OpenNebula::MarketPlaceAppExt
[Template.new_with_id(id, @client),
"Error deleting template #{id}"]
}
delete_method = 'delete(true)'
else
obj_factory = lambda {|v|
id = v[:image].first
[Image.new_with_id(id, @client),
"Error deleting image #{id}"]
}
delete_method = 'delete'
end
exported.each do |_, v|
obj, err_msg = obj_factory.call(v)
next unless OpenNebula.is_error?(obj.delete(true))
next unless OpenNebula.is_error?(obj.send(delete_method))
ret << err_msg
end

View File

@ -1,61 +0,0 @@
:plans:
Type 2A5:
cpu: 1
memory: 96.0
c2.large.arm:
cpu: 1
memory: 128.0
c2.medium.x86:
cpu: 1
memory: 64.0
c3.medium.x86:
cpu: 1
memory: 64.0
c3.small.x86:
cpu: 1
memory: 32.0
g2.large.x86:
cpu: 2
memory: 192.0
m2.xlarge.x86:
cpu: 2
memory: 384.0
m3.large.x86:
cpu: 1
memory: 256.0
n2.xlarge.x86:
cpu: 2
memory: 384.0
s3.xlarge.x86:
cpu: 2
memory: 192.0
x2.xlarge.x86:
cpu: 2
memory: 384.0
x.large.arm:
cpu: 2
memory: 256.0
c1.large.arm:
cpu: 2
memory: 128.0
c1.large.arm.xda:
cpu: 2
memory: 128.0
c1.small.x86:
cpu: 1
memory: 32.0
c1.xlarge.x86:
cpu: 2
memory: 128.0
m1.xlarge.x86:
cpu: 2
memory: 256.0
s1.large.x86:
cpu: 1
memory: 64.0
t1.small.x86:
cpu: 1
memory: 8.0
x1.small.x86:
cpu: 1
memory: 32.0

View File

@ -1,52 +0,0 @@
#!/usr/bin/env ruby
require 'json'
require 'net/http'
unless ARGV[0]
STDERR.puts 'No API token provied'
STDERR.puts '`packet_plans.rb` <API_TOKEN>'
exit(-1)
end
uri = URI('https://api.packet.net/plans')
req = Net::HTTP::Get.new(uri)
req['Accept'] = 'application/json'
req['X-Auth-Token'] = ARGV[0]
res = Net::HTTP.new(uri.hostname, uri.port)
res.use_ssl = true
response = res.request(req)
unless response.is_a? Net::HTTPOK
STDERR.puts 'Error getting plans from Packet'
exit(-1)
end
plans = JSON.parse(response.body)['plans']
file = ":plans:\n"
plans.each do |plan|
specs = plan['specs']
specs['cpus'].nil? ? cpu = 0 : cpu = specs['cpus'][0]['count']
specs['memory'].nil? ? mem = 0 : mem = specs['memory']['total']
next if cpu == 0 || mem == 0
file << " #{plan['name']}:\n"
file << " cpu: #{cpu}\n"
file << " memory: #{mem[/\d+/]}.0\n"
end
puts file
puts
print 'Do you want to overwrite file packet_driver.conf? '
over = STDIN.readline.chop.downcase
exit if over != 'yes'
File.open('packet_driver.conf', 'w') {|f| f.write(file) }

View File

@ -23,6 +23,12 @@ require 'base64'
require 'erb'
require 'ostruct'
if !ONE_LOCATION
ANSIBLE_LOCATION = '/usr/share/one/oneprovision/ansible'
else
ANSIBLE_LOCATION = ONE_LOCATION + '/share/oneprovision/ansible'
end
# Default provision parameters
CONFIG_DEFAULTS = {
'connection' => {
@ -75,11 +81,12 @@ module OneProvision
#
# @param hosts [OpenNebula::Host Array] Hosts to configure
# @param hosts [OpenNebula::Datastore array] Datastores for vars
# @param provision [OpenNebula::Provision] Provision info
# @param ping [Boolean] True to check ping to hosts
def configure(hosts, datastores, ping = true)
def configure(hosts, datastores, provision = nil, ping = true)
return if hosts.nil? || hosts.empty?
Driver.retry_loop 'Failed to configure hosts' do
Driver.retry_loop('Failed to configure hosts', provision) do
check_ansible_version
ansible_dir = generate_ansible_configs(hosts, datastores)

View File

@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
module OneProvision
# Driver
@ -75,17 +74,17 @@ module OneProvision
end
end
if provision
provision.state = Provision::STATE['ERROR']
provision.update
end
case choice
when :retry
sleep(seconds) if seconds
retry
when :quit
if provision
provision.state = Provision::STATE['ERROR']
provision.update
end
exit(-1)
when :skip
return :skip
@ -95,11 +94,6 @@ module OneProvision
Utils.fail('Cleanup unsupported for this operation')
end
if provision
provision.state = Provision::STATE['ERROR']
provision.update
end
exit(-1)
end
end
@ -209,7 +203,7 @@ module OneProvision
terraform = Terraform.singleton(provider, tf)
terraform.generate_deployment_file(provision)
terraform.send(action)
terraform.send(action, provision)
end
end

View File

@ -30,7 +30,7 @@ module OneProvision
'CONFIGURING' => 2,
'RUNNING' => 3,
'ERROR' => 4,
'DONE' => 5
'DELETING' => 5
}
STATE_STR = %w[
@ -39,7 +39,7 @@ module OneProvision
CONFIGURING
RUNNING
ERROR
DONE
DELETING
]
# Available resources that can be created with the provision
@ -197,6 +197,8 @@ module OneProvision
path = 'resource'
end
return [] unless @body['provision'][path][object]
resource = Resource.object(object)
@body['provision'][path][object].each do |o|
@ -299,15 +301,7 @@ module OneProvision
OneProvisionLogger.info('Deploying')
ips = nil
ids = nil
state = nil
conf = nil
Driver.retry_loop('Failed to deploy hosts', self) do
ips, ids, state, conf = Driver.tf_action(self,
'deploy')
end
ips, ids, state, conf = Driver.tf_action(self, 'deploy')
OneProvisionLogger.info('Monitoring hosts')
@ -338,10 +332,6 @@ module OneProvision
rescue OneProvisionCleanupException
delete(cleanup, timeout)
self.state = STATE['DONE']
update
-1
end
end
@ -351,9 +341,9 @@ module OneProvision
# @param force [Boolean] Force the configuration although provision
# is already configured
def configure(force = false)
if state == STATE['DONE']
unless [STATE['RUNNING'], STATE['ERROR']].include?(state)
return OpenNebula::Error.new(
'Provision is DONE, can\'t configure it'
"Can't configure provision in #{STATE_STR[state]}"
)
end
@ -365,7 +355,7 @@ module OneProvision
update
rc = Ansible.configure(hosts, datastores)
rc = Ansible.configure(hosts, datastores, self)
if rc == 0
self.state = STATE['RUNNING']
@ -381,12 +371,6 @@ module OneProvision
# @param cleanup [Boolean] True to delete running VMs and images
# @param timeout [Integer] Timeout for deleting running VMs
def delete(cleanup, timeout)
if state == STATE['DONE']
return OpenNebula::Error.new(
'Provision is DONE, can\'t delete it'
)
end
if running_vms? && !cleanup
Utils.fail('Provision with running VMs can\'t be deleted')
end
@ -395,6 +379,10 @@ module OneProvision
Utils.fail('Provision with images can\'t be deleted')
end
self.state = STATE['DELETING']
update
delete_vms(timeout) if cleanup
delete_images(timeout) if cleanup
@ -778,7 +766,7 @@ module OneProvision
#
# @param timeout [Integer] Timeout for deleting running VMs
def delete_vms(timeout)
Driver.retry_loop 'Failed to delete running_vms' do
Driver.retry_loop('Failed to delete running_vms', self) do
next if hosts.nil?
d_hosts = []
@ -811,7 +799,7 @@ module OneProvision
#
# @param timeout [Integer] Timeout for deleting running VMs
def delete_images(timeout)
Driver.retry_loop 'Failed to delete images' do
Driver.retry_loop('Failed to delete images', self) do
d_datastores = []
next if datastores.nil?
@ -900,7 +888,7 @@ module OneProvision
objects[resource].delete_if do |obj|
msg = "#{resource.chomp('s')} #{obj['id']}"
Driver.retry_loop "Failed to delete #{msg}" do
Driver.retry_loop("Failed to delete #{msg}", self) do
OneProvisionLogger.debug("Deleting OpenNebula #{msg}")
o = Resource.object(resource)

View File

@ -19,6 +19,13 @@ require 'ostruct'
require 'yaml'
require 'zlib'
if !ONE_LOCATION
PROVIDERS_LOCATION = '/usr/lib/one/oneprovision/lib/terraform/providers'
else
PROVIDERS_LOCATION = ONE_LOCATION +
'/lib/oneprovision/lib/terraform/providers'
end
# Module OneProvision
module OneProvision
@ -127,16 +134,18 @@ module OneProvision
# Deploy infra via Terraform
#
# @param provision [OpenNebula::Provision] Provision information
#
# @return [String, String]
# - IPs for each deployed host
# - Deploy ID for each host
# - Terraform state in base64
# - Terraform config in base64
def deploy
tempdir = init(false, false)
def deploy(provision)
tempdir = init(provision, false, false)
# Apply
Driver.retry_loop "Driver action 'tf deploy' failed" do
Driver.retry_loop("Driver action 'tf deploy' failed", provision) do
_, e, s = Driver.run(
"cd #{tempdir}; terraform apply -auto-approve"
)
@ -169,7 +178,7 @@ module OneProvision
[ips, ids, state, conf]
ensure
FileUtils.rm_r(tempdir) if File.exist?(tempdir)
FileUtils.rm_r(tempdir) if tempdir && File.exist?(tempdir)
end
# Get polling information from a host
@ -182,21 +191,22 @@ module OneProvision
output(tempdir, "ip_#{id}")
ensure
FileUtils.rm_r(tempdir) if File.exist?(tempdir)
FileUtils.rm_r(tempdir) if tempdir && File.exist?(tempdir)
end
# Destroy infra via Terraform
#
# @param target [String] Target to destroy
# @param provision [OpenNebula::Provision] Provision information
# @param target [String] Target to destroy
#
# @return [Array]
# - Terraform state in base64
# - Terraform config in base64
def destroy(target = nil)
tempdir = init
def destroy(provision, target = nil)
tempdir = init(provision)
# Destroy
Driver.retry_loop "Driver action 'tf destroy' failed" do
Driver.retry_loop("Driver action 'tf destroy' failed", provision) do
_, e, s = Driver.run(
"cd #{tempdir}; terraform destroy #{target} -auto-approve"
)
@ -214,7 +224,7 @@ module OneProvision
[state, conf]
ensure
FileUtils.rm_r(tempdir) if File.exist?(tempdir)
FileUtils.rm_r(tempdir) if tempdir && File.exist?(tempdir)
end
# Destroys a cluster
@ -339,9 +349,10 @@ module OneProvision
# Initialize Terraform directory content
#
# @param state [Boolean] True to copy state, false otherwise
# @param decode [Boolean] True to decode @conf and @state
def init(state = true, decode = true)
# @param provisino [OpenNebula::Provision] Provision information
# @param state [Boolean] True to copy state, false otherwise
# @param decode [Boolean] True to decode @conf and @state
def init(provision = nil, state = true, decode = true)
tempdir = Dir.mktmpdir('tf')
if decode
@ -368,7 +379,7 @@ module OneProvision
upgrade(tempdir)
# Init
Driver.retry_loop "Driver action 'tf init' failed" do
Driver.retry_loop("Driver action 'tf init' failed", provision) do
_, e, s = Driver.run("cd #{tempdir}; terraform init")
unless s && s.success?

View File

@ -70,7 +70,7 @@ EOF
)
# try with quiesce first (needs guest agent)
$SNAP_CMD --quiesce || $SNAP_CMD
$SNAP_CMD --quiesce >/dev/null || $SNAP_CMD >/dev/null
# copy base.1 to the replica
ssh $REPLICA_HOST "mkdir -p $REPLICA_RECOVERY_SNAPS_DIR/$VMID/$DISK_NAME.snap"
@ -83,6 +83,6 @@ rsync -q $DISK_PATH.snap/base.1 \
virsh -c ${LIBVIRT_URI} blockcommit one-${VMID} $SNAP_PATH \
--base $DISK_PATH.snap/base.1 \
--top $SNAP_PATH \
--active --pivot --wait
--active --pivot --wait >/dev/null
stat -c "%Y" $SNAP_PATH

View File

@ -24,11 +24,11 @@ module VXLAN
# This function creates and activate a VLAN device
############################################################################
def create_vlan_dev
vxlan_mode = @nic[:conf][:vxlan_mode] || 'multicast'
vxlan_mode = conf_attribute(@nic, :vxlan_mode, 'multicast')
group = ""
if vxlan_mode.downcase == 'evpn'
vxlan_tep = @nic[:conf][:vxlan_tep] || 'dev'
vxlan_tep = conf_attribute(@nic, :vxlan_tep, 'dev')
if vxlan_tep.downcase == 'dev'
tep = "dev #{@nic[:phydev]}"
@ -37,9 +37,9 @@ module VXLAN
end
else
begin
ipaddr = IPAddr.new @nic[:conf][:vxlan_mc]
ipaddr = IPAddr.new conf_attribute(@nic, :vxlan_mc, '239.0.0.0')
rescue
ipaddr = IPAddr.new "239.0.0.0"
ipaddr = IPAddr.new '239.0.0.0'
end
mc = ipaddr.to_i + @nic[@attr_vlan_id].to_i
@ -105,4 +105,10 @@ module VXLAN
end
return nil
end
def conf_attribute(nic, name, default)
return nic[name] unless nic[name].nil?
nic[:conf][name] || default
end
end