CLOUDSTACK-4787: Allow users to select disk controller for VM/template

- Adds new controller types in the UI, for selecting root disk controller while
  registering templates
- Fixes bug to not override disk controller type if provided in the details (either
  vm details or from template details)

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 41a1872..3a24698 100755
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -1195,7 +1195,7 @@
             String.class,
             "vmware.root.disk.controller",
             "ide",
-            "Specify the default disk controller for root volumes, valid values are scsi, ide",
+            "Specify the default disk controller for root volumes, valid values are scsi, ide, osdefault. Please check documentation for more details on each of these values.",
             null),
     VmwareSystemVmNicDeviceType(
             "Advanced",
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 6f49bb2..35aafb8 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -3117,11 +3117,16 @@
                         s_logger.info("guestOS is OSX : overwrite root disk controller to scsi, use smc and efi");
                     } else {
                         String controllerSetting = _configDao.getValue("vmware.root.disk.controller");
-                        vm.setDetail(VmDetailConstants.ROOK_DISK_CONTROLLER, controllerSetting);
-                        if (controllerSetting.equalsIgnoreCase("scsi")) {
-                            vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "scsi");
-                        } else {
-                            vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "osdefault");
+                        // Don't override if VM already has root/data disk controller detail
+                        if (vm.getDetail(VmDetailConstants.ROOK_DISK_CONTROLLER) == null) {
+                            vm.setDetail(VmDetailConstants.ROOK_DISK_CONTROLLER, controllerSetting);
+                        }
+                        if (vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER) == null) {
+                            if (controllerSetting.equalsIgnoreCase("scsi")) {
+                                vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "scsi");
+                            } else {
+                                vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "osdefault");
+                            }
                         }
                     }
                 }
diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js
index 6d09b51..bff971c 100644
--- a/ui/scripts/templates.js
+++ b/ui/scripts/templates.js
@@ -281,6 +281,26 @@
                                                 id: "ide",
                                                 description: "ide"
                                             });
+                                            items.push({
+                                                id: "osdefault",
+                                                description: "osdefault"
+                                            });
+                                            items.push({
+                                                id: "pvscsi",
+                                                description: "pvscsi"
+                                            });
+                                            items.push({
+                                                id: "lsilogic",
+                                                description: "lsilogic"
+                                            });
+                                            items.push({
+                                                id: "lsisas1068",
+                                                description: "lsilogicsas"
+                                            });
+                                            items.push({
+                                                id: "buslogic",
+                                                description: "buslogic"
+                                            });
                                             args.response.success({
                                                 data: items
                                             });