foreman_azure_rm 2.2.0 → 2.2.5

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: 416621db4c525470113b126a84a30a5701999e6bc442f6e18beb0bdd6b3379a3
4
- data.tar.gz: 6ec1793bc3394b0a19f92f5ad98a33c005e30fce89bd549ebde954529ab7d895
3
+ metadata.gz: 39f6ca7eb686ea697b8c9f506303f41e545e46e2ad5aeb72fe376edb9780ee64
4
+ data.tar.gz: bfd45c748455ba48ced60736ec4682708a223e862fc726e567eeb424c27fa874
5
5
  SHA512:
6
- metadata.gz: f8a953836164727d9bba985be5d77b8211c73bc2cc20f45c7de563d49fb06cd32652695e6b4a0b42c19e0dcd5a5d86b51b347562b460f90eb33342f518044fd7
7
- data.tar.gz: 79cbe567f0cb3556b046f208c6f7218876c4ab10fb8b74d4ae6e2d9df8a9f601b8a895cff46e236630c306f1f977a00c5976517af99c39744b6060a72b0cfda7
6
+ metadata.gz: cf021fdd847e111d38db05a4ace1070dd4bbaa4d03979405a424b55eb84b94da216b36883a6bc9957ba0c6041a0301e77586b687619a9ad23742dd26229d08b1
7
+ data.tar.gz: d8ff32ba98f6125b0a1200b4d93491c5735c355747aba3d5e951db72c58883879b7bab6021162f5979dda3fbac6bd325c1588881a9c000b3f1725677a8627f15
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Foreman AzureRm Plugin
2
2
 
3
3
  ## Description
