mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-21 14:50:08 +03:00
Feature 1685: Add better checks, minor code refactor
This commit is contained in:
parent
93309d0c50
commit
565e0f3187
@ -96,6 +96,8 @@ class LXDClient
|
||||
response = get("operations/#{operation_id}/wait#{timeout}")
|
||||
|
||||
raise LXDError, response if response['metadata']['status'] == 'Failure'
|
||||
|
||||
response
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -139,6 +139,7 @@ class Container
|
||||
cmd = "#{Mapper::COMMANDS[:lsblk]} -J"
|
||||
_rc, o, _e = Command.execute(cmd, false)
|
||||
|
||||
# TODO: Add extra mounts to raise
|
||||
raise "Container rootfs still mounted \n#{o}" if o.include?(@rootfs_dir)
|
||||
|
||||
wait?(@client.delete("#{CONTAINERS}/#{name}"), wait, timeout)
|
||||
@ -182,8 +183,13 @@ class Container
|
||||
change_state(__method__, options)
|
||||
end
|
||||
|
||||
def stop(options = {})
|
||||
def stop(options = { :timeout => 120 })
|
||||
change_state(__method__, options)
|
||||
rescue StandardError => exception
|
||||
raise exception unless exception.class == Net::ReadTimeout
|
||||
|
||||
OpenNebula.log_error "Timeout detected\n#{exception}\nForcing shutdown"
|
||||
stop(:force => true)
|
||||
end
|
||||
|
||||
def restart(options = {})
|
||||
@ -402,7 +408,7 @@ class Container
|
||||
options.update(:action => action)
|
||||
|
||||
response = @client.put("#{CONTAINERS}/#{name}/state", options)
|
||||
wait?(response, options[:wait], options[:timeout])
|
||||
status = wait?(response, options[:wait], options[:timeout])
|
||||
|
||||
@lxc = @client.get("#{CONTAINERS}/#{name}")['metadata']
|
||||
|
||||
|
@ -92,7 +92,7 @@ class Mapper
|
||||
# @param disk [XMLElement] with the disk data
|
||||
# @param directory [String] where the disk has to be mounted
|
||||
#
|
||||
# @return nil
|
||||
# @return nil
|
||||
def do_unmap(device, one_vm, disk, directory)
|
||||
OpenNebula.log_error("unmap function not implemented for #{self.class}")
|
||||
return nil
|
||||
@ -256,76 +256,21 @@ class Mapper
|
||||
# @param partitions [Array] with partition device names
|
||||
# @param path [String] to directory to mount the disk partitions
|
||||
def mount(partitions, path)
|
||||
# TODO: Unmap device if mount fails
|
||||
# Single partition
|
||||
# ----------------
|
||||
return mount_dev(partitions[0]['path'], path) if partitions.size == 1
|
||||
|
||||
# Multiple partitions
|
||||
# -------------------
|
||||
rc = true
|
||||
fstab = ''
|
||||
fstab = find_fstab(partitions, path)
|
||||
|
||||
# Look for fstab and mount rootfs in path. First partition with
|
||||
# a /etc/fstab file is used as rootfs and it is kept mounted
|
||||
partitions.each do |p|
|
||||
OpenNebula.log("Looking for fstab on #{p['path']}")
|
||||
|
||||
rc = mount_dev(p['path'], path)
|
||||
|
||||
return false if !rc
|
||||
|
||||
bin = COMMANDS[:catfstab]
|
||||
bin = COMMANDS[:cat] unless path.include?('containers/one-')
|
||||
|
||||
cmd = "#{bin} #{path}/etc/fstab"
|
||||
|
||||
_rc, fstab, _e = Command.execute(cmd, false)
|
||||
|
||||
if fstab.empty?
|
||||
return false unless umount_dev(p['path'])
|
||||
|
||||
next
|
||||
end
|
||||
|
||||
OpenNebula.log("Found fstab on #{p['path']}")
|
||||
break
|
||||
end
|
||||
|
||||
if fstab.empty?
|
||||
OpenNebula.log_error('No fstab file found')
|
||||
if !fstab
|
||||
# TODO: Unmap the device
|
||||
return false
|
||||
end
|
||||
|
||||
# Parse fstab contents & mount partitions
|
||||
fstab.each_line do |l|
|
||||
next if l.strip.chomp.empty?
|
||||
next if l =~ /\s*#/
|
||||
|
||||
fs, mount_point, type, opts, dump, pass = l.split
|
||||
|
||||
if l =~ /^\s*LABEL=/ # disk by LABEL
|
||||
value = fs.split("=").last.strip.chomp
|
||||
key = 'label'
|
||||
elsif l =~ /^\s*UUID=/ #disk by UUID
|
||||
value = fs.split("=").last.strip.chomp
|
||||
key = 'uuid'
|
||||
else #disk by device - NOT SUPPORTED or other FS
|
||||
next
|
||||
end
|
||||
|
||||
next if %w[/ swap].include?(mount_point)
|
||||
|
||||
partitions.each { |p|
|
||||
next if p[key] != value
|
||||
|
||||
rc = mount_dev(p['path'], path + mount_point)
|
||||
return false if !rc
|
||||
|
||||
break
|
||||
}
|
||||
end
|
||||
|
||||
rc
|
||||
parse_fstab(partitions, path, fstab)
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
@ -349,8 +294,6 @@ class Mapper
|
||||
rc, _out, err = Command.execute("#{COMMANDS[:mount]} #{dev} #{path}", true)
|
||||
|
||||
if rc != 0
|
||||
return true if err.include?("unknown filesystem type 'swap'")
|
||||
|
||||
OpenNebula.log_error("mount_dev: #{err}")
|
||||
return false
|
||||
end
|
||||
@ -436,10 +379,12 @@ class Mapper
|
||||
false
|
||||
end
|
||||
|
||||
# Extracts the partiton table from a device
|
||||
def show_parts(device)
|
||||
action_parts(device, '-s -av')
|
||||
end
|
||||
|
||||
# Hides the partiton table from a device
|
||||
def hide_parts(device)
|
||||
action_parts(device, '-d')
|
||||
end
|
||||
@ -459,7 +404,7 @@ class Mapper
|
||||
_rc, out, _err = Command.execute("#{COMMANDS[:lsblk]} -J", false)
|
||||
|
||||
if out.include?(path)
|
||||
OpenNebula.log_error("mount_dev: Mount detected in #{path}")
|
||||
OpenNebula.log_error("#{__method__}: Mount detected in #{path}")
|
||||
return true
|
||||
end
|
||||
false
|
||||
@ -480,4 +425,70 @@ class Mapper
|
||||
false
|
||||
end
|
||||
|
||||
# Look for fstab and mount rootfs in path. First partition with
|
||||
# a /etc/fstab file is used as rootfs and it is kept mounted
|
||||
def find_fstab(partitions, path)
|
||||
fstab = ''
|
||||
partitions.each do |p|
|
||||
OpenNebula.log("Looking for fstab on #{p['path']}")
|
||||
|
||||
rc = mount_dev(p['path'], path)
|
||||
next unless rc
|
||||
|
||||
bin = COMMANDS[:catfstab]
|
||||
bin = COMMANDS[:cat] unless path.include?('containers/one-')
|
||||
|
||||
cmd = "#{bin} #{path}/etc/fstab"
|
||||
|
||||
_rc, fstab, _e = Command.execute(cmd, false)
|
||||
|
||||
if fstab.empty?
|
||||
return false unless umount_dev(p['path'])
|
||||
|
||||
next
|
||||
end
|
||||
|
||||
OpenNebula.log("Found fstab on #{p['path']}")
|
||||
break
|
||||
end
|
||||
|
||||
return fstab unless fstab.empty?
|
||||
|
||||
OpenNebula.log_error('No fstab file found')
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
# Parse fstab contents & mount partitions
|
||||
def parse_fstab(partitions, path, fstab)
|
||||
fstab.each_line do |l|
|
||||
next if l.strip.chomp.empty?
|
||||
next if l =~ /\s*#/
|
||||
|
||||
fs, mount_point, _type, _opts, _dump, _pass = l.split
|
||||
|
||||
if l =~ /^\s*LABEL=/ # disk by LABEL
|
||||
value = fs.split('=').last.strip.chomp
|
||||
key = 'label'
|
||||
elsif l =~ /^\s*UUID=/ # disk by UUID
|
||||
value = fs.split('=').last.strip.chomp
|
||||
key = 'uuid'
|
||||
else # disk by device - NOT SUPPORTED or other FS
|
||||
next
|
||||
end
|
||||
|
||||
next if %w[/ swap].include?(mount_point)
|
||||
|
||||
partitions.each {|p|
|
||||
next if p[key] != value
|
||||
|
||||
return false unless mount_dev(p['path'], path + mount_point)
|
||||
|
||||
break
|
||||
}
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -19,9 +19,10 @@ require 'yaml'
|
||||
# This class reads and holds configuration attributes for the LXD driver
|
||||
class LXDConfiguration < Hash
|
||||
|
||||
# TODO: Create lxdrc file from this hash to avoid duplicated config
|
||||
DEFAULT_CONFIGURATION = {
|
||||
:vnc => {
|
||||
:command => '/bin/bash',
|
||||
:command => '/bin/login',
|
||||
:width => '800',
|
||||
:height => '600',
|
||||
:timeout => '300'
|
||||
@ -183,7 +184,7 @@ class OpenNebulaVM
|
||||
end
|
||||
end
|
||||
|
||||
def get_context_disk()
|
||||
def get_context_disk
|
||||
@xml.element('//TEMPLATE/CONTEXT')
|
||||
end
|
||||
|
||||
@ -376,15 +377,16 @@ class OpenNebulaVM
|
||||
# Creates or closes a connection to a container rfb port depending on signal
|
||||
def vnc_command(signal)
|
||||
data = @xml.element('//TEMPLATE/GRAPHICS')
|
||||
return unless data && data['PORT'] && data['TYPE'] && data['TYPE'].casecmp('vnc').zero?
|
||||
return unless data && data['TYPE'].casecmp('vnc').zero?
|
||||
|
||||
pass = data['PASSWD']
|
||||
pass = '-' unless pass && !pass.empty?
|
||||
pass = '-' if pass.empty?
|
||||
|
||||
case signal
|
||||
when 'start'
|
||||
# TODO: Allow to set vnc command on VM template
|
||||
command = @lxdrc[:vnc][:command]
|
||||
command = data['COMMAND'] unless data['COMMAND'].empty?
|
||||
|
||||
"#{data['PORT']} #{pass} lxc exec #{@vm_name} #{command}\n"
|
||||
when 'stop'
|
||||
"-#{data['PORT']}\n"
|
||||
|
@ -71,16 +71,21 @@ else
|
||||
mapped = container.setup_storage('map')
|
||||
raise 'failed to setup container storage' unless mapped
|
||||
|
||||
if container.start != 'Running'
|
||||
OpenNebula.log_error('Container failed to start')
|
||||
begin
|
||||
operation = container.start
|
||||
raise operation if container.status != 'Running'
|
||||
rescue LXDError => exception
|
||||
storage_deleted = container.setup_storage('unmap')
|
||||
|
||||
deleted = container.setup_storage('unmap')
|
||||
raise 'failed to dismantle container storage' unless deleted
|
||||
if storage_deleted
|
||||
container.delete
|
||||
else
|
||||
OpenNebula.log_error 'failed to dismantle container storage'
|
||||
end
|
||||
|
||||
container.delete
|
||||
|
||||
raise LXDError, container.status
|
||||
raise LXDError, exception
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
@ -44,13 +44,9 @@ end
|
||||
|
||||
if !container.wild?
|
||||
unmapped = container.setup_storage('unmap')
|
||||
unless unmapped
|
||||
container.start
|
||||
raise 'Failed to dismantle container storage'
|
||||
end
|
||||
raise 'Failed to dismantle container storage' unless unmapped
|
||||
|
||||
container.delete
|
||||
|
||||
end
|
||||
|
||||
container.vnc('stop')
|
||||
|
Loading…
x
Reference in New Issue
Block a user