From 07f77074033fd90f44e8a1dcedb60a205f287e28 Mon Sep 17 00:00:00 2001 From: Alejandro Huertas Herrero Date: Tue, 19 Apr 2022 11:26:22 +0200 Subject: [PATCH] F #5803: Add new CLI command (#1953) (cherry picked from commit 6549313966d7d71ffe7c2963e169d92cc34cbb17) --- install.sh | 6 +++ share/man/build.sh | 3 ++ src/cli/oneirb | 131 +++++++++++++++++++++++++++++++++++++++++++++ src/cli/onelog | 101 ++++++++++++++++++++++++++++++++++ src/cli/onevm | 34 ++++++++++++ 5 files changed, 275 insertions(+) create mode 100755 src/cli/oneirb create mode 100755 src/cli/onelog diff --git a/install.sh b/install.sh index d02f3bef9b..41a2c33401 100755 --- a/install.sh +++ b/install.sh @@ -991,6 +991,8 @@ BIN_FILES="src/nebula/oned \ src/cli/onevcenter \ src/cli/onevntemplate \ src/cli/onehook \ + src/cli/onelog \ + src/cli/oneirb \ src/onedb/onedb \ src/onevmdump/onevmdump \ share/scripts/qemu-kvm-one-gen \ @@ -2521,6 +2523,8 @@ CLI_BIN_FILES="src/cli/onevm \ src/cli/onemarketapp \ src/cli/onemarket \ src/cli/onevntemplate \ + src/cli/oneirb \ + src/cli/onelog \ src/cli/onehook" CLI_CONF_FILES="src/cli/etc/onegroup.yaml \ @@ -3025,6 +3029,8 @@ MAN_FILES="share/man/oneacct.1.gz \ share/man/oneshowback.1.gz \ share/man/oneacl.1.gz \ share/man/onehook.1.gz \ + share/man/onelog.1.gz \ + share/man/oneirb.1.gz \ share/man/onehost.1.gz \ share/man/oneimage.1.gz \ share/man/oneuser.1.gz \ diff --git a/share/man/build.sh b/share/man/build.sh index 1fd630f54e..361eaa7007 100755 --- a/share/man/build.sh +++ b/share/man/build.sh @@ -53,6 +53,9 @@ COMMANDS=( 'oneflow' 'Manage oneFlow Services' 'oneflow-template' 'Manage oneFlow Templates' 'onevmdump' 'Dumps VM content' + + 'onelog' 'Access to OpenNebula services log files' + 'oneirb' 'Opens an irb session' ) DIR_BUILD=$(mktemp -d) diff --git a/src/cli/oneirb b/src/cli/oneirb new file mode 100755 index 0000000000..10b018553c --- /dev/null +++ b/src/cli/oneirb @@ -0,0 +1,131 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2022, 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. # +#--------------------------------------------------------------------------- # + +ONE_LOCATION = ENV['ONE_LOCATION'] + +if !ONE_LOCATION + RUBY_LIB_LOCATION = '/usr/lib/one/ruby' + GEMS_LOCATION = '/usr/share/one/gems' +else + RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby' + GEMS_LOCATION = ONE_LOCATION + '/share/gems' +end + +# %%RUBYGEMS_SETUP_BEGIN%% +if File.directory?(GEMS_LOCATION) + real_gems_path = File.realpath(GEMS_LOCATION) + if !defined?(Gem) || Gem.path != [real_gems_path] + $LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ } + + # Suppress warnings from Rubygems + # https://github.com/OpenNebula/one/issues/5379 + begin + verb = $VERBOSE + $VERBOSE = nil + require 'rubygems' + Gem.use_paths(real_gems_path) + ensure + $VERBOSE = verb + end + end +end +# %%RUBYGEMS_SETUP_END%% + +$LOAD_PATH << RUBY_LIB_LOCATION +$LOAD_PATH << RUBY_LIB_LOCATION + '/cli' +$LOAD_PATH << RUBY_LIB_LOCATION + '/oneflow/lib' + +################################################################################ +# Required libraries +################################################################################ + +require 'base64' +require 'csv' +require 'date' +require 'digest/md5' +require 'erb' +require 'json' +require 'nokogiri' +require 'openssl' +require 'ox' +require 'pp' +require 'set' +require 'socket' +require 'sqlite3' +require 'tempfile' +require 'time' +require 'uri' +require 'yaml' + +require 'opennebula' +require 'vcenter_driver' + +# Include OpenNebula to avoid having to use OpenNebula:: namespace +include OpenNebula + +################################################################################ +# vCenter helper functions +################################################################################ + +# Get VIClient object from host +# +# @param id [Integer] Host ID +def vi_client_host(id) + VCenterDriver::VIClient.new_from_host(id) +end + +# Get VM vCenter object +# +# @param id [Integer] VM ID +def vm(id) + one_vm = VCenterDriver::VIHelper.one_item(OpenNebula::VirtualMachine, id) + + did = one_vm['DEPLOY_ID'] + hid = one_vm.retrieve_xmlelements( + 'HISTORY_RECORDS/HISTORY/HID' + ).last.text.to_i + + VCenterDriver::VirtualMachine.new_one(vi_client_host(hid), did, one_vm) +end + +# Get host vCenter object +# +# @param id [Integer] Host ID +def host(id) + vi_client = vi_client_host(id) + one_h = VCenterDriver::VIHelper.one_item(OpenNebula::Host, hid) + + VCenterDriver::ClusterComputeResource.new_from_ref( + one_h['TEMPLATE/VCENTER_CCR_REF'], + vi_client + ) +end + +################################################################################ +# Open irb session +################################################################################ + +puts '* You can use the function vi_client_host(id) to get vCenter client' +puts '* You can use the function vm(id) to get vCenter VM' +puts '* You can use the function host(id) to get vCenter host' + +@client = Client.new +version = '>= 0' + +gem 'pry', version +load Gem.bin_path('pry', 'pry', version) diff --git a/src/cli/onelog b/src/cli/onelog new file mode 100755 index 0000000000..470b8cb7f2 --- /dev/null +++ b/src/cli/onelog @@ -0,0 +1,101 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2022, 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. # +#--------------------------------------------------------------------------- # + +ONE_LOCATION = ENV['ONE_LOCATION'] + +if !ONE_LOCATION + RUBY_LIB_LOCATION = '/usr/lib/one/ruby' +else + RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby' +end + +$LOAD_PATH << RUBY_LIB_LOCATION +$LOAD_PATH << RUBY_LIB_LOCATION + '/cli' + +# Default pager to check logs +DEFAULT_PAGER = 'less' + +# List of OpenNebula services and the logs files +SERVICES = { + 'fireedge' => { :log => 'fireedge.log', :error => 'fireedge.error' }, + 'monitor' => 'monitor.log', + 'novnc' => 'novnc.log', + 'oned' => 'oned.log', + 'onehem' => { :log => 'onehem.log', :error => 'onehem.error' }, + 'sched' => 'sched.log', + 'sunstone' => { :log => 'sunstone.log', :error => 'sunstone.error' }, + 'vcenter' => 'vcenter_monitor.log' +} + +require 'command_parser' +require 'one_helper' + +CommandParser::CmdParser.new(ARGV) do + usage '`onelog` [] []' + version OpenNebulaHelper::ONE_VERSION + + TYPE = { + :name => 'type', + :short => '-t type', + :large => '--type type', + :format => String, + :description => 'Log type (log/error) [default: log]' + } + + PAGER = { + :name => 'pager', + :short => '-p pager', + :large => '--pager pager', + :format => String, + :description => 'Pager to use to read logs [defaul: less]' + } + + PAGER_OPTS = { + :name => 'pager_opts', + :large => '--pager-opts pager_opts', + :format => String, + :description => 'Pager options' + } + + get_desc = <<-EOT.unindent + Gets log from an specific OpenNebula service + EOT + + command :get, get_desc, :service, :options => [TYPE, PAGER, PAGER_OPTS] do + unless SERVICES[args[0]] + STDERR.puts "Service '#{args[0]}' not found" + exit 1 + end + + if options[:type] && !SERVICES[args[0]][options[:type].to_sym] + STDERR.puts "Log file type '#{options[:type]}' not found" + exit 1 + end + + if (SERVICES[args[0]].is_a? Hash) && !options[:type] + options[:type] = :log + end + + type = options[:type].to_sym + pager = options[:pager] || DEFAULT_PAGER + + type.nil? ? file = SERVICES[args[0]] : file = SERVICES[args[0]][type] + + system("#{pager} #{options[:pager_opts]} /var/log/one/#{file}") + end +end diff --git a/src/cli/onevm b/src/cli/onevm index 0ccd9aac12..5a14c2e912 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -49,6 +49,9 @@ end $LOAD_PATH << RUBY_LIB_LOCATION $LOAD_PATH << RUBY_LIB_LOCATION + '/cli' +# Default VNC viewer +DEFAULT_VNC = 'vinagre' + require 'command_parser' require 'one_helper/onevm_helper' require 'one_helper/onedatastore_helper' @@ -239,6 +242,13 @@ CommandParser::CmdParser.new(ARGV) do :description => 'SSH options to use' } + VNC = { + :name => 'vnc', + :large => '--vnc vnc', + :format => String, + :description => 'VNC client to use' + } + OpenNebulaHelper::TEMPLATE_OPTIONS_VM.delete_if do |v| %w[as_gid as_uid].include?(v[:name]) end @@ -1666,6 +1676,30 @@ CommandParser::CmdParser.new(ARGV) do end end + connect_desc = <<-EOT.unindent + Opens a VNC session to the VM + EOT + + command :vnc, connect_desc, :vmid, :options => [VNC] do + helper.perform_action(args[0], options, 'VNC') do |vm| + rc = vm.info + + if OpenNebula.is_error?(rc) + STDERR.puts rc.message + exit(1) + end + + host = vm['HISTORY_RECORDS/HISTORY[last()]/HOSTNAME'] + port = vm['TEMPLATE/GRAPHICS/PORT'] + + vncviewer = options['vnc'] || DEFAULT_VNC + + cmd = [vncviewer, "#{host}::#{port}"] + + exec(*cmd) + end + end + # Deprecated commands deprecated_command(:shutdown, 'terminate')