opennebula-cli 6.6.3 → 6.7.80.pre

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e74dc25cf00cc6c901701dcfef74bb0d5f34145ca4ce12d3a2aae23f4f0ce83
4
- data.tar.gz: fabdc4659737fb9adc7219d04b0057034ad04503f1c28e68912c748f02405952
3
+ metadata.gz: eee545474bf0e6d7e0e17736dbe8368ee4c202290a1d2fd2eb78f7ff2fa3d7ce
4
+ data.tar.gz: 69482fde22ac494444d5ee6d46b1c6c3139bab455ef4249a01635b2c742d7613
5
5
  SHA512:
6
- metadata.gz: a2cd0831f008fb2b52ea545c2d1615a8cc0e31e376199e6b52dab49553b1677e6628dbafd0fde22544562d4c8bea00572ce1b20e353dc45e096e5f721d5a35c9
7
- data.tar.gz: 10d16e841304506cb3978fd67d8349e7f7684bbe70fc2f7351a2fcc1129f41af9a626a8580099f24415d879d280b1e085ce7b29ff523e35b13e6c04d66e0a71d
6
+ metadata.gz: '01459d545a24766ff69ebd323d09ee805f09dfe27805b9bfe980ee38340bcb5ef6ad268936cc45c9d8ecfd0895abdc638c6451d61a461c34ee073400abbcf506'
7
+ data.tar.gz: 8a7a12b5f0bac4ccb3685f816f74efd6612593b2c11205bb3417d96280478f80d9081ec47379ca6876feb8110230fc0e062e8a5a756102d363064ec76d18dcc0
data/bin/onebackupjob ADDED
@@ -0,0 +1,373 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # -------------------------------------------------------------------------- #
4
+ # Copyright 2002-2023, OpenNebula Project, OpenNebula Systems #
5
+ # #
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may #
7
+ # not use this file except in compliance with the License. You may obtain #
8
+ # a copy of the License at #
9
+ # #
10
+ # http://www.apache.org/licenses/LICENSE-2.0 #
11
+ # #
12
+ # Unless required by applicable law or agreed to in writing, software #
13
+ # distributed under the License is distributed on an "AS IS" BASIS, #
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15
+ # See the License for the specific language governing permissions and #
16
+ # limitations under the License. #
17
+ #--------------------------------------------------------------------------- #
18
+
19
+ ONE_LOCATION = ENV['ONE_LOCATION']
20
+
21
+ if !ONE_LOCATION
22
+ RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
24
+ else
25
+ RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ # %%RUBYGEMS_SETUP_BEGIN%%
30
+ if File.directory?(GEMS_LOCATION)
31
+ real_gems_path = File.realpath(GEMS_LOCATION)
32
+ if !defined?(Gem) || Gem.path != [real_gems_path]
33
+ $LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
34
+
35
+ # Suppress warnings from Rubygems
36
+ # https://github.com/OpenNebula/one/issues/5379
37
+ begin
38
+ verb = $VERBOSE
39
+ $VERBOSE = nil
40
+ require 'rubygems'
41
+ Gem.use_paths(real_gems_path)
42
+ ensure
43
+ $VERBOSE = verb
44
+ end
45
+ end
46
+ end
47
+ # %%RUBYGEMS_SETUP_END%%
48
+
49
+ $LOAD_PATH << RUBY_LIB_LOCATION
50
+ $LOAD_PATH << RUBY_LIB_LOCATION + '/cli'
51
+
52
+ require 'tempfile'
53
+ require 'command_parser'
54
+ require 'one_helper/onebackupjob_helper'
55
+
56
+ CommandParser::CmdParser.new(ARGV) do
57
+ usage '`onebackupjob` <command> [<args>] [<options>]'
58
+ version OpenNebulaHelper::ONE_VERSION
59
+
60
+ helper = OneBackupJobHelper.new
61
+
62
+ before_proc do
63
+ helper.set_client(options)
64
+ end
65
+
66
+ USE = {
67
+ :name => 'use',
68
+ :large => '--use',
69
+ :description => 'lock use actions'
70
+ }
71
+
72
+ MANAGE = {
73
+ :name => 'manage',
74
+ :large => '--manage',
75
+ :description => 'lock manage actions'
76
+ }
77
+
78
+ ADMIN = {
79
+ :name => 'admin',
80
+ :large => '--admin',
81
+ :description => 'lock admin actions'
82
+ }
83
+
84
+ ALL = {
85
+ :name => 'all',
86
+ :large => '--all',
87
+ :description => 'lock all actions'
88
+ }
89
+
90
+ ########################################################################
91
+ # Global Options
92
+ ########################################################################
93
+ set :option, CommandParser::OPTIONS + OpenNebulaHelper::CLIENT_OPTIONS
94
+
95
+ list_options = CLIHelper::OPTIONS
96
+ list_options += OpenNebulaHelper::FORMAT
97
+ list_options << OpenNebulaHelper::NUMERIC
98
+ list_options << OpenNebulaHelper::DESCRIBE
99
+
100
+ ########################################################################
101
+ # Formatters for arguments
102
+ ########################################################################
103
+ set :format, :groupid, OpenNebulaHelper.rname_to_id_desc('GROUP') do |arg|
104
+ OpenNebulaHelper.rname_to_id(arg, 'GROUP')
105
+ end
106
+
107
+ set :format, :userid, OpenNebulaHelper.rname_to_id_desc('USER') do |arg|
108
+ OpenNebulaHelper.rname_to_id(arg, 'USER')
109
+ end
110
+
111
+ set :format, :backupjobid, OneBackupJobHelper.to_id_desc do |arg|
112
+ helper.to_id(arg)
113
+ end
114
+
115
+ set :format, :backupjobid_list, OneBackupJobHelper.list_to_id_desc do |arg|
116
+ helper.list_to_id(arg)
117
+ end
118
+
119
+ set :format, :filterflag, OneBackupJobHelper.filterflag_to_i_desc do |arg|
120
+ helper.filterflag_to_i(arg)
121
+ end
122
+
123
+ ########################################################################
124
+ # Commands
125
+ ########################################################################
126
+
127
+ create_desc = <<-EOT.unindent
128
+ Creates a new Backup Job
129
+ Examples:
130
+ - using a template description file:
131
+
132
+ onebackupjob create weekly_backup.tmpl
133
+ EOT
134
+
135
+ command :create,
136
+ create_desc,
137
+ [:file, nil],
138
+ :options => [OpenNebulaHelper::SCHEDULE_OPTIONS] +
139
+ OneBackupJobHelper::TEMPLATE_OPTIONS do
140
+ rc = nil
141
+
142
+ helper.create_resource(options) do |bj|
143
+ begin
144
+ if args[0]
145
+ template = File.read(args[0])
146
+ else
147
+ template = OneBackupJobHelper.create_backupjob_template(options)
148
+ end
149
+
150
+ rc = bj.allocate(template)
151
+ rescue StandardError => e
152
+ STDERR.puts e.message
153
+ exit(-1)
154
+ end
155
+
156
+ if OpenNebula.is_error?(rc)
157
+ puts rc.message
158
+ exit(-1)
159
+ end
160
+
161
+ helper.schedule_actions([bj.id], options) unless options[:schedule].nil?
162
+ end
163
+ end
164
+
165
+ delete_desc = <<-EOT.unindent
166
+ Deletes the given Backup Job
167
+ EOT
168
+
169
+ command :delete, delete_desc, [:range, :backupjobid_list] do
170
+ helper.perform_actions(args[0], options, 'deleting') do |bj|
171
+ bj.delete
172
+ end
173
+ end
174
+
175
+ update_desc = <<-EOT.unindent
176
+ Update the Backup Job contents. If a path is not provided the editor will
177
+ be launched to modify the current content.
178
+ EOT
179
+
180
+ command :update, update_desc, :backupjobid, [:file, nil],
181
+ :options => OpenNebulaHelper::APPEND do
182
+ helper.perform_action(args[0], options, 'modified') do |obj|
183
+ if args[1]
184
+ str = File.read(args[1])
185
+ elsif options[:append]
186
+ OpenNebulaHelper.editor_input
187
+ else
188
+ rc = obj.info
189
+
190
+ if OpenNebula.is_error?(rc)
191
+ puts rc.message
192
+ exit(-1)
193
+ end
194
+
195
+ obj.delete_element('TEMPLATE/SCHED_ACTION')
196
+
197
+ str = OpenNebulaHelper.editor_input(obj.template_like_str('TEMPLATE'))
198
+ end
199
+
200
+ obj.update(str, options[:append])
201
+ end
202
+ end
203
+
204
+ chgrp_desc = <<-EOT.unindent
205
+ Changes the Backup Job group
206
+ EOT
207
+
208
+ command :chgrp, chgrp_desc, [:range, :backupjobid_list], :groupid do
209
+ helper.perform_actions(args[0], options, 'Group changed') do |bj|
210
+ bj.chown(-1, args[1].to_i)
211
+ end
212
+ end
213
+
214
+ chown_desc = <<-EOT.unindent
215
+ Changes the Backup Job owner and group
216
+ EOT
217
+
218
+ command :chown, chown_desc, [:range, :backupjobid_list], :userid,
219
+ [:groupid, nil] do
220
+ args[2].nil? ? gid = -1 : gid = args[2].to_i
221
+ helper.perform_actions(args[0], options,
222
+ 'Owner/Group changed') do |bj|
223
+ bj.chown(args[1].to_i, gid)
224
+ end
225
+ end
226
+
227
+ chmod_desc = <<-EOT.unindent
228
+ Changes the BackupJob permissions
229
+ EOT
230
+
231
+ command :chmod, chmod_desc, [:range, :backupjobid_list], :octet do
232
+ helper.perform_actions(args[0], options,
233
+ 'Permissions changed') do |bj|
234
+ bj.chmod_octet(OpenNebulaHelper.to_octet(args[1]))
235
+ end
236
+ end
237
+
238
+ rename_desc = <<-EOT.unindent
239
+ Renames the Backup Job
240
+ EOT
241
+
242
+ command :rename, rename_desc, :backupjobid, :name do
243
+ helper.perform_action(args[0], options, 'renamed') do |bj|
244
+ bj.rename(args[1])
245
+ end
246
+ end
247
+
248
+ list_desc = <<-EOT.unindent
249
+ Lists Backup Jobs in the pool. #{OneBackupJobHelper.list_layout_help}
250
+ EOT
251
+
252
+ command :list, list_desc, [:filterflag, nil], :options => list_options do
253
+ helper.list_pool(options, false, args[0])
254
+ end
255
+
256
+ show_desc = <<-EOT.unindent
257
+ Shows information for the given Backup Job
258
+ EOT
259
+
260
+ command :show, show_desc, :backupjobid,
261
+ :options => [OpenNebulaHelper::FORMAT] do
262
+ helper.show_resource(args[0], options)
263
+ end
264
+
265
+ lock_desc = <<-EOT.unindent
266
+ Locks a Backup Job to prevent certain actions defined by different levels.
267
+ The show action will never be locked.
268
+ Levels:
269
+ [Use]: locks Admin, Manage and Use actions.
270
+ [Manage]: locks Manage and Use actions.
271
+ [Admin]: locks only Admin actions.
272
+ EOT
273
+
274
+ command :lock, lock_desc, [:range, :backupjobid_list],
275
+ :options => [USE, MANAGE, ADMIN, ALL] do
276
+ helper.perform_actions(args[0], options, 'Backup Job locked') do |bj|
277
+ if !options[:use].nil?
278
+ level = 1
279
+ elsif !options[:manage].nil?
280
+ level = 2
281
+ elsif !options[:admin].nil?
282
+ level = 3
283
+ elsif !options[:all].nil?
284
+ level = 4
285
+ else
286
+ level = 1
287
+ end
288
+ bj.lock(level)
289
+ end
290
+ end
291
+
292
+ unlock_desc = <<-EOT.unindent
293
+ Unlocks an Backup Job.
294
+ EOT
295
+
296
+ command :unlock, unlock_desc, [:range, :backupjobid_list] do
297
+ helper.perform_actions(args[0], options, 'Backup Job unlocked') do |bj|
298
+ bj.unlock
299
+ end
300
+ end
301
+
302
+ backup_desc = <<-EOT.unindent
303
+ Start the Backup Job execution.
304
+ EOT
305
+
306
+ command :backup, backup_desc, [:range, :backupjobid_list],
307
+ :options => OpenNebulaHelper::SCHEDULE_OPTIONS do
308
+ if !options[:schedule].nil?
309
+ helper.schedule_actions(args[0], options)
310
+ else
311
+ helper.perform_actions(args[0], options, 'Starting Backups') do |bj|
312
+ bj.backup
313
+ end
314
+ end
315
+ end
316
+
317
+ cancel_desc = <<-EOT.unindent
318
+ Cancel pending Backup Job, remove Virtual Machines from the outdated list,
319
+ call cancel action on all ongoing VM backup operations.
320
+ EOT
321
+
322
+ command :cancel, cancel_desc, [:range, :backupjobid_list] do
323
+ helper.perform_actions(args[0], options, 'Backups canceled') do |bj|
324
+ bj.cancel
325
+ end
326
+ end
327
+
328
+ retry_desc = <<-EOT.unindent
329
+ Retry failed Backup Job. Trigger backup for Virtual Machines from error list.
330
+ EOT
331
+
332
+ command :retry, retry_desc, [:range, :backupjobid_list] do
333
+ helper.perform_actions(args[0], options,
334
+ 'Retrying backups for failed Virtual Machines') do |bj|
335
+ bj.retry
336
+ end
337
+ end
338
+
339
+ priority_desc = <<-EOT.unindent
340
+ Change the priority of the Backup Job. Only oneadmin may increase priority over 50.
341
+ EOT
342
+
343
+ command :priority, priority_desc, [:range, :backupjobid_list], :priority do
344
+ helper.perform_actions(args[0], options, 'Priority changed') do |bj|
345
+ bj.priority(args[1].to_i)
346
+ end
347
+ end
348
+
349
+ sched_delete_desc = <<-EOT.unindent
350
+ Remove a Scheduled Action from the Backup Job.
351
+ EOT
352
+
353
+ command :"sched-delete", sched_delete_desc, :bjid, :schedid do
354
+ schedid = args[1]
355
+
356
+ helper.perform_action(args[0], options, 'Scheduled Action deleted') do |bj|
357
+ bj.sched_action_delete(schedid)
358
+ end
359
+ end
360
+
361
+ sched_update_desc = <<-EOT.unindent
362
+ Update a Scheduled Action for the Backup Job.
363
+ EOT
364
+
365
+ command :"sched-update", sched_update_desc, :bjid, :schedid,
366
+ [:file, nil] do
367
+ bj_id = args[0]
368
+ sched_id = args[1]
369
+ file = args[2]
370
+
371
+ helper.update_schedule_action(bj_id, sched_id, file, options)
372
+ end
373
+ end
data/bin/onedatastore CHANGED
@@ -102,16 +102,19 @@ CommandParser::CmdParser.new(ARGV) do
102
102
  ########################################################################
