From d10c8e2a1d01d97c4912f2c3d6b262d457fc5e3b Mon Sep 17 00:00:00 2001 From: Kelven Yang Date: Thu, 4 Aug 2011 18:27:45 -0700 Subject: [PATCH] bug 10765: fix step 2 - programming VNC server to let it chose the right keyboard mapping to load into --- .../cloud/agent/api/to/VirtualMachineTO.java | 8 ++++++++ api/src/com/cloud/api/ApiConstants.java | 1 + .../com/cloud/api/commands/DeployVMCmd.java | 14 ++++++++++--- api/src/com/cloud/vm/UserVmService.java | 6 +++--- api/src/com/cloud/vm/VirtualMachine.java | 6 ++++++ core/src/com/cloud/vm/UserVmVO.java | 1 + core/src/com/cloud/vm/VMInstanceVO.java | 5 +++++ .../cloud/hypervisor/HypervisorGuruBase.java | 2 ++ .../src/com/cloud/vm/UserVmManagerImpl.java | 20 ++++++++++++------- 9 files changed, 50 insertions(+), 13 deletions(-) diff --git a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java index 20d824c8ede..6f5c9448fec 100644 --- a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java +++ b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java @@ -192,4 +192,12 @@ public class VirtualMachineTO { public void setVncPassword(String vncPassword) { this.vncPassword = vncPassword; } + + public Map getDetails() { + return params; + } + + public void setDetails(Map params) { + this.params = params; + } } diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 7372dedf4a7..0d9654c4f12 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -253,4 +253,5 @@ public class ApiConstants { public static final String SNAPSHOT_RESERVATION = "snapshotreservation"; public static final String REDUNDANT_ROUTER = "redundantrouter"; public static final String IP_NETWORK_LIST = "iptonetworklist"; + public static final String KEYBOARD="keyboard"; } diff --git a/api/src/com/cloud/api/commands/DeployVMCmd.java b/api/src/com/cloud/api/commands/DeployVMCmd.java index 126762ce3e5..dc57f858831 100644 --- a/api/src/com/cloud/api/commands/DeployVMCmd.java +++ b/api/src/com/cloud/api/commands/DeployVMCmd.java @@ -120,6 +120,10 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { @Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, description="the ip address for default vm's network") private String ipAddress; + + @Parameter(name=ApiConstants.KEYBOARD, type=CommandType.STRING, description="an optional keyboard device type for the virtual machine. valid value can be one of de,de-ch,es,fi,fr,fr-be,fr-ch,is,it,jp,nl-be,no,pt,uk,us") + private String keyboard; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -226,6 +230,10 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { private String getIpAddress() { return ipAddress; } + + private String getKeyboard() { + return keyboard; + } private Map getIpToNetworkMap() { if ((networkIds != null || ipAddress != null) && ipToNetworkList != null) { @@ -375,18 +383,18 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { throw new InvalidParameterValueException("Can't specify network Ids in Basic zone"); } else { vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(), owner, name, - displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), ipAddress); + displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), ipAddress, keyboard); } } else { if (zone.isSecurityGroupEnabled()) { vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), getSecurityGroupIdList(), - owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), ipAddress); + owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), ipAddress, keyboard); } else { if (getSecurityGroupIdList() != null && !getSecurityGroupIdList().isEmpty()) { throw new InvalidParameterValueException("Can't create vm with security groups; security group feature is not enabled per zone"); } vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, getNetworkIds(), owner, name, displayName, - diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), ipAddress); + diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), ipAddress, keyboard); } } } diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index 1bde379e61f..38b49742f5f 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -185,7 +185,7 @@ public interface UserVmService { * @throws InsufficientResourcesException */ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List securityGroupIdList, Account owner, String hostName, - String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map requestedIps, String defaultIp) + String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map requestedIps, String defaultIp, String keyboard) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** @@ -240,7 +240,7 @@ public interface UserVmService { * @throws InsufficientResourcesException */ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, List securityGroupIdList, - Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map requestedIps, String defaultIp) + Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map requestedIps, String defaultIp, String keyboard) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** @@ -293,7 +293,7 @@ public interface UserVmService { * @throws InsufficientResourcesException */ UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, Account owner, String hostName, - String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map requestedIps, String defaultIp) + String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map requestedIps, String defaultIp, String keyboard) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index 5cad493161f..7de8016bec7 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -18,6 +18,7 @@ package com.cloud.vm; import java.util.Date; +import java.util.Map; import com.cloud.acl.ControlledEntity; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -30,6 +31,9 @@ import com.cloud.utils.fsm.StateObject; * */ public interface VirtualMachine extends RunningOn, ControlledEntity, StateObject { + + public static final String PARAM_KEY_KEYBOARD = "keyboard"; + public enum State { Starting(true, "VM is being started. At this state, you should find host id filled which means it's being started on that host."), Running(false, "VM is running. host id has the host that it is running on."), @@ -275,4 +279,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, StateObject Type getType(); HypervisorType getHypervisorType(); + + public Map getDetails(); } diff --git a/core/src/com/cloud/vm/UserVmVO.java b/core/src/com/cloud/vm/UserVmVO.java index f6d00247b53..953bedcf43a 100755 --- a/core/src/com/cloud/vm/UserVmVO.java +++ b/core/src/com/cloud/vm/UserVmVO.java @@ -119,6 +119,7 @@ public class UserVmVO extends VMInstanceVO implements UserVm { this.displayName = displayName; } + @Override public Map getDetails() { return details; } diff --git a/core/src/com/cloud/vm/VMInstanceVO.java b/core/src/com/cloud/vm/VMInstanceVO.java index 92d3495732f..60b00a1b2fc 100644 --- a/core/src/com/cloud/vm/VMInstanceVO.java +++ b/core/src/com/cloud/vm/VMInstanceVO.java @@ -19,6 +19,7 @@ package com.cloud.vm; import java.util.Date; +import java.util.Map; import java.util.Random; import javax.persistence.Column; @@ -393,6 +394,10 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject getDetails() { + return null; } transient String toString; diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index 197739abb18..798b25e067e 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -79,6 +79,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis } else { to.setArch("x86_64"); } + + to.setDetails(vm.getDetails()); return to; } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index b0cdc355bcc..488d83682e4 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2040,7 +2040,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager @Override public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List securityGroupIdList, Account owner, - String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map requestedIps, String defaultIp) + String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map requestedIps, String defaultIp, String keyboard) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = UserContext.current().getCaller(); @@ -2092,13 +2092,13 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, - diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIp); + diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIp, keyboard); } @Override public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, - String sshKeyPair, Map requestedIps, String defaultIp) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, + String sshKeyPair, Map requestedIps, String defaultIp, String keyboard) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = UserContext.current().getCaller(); @@ -2203,12 +2203,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, - diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIp); + diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIp, keyboard); } @Override public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, Account owner, String hostName, - String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map requestedIps, String defaultIp) + String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map requestedIps, String defaultIp, String keyboard) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = UserContext.current().getCaller(); @@ -2326,12 +2326,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } } - return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIp); + return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIp, keyboard); } @DB @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true) protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, String hostName, String displayName, Account owner, Long diskOfferingId, - Long diskSize, List networkList, List securityGroupIdList, String group, String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, Map requestedIps, String defaultNetworkIp) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException { + Long diskSize, List networkList, List securityGroupIdList, String group, String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, Map requestedIps, String defaultNetworkIp, String keyboard) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException { _accountMgr.checkAccess(caller, owner); long accountId = owner.getId(); @@ -2514,6 +2514,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (sshPublicKey != null) { vm.setDetail("SSH.PublicKey", sshPublicKey); } + + if(keyboard != null && !keyboard.isEmpty()) + vm.setDetail(VirtualMachine.PARAM_KEY_KEYBOARD, keyboard); if (isIso) { vm.setIsoId(template.getId()); @@ -2653,6 +2656,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager @Override public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { UserVmVO vm = profile.getVirtualMachine(); + Map details = _vmDetailsDao.findDetails(vm.getId()); + vm.setDetails(details); + Account owner = _accountDao.findById(vm.getAccountId()); if (owner == null) {