1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-29 18:50:08 +03:00

F OpenNebula/one#6242: Allow templates via STDIN on CLI (#2660)

This commit is contained in:
Daniel Clavijo Coca 2023-07-07 02:21:38 -06:00 committed by GitHub
parent 6bbfbb03e4
commit 1804583ece
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 168 additions and 80 deletions

View File

@ -18,6 +18,7 @@ require 'cli_helper'
require 'open3'
require 'io/console'
require 'time'
require 'io/wait'
begin
require 'opennebula'
@ -49,6 +50,8 @@ module OpenNebulaHelper
EDITOR_PATH='/usr/bin/vi'
TEMPLATE_INPUT = 'A template can be passed as a file with or the content via STDIN'
########################################################################
# Options
########################################################################
@ -103,6 +106,22 @@ module OpenNebulaHelper
:description => 'Append new attributes to the current template'
}
FILE = {
:name => 'file',
:short => '-f file',
:large => '--file file',
:description => 'Selects the template file',
:format => String,
:proc => lambda {|o, options|
if File.file?(o)
options[:file] = o
else
STDERR.puts "File `#{options[:file]}` doesn't exist"
exit(-1)
end
}
}
# Command line VM template options
TEMPLATE_NAME_VM={
:name => 'name',
@ -614,6 +633,10 @@ module OpenNebulaHelper
"The default columns and their layout can be configured in #{conf_file}"
end
def self.template_input_help(object_name)
"#{TEMPLATE_INPUT}\nWhen using a template add only one #{object_name} instance."
end
def initialize(_secret = nil, _endpoint = nil)
@client=nil

View File

@ -362,7 +362,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
tmp_str = OpenNebulaHelper.schedule_action_tmpl(options, action, warning)
perform_actions( ids, options, message) do |vm|
perform_actions(ids, options, message) do |vm|
rc = vm.sched_action_add(tmp_str)
if OpenNebula.is_error?(rc)

View File

@ -102,16 +102,19 @@ CommandParser::CmdParser.new(ARGV) do
########################################################################
create_desc = <<-EOT.unindent
Creates a new Datastore from the given template file
Creates a new Datastore from the given template
#{OpenNebulaHelper::TEMPLATE_INPUT}
EOT
command :create, create_desc, :file,
command :create, create_desc, [:file, nil],
:options => [OneClusterHelper::CLUSTER] do
cid = options[:cluster] || ClusterPool::NONE_CLUSTER_ID
helper.create_resource(options) do |datastore|
begin
template = File.read(args[0])
template = File.read(args[0]) if args[0]
template = STDIN.read if STDIN.wait_readable(0)
datastore.allocate(template, cid)
rescue StandardError => e
STDERR.puts e.message

View File

@ -178,12 +178,24 @@ CommandParser::CmdParser.new(ARGV) do
###
create_desc = <<-EOT.unindent
Create a new Service Template
Create a new Service Template from a json service definition
#{OpenNebulaHelper::TEMPLATE_INPUT}
EOT
command :create, create_desc, :file, :options => Service::JSON_FORMAT do
client = helper.client(options)
response = client.post(RESOURCE_PATH, File.read(args[0]))
command :create, create_desc, [:file, nil], :options => Service::JSON_FORMAT do
client = helper.client(options)
template = nil
template = File.read(args[0]) if args[0]
template = STDIN.read if STDIN.wait_readable(0)
if template.nil?
STDERR.puts 'A template must be provided'
exit(-1)
end
response = client.post(RESOURCE_PATH, template)
if CloudClient.is_error?(response)
[response.code.to_i, response.to_s]
@ -233,6 +245,9 @@ CommandParser::CmdParser.new(ARGV) do
instantiate_desc = <<-EOT.unindent
Instantiate a Service Template
Optionally append modifications with a json service definition
#{OpenNebulaHelper::TEMPLATE_INPUT}
EOT
command :instantiate, instantiate_desc, :templateid, [:file, nil],
@ -243,8 +258,11 @@ CommandParser::CmdParser.new(ARGV) do
client = helper.client(options)
number.times do
params['merge_template'] = nil
params['merge_template'] = JSON.parse(File.read(args[1])) if args[1]
template = nil
template = File.read(args[1]) if args[1]
template = STDIN.read if STDIN.wait_readable(0)
params['merge_template'] = JSON.parse(template) if template
unless params['merge_template']
response = client.get("#{RESOURCE_PATH}/#{args[0]}")

View File

@ -180,6 +180,8 @@ CommandParser::CmdParser.new(ARGV) do
oneimage create -d default centOS.tmpl
#{OpenNebulaHelper::TEMPLATE_INPUT}
- new image "arch" using a path:
oneimage create -d default --name arch --path /tmp/arch.img
@ -213,9 +215,10 @@ CommandParser::CmdParser.new(ARGV) do
check_capacity = true
end
if args[0] && OpenNebulaHelper.create_template_options_used?(options)
STDERR.puts 'You can not use both template file and template' \
' creation options.'
if (args[0] || STDIN.wait_readable(0)) &&
OpenNebulaHelper.create_template_options_used?(options)
STDERR.puts 'You cannot use both template and template creation options.'
next -1
end
@ -232,6 +235,8 @@ CommandParser::CmdParser.new(ARGV) do
begin
if args[0]
template = File.read(args[0])
elsif STDIN.wait_readable(0)
template = STDIN.read
else
res = OneImageHelper.create_image_template(options)

View File

@ -98,13 +98,15 @@ CommandParser::CmdParser.new(ARGV) do
########################################################################
create_desc = <<-EOT.unindent
Creates a new Marketplace from the given template file
Creates a new Marketplace from the given template
#{OpenNebulaHelper::TEMPLATE_INPUT}
EOT
command :create, create_desc, :file do
command :create, create_desc, [:file, nil] do
helper.create_resource(options) do |marketplace|
begin
template = File.read(args[0])
template = File.read(args[0]) if args[0]
template = STDIN.read if STDIN.wait_readable(0)
marketplace.allocate(template)
rescue StandardError => e
STDERR.puts e.message

View File

@ -178,6 +178,8 @@ CommandParser::CmdParser.new(ARGV) do
create_desc = <<-EOT.unindent
Creates a new marketplace app in the given marketplace
#{OpenNebulaHelper::TEMPLATE_INPUT}
EOT
command :create, create_desc, [:file, nil],
@ -189,7 +191,7 @@ CommandParser::CmdParser.new(ARGV) do
exit(-1)
end
if args[0] &&
if (args[0] || STDIN.wait_readable(0)) &&
OneMarketPlaceAppHelper.create_template_options_used?(options)
STDERR.puts 'You can not use both template file and template'\
' creation options.'
@ -200,6 +202,8 @@ CommandParser::CmdParser.new(ARGV) do
begin
if args[0]
template = File.read(args[0])
elsif STDIN.wait_readable(0)
template = STDIN.read
else
res = OneMarketPlaceAppHelper
.create_datastore_template(options)

View File

@ -149,6 +149,8 @@ CommandParser::CmdParser.new(ARGV) do
onetemplate create vm_description.tmpl
#{OpenNebulaHelper::TEMPLATE_INPUT}
- new VM Template named "arch vm" with a disk and a nic:
onetemplate create --name "arch vm" --memory 128 --cpu 1 \\
@ -164,9 +166,10 @@ CommandParser::CmdParser.new(ARGV) do
command :create, create_desc, [:file, nil], :options =>
[OneTemplateHelper::VM_NAME] + OpenNebulaHelper::TEMPLATE_OPTIONS +
[OpenNebulaHelper::DRY] do
if args[0] && OpenNebulaHelper.create_template_options_used?(options)
STDERR.puts 'You can not use both template file and template' \
' creation options.'
if (args[0] || STDIN.wait_readable(0)) &&
OpenNebulaHelper.create_template_options_used?(options)
STDERR.puts 'You can not use both template file and template creation options.'
next -1
end
@ -174,6 +177,8 @@ CommandParser::CmdParser.new(ARGV) do
begin
if args[0]
template = File.read(args[0])
elsif STDIN.wait_readable(0)
template = STDIN.read
else
res = OpenNebulaHelper.create_template(options)
@ -248,13 +253,13 @@ CommandParser::CmdParser.new(ARGV) do
EOT
command :instantiate, instantiate_desc, :templateid, [:file, nil],
:options => instantiate_options +
OpenNebulaHelper::TEMPLATE_OPTIONS do
:options => instantiate_options + OpenNebulaHelper::TEMPLATE_OPTIONS do
exit_code = 0
if args[1] && OpenNebulaHelper.create_template_options_used?(options)
STDERR.puts 'You cannot use both template file and template' \
' creation options.'
if (args[1] || STDIN.wait_readable(0)) &&
OpenNebulaHelper.create_template_options_used?(options)
STDERR.puts 'You cannot use both template and template creation options.'
next -1
end
@ -300,6 +305,8 @@ CommandParser::CmdParser.new(ARGV) do
if args[1]
extra_template = File.read(args[1])
elsif STDIN.wait_readable(0)
extra_template = STDIN.read
else
res = OpenNebulaHelper.create_template(options, t)

View File

@ -349,7 +349,9 @@ CommandParser::CmdParser.new(ARGV) do
number = options[:multiple] || 1
exit_code = nil
if args[0] && OpenNebulaHelper.create_template_options_used?(options)
if (args[0] || STDIN.wait_readable(0)) &&
OpenNebulaHelper.create_template_options_used?(options)
STDERR.puts 'You can not use both template file and template'\
' creation options.'
exit(-1)
@ -358,6 +360,8 @@ CommandParser::CmdParser.new(ARGV) do
begin
if args[0]
template = File.read(args[0])
elsif STDIN.wait_readable(0)
template = STDIN.read
else
res = OpenNebulaHelper.create_template(options)
@ -590,6 +594,8 @@ CommandParser::CmdParser.new(ARGV) do
deployment, in a standard installation the Scheduler is in charge
of this decision
#{OpenNebulaHelper::TEMPLATE_INPUT}
States: PENDING, HOLD, STOPPED, UNDEPLOYED
EOT
@ -598,7 +604,7 @@ CommandParser::CmdParser.new(ARGV) do
[:range, :vmid_list],
:hostid,
[:datastoreid, nil],
:options => [ENFORCE, OneVMHelper::FILE] do
:options => [ENFORCE, OpenNebulaHelper::FILE] do
host_id = args[1]
verbose = "deploying in host #{host_id}"
@ -609,6 +615,8 @@ CommandParser::CmdParser.new(ARGV) do
if options[:file]
extra_template = File.read(options[:file])
elsif STDIN.wait_readable(0)
extra_template = STDIN.read
end
helper.perform_actions(args[0], options, verbose) do |vm|
@ -754,25 +762,21 @@ CommandParser::CmdParser.new(ARGV) do
end
disk_attach_desc = <<-EOT.unindent
Attaches a disk to a running VM. When using --file add only one
DISK instance.
Attaches a disk to a running VM.
#{OneVMHelper.template_input_help('DISK')}
States: RUNNING, POWEROFF
EOT
command :"disk-attach", disk_attach_desc, :vmid,
:options => [OneVMHelper::FILE, OneVMHelper::IMAGE,
:options => [OpenNebulaHelper::FILE, OneVMHelper::IMAGE,
TARGET, CACHE, DISCARD, PREFIX] do
if options[:file].nil? && options[:image].nil?
STDERR.puts 'Provide a template file or an image:'
STDERR.puts '\t--file <file>'
STDERR.puts '\t--image <image>'
exit(-1)
end
if options[:file]
template = File.read(options[:file])
else
elsif STDIN.wait_readable(0)
template = STDIN.read
elsif options[:image]
image_id = options[:image]
target = options[:target]
prefix = options[:prefix]
@ -794,6 +798,11 @@ CommandParser::CmdParser.new(ARGV) do
end
template << ' ]'
else
STDERR.puts 'Provide a template or an image:'
STDERR.puts '\t--file <file>'
STDERR.puts '\t--image <image>'
exit(-1)
end
helper.perform_action(args[0], options, 'Attaching disk') do |vm|
@ -816,37 +825,35 @@ CommandParser::CmdParser.new(ARGV) do
end
nic_attach_desc = <<-EOT.unindent
Attaches a NIC to a VM. When using --file add only one NIC instance.
Attaches a NIC to a VM.
To attach a nic alias
#{OneVMHelper.template_input_help('NIC')}
To hotplug a PCI device and use it as a NIC interface in the VM select
it with --pci (short_address) or --pci_device (device ID),
--pci_class (class ID) and/or --pci_vendor (vendor ID).
To attach a nic alias, use --file or --alias option.
States: RUNNING, POWEROFF
EOT
command :"nic-attach", nic_attach_desc, :vmid,
:options => [OneVMHelper::FILE,
OneVMHelper::NETWORK,
OneVMHelper::IP,
OneVMHelper::ALIAS,
OneVMHelper::NIC_NAME,
PCI,
PCI_CLASS,
PCI_VENDOR,
PCI_DEVICE] do
if options[:file].nil? && options[:network].nil?
STDERR.puts 'Provide a template file or a network:'
STDERR.puts "\t--file <file>"
STDERR.puts "\t--network <network>"
exit(-1)
end
:options => [
OpenNebulaHelper::FILE,
OneVMHelper::NETWORK,
OneVMHelper::IP,
OneVMHelper::ALIAS,
OneVMHelper::NIC_NAME,
PCI,
PCI_CLASS,
PCI_VENDOR,
PCI_DEVICE
] do
if options[:file]
template = File.read(options[:file])
else
elsif STDIN.wait_readable(0)
template = STDIN.read
elsif options[:network]
network_id = options[:network]
ip = options[:ip]
nic_alias = options[:alias]
@ -878,6 +885,11 @@ CommandParser::CmdParser.new(ARGV) do
template << ", IP = #{ip}" if ip
template << ", NAME = #{nic_name}" if nic_name
template << ']'
else
STDERR.puts 'Provide a network or a template:'
STDERR.puts "\t--file <file>"
STDERR.puts "\t--network <network>"
exit(-1)
end
helper.perform_action(args[0], options, 'Attaching NIC') do |vm|
@ -1258,13 +1270,15 @@ CommandParser::CmdParser.new(ARGV) do
Resizes the capacity of a Virtual Machine (offline, the VM cannot be
RUNNING)
#{OpenNebulaHelper::TEMPLATE_INPUT}
EOT
command :resize, resize_desc, :vmid,
:options => OpenNebulaHelper::CAPACITY_OPTIONS_VM +
[ENFORCE, OneVMHelper::FILE] do
:options => OpenNebulaHelper::CAPACITY_OPTIONS_VM + [ENFORCE, OpenNebulaHelper::FILE] do
if options[:file]
template = File.read(options[:file])
elsif STDIN.wait_readable(0)
template = STDIN.read
else
template = ''
@ -1317,8 +1331,10 @@ CommandParser::CmdParser.new(ARGV) do
In running state only changes in CONTEXT and BACKUP_CONFIG take effect
immediately, other values may need a VM restart.
This command accepts a template file or opens an editor, the full list of
configuration attributes are:
This command accepts a template or opens an editor.
#{OpenNebulaHelper::TEMPLATE_INPUT}
The full list of configuration attributes are:
OS = ["ARCH", "MACHINE", "KERNEL", "INITRD", "BOOTLOADER", "BOOT", "UUID"]
FEATURES = ["ACPI", "PAE", "APIC", "LOCALTIME", "HYPERV", "GUEST_AGENT", "IOTHREADS"]
@ -1336,6 +1352,7 @@ CommandParser::CmdParser.new(ARGV) do
begin
template = File.read(args[1]) if args[1]
template = STDIN.read if STDIN.wait_readable(0)
rescue StandardError => e
STDERR.puts "Error reading template: #{e.message}."
exit(-1)

View File

@ -161,15 +161,18 @@ CommandParser::CmdParser.new(ARGV) do
########################################################################
create_desc = <<-EOT.unindent
Creates a new Virtual Network from the given template file
Creates a new Virtual Network from the given template
#{OpenNebulaHelper::TEMPLATE_INPUT}
EOT
command :create, create_desc, :file, :options => CREATE_OPTIONS do
command :create, create_desc, [:file, nil], :options => CREATE_OPTIONS do
cid = options[:cluster] || ClusterPool::NONE_CLUSTER_ID
helper.create_resource(options) do |vn|
begin
template = File.read(args[0])
template = File.read(args[0]) if args[0]
template = STDIN.read if STDIN.wait_readable(0)
vn.allocate(template, cid)
rescue StandardError => e
STDERR.puts "Error creating network: #{e.message}"

View File

@ -134,13 +134,14 @@ CommandParser::CmdParser.new(ARGV) do
create_desc = <<-EOT.unindent
Creates a new Virtual Router from the given description
#{OpenNebulaHelper::TEMPLATE_INPUT}
EOT
command :create, create_desc, :file do
command :create, create_desc, [:file, nil] do
helper.create_resource(options) do |obj|
begin
template = File.read(args[0])
template = File.read(args[0]) if args[0]
template = STDIN.read if STDIN.wait_readable(0)
obj.allocate(template)
rescue StandardError => e
STDERR.puts e.message
@ -153,6 +154,8 @@ CommandParser::CmdParser.new(ARGV) do
Creates a new VM instance from the given Template. This VM can be
managed with the 'onevm' command.
#{OpenNebulaHelper::TEMPLATE_INPUT}
The NIC elements defined in the Virtual Router will be used. The
source Template can be modified adding or replacing attributes with
the optional file argument, or with the options.
@ -168,9 +171,10 @@ CommandParser::CmdParser.new(ARGV) do
:vrouterid, :templateid, [:file, nil],
:options => instantiate_options +
OpenNebulaHelper::TEMPLATE_OPTIONS do
if args[2] && OpenNebulaHelper.create_template_options_used?(options)
STDERR.puts 'You cannot use both template file and template' \
' creation options.'
if (args[2] || STDIN.wait_readable(0)) &&
OpenNebulaHelper.create_template_options_used?(options)
STDERR.puts 'You cannot use both template and template creation options.'
exit(-1)
end
@ -194,6 +198,8 @@ CommandParser::CmdParser.new(ARGV) do
if args[2]
extra_template = File.read(args[2])
elsif STDIN.wait_readable(0)
extra_template = STDIN.read
else
res = OpenNebulaHelper.create_template(options, t)
@ -292,20 +298,15 @@ CommandParser::CmdParser.new(ARGV) do
EOT
command :"nic-attach", nic_attach_desc, :vrouterid,
:options => [OneVMHelper::FILE,
:options => [OpenNebulaHelper::FILE,
OneVMHelper::NETWORK,
OneVMHelper::IP,
OneVirtualRouterHelper::FLOAT] do
if options[:file].nil? && options[:network].nil?
STDERR.puts 'Provide a template file or a network:'
STDERR.puts "\t--file <file>"
STDERR.puts "\t--network <network>"
exit(-1)
end
if options[:file]
template = File.read(options[:file])
else
elsif STDIN.wait_readable(0)
template = STDIN.read
elsif options[:network]
network_id = options[:network]
ip = options[:ip]
float = options[:float]
@ -321,6 +322,11 @@ CommandParser::CmdParser.new(ARGV) do
end
template += ' ]'
else
STDERR.puts 'Provide a template or a network:'
STDERR.puts "\t--file <file>"
STDERR.puts "\t--network <network>"
exit(-1)
end
helper.perform_action(args[0], options, 'Attach NIC') do |vr|