Skip to content

Commit

Permalink
Merge pull request #20168 from simaishi/revert_ims13
Browse files Browse the repository at this point in the history
Revert v2v warm migration and UCI changes
  • Loading branch information
Fryguy authored May 28, 2020
2 parents cd61222 + 0b5bf97 commit 5996d45
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 517 deletions.
125 changes: 23 additions & 102 deletions app/models/conversion_host.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,50 +159,14 @@ def ipaddress(family = 'ipv4')
# @raise [Net::SSH::HostKeyMismatch] if conversion host key has changed
# @raise [JSON::GeneratorError] if limits hash can't be converted to JSON
# @raise [StandardError] if any other problem happens
def apply_task_limits(task_id, limits = {})
connect_ssh do |ssu|
ssu.put_file("/tmp/#{task_id}-limits.json", limits.to_json)
command = AwesomeSpawn.build_command_line("mv", ["/tmp/#{task_id}-limits.json", "/var/lib/uci/#{task_id}/limits.json"])
ssu.shell_exec(command, nil, nil, nil)
end
def apply_task_limits(path, limits = {})
connect_ssh { |ssu| ssu.put_file(path, limits.to_json) }
rescue Net::SSH::AuthenticationFailed, Net::SSH::HostKeyMismatch => err
raise "Failed to connect and apply limits for task '#{task_id}' with [#{err.class}: #{err}]"
raise "Failed to connect and apply limits in file '#{path}' with [#{err.class}: #{err}]"
rescue JSON::GeneratorError => err
raise "Could not generate JSON from limits '#{limits}' with [#{err.class}: #{err}]"
rescue => err
raise "Could not apply the limits for task '#{task_id}' on '#{resource.name}' with [#{err.class}: #{err}]"
end

# Prepare the conversion assets for a specific task.
#
# @param [Integer] id of the task that needs the preparation
# @param [Hash] conversion options to write on the conversion host
#
# @return [Integer] length of data written to conversion options file
#
# @raise [Net::SSH::AuthenticationFailed] if conversion host credentials are invalid
# @raise [Net::SSH::HostKeyMismatch] if conversion host key has changed
# @raise [JSON::GeneratorError] if limits hash can't be converted to JSON
# @raise [StandardError] if any other problem happens
def prepare_conversion(task_id, conversion_options)
filtered_options = filter_options(conversion_options)

connect_ssh do |ssu|
# Prepare the conversion folders
command = AwesomeSpawn.build_command_line("mkdir", [:p, "/var/lib/uci/#{task_id}", "/var/log/uci/#{task_id}"])
ssu.shell_exec(command, nil, nil, nil)

# Write the conversion options file
ssu.put_file("/tmp/#{task_id}-input.json", conversion_options.to_json)
command = AwesomeSpawn.build_command_line("mv", ["/tmp/#{task_id}-input.json", "/var/lib/uci/#{task_id}/input.json"])
ssu.shell_exec(command, nil, nil, nil)
end
rescue Net::SSH::AuthenticationFailed, Net::SSH::HostKeyMismatch => err
raise "Failed to connect and prepare conversion for task '#{task_id}' with [#{err.class}: #{err}]"
rescue JSON::GeneratorError => err
raise "Could not generate JSON for task '#{task_id}' from options '#{filtered_options}' with [#{err.class}: #{err}]"
rescue => err
raise "Preparation of conversion for task '#{task_id}' failed on '#{resource.name}' with [#{err.class}: #{err}]"
raise "Could not apply the limits in file '#{path}' on '#{resource.name}' with [#{err.class}: #{err}]"
end

# Checks that LUKS keys vault exists and is valid JSON
Expand All @@ -225,71 +189,28 @@ def luks_keys_vault_valid?
false
end

# Build the podman command to execute conversion
#
# @param [Integer] id of the task that conversion applies to
#
# @return [String] podman command to be executed on conversion host
def build_podman_command(task_id, conversion_options)
uci_settings = Settings.transformation.uci.container
uci_image = uci_settings.image
uci_image = "#{uci_settings.registry}/#{uci_image}" if uci_settings.registry.present?