103
103
 
104
104
  create_desc = <<-EOT.unindent
105
- Creates a new Datastore from the given template file
105
+ Creates a new Datastore from the given template
106
+
107
+ #{OpenNebulaHelper::TEMPLATE_INPUT}
106
108
  EOT
107
109
 
108
- command :create, create_desc, :file,
110
+ command :create, create_desc, [:file, nil],
109
111
  :options => [OneClusterHelper::CLUSTER] do
110
112
  cid = options[:cluster] || ClusterPool::NONE_CLUSTER_ID
111
113
 
112
114
  helper.create_resource(options) do |datastore|
113
115
  begin
114
- template = File.read(args[0])
116
+ template = File.read(args[0]) if args[0]
117
+ template = STDIN.read if STDIN.wait_readable(0)
115
118
  datastore.allocate(template, cid)
116
119
  rescue StandardError => e
117
120
  STDERR.puts e.message
data/bin/oneflow-template CHANGED
@@ -178,12 +178,24 @@ CommandParser::CmdParser.new(ARGV) do
178
178
  ###
179
179
 
180
180
  create_desc = <<-EOT.unindent
181
- Create a new Service Template
181
+ Create a new Service Template from a json service definition
182
+
183
+ #{OpenNebulaHelper::TEMPLATE_INPUT}
182
184
  EOT
