From 80bcf3ce9ddf53f7e94f577ae2db1d7b3e2dfd91 Mon Sep 17 00:00:00 2001 From: Daniel Clavijo Coca Date: Thu, 21 Apr 2022 09:04:20 -0500 Subject: [PATCH] F OpenNebula/one#5667: Add utility code (#1938) --- src/vmm_mad/remotes/lib/command.rb | 12 ++-- src/vmm_mad/remotes/lib/lxc/container.rb | 66 ++++++++++++++----- .../remotes/lib/lxc/storage/mappers/qcow2.rb | 2 +- .../remotes/lib/lxc/storage/mappers/rbd.rb | 2 +- 4 files changed, 60 insertions(+), 22 deletions(-) diff --git a/src/vmm_mad/remotes/lib/command.rb b/src/vmm_mad/remotes/lib/command.rb index 67566668eb..34f2168a8e 100644 --- a/src/vmm_mad/remotes/lib/command.rb +++ b/src/vmm_mad/remotes/lib/command.rb @@ -22,28 +22,32 @@ require 'open3' # locking capabilites using flock module Command - def self.execute(cmd, block) + def self.execute(cmd, block, verbose = 0) stdout = '' stderr = '' begin fd = lock if block + STDERR.puts "Running command #{cmd}" if verbose >= 1 + stdout, stderr, s = Open3.capture3(cmd) ensure unlock(fd) if block end + STDERR.puts "#{stdout}\n#{stderr}" if verbose == 2 + [s.exitstatus, stdout, stderr] end def self.execute_once(cmd, lock) - execute(cmd, lock) unless running?(cmd.split[0]) + execute(cmd, lock, 1) unless running?(cmd.split[0]) end # Returns true/false if status is 0/!=0 and logs error if needed def self.execute_rc_log(cmd, lock = false) - rc, _stdout, stderr = execute(cmd, lock) + rc, _stdout, stderr = execute(cmd, lock, 1) STDERR.puts stderr unless rc.zero? @@ -52,7 +56,7 @@ module Command # Execute cmd and logs error if needed def self.execute_log(cmd, lock = false) - rc = execute(cmd, lock) + rc = execute(cmd, lock, 1) STDERR.puts rc[2] unless rc[0].zero? diff --git a/src/vmm_mad/remotes/lib/lxc/container.rb b/src/vmm_mad/remotes/lib/lxc/container.rb index 7127c69f08..7921c6bd50 100644 --- a/src/vmm_mad/remotes/lib/lxc/container.rb +++ b/src/vmm_mad/remotes/lib/lxc/container.rb @@ -30,9 +30,15 @@ class Container #----------------------------------------------------------------------- # @param [LXCVM] ONE VM information (XML), LXC specilization # @param [LXCClient] client to interact with LXC (command line) + # @param [name] container name to interact with LXC (command line) + + attr_reader :name + def initialize(one, client) @one = one @client = client + + @name = @one.vm_name end class << self @@ -46,6 +52,40 @@ class Container end + #----------------------------------------------------------------------- + # Monitoring + #----------------------------------------------------------------------- + + STATES = { + :running => 'RUNNING', + :stopped => 'STOPPED' + } + + # Get container config + # -c, --config=KEY show configuration variable KEY from running container + + # TODO: Validate, LXC doesn't correctly put exit status + # root@ubuntu1804-lxc-lvm-ssh-6-3-QQ57P-1:~# lxc-info ubuntu -c arch + # arch invalid + # root@ubuntu1804-lxc-lvm-ssh-6-3-QQ57P-1:~# echo $? + # 0 + + def config(config_str) + @client.info(@name, { :c => config_str }) + end + + def state + @client.info(@name, { :s => nil })['State'] + end + + def running? + state == STATES[:running] + end + + def stopped? + state == STATES[:stopped] + end + #----------------------------------------------------------------------- # Life Cycle Operations #----------------------------------------------------------------------- @@ -78,13 +118,13 @@ class Container options[:config] = "#{@one.location}/deployment.file" File.write(options[:config], @one.to_lxc) - @client.create(@one.vm_name, options) + @client.create(@name, options) end # Remove container in Linux def cancel options = { :kill => nil } - rc = @client.stop(@one.vm_name, options) + rc = @client.stop(@name, options) return false unless rc @@ -93,7 +133,7 @@ class Container end def start - rc = @client.start(@one.vm_name) + rc = @client.start(@name) # Clean if container fails to start if !rc @@ -105,7 +145,7 @@ class Container end def shutdown - rc = @client.stop(@one.vm_name) + rc = @client.stop(@name) return false unless rc @@ -114,7 +154,7 @@ class Container end def reboot - rc = @client.stop(@one.vm_name) + rc = @client.stop(@name) # Remove nic from ovs-switch if needed @one.get_nics.each do |nic| @@ -123,7 +163,7 @@ class Container return false unless rc - @client.start(@one.vm_name) + @client.start(@name) end def clean(ignore_err = false) @@ -138,7 +178,7 @@ class Container FileUtils.rm_rf(@one.bind_folder) if Dir.exist?(@one.bind_folder) # Destroy container - @client.destroy(@one.vm_name) if @client.list.include?(@one.vm_name) + @client.destroy(@name) if @client.list.include?(@name) end #--------------------------------------------------------------------------- @@ -151,20 +191,14 @@ class Container private - STATES = { - :running => 'RUNNING', - :stopped => 'STOPPED' - } - # Waits for the container to be RUNNING # @param timeout[Integer] seconds to wait for the conatiner to start def wait_deploy(timeout) t_start = Time.now - next while (Time.now - t_start < timeout) && - (@client.info(@one.vm_name)['State'] != STATES[:running]) + next while (Time.now - t_start < timeout) && !running? - @client.info(@one.vm_name)['State'] == STATES[:running] + running? end def del_bridge_port(nic) @@ -173,7 +207,7 @@ class Container cmd = 'sudo -n ovs-vsctl --if-exists del-port '\ "#{nic['BRIDGE']} #{nic['TARGET']}" - rc, _o, e = Command.execute(cmd, false) + rc, _o, e = Command.execute(cmd, false, 1) return true if rc.zero? diff --git a/src/vmm_mad/remotes/lib/lxc/storage/mappers/qcow2.rb b/src/vmm_mad/remotes/lib/lxc/storage/mappers/qcow2.rb index 181df71b90..82d11410b9 100644 --- a/src/vmm_mad/remotes/lib/lxc/storage/mappers/qcow2.rb +++ b/src/vmm_mad/remotes/lib/lxc/storage/mappers/qcow2.rb @@ -73,7 +73,7 @@ class Qcow2Mapper def nbd_version cmd = "#{@commands[:nbd]} -V" - rc, out, _err = Command.execute(cmd, false) + rc, out, _err = Command.execute(cmd, false, 1) return '0.0.0' unless rc.zero? diff --git a/src/vmm_mad/remotes/lib/lxc/storage/mappers/rbd.rb b/src/vmm_mad/remotes/lib/lxc/storage/mappers/rbd.rb index dd284d891b..7f3de204fd 100644 --- a/src/vmm_mad/remotes/lib/lxc/storage/mappers/rbd.rb +++ b/src/vmm_mad/remotes/lib/lxc/storage/mappers/rbd.rb @@ -42,7 +42,7 @@ class RBDMapper return unless dsrc - rc, out, err = Command.execute("#{@map_cmd} #{dsrc}", true) + rc, out, err = Command.execute("#{@map_cmd} #{dsrc}", true, 1) unless rc.zero? OpenNebula.log_error("#{__method__}: #{err}")