params = [
"run",
:detach,
:privileged,
[:name, "conversion-#{task_id}"],
[:network, "host"],
[:volume, "/dev:/dev"],
[:volume, "/etc/pki/ca-trust:/etc/pki/ca-trust"],
[:volume, "/var/tmp:/var/tmp"],
[:volume, "/var/lib/uci/#{task_id}:/var/lib/uci"],
[:volume, "/var/log/uci/#{task_id}:/var/log/uci"],
]
params << [:volume, "/opt/vmware-vix-disklib-distrib:/opt/vmware-vix-disklib-distrib"] unless conversion_options[:transport_method] == 'ssh'
params << [:volume, "/root/.ssh/id_rsa:/var/lib/uci/ssh_private_key"] if conversion_options[:transport_method] == 'ssh'
params << [:volume, "/root/.v2v_luks_keys_vault.json:/var/lib/uci/luks_keys_vault.json"] if luks_keys_vault_valid?
params << uci_image

AwesomeSpawn.build_command_line("/usr/bin/podman", params)
end

# Run the virt-v2v-wrapper script on the remote host and return a hash
# result from the parsed JSON output.
#
# Certain sensitive fields are filtered in the error messages to prevent
# that information from showing up in the UI or logs.
#
# @param [Integer] id of the task that conversion applies to
def run_conversion(task_id, conversion_options)
def run_conversion(conversion_options)
filtered_options = filter_options(conversion_options)
prepare_conversion(task_id, conversion_options)
connect_ssh { |ssu| ssu.shell_exec(build_podman_command(task_id, conversion_options), nil, nil, nil) }
command = AwesomeSpawn.build_command_line("/usr/bin/virt-v2v-wrapper")
result = connect_ssh { |ssu| ssu.shell_exec(command, nil, nil, conversion_options.to_json) }
JSON.parse(result)
rescue Net::SSH::AuthenticationFailed, Net::SSH::HostKeyMismatch => err
raise "Failed to connect and run conversion using options #{filtered_options} with [#{err.class}: #{err}]"
rescue JSON::ParserError
raise "Could not parse result data after running virt-v2v-wrapper using options: #{filtered_options}. Result was: #{result}"
rescue => err
raise "Starting conversion for task '#{task_id}' failed on '#{resource.name}' with [#{err.class}: #{err}]"
end

def create_pause_disks_precopy_file(task_id)
command = AwesomeSpawn.build_command_line("touch", ["/var/lib/uci/#{task_id}/pause_operations"])
connect_ssh { |ssu| ssu.shell_exec(command, nil, nil, nil) }
true
rescue
false
end

def delete_pause_disks_precopy_file(task_id)
command = AwesomeSpawn.build_command_line("rm", {:f =>["/var/lib/uci/#{task_id}/pause_operations"]})
connect_ssh { |ssu| ssu.shell_exec(command, nil, nil, nil) }
true
rescue
false
raise "Starting conversion failed on '#{resource.name}' with [#{err.class}: #{err}]"
end

def create_cutover_file(task_id)
command = AwesomeSpawn.build_command_line("touch", ["/var/lib/uci/#{task_id}/cutover"])
def create_cutover_file(path)
command = AwesomeSpawn.build_command_line("touch", [path])
connect_ssh { |ssu| ssu.shell_exec(command, nil, nil, nil) }
true
rescue
Expand All @@ -299,8 +220,8 @@ def create_cutover_file(task_id)
# Kill a specific remote process over ssh, sending the specified +signal+, or 'TERM'
# if no signal is specified.
#
def kill_virtv2v(task_id, signal = 'TERM')
command = AwesomeSpawn.build_command_line("/usr/bin/podman", ["exec", "conversion-#{task_id}", "/usr/bin/killall", :signal, signal, "virt-v2v"])
def kill_virtv2v(pid, signal = 'TERM')
command = AwesomeSpawn.build_command_line("/bin/kill", [:s, signal, pid])
connect_ssh { |ssu| ssu.shell_exec(command, nil, nil, nil) }
true
rescue
Expand All @@ -310,15 +231,15 @@ def kill_virtv2v(task_id, signal = 'TERM')
# Retrieve the conversion state information from a remote file as a stream.
# Then parse and return the stream data as a hash using JSON.parse.
#
def get_conversion_state(task_id)
json_state = connect_ssh { |ssu| ssu.get_file("/var/lib/uci/#{task_id}/state.json", nil) }
def get_conversion_state(path)
json_state = connect_ssh { |ssu| ssu.get_file(path, nil) }
JSON.parse(json_state)
rescue Net::SSH::AuthenticationFailed, Net::SSH::HostKeyMismatch => err
raise "Failed to connect and retrieve conversion state data from file '/var/lib/uci/#{task_id}/state.json' with [#{err.class}: #{err}]"
raise "Failed to connect and retrieve conversion state data from file '#{path}' with [#{err.class}: #{err}]"
rescue JSON::ParserError
raise "Could not parse conversion state data from file '/var/lib/uci/#{task_id}/state.json': #{json_state}"
raise "Could not parse conversion state data from file '#{path}': #{json_state}"
rescue => err
raise "Error retrieving and parsing conversion state file '/var/lib/uci/#{task_id}/state.json' from '#{resource.name}' with [#{err.class}: #{err}"
raise "Error retrieving and parsing conversion state file '#{path}' from '#{resource.name}' with [#{err.class}: #{err}"
end