183
185
 
184
- command :create, create_desc, :file, :options => Service::JSON_FORMAT do
185
- client = helper.client(options)
186
- response = client.post(RESOURCE_PATH, File.read(args[0]))
186
+ command :create, create_desc, [:file, nil], :options => Service::JSON_FORMAT do
187
+ client = helper.client(options)
188
+
189
+ template = nil
190
+ template = File.read(args[0]) if args[0]
191
+ template = STDIN.read if STDIN.wait_readable(0)
192
+
193
+ if template.nil?
194
+ STDERR.puts 'A template must be provided'
195
+ exit(-1)
196
+ end
197
+
198
+ response = client.post(RESOURCE_PATH, template)
187
199
 
188
200
  if CloudClient.is_error?(response)
189
201
  [response.code.to_i, response.to_s]
@@ -233,6 +245,9 @@ CommandParser::CmdParser.new(ARGV) do
233
245
 
234
246
  instantiate_desc = <<-EOT.unindent
235
247
  Instantiate a Service Template
248
+ Optionally append modifications with a json service definition
249
+
250
+ #{OpenNebulaHelper::TEMPLATE_INPUT}
236
251
  EOT
237
252
 
238
253
  command :instantiate, instantiate_desc, :templateid, [:file, nil],
@@ -243,8 +258,11 @@ CommandParser::CmdParser.new(ARGV) do
243
258
  client = helper.client(options)