4
- ```foreman_azure_rm``` adds [Microsoft Azure Resource Manager](http://azure.com/) as a compute resource for The Foreman
4
+ ```foreman_azure_rm``` adds [Microsoft Azure Resource Manager](http://azure.com/) as a Compute Resource for The Foreman
5
5
 
6
6
  * Website: [TheForeman.org](http://theforeman.org)
7
7
  * ForemanAzureRm: [Plugin manual](https://theforeman.org/plugins/foreman_azure)
@@ -11,7 +11,7 @@
11
11
 
12
12
  ### Bundle (Gem)
13
13
 
14
- Add the following to bundler.d/Gemfile.local.rb in your Foreman installation directory (/usr/share/foreman by default)
14
+ Add the following to `bundler.d/Gemfile.local.rb` in your Foreman installation directory `/usr/share/foreman`
15
15
 
16
16
  ```console
17
17
  $ gem 'foreman_azure_rm'
@@ -55,7 +55,6 @@ Then run `bundle install` from the same directory
55
55
  * VM creation
56
56
  * Provisions using Finish and User data templates from Foreman
57
57
  * Supports cloud-config provisioning
58
- * Currently supports only provisioning of Linux platforms
59
58
  * Provisioning using [Public Images](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/cli-ps-findimage)
60
59
  * Provision using custom images
61
60
  * Provision using shared image galleries
@@ -64,6 +63,7 @@ Then run `bundle install` from the same directory
64
63
  * Support to add multiple data disks/volumes (standard or premium)
65
64
  * VM Extension with Custom Script and File URIs support
66
65
  * Static or dynamic addresses on a per NIC basis
66
+ * Support for NVIDIA Drivers or CUDA on Linux and Windows
67
67
  * Limited extension support
68
68
  * Microsoft's custom script extension
69
69
  * Puppet Lab's Puppet agent extension for Windows
@@ -74,16 +74,16 @@ Go to **Infrastructure > Compute Resources** and click on "New Compute Resource"
74
74
 
75
75
  Choose the **Azure Resource Manager provider**, and fill in all the fields. You need a Subscription ID, Tenant ID, Client ID and a Client Secret which you can generate from your [Microsoft Azure subscription](https://docs.bmc.com/docs/cloudlifecyclemanagement/46/setting-up-a-tenant-id-client-id-and-client-secret-for-azure-resource-manager-provisioning-669202145.html#SettingupaTenantID,ClientID,andClientSecretforAzureResourceManagerprovisioning-SetupTenantIDPrereqPrerequisites)
76
76
 
77
- That's it. You're now ready to create and manage Azure resources in your new Azure Resource Manager compute resource. You should see something like this in the Compute Resource page:
77
+ That's it. You're now ready to create and manage Azure resources in your new Azure Resource Manager Compute Resource. You should see something like this in the Compute Resource page:
78
78
 
79
79
 
80
- ![](https://i.imgur.com/vsamP4G.png)
80
+ ![](https://i.imgur.com/yMGg3A6.png)
81
81
 
82
82
 
83
83
  ![](https://i.imgur.com/Ag9tH55.png)
84
84
 
85
85
 
86
- ![](https://i.imgur.com/fNjlFci.png)
86
+ ![](https://i.imgur.com/OKoGgUY.png)
87
87
 
88
88
 
89
89
  ## Planned Features
@@ -91,7 +91,6 @@ That's it. You're now ready to create and manage Azure resources in your new Azu
91
91
 
92
92
  ## Known Limitations
93
93
  * Please note that currently username is expected to be the same on both Virtual Machine tab for Host creation and during Image creation for Compute Resource. The password field for Image creation is optional.
94
- * Unable to provision using Windows Images
95
94
 
96
95
  ## Links
97
96
  * [Issue tracker](https://projects.theforeman.org/projects/azurerm)
@@ -10,8 +10,7 @@ module AzureComputeResourceHelper
10
10
  end
11
11
  selectable_f(f, :url, regions, {}, {:label => _('Azure Region'), :disabled => regions.empty?, :required => true, :help_inline_permanent => load_button_f(f, regions.present?, _("Load Regions")) })
12
12
  end
13
- def azure_doc_url
13
+ def azure_doc_version
14
14
  doc_version = Foreman::Plugin.find(:foreman_azure_rm).version.scan(/\d+\.\d+/).first + '.x'
15
- "https://theforeman.org/plugins/foreman_azure/#{doc_version}"
16
15
  end
17
16
  end
@@ -4,7 +4,7 @@ module ForemanAzureRm
4
4
  module ManagedVM
5
5
  extend ActiveSupport::Concern
6
6
 
7
- def define_managed_storage_profile(vm_name, os_disk_caching, platform, premium_os_disk)
7
+ def define_managed_storage_profile(vm_name, os_disk_caching, platform, premium_os_disk, os_disk_size_gb)
8
8
  storage_profile = ComputeModels::StorageProfile.new
9
9
  os_disk = ComputeModels::OSDisk.new
10
10
  managed_disk_params = ComputeModels::ManagedDiskParameters.new
@@ -12,6 +12,7 @@ module ForemanAzureRm
12
12
  # Create OS disk
13
13
  os_disk.name = "#{vm_name}-osdisk"
14
14
  os_disk.os_type = platform
15
+ os_disk.disk_size_gb = os_disk_size_gb
15
16
  os_disk.create_option = ComputeModels::DiskCreateOptionTypes::FromImage
16
17
  os_disk.caching = disk_caching(os_disk_caching)
17
18
  managed_disk_params.storage_account_type = if premium_os_disk == 'true'
@@ -122,7 +123,7 @@ module ForemanAzureRm
122
123
  def create_nics(region, args = {})
123
124
  nics = []
124
125
  args[:interfaces_attributes].each do |nic, attrs|
125
- private_ip = (attrs[:private_ip] == 'false') ? false : true
126
+ private_ip = Foreman::Cast.to_bool(attrs[:private_ip])
126
127
  priv_ip_alloc = if private_ip
127
128
  NetworkModels::IPAllocationMethod::Static
128
129
  else
@@ -187,21 +188,23 @@ module ForemanAzureRm
187
188
  os_profile.admin_password = vm_hash[:password]
188
189
 
189
190
  # Adding the ssh-key support for authentication
190
- os_profile.linux_configuration = ComputeModels::LinuxConfiguration.new.tap do |linux|
191
- linux.disable_password_authentication = vm_hash[:disable_password_authentication]
192
- linux.ssh = ComputeModels::SshConfiguration.new.tap do |ssh_config|
193
- ssh_config.public_keys = [
194
- ComputeModels::SshPublicKey.new.tap do |foreman_key|
195
- foreman_key.key_data = key_pair.public
196
- foreman_key.path = "/home/#{vm_hash[:username]}/.ssh/authorized_keys"
191
+ if vm_hash[:platform] == 'Linux'
192
+ os_profile.linux_configuration = ComputeModels::LinuxConfiguration.new.tap do |linux|
193
+ linux.disable_password_authentication = vm_hash[:disable_password_authentication]
194
+ linux.ssh = ComputeModels::SshConfiguration.new.tap do |ssh_config|
195
+ ssh_config.public_keys = [
196
+ ComputeModels::SshPublicKey.new.tap do |foreman_key|
197
+ foreman_key.key_data = key_pair.public
198
+ foreman_key.path = "/home/#{vm_hash[:username]}/.ssh/authorized_keys"
199
+ end
200
+ ]
201
+ if vm_hash[:ssh_key_data].present?
202
+ key_data = vm_hash[:ssh_key_data]
203
+ pub_key = ComputeModels::SshPublicKey.new
204
+ pub_key.key_data = key_data
205
+ pub_key.path = "/home/#{vm_hash[:username]}/.ssh/authorized_keys"
206
+ ssh_config.public_keys << pub_key
197
207
  end
198
- ]
199
- if vm_hash[:ssh_key_data].present?
200
- key_data = vm_hash[:ssh_key_data]
201
- pub_key = ComputeModels::SshPublicKey.new
202
- pub_key.key_data = key_data
203
- pub_key.path = "/home/#{vm_hash[:username]}/.ssh/authorized_keys"
204
- ssh_config.public_keys << pub_key
205
208
  end
206
209
  end
207
210
  end
@@ -212,7 +215,8 @@ module ForemanAzureRm
212
215
  vm_hash[:name],
213
216
  vm_hash[:os_disk_caching],
214
217
  vm_hash[:platform],
215
- vm_hash[:premium_os_disk]
218
+ vm_hash[:premium_os_disk],
219
+ vm_hash[:os_disk_size_gb]
216
220
  )
217
221
  vm.hardware_profile = ComputeModels::HardwareProfile.new.tap do |hw_profile|
218
222
  hw_profile.vm_size = vm_hash[:vm_size]
@@ -235,23 +239,65 @@ module ForemanAzureRm
235
239
  if args[:script_command].present? || args[:script_uris].present?
236
240
  args[:script_uris] ||= args[:script_uris].to_s
237
241
  extension = ComputeModels::VirtualMachineExtension.new
238
- if args[:platform] == 'Linux'
242
+
243
+ case args[:platform]
244
+ # https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/custom-script-linux
245
+ when 'Linux'
239
246
  extension.publisher = 'Microsoft.Azure.Extensions'
240
247
  extension.virtual_machine_extension_type = 'CustomScript'
241
248
  extension.type_handler_version = '2.0'
249
+ # https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/custom-script-windows
250
+ when 'Windows'
251
+ extension.publisher = 'Microsoft.Compute'
252
+ extension.virtual_machine_extension_type = 'CustomScriptExtension'
253
+ extension.type_handler_version = '1.10'
254
+ else
255
+ raise RuntimeError, "Unsupported platform #{args[:platform]}"
242
256
  end
257
+
243
258
  extension.auto_upgrade_minor_version = true
244
259
  extension.location = region
245
260
  extension.settings = {
246
261
  'commandToExecute' => args[:script_command],
247
262
  'fileUris' => args[:script_uris].split(',')
248
263
  }
264
+
265
+ extension_for_log = "#{extension.publisher}/#{extension.virtual_machine_extension_type}/#{extension.type_handler_version}"
266
+ Foreman::Logging.logger('app').info "Azure RM machine #{args[:name]}: creating #{extension_for_log} extension"
249
267
  sdk.create_or_update_vm_extensions(args[:resource_group],
250
268
  args[:vm_name],
251
269
  'ForemanCustomScript',
252
270
  extension)
253
271
  end
254
272
  end
273
+
274
+ def create_vm_nvidia_gpu_extension(region, args = {})
275
+ extension = ComputeModels::VirtualMachineExtension.new
276
+ extension.publisher = 'Microsoft.HpcCompute'
277
+ extension.type_handler_version = '1.3'
278
+ extension.auto_upgrade_minor_version = true
279
+ extension.location = region
280
+
281
+ case args[:platform]
282
+ # https://docs.microsoft.com/fr-fr/azure/virtual-machines/extensions/hpccompute-gpu-linux
283
+ when 'Linux'
284
+ extension_name = 'NvidiaGpuDriverLinux'
285
+ # https://docs.microsoft.com/fr-fr/azure/virtual-machines/extensions/hpccompute-gpu-windows
286
+ when 'Windows'
287
+ extension_name = 'NvidiaGpuDriverWindows'
288
+ else
289
+ raise RuntimeError, "Unsupported platform #{args[:platform]}"
290
+ end
291
+ extension.virtual_machine_extension_type = extension_name
292
+
293
+ extension_for_log = "#{extension.publisher}/#{extension.virtual_machine_extension_type}/#{extension.type_handler_version}"
294
+ Foreman::Logging.logger('app').info "Azure RM machine #{args[:name]}: creating #{extension_for_log} extension"
295
+ sdk.create_or_update_vm_extensions(args[:resource_group],
296
+ args[:vm_name],
297
+ extension_name,
298
+ extension)
299
+ end
300
+
255
301
  end
256
302
  end
257
303
  end
@@ -43,7 +43,7 @@ module ForemanAzureRm
43
43
  end
44
44
 
45
45
  def cloud
46
- attrs[:cloud]
46
+ attrs[:cloud] || 'azure'
47
47
  end
48
48
 
49
49
  def cloud=(name)
@@ -115,7 +115,9 @@ module ForemanAzureRm
115
115
  platform: opts[:platform],
116
116
  ssh_key_data: opts[:ssh_key_data],
117
117
  os_disk_caching: opts[:os_disk_caching],
118
- premium_os_disk: opts[:premium_os_disk]
118
+ premium_os_disk: opts[:premium_os_disk],
119
+ os_disk_size_gb: opts[:os_disk_size_gb],
120
+ nvidia_gpu_extension: opts[:nvidia_gpu_extension],
119
121
  )
120
122
  if opts[:interfaces].present?
121
123
  ifaces = []
@@ -126,7 +128,16 @@ module ForemanAzureRm
126
128
 
127
129
  vols = opts.fetch(:volumes, []).map { |vols_attrs| new_volume(vols_attrs) } if opts[:volumes].present?
128
130
 
129
- AzureRmCompute.new(azure_vm: raw_vm ,sdk: sdk, resource_group: opts[:resource_group], nics: ifaces, volumes: vols, script_command: opts[:script_command], script_uris: opts[:script_uris])
131
+ AzureRmCompute.new(
132
+ azure_vm: raw_vm,
133
+ sdk: sdk,
134
+ resource_group: opts[:resource_group],
135
+ nics: ifaces,
136
+ volumes: vols,
137
+ script_command: opts[:script_command],
138
+ script_uris: opts[:script_uris],
139
+ nvidia_gpu_extension: Foreman::Cast.to_bool(opts[:nvidia_gpu_extension]),
140
+ )
130
141
  end
131
142
 
132
143
  def provided_attributes
@@ -268,23 +279,26 @@ module ForemanAzureRm
268
279
  args = args.to_h.deep_symbolize_keys
269
280
  args[:vm_name] = args[:name].split('.')[0]
270
281
  nics = create_nics(region, args)
271
- if args[:password].present? && !args[:ssh_key_data].present?
272
- # Any change to sudoers_cmd and formation of new
273
- # args[:script_command] must be accordingly changed
274
- # in script_command method in AzureRmCompute class
275
- sudoers_cmd = "$echo #{args[:password]} | sudo -S echo '\"#{args[:username]}\" ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/waagent"
276
- if args[:script_command].present?
277
- # to run the script_cmd given through form as username
278
- user_command = args[:script_command]
279
- args[:script_command] = sudoers_cmd + " ; su - \"#{args[:username]}\" -c \"#{user_command}\""
282
+
283
+ if args[:platform] == 'Linux'
284
+ if args[:password].present? && !args[:ssh_key_data].present?
285
+ # Any change to sudoers_cmd and formation of new
286
+ # args[:script_command] must be accordingly changed
287
+ # in script_command method in AzureRmCompute class
288
+ sudoers_cmd = "$echo #{args[:password]} | sudo -S echo '\"#{args[:username]}\" ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/waagent"
289
+ if args[:script_command].present?
290
+ # to run the script_cmd given through form as username
291
+ user_command = args[:script_command]
292
+ args[:script_command] = sudoers_cmd + " ; su - \"#{args[:username]}\" -c \"#{user_command}\""
293
+ else
294
+ args[:script_command] = sudoers_cmd
295
+ end
296
+ disable_password_auth = false
297
+ elsif args[:ssh_key_data].present? && !args[:password].present?
298
+ disable_password_auth = true
280
299
  else
281
- args[:script_command] = sudoers_cmd
300
+ disable_password_auth = false
282
301
  end
283
- disable_password_auth = false
284
- elsif args[:ssh_key_data].present? && !args[:password].present?
285
- disable_password_auth = true
286
- else
287
- disable_password_auth = false
288
302
  end
289
303
 
290
304
  vm = create_managed_virtual_machine(
@@ -301,15 +315,31 @@ module ForemanAzureRm
301
315
  image_id: args[:image_id],
302
316
  os_disk_caching: args[:os_disk_caching],
303
317
  premium_os_disk: args[:premium_os_disk],
318
+ os_disk_size_gb: args[:os_disk_size_gb],
304
319
  data_disks: args[:volumes_attributes],
305
320
  custom_data: args[:user_data],
306
321
  script_command: args[:script_command],
307
322
  script_uris: args[:script_uris],
323
+ nvidia_gpu_extension: args[:nvidia_gpu_extension],
308
324
  )
309
325
  logger.debug "Virtual Machine #{args[:vm_name]} Created Successfully."
326
+ # request NVIDIA GPU driver and CUDA stack
327
+ if Foreman::Cast.to_bool(args[:nvidia_gpu_extension])
328
+ create_vm_nvidia_gpu_extension(region, args)
329
+ end
330
+ # as this extension may contains postinstall script, call it after others
310
331
  create_vm_extension(region, args)
311
332
  # return the vm object using azure_vm
312
- AzureRmCompute.new(azure_vm: vm, sdk: sdk, resource_group: args[:resource_group], nics: vm_nics(vm), volumes: vm_disks(vm), script_command: user_command, script_uris: args[:script_uris])
333
+ AzureRmCompute.new(
334
+ azure_vm: vm,
335
+ sdk: sdk,
336
+ resource_group: args[:resource_group],
337
+ nics: vm_nics(vm),
338
+ volumes: vm_disks(vm),
339
+ script_command: user_command,
340
+ script_uris: args[:script_uris],
341
+ nvidia_gpu_extension: Foreman::Cast.to_bool(args[:nvidia_gpu_extension]),
342
+ )
313
343
  rescue RuntimeError => e
314
344
  Foreman::Logging.exception('Unhandled AzureRm error', e)
315
345
  destroy_vm vm.id if vm
@@ -5,17 +5,19 @@ module ForemanAzureRm
5
5
  attr_accessor :resource_group
6
6
  attr_accessor :nics
7
7
  attr_accessor :script_command, :script_uris
8
+ attr_accessor :nvidia_gpu_extension
8
9
  attr_accessor :volumes
9
10
 
10
11
  delegate :name, to: :azure_vm, allow_nil: true
11
12
 
12
13
  def initialize(azure_vm: ComputeModels::VirtualMachine.new,
13
- sdk: sdk,
14
+ sdk: nil,
14
15
  resource_group: azure_vm.resource_group,
15
16
  nics: [],
16
17
  volumes: [],
17
18
  script_command: nil,
18
- script_uris: nil)
19
+ script_uris: nil,
20
+ nvidia_gpu_extension: false)
19
21
 
20
22
  @azure_vm = azure_vm
21
23
  @sdk = sdk
@@ -24,6 +26,7 @@ module ForemanAzureRm
24
26
  @volumes ||= volumes
25
27
  @script_command ||= script_command
26
28
  @script_uris ||= script_uris
29
+ @nvidia_gpu_extension ||= nvidia_gpu_extension
27
30
  @azure_vm.hardware_profile ||= ComputeModels::HardwareProfile.new
28
31
  @azure_vm.os_profile ||= ComputeModels::OSProfile.new
29
32
  @azure_vm.os_profile.linux_configuration ||= ComputeModels::LinuxConfiguration.new
@@ -179,6 +182,10 @@ module ForemanAzureRm
179
182
  @azure_vm.storage_profile.os_disk.managed_disk.storage_account_type
180
183
  end
181
184
 
185
+ def os_disk_size_gb
186
+ @azure_vm.storage_profile.os_disk.disk_size_gb
187
+ end
188
+
182
189
  def os_disk_caching
183
190
  @azure_vm.storage_profile.os_disk.caching
184
191
  end
@@ -204,8 +211,24 @@ module ForemanAzureRm
204
211
  def vm_extension
205
212
  return nil unless @azure_vm.resources
206
213
  @vm_extension ||= begin
207
- ext_name = @azure_vm.resources.first.id.split('/')[-1]
208
- sdk.get_vm_extension(@azure_vm.resource_group, name, ext_name)
214
+ @azure_vm.resources.each do |ext|
215
+ ext_name = ext.id.split('/')[-1]
216
+ next unless ext_name == 'ForemanCustomScript'
217
+ return sdk.get_vm_extension(@azure_vm.resource_group, name, ext_name)
218
+ end
219
+ nil
220
+ end
221
+ end
222
+
223
+ def vm_nvidia_gpu_extension
224
+ return nil unless @azure_vm.resources
225
+ @vm_nvidia_gpu_extension ||= begin
226
+ @azure_vm.resources.each do |ext|
227
+ ext_name = ext.id.split('/')[-1]
228
+ next unless ['NvidiaGpuDriverLinux', 'NvidiaGpuDriverWindows'].include? ext_name
229
+ return sdk.get_vm_extension(@azure_vm.resource_group, name, ext_name)
230
+ end
231
+ nil
209
232
  end
210
233
  end
211
234
 
@@ -215,7 +238,7 @@ module ForemanAzureRm
215
238
  # Index is based on script_command that is being injected
216
239
  # from the code in #create_vm. It can be partly hard-coded
217
240
  # since the command shall no change frequently.
218
- if ssh_key_data.nil?
241
+ if ssh_key_data.nil? && platform == 'Linux'
219
242
  user_cmd_index = (vm_extension.settings["commandToExecute"].index("-c"))+ 4
220
243
  script_command = vm_extension.settings["commandToExecute"][user_cmd_index..-2]
221
244
  else
@@ -234,5 +257,14 @@ module ForemanAzureRm
234
257
  @script_uris
235
258
  end
236
259
  end
260
+
261
+ def nvidia_gpu_extension
262
+ if vm_nvidia_gpu_extension.present?
263
+ true
264
+ else
265
+ @nvidia_gpu_extension
266
+ end
267
+ end
268
+
237
269
  end
238
270
  end
@@ -1 +1 @@
1
- attributes :azure_environment, :tenant, :app_ident, :sub_id, :region
1
+ attributes :cloud, :tenant, :app_ident, :sub_id, :region
@@ -4,8 +4,7 @@
4
4
  ['China', 'azurechina'],
5
5
  ['Germany', 'azuregermancloud'],
6
6
  ], {}, { :label => _('Cloud'), :required => true } %>
7
- <%= text_f f, :app_ident, :label => _('Client ID'), :required => true, :help_inline => link_to(icon_text('help', _('Documentation'), :kind => 'pficon'),
8
- azure_doc_url, :rel => 'external', :class => 'btn btn-default btn-docs', :target => '_blank') %>
7
+ <%= text_f f, :app_ident, :label => _('Client ID'), :required => true, :help_inline => link_to('Documentation', external_link_path(type: 'plugin_manual', name: 'foreman_azure', version: azure_doc_version), :kind => 'pficon', :rel => 'external', :class => 'btn btn-default btn-docs', :target => '_blank') %>
9
8
  <%= password_f f, :password, :label => _('Client Secret'), :keep_value => true, :required => true %>
10
9
  <%= text_f f, :user, :label => _('Subscription ID'), :required => true %>
11
10
  <%= text_f f, :uuid, :label => _('Tenant ID'), :required => true %>
@@ -132,7 +132,6 @@
132
132
  <%= password_f f, :password,
133
133
  {
134
134
  :label => _('Password'),
135
- :required => true,
136
135
  :placeholder => "********",
137
136
  :value => f.object.password
138
137
 
@@ -154,6 +153,16 @@
154
153
  'false'
155
154
  %>
156
155
 
156
+ <%= number_f f, :os_disk_size_gb,
157
+ {
158
+ :label => _('Override OS Disk Size (GB)'),
159
+ :label_help => _("Leave empty to use default image size"),
160
+ :required => false,
161
+ :min => 1,
162
+ :class => "col-md-2",
163
+ }
164
+ %>
165
+
157
166
  <%= selectable_f f, :os_disk_caching, %w(None ReadOnly ReadWrite),
158
167
  { :include_blank => _("Azure's Default") },
159
168
  {
@@ -176,6 +185,16 @@
176
185
  }
177
186
  %>
178
187
 
188
+ <%= checkbox_f f, :nvidia_gpu_extension,
189
+ {
190
+ :label => _('NVIDIA driver / CUDA'),
191
+ :label_size => "col-md-2",
192
+ :label_help => _("Deploy NVIDIA GPU driver and CUDA (Azure Extension Microsoft.HpcCompute/NvidiaGpuDriver{Linux,Windows}/1.3)"),
193
+ },
194
+ 'true',
195
+ 'false'
196
+ %>
197
+
179
198
  <div id="image_selection">
180
199
  <%= select_f f, :image_id, images, :uuid, :name,
181
200
  { :include_blank => (images.empty? or images.size == 1) ? false : _('Please select an image') },