# Get and return the contents of the remote conversion log at +path+.
Expand All @@ -343,7 +264,7 @@ def check_conversion_host_role(miq_task_id = nil)
tag_resource_as('disabled')
end

def enable_conversion_host_role(vmware_vddk_package_url = nil, vmware_ssh_private_key = nil, tls_ca_certs = nil, miq_task_id = nil)
def enable_conversion_host_role(vmware_vddk_package_url = nil, vmware_ssh_private_key = nil, openstack_tls_ca_certs = nil, miq_task_id = nil)
return if resource.nil? || resource.ext_management_system.nil?
raise "vmware_vddk_package_url is mandatory if transformation method is vddk" if vddk_transport_supported && vmware_vddk_package_url.nil?
raise "vmware_ssh_private_key is mandatory if transformation_method is ssh" if ssh_transport_supported && vmware_ssh_private_key.nil?
Expand All @@ -354,7 +275,7 @@ def enable_conversion_host_role(vmware_vddk_package_url = nil, vmware_ssh_privat
:v2v_transport_method => source_transport_method,
:v2v_vddk_package_url => vmware_vddk_package_url,
:v2v_ssh_private_key => vmware_ssh_private_key,
:v2v_ca_bundle => tls_ca_certs || resource.ext_management_system.connection_configurations['default'].certificate_authority
:v2v_ca_bundle => openstack_tls_ca_certs || resource.ext_management_system.connection_configurations['default'].certificate_authority
}.compact
ansible_playbook(playbook, extra_vars, miq_task_id)
ensure
Expand Down Expand Up @@ -477,7 +398,7 @@ def ansible_playbook(playbook, extra_vars = {}, miq_task_id = nil, auth_type = '
raise MiqException::MiqInvalidCredentialsError, _("Unknown auth type: %{auth_type}") % {:auth_type => auth.authtype}
end

extra_vars.each { |k, v| params << {:extra_vars= => "#{k}='#{v}'"} }
params << {:extra_vars => "'#{extra_vars.to_json}'"}

command = AwesomeSpawn.build_command_line("ansible-playbook", params)
result = AwesomeSpawn.run(command)
Expand Down
4 changes: 2 additions & 2 deletions app/models/conversion_host/configurations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def enable(params, auth_user = nil)

ssh_key = params.delete(:conversion_host_ssh_private_key)

tls_ca_certs = params.delete(:tls_ca_certs)
openstack_tls_ca_certs = params.delete(:openstack_tls_ca_certs)

new(params).tap do |conversion_host|
if ssh_key
Expand All @@ -90,7 +90,7 @@ def enable(params, auth_user = nil)
)
end

conversion_host.enable_conversion_host_role(vmware_vddk_package_url, vmware_ssh_private_key, tls_ca_certs, miq_task_id)
conversion_host.enable_conversion_host_role(vmware_vddk_package_url, vmware_ssh_private_key, openstack_tls_ca_certs, miq_task_id)
conversion_host.save!

if miq_task_id
Expand Down
Loading

0 comments on commit 5996d45

Please sign in to comment.