244
259
 
245
260
  number.times do
246
- params['merge_template'] = nil
247
- params['merge_template'] = JSON.parse(File.read(args[1])) if args[1]
261
+ template = nil
262
+ template = File.read(args[1]) if args[1]
263
+ template = STDIN.read if STDIN.wait_readable(0)
264
+
265
+ params['merge_template'] = JSON.parse(template) if template
248
266
 
249
267
  unless params['merge_template']
250
268
  response = client.get("#{RESOURCE_PATH}/#{args[0]}")
data/bin/oneimage CHANGED
@@ -180,6 +180,8 @@ CommandParser::CmdParser.new(ARGV) do
180
180
 
181
181
  oneimage create -d default centOS.tmpl
182
182
 
183
+ #{OpenNebulaHelper::TEMPLATE_INPUT}
184
+
183
185
  - new image "arch" using a path:
184
186
 
185
187
  oneimage create -d default --name arch --path /tmp/arch.img
@@ -213,9 +215,10 @@ CommandParser::CmdParser.new(ARGV) do
213
215
  check_capacity = true
214
216
  end
215
217
 
216
- if args[0] && OpenNebulaHelper.create_template_options_used?(options)
217
- STDERR.puts 'You can not use both template file and template' \
218
- ' creation options.'
218
+ if (args[0] || STDIN.wait_readable(0)) &&
219
+ OpenNebulaHelper.create_template_options_used?(options)
220
+
221
+ STDERR.puts 'You cannot use both template and template creation options.'
219
222
  next -1
220
223
  end
221
224
 
@@ -232,6 +235,8 @@ CommandParser::CmdParser.new(ARGV) do
232
235
  begin
233
236
  if args[0]
234
237
  template = File.read(args[0])
238
+ elsif STDIN.wait_readable(0)
239
+ template = STDIN.read
235
240
  else
236
241
  res = OneImageHelper.create_image_template(options)
237
242
 
data/bin/onemarket CHANGED
@@ -98,13 +98,15 @@ CommandParser::CmdParser.new(ARGV) do
98
98
  ########################################################################
99
99
 
100
100
  create_desc = <<-EOT.unindent
101
- Creates a new Marketplace from the given template file
101
+ Creates a new Marketplace from the given template
102
+ #{OpenNebulaHelper::TEMPLATE_INPUT}
102
103
  EOT
103
104
 
104
- command :create, create_desc, :file do
105
+ command :create, create_desc, [:file, nil] do
105
106
  helper.create_resource(options) do |marketplace|
106
107
  begin
107
- template = File.read(args[0])
108
+ template = File.read(args[0]) if args[0]
109
+ template = STDIN.read if STDIN.wait_readable(0)
108
110
  marketplace.allocate(template)
109
111
  rescue StandardError => e
110
112
  STDERR.puts e.message
data/bin/onemarketapp CHANGED
@@ -178,6 +178,8 @@ CommandParser::CmdParser.new(ARGV) do
178
178
 
179
179
  create_desc = <<-EOT.unindent
180
180
  Creates a new marketplace app in the given marketplace
181
+
182
+ #{OpenNebulaHelper::TEMPLATE_INPUT}
181
183
  EOT
182
184
 
183
185
  command :create, create_desc, [:file, nil],
@@ -189,7 +191,7 @@ CommandParser::CmdParser.new(ARGV) do
189
191
  exit(-1)
190
192
  end
191
193
 
192
- if args[0] &&
194
+ if (args[0] || STDIN.wait_readable(0)) &&
193
195
  OneMarketPlaceAppHelper.create_template_options_used?(options)
194
196
  STDERR.puts 'You can not use both template file and template'\
195
197
  ' creation options.'
@@ -200,6 +202,8 @@ CommandParser::CmdParser.new(ARGV) do
200
202
  begin
201
203
  if args[0]
202
204
  template = File.read(args[0])
205
+ elsif STDIN.wait_readable(0)
206
+ template = STDIN.read
203
207
  else
204
208
  res = OneMarketPlaceAppHelper
205
209
  .create_datastore_template(options)
data/bin/onetemplate CHANGED
@@ -149,6 +149,8 @@ CommandParser::CmdParser.new(ARGV) do
149
149
 
150
150
  onetemplate create vm_description.tmpl
151
151
 
152
+ #{OpenNebulaHelper::TEMPLATE_INPUT}
153
+
152
154
  - new VM Template named "arch vm" with a disk and a nic:
153
155
 
154
156
  onetemplate create --name "arch vm" --memory 128 --cpu 1 \\
@@ -164,9 +166,10 @@ CommandParser::CmdParser.new(ARGV) do
164
166
  command :create, create_desc, [:file, nil], :options =>
165
167
  [OneTemplateHelper::VM_NAME] + OpenNebulaHelper::TEMPLATE_OPTIONS +
166
168
  [OpenNebulaHelper::DRY] do
167
- if args[0] && OpenNebulaHelper.create_template_options_used?(options)
168
- STDERR.puts 'You can not use both template file and template' \
169
- ' creation options.'
169
+ if (args[0] || STDIN.wait_readable(0)) &&
170
+ OpenNebulaHelper.create_template_options_used?(options)
171
+
172
+ STDERR.puts 'You can not use both template file and template creation options.'
170
173
  next -1
171
174
  end
172
175
 
@@ -174,6 +177,8 @@ CommandParser::CmdParser.new(ARGV) do
174
177
  begin
175
178
  if args[0]
176
179
  template = File.read(args[0])
180
+ elsif STDIN.wait_readable(0)
181
+ template = STDIN.read
177
182
  else
178
183
  res = OpenNebulaHelper.create_template(options)
179
184
 
@@ -248,13 +253,13 @@ CommandParser::CmdParser.new(ARGV) do
248
253
  EOT
249
254
 
250
255
  command :instantiate, instantiate_desc, :templateid, [:file, nil],
251
- :options => instantiate_options +
252
- OpenNebulaHelper::TEMPLATE_OPTIONS do
256
+ :options => instantiate_options + OpenNebulaHelper::TEMPLATE_OPTIONS do
253
257
  exit_code = 0
254
258
 
255
- if args[1] && OpenNebulaHelper.create_template_options_used?(options)
256
- STDERR.puts 'You cannot use both template file and template' \
257
- ' creation options.'
259
+ if (args[1] || STDIN.wait_readable(0)) &&
260
+ OpenNebulaHelper.create_template_options_used?(options)
261
+
262
+ STDERR.puts 'You cannot use both template and template creation options.'
258
263
  next -1
259
264
  end
260
265
 
@@ -300,6 +305,8 @@ CommandParser::CmdParser.new(ARGV) do
300
305
 
301
306
  if args[1]
302
307
  extra_template = File.read(args[1])
308
+ elsif STDIN.wait_readable(0)
309
+ extra_template = STDIN.read
303
310
  else
304
311
  res = OpenNebulaHelper.create_template(options, t)
305
312