diff --git a/agent/conf/agent.properties b/agent/conf/agent.properties index 5f5f3682afd..a7376b68947 100644 --- a/agent/conf/agent.properties +++ b/agent/conf/agent.properties @@ -114,3 +114,7 @@ domr.scripts.dir=scripts/network/domr/kvm # for examples:"Conroe" "Penryn", "Nehalem", "Westmere", "pentiumpro" and so # on,run virsh capabilities for more details. # guest.cpu.model= +# +# vm.memballoon.disable=true +# Disable memory ballooning on vm guests for overcommit, by default overcommit +# feature enables balloon and sets currentMemory to a minimum value. diff --git a/api/src/com/cloud/agent/api/to/IpAddressTO.java b/api/src/com/cloud/agent/api/to/IpAddressTO.java index 5f31313eba9..1169820e19a 100644 --- a/api/src/com/cloud/agent/api/to/IpAddressTO.java +++ b/api/src/com/cloud/agent/api/to/IpAddressTO.java @@ -33,6 +33,8 @@ public class IpAddressTO { private Integer networkRate; private TrafficType trafficType; private String networkName; + private Integer nicDevId; + private boolean newNic; public IpAddressTO(long accountId, String ipAddress, boolean add, boolean firstIP, boolean sourceNat, String broadcastUri, String vlanGateway, String vlanNetmask, String vifMacAddress, Integer networkRate, boolean isOneToOneNat) { @@ -116,4 +118,19 @@ public class IpAddressTO { return networkRate; } + public Integer getNicDevId() { + return nicDevId; + } + + public void setNicDevId(Integer nicDevId) { + this.nicDevId = nicDevId; + } + + public boolean isNewNic() { + return newNic; + } + + public void setNewNic(boolean newNic) { + this.newNic = newNic; + } } diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 62151a4f0c0..6dc67521663 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -113,6 +113,7 @@ public interface Network extends ControlledEntity, StateObject, I public static final Provider VirtualRouter = new Provider("VirtualRouter", false); public static final Provider JuniperContrailRouter = new Provider("JuniperContrailRouter", false); + public static final Provider JuniperContrailVpcRouter = new Provider("JuniperContrailVpcRouter", false); public static final Provider JuniperSRX = new Provider("JuniperSRX", true); public static final Provider PaloAlto = new Provider("PaloAlto", true); public static final Provider F5BigIp = new Provider("F5BigIp", true); diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 250121e452b..1731b119d5e 100755 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -110,7 +110,7 @@ public interface NetworkService { long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType); - PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String xenLabel, String kvmLabel, String vmwareLabel, + PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan, String hypervLabel); PhysicalNetworkTrafficType getPhysicalNetworkTrafficType(Long id); diff --git a/api/src/com/cloud/network/Networks.java b/api/src/com/cloud/network/Networks.java index b2c04cda00c..1e4d2294641 100755 --- a/api/src/com/cloud/network/Networks.java +++ b/api/src/com/cloud/network/Networks.java @@ -94,7 +94,22 @@ public class Networks { return uri.getSchemeSpecificPart(); } }, - Mido("mido", String.class), Pvlan("pvlan", String.class), Vxlan("vxlan", Long.class), UnDecided(null, null), OpenDaylight("opendaylight", String.class); + Mido("mido", String.class), Pvlan("pvlan", String.class), + Vxlan("vxlan", Long.class) { + @Override + public URI toUri(T value) { + try { + if (value.toString().contains("://")) + return new URI(value.toString()); + else + return new URI("vxlan://" + value.toString()); + } catch (URISyntaxException e) { + throw new CloudRuntimeException( + "Unable to convert to broadcast URI: " + value); + } + } + }, + UnDecided(null, null), OpenDaylight("opendaylight", String.class); private final String scheme; private final Class type; diff --git a/api/src/com/cloud/network/rules/FirewallRule.java b/api/src/com/cloud/network/rules/FirewallRule.java index 4cfa42b3770..274242ad394 100644 --- a/api/src/com/cloud/network/rules/FirewallRule.java +++ b/api/src/com/cloud/network/rules/FirewallRule.java @@ -36,7 +36,8 @@ public interface FirewallRule extends ControlledEntity, Identity, InternalIdenti Staged, // Rule been created but has never got through network rule conflict detection. Rules in this state can not be sent to network elements. Add, // Add means the rule has been created and has gone through network rule conflict detection. Active, // Rule has been sent to the network elements and reported to be active. - Revoke // Revoke means this rule has been revoked. If this rule has been sent to the network elements, the rule will be deleted from database. + Revoke, // Revoke means this rule has been revoked. If this rule has been sent to the network elements, the rule will be deleted from database. + Deleting // rule has been revoked and is scheduled for deletion } enum TrafficType { diff --git a/api/src/com/cloud/network/vpc/StaticRoute.java b/api/src/com/cloud/network/vpc/StaticRoute.java index ccdbec899b8..5707ca14024 100644 --- a/api/src/com/cloud/network/vpc/StaticRoute.java +++ b/api/src/com/cloud/network/vpc/StaticRoute.java @@ -25,7 +25,8 @@ public interface StaticRoute extends ControlledEntity, Identity, InternalIdentit Staged, // route been created but has never got through network rule conflict detection. Routes in this state can not be sent to VPC virtual router. Add, // Add means the route has been created and has gone through network rule conflict detection. Active, // Route has been sent to the VPC router and reported to be active. - Revoke // Revoke means this route has been revoked. If this route has been sent to the VPC router, the route will be deleted from database. + Revoke, // Revoke means this route has been revoked. If this route has been sent to the VPC router, the route will be deleted from database. + Deleting // rule has been revoked and is scheduled for deletion } /** diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index 41931f0949b..275510e1a1a 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -51,7 +51,9 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit CustomerGateway(false, true), VpnConnection(false, true), User(true, true), - DiskOffering(false, true); + DiskOffering(false, true), + AutoScaleVmProfile(false, true), + AutoScaleVmGroup(false, true); ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) { this.resourceTagsSupport = resourceTagsSupport; diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index 84f0872f909..36648840448 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -82,7 +82,7 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba s_fsm.addTransition(Destroy, Event.ExpungingRequested, Expunging); s_fsm.addTransition(Expunging, Event.ExpungingRequested, Expunging); s_fsm.addTransition(Expunging, Event.OperationSucceeded, Expunged); - s_fsm.addTransition(Expunging, Event.OperationFailed, Expunging); + s_fsm.addTransition(Expunging, Event.OperationFailed, Destroy); s_fsm.addTransition(Ready, Event.SnapshotRequested, Snapshotting); s_fsm.addTransition(Snapshotting, Event.OperationSucceeded, Ready); s_fsm.addTransition(Snapshotting, Event.OperationFailed, Ready); diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 751763042c3..353587255dc 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -344,6 +344,7 @@ public class ApiConstants { public static final String CAPACITY_IOPS = "capacityiops"; public static final String NETWORK_SPEED = "networkspeed"; public static final String BROADCAST_DOMAIN_RANGE = "broadcastdomainrange"; + public static final String ISOLATION_METHOD = "isolationmethod"; public static final String ISOLATION_METHODS = "isolationmethods"; public static final String PHYSICAL_NETWORK_ID = "physicalnetworkid"; public static final String DEST_PHYSICAL_NETWORK_ID = "destinationphysicalnetworkid"; diff --git a/api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java b/api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java index 620c5ed8faa..3eaa0530646 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java @@ -48,7 +48,7 @@ public class GenerateAlertCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Name of the alert", required = true) private String name; - @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "Alert description", required = true) + @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "Alert description", required = true, length = 999) private String description; @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "Zone id for which alert is generated") diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java b/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java index e6e18cb9ffa..0fcb8f87e54 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java @@ -77,6 +77,10 @@ public class AddTrafficTypeCmd extends BaseAsyncCreateCmd { @Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, description = "The VLAN id to be used for Management traffic by VMware host") private String vlan; + @Parameter(name=ApiConstants.ISOLATION_METHOD, type=CommandType.STRING, description="Used if physical network has multiple isolation types and traffic type is public." + + " Choose which isolation method. Valid options currently 'vlan' or 'vxlan', defaults to 'vlan'.") + private String isolationMethod; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -118,6 +122,14 @@ public class AddTrafficTypeCmd extends BaseAsyncCreateCmd { return vlan; } + public String getIsolationMethod() { + if (isolationMethod != null && !isolationMethod.isEmpty()) { + return isolationMethod; + } else { + return "vlan"; + } + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -148,7 +160,7 @@ public class AddTrafficTypeCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException { PhysicalNetworkTrafficType result = - _networkService.addTrafficTypeToPhysicalNetwork(getPhysicalNetworkId(), getTrafficType(), getXenLabel(), getKvmLabel(), getVmwareLabel(), + _networkService.addTrafficTypeToPhysicalNetwork(getPhysicalNetworkId(), getTrafficType(), getIsolationMethod(), getXenLabel(), getKvmLabel(), getVmwareLabel(), getSimulatorLabel(), getVlan(), getHypervLabel()); if (result != null) { setEntityId(result.getId()); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java index b00530967df..1affd751040 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java @@ -18,9 +18,6 @@ package org.apache.cloudstack.api.command.user.autoscale; import java.util.ArrayList; import java.util.List; - -import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.AclEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -28,7 +25,10 @@ import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse; import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.TemplateResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.log4j.Logger; import com.cloud.network.as.AutoScaleVmProfile; @@ -48,9 +48,15 @@ public class ListAutoScaleVmProfilesCmd extends BaseListProjectAndAccountResourc @Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class, description = "the templateid of the autoscale vm profile") private Long templateId; + @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, description = "list profiles by service offering id") + private Long serviceOffId; + @Parameter(name = ApiConstants.OTHER_DEPLOY_PARAMS, type = CommandType.STRING, description = "the otherdeployparameters of the autoscale vm profile") private String otherDeployParams; + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, since = "4.4", description = "availability zone for the auto deployed virtual machine") + private Long zoneId; + // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// @@ -67,10 +73,18 @@ public class ListAutoScaleVmProfilesCmd extends BaseListProjectAndAccountResourc return otherDeployParams; } + public Long getServiceOfferingId() { + return serviceOffId; + } + + public Long getZoneId() { + return zoneId; + } // /////////////////////////////////////////////////// // ///////////// API Implementation/////////////////// // /////////////////////////////////////////////////// + @Override public String getCommandName() { return s_name; diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java index 4ea4a588cea..4b0ea544c5e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java @@ -1,3 +1,4 @@ + // Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information @@ -42,7 +43,7 @@ public class AssignCertToLoadBalancerCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(AssignCertToLoadBalancerCmd.class.getName()); - private static final String s_name = "assignCertToLoadBalancer"; + private static final String s_name = "assigncerttoloadbalancerresponse"; @Parameter(name = ApiConstants.LBID, type = CommandType.UUID, diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java index e92d20801c4..ea420f31bf5 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java @@ -41,7 +41,7 @@ public class RemoveCertFromLoadBalancerCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RemoveCertFromLoadBalancerCmd.class.getName()); - private static final String s_name = "removeCertFromLoadBalancer"; + private static final String s_name = "removecertfromloadbalancerresponse"; @Parameter(name = ApiConstants.LBID, type = CommandType.UUID, diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java index c0e8d3e16a6..439879add9b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java @@ -130,7 +130,7 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd { try { result = _networkService.allocateSecondaryGuestIP(getNicId(), getIpaddress()); } catch (InsufficientAddressCapacityException e) { - throw new InvalidParameterValueException("Allocating guest ip for nic failed"); + throw new InvalidParameterValueException("Allocating guest ip for nic failed : " + e.getMessage()); } if (result != null) { diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java index c98289c42a0..ebcda164709 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java @@ -16,7 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.user.volume; import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.AclEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; @@ -31,7 +30,6 @@ import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.DiskOfferingResponse; import org.apache.cloudstack.api.response.VolumeResponse; import org.apache.cloudstack.context.CallContext; - import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; @@ -52,7 +50,7 @@ public class ResizeVolumeCmd extends BaseAsyncCmd { ///////////////////////////////////////////////////// @ACL(accessType = AccessType.OperateEntry) - @Parameter(name=ApiConstants.ID, entityType=VolumeResponse.class, type=CommandType.UUID, description="the ID of the disk volume") + @Parameter(name = ApiConstants.ID, entityType = VolumeResponse.class, required = true, type = CommandType.UUID, description = "the ID of the disk volume") private Long id; @Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, required = false, description = "New volume size in G") diff --git a/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java b/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java index edf5a21b673..94c0a55de6a 100644 --- a/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java +++ b/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java @@ -24,7 +24,7 @@ import org.apache.cloudstack.framework.config.Configurable; @Local(value = {ApiServiceConfiguration.class}) public class ApiServiceConfiguration implements Configurable { public static final ConfigKey ManagementHostIPAdr = new ConfigKey("Advanced", String.class, "host", "localhost", "The ip address of management server", true); - public static final ConfigKey ApiServletPath = new ConfigKey("Advanced", String.class, "api.servlet.endpoint", "http://localhost:8080/client/api?", + public static final ConfigKey ApiServletPath = new ConfigKey("Advanced", String.class, "endpointe.url", "http://localhost:8080/client/api", "API end point. Can be used by CS components/services deployed remotely, for sending CS API requests", true); @Override diff --git a/awsapi/pom.xml b/awsapi/pom.xml index d9f562735a3..4a6c89c9e5f 100644 --- a/awsapi/pom.xml +++ b/awsapi/pom.xml @@ -142,7 +142,7 @@ org.opensaml - opensaml + opensaml1 @@ -162,7 +162,7 @@ org.opensaml - opensaml + opensaml1 @@ -178,7 +178,7 @@ org.opensaml - opensaml + opensaml1 @@ -194,7 +194,7 @@ org.opensaml - opensaml + opensaml1 @@ -210,7 +210,7 @@ org.opensaml - opensaml + opensaml1 diff --git a/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java b/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java index 0f40c934de2..d901c53aebe 100644 --- a/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java +++ b/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java @@ -354,13 +354,19 @@ public class DimeDelimitedInputStream extends FilterInputStream { } //OPTIONS_LENGTH - int optionsLength = ((((int)header[2]) << 8) & 0xff00) | ((int)header[3]); + int oneButLastByte = (((int)header[2]) << 8) & 0xff00; + int lastByte = (int)header[3] & 0xff; + int optionsLength = oneButLastByte | lastByte; //ID_LENGTH - int idLength = ((((int)header[4]) << 8) & 0xff00) | ((int)header[5]); + oneButLastByte = ((((int)header[4]) << 8) & 0xff00); + lastByte = ((int)header[5]) & 0xff; + int idLength = oneButLastByte | lastByte; //TYPE_LENGTH - int typeLength = ((((int)header[6]) << 8) & 0xff00) | ((int)header[7]); + oneButLastByte = ((((int)header[6]) << 8) & 0xff00); + lastByte = ((int)header[7]) & 0xff; + int typeLength = oneButLastByte | lastByte; //DATA_LENGTH recordLength = diff --git a/awsapi/src/com/cloud/bridge/model/SObjectItemVO.java b/awsapi/src/com/cloud/bridge/model/SObjectItemVO.java index 5eada3c136d..77077c6a2b6 100644 --- a/awsapi/src/com/cloud/bridge/model/SObjectItemVO.java +++ b/awsapi/src/com/cloud/bridge/model/SObjectItemVO.java @@ -168,7 +168,7 @@ public class SObjectItemVO { } if (theObject.getId() != null) { - if (!theObject.getId().equals(((SObjectItemVO)other).getTheObject())) + if (!theObject.getId().equals(((SObjectItemVO)other).getTheObject().getId())) return false; } else { if (((SObjectItemVO)other).getTheObject() != null) diff --git a/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java b/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java index dac18e42d20..d44f1d1101e 100644 --- a/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java +++ b/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java @@ -1977,6 +1977,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface { DescribeAddressesResponseItemType item = new DescribeAddressesResponseItemType(); item.setPublicIp(addr.getIpAddress()); item.setInstanceId(addr.getAssociatedInstanceId()); + item.setDomain("standard"); // Since VPC is not supported by AWSAPI default to 'standard' items.add(item); } DescribeAddressesResponseInfoType descAddrRespInfoType = new DescribeAddressesResponseInfoType(); diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 29dfdadfd00..b0116bdf2f3 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -593,6 +593,11 @@ addBigSwitchVnsDevice=1 deleteBigSwitchVnsDevice=1 listBigSwitchVnsDevices=1 +#### stratosphere ssp commands + +addStratosphereSsp=1 +deleteStratoshereSsp=1 + #### host simulator commands configureSimulator=1 diff --git a/core/src/com/cloud/agent/api/GetVmConfigAnswer.java b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java new file mode 100644 index 00000000000..46e003ecae3 --- /dev/null +++ b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java @@ -0,0 +1,68 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +import java.util.List; + +public class GetVmConfigAnswer extends Answer { + + String vmName; + List nics; + + protected GetVmConfigAnswer() { + } + + public GetVmConfigAnswer(String vmName, List nics) { + this.vmName = vmName; + this.nics = nics; + } + + public String getVmName() { + return vmName; + } + + public List getNics() { + return nics; + } + + public class NicDetails { + String macAddress; + int vlanid; + + public NicDetails() { + } + + public NicDetails(String macAddress, int vlanid) { + this.macAddress = macAddress; + this.vlanid = vlanid; + } + + public String getMacAddress() { + return macAddress; + } + + public int getVlanid() { + return vlanid; + } + + } + + @Override + public boolean executeInSequence() { + return false; + } +} \ No newline at end of file diff --git a/core/src/com/cloud/agent/api/GetVmConfigCommand.java b/core/src/com/cloud/agent/api/GetVmConfigCommand.java new file mode 100644 index 00000000000..9133bd6b2c3 --- /dev/null +++ b/core/src/com/cloud/agent/api/GetVmConfigCommand.java @@ -0,0 +1,46 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + + +import java.util.List; + +import com.cloud.agent.api.to.NicTO; + +public class GetVmConfigCommand extends Command { + String vmName; + List nics; + protected GetVmConfigCommand() { + } + + public GetVmConfigCommand(String vmName) { + this.vmName = vmName; + } + + public String getVmName() { + return vmName; + } + + public void setNics(List nics){ + this.nics = nics; + } + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java b/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java new file mode 100644 index 00000000000..1140485c67c --- /dev/null +++ b/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java @@ -0,0 +1,36 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class ModifyVmNicConfigAnswer extends Answer { + String vmName; + protected ModifyVmNicConfigAnswer() { + } + + public ModifyVmNicConfigAnswer(String vmName) { + this.vmName = vmName; + } + + public String getVmName() { + return vmName; + } + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java new file mode 100644 index 00000000000..0230beca732 --- /dev/null +++ b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java @@ -0,0 +1,42 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + + +public class ModifyVmNicConfigCommand extends Command { + String vmName; + int vlan; + String macAddress; + protected ModifyVmNicConfigCommand() { + } + + public ModifyVmNicConfigCommand(String vmName, int vlan, String macAddress) { + this.vmName = vmName; + this.vlan = vlan; + this.macAddress = macAddress; + } + + public String getVmName() { + return vmName; + } + + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java b/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java index 9a2bea875b4..217e962d18a 100644 --- a/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java +++ b/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java @@ -16,10 +16,10 @@ // under the License. package com.cloud.agent.api.routing; -import java.util.HashMap; - import com.cloud.agent.api.Command; +import java.util.HashMap; + public abstract class NetworkElementCommand extends Command { HashMap accessDetails = new HashMap(0); @@ -35,6 +35,8 @@ public abstract class NetworkElementCommand extends Command { public static final String VPC_PRIVATE_GATEWAY = "vpc.gateway.private"; public static final String FIREWALL_EGRESS_DEFAULT = "firewall.egress.default"; + private String routerAccessIp; + protected NetworkElementCommand() { super(); } @@ -52,4 +54,11 @@ public abstract class NetworkElementCommand extends Command { return false; } + public String getRouterAccessIp() { + return routerAccessIp; + } + + public void setRouterAccessIp(String routerAccessIp) { + this.routerAccessIp = routerAccessIp; + } } diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java new file mode 100644 index 00000000000..243098abeab --- /dev/null +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java @@ -0,0 +1,27 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.resource.virtualnetwork; + +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.utils.ExecutionResult; + +public interface VirtualRouterDeployer { + ExecutionResult executeInVR(String routerIp, String script, String args); + ExecutionResult createFileInVR(String routerIp, String path, String filename, String content); + ExecutionResult prepareCommand(NetworkElementCommand cmd); + ExecutionResult cleanupCommand(NetworkElementCommand cmd); +} diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 732d7b4e385..1ed38644536 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -25,9 +25,8 @@ import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.GetDomRVersionAnswer; import com.cloud.agent.api.GetDomRVersionCmd; -import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; -import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; -import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; +import com.cloud.agent.api.SetupGuestNetworkAnswer; +import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.routing.CreateIpAliasCommand; import com.cloud.agent.api.routing.DeleteIpAliasCommand; import com.cloud.agent.api.routing.DhcpEntryCommand; @@ -35,6 +34,7 @@ import com.cloud.agent.api.routing.DnsMasqConfigCommand; import com.cloud.agent.api.routing.IpAliasTO; import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; +import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; @@ -42,9 +42,13 @@ import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetFirewallRulesAnswer; import com.cloud.agent.api.routing.SetFirewallRulesCommand; import com.cloud.agent.api.routing.SetMonitorServiceCommand; +import com.cloud.agent.api.routing.SetNetworkACLAnswer; +import com.cloud.agent.api.routing.SetNetworkACLCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; +import com.cloud.agent.api.routing.SetSourceNatAnswer; +import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.SetStaticRouteAnswer; @@ -55,33 +59,22 @@ import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.to.DhcpTO; import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; -import com.cloud.exception.InternalErrorException; import com.cloud.network.HAProxyConfigurator; import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.rules.FirewallRule; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; -import com.cloud.utils.component.ComponentLifecycle; -import com.cloud.utils.component.Manager; import com.cloud.utils.net.NetUtils; -import com.cloud.utils.script.OutputInterpreter; -import com.cloud.utils.script.Script; -import com.cloud.utils.ssh.SshHelper; import com.google.gson.Gson; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; -import javax.ejb.Local; import javax.naming.ConfigurationException; -import java.io.BufferedReader; -import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.net.InetSocketAddress; -import java.net.URL; -import java.net.URLConnection; import java.nio.channels.SocketChannel; import java.util.HashMap; import java.util.List; @@ -95,24 +88,27 @@ import java.util.Map; * || Param Name | Description | Values | Default || * } **/ -@Local(value = {VirtualRoutingResource.class}) -public class VirtualRoutingResource implements Manager { +public class VirtualRoutingResource { private static final Logger s_logger = Logger.getLogger(VirtualRoutingResource.class); - private String _publicIpAddress; - private String _publicEthIf; - private String _privateEthIf; - private String _routerProxyPath; + private VirtualRouterDeployer _vrDeployer; - private int _timeout; - private int _startTimeout; - private String _scriptsDir; private String _name; private int _sleep; private int _retry; private int _port; + public VirtualRoutingResource(VirtualRouterDeployer deployer) { + this._vrDeployer = deployer; + } + public Answer executeRequest(final Command cmd) { try { + ExecutionResult rc = _vrDeployer.prepareCommand((NetworkElementCommand)cmd); + if (!rc.isSuccess()) { + s_logger.error("Failed to prepare VR command due to " + rc.getDetails()); + return new Answer(cmd, false, rc.getDetails()); + } + if (cmd instanceof SetPortForwardingRulesVpcCommand) { return execute((SetPortForwardingRulesVpcCommand)cmd); } else if (cmd instanceof SetPortForwardingRulesCommand) { @@ -123,12 +119,6 @@ public class VirtualRoutingResource implements Manager { return execute((SetStaticNatRulesCommand)cmd); } else if (cmd instanceof LoadBalancerConfigCommand) { return execute((LoadBalancerConfigCommand)cmd); - } else if (cmd instanceof IpAssocCommand) { - return execute((IpAssocCommand)cmd); - } else if (cmd instanceof CheckConsoleProxyLoadCommand) { - return execute((CheckConsoleProxyLoadCommand)cmd); - } else if (cmd instanceof WatchConsoleProxyLoadCommand) { - return execute((WatchConsoleProxyLoadCommand)cmd); } else if (cmd instanceof SavePasswordCommand) { return execute((SavePasswordCommand)cmd); } else if (cmd instanceof DhcpEntryCommand) { @@ -158,12 +148,27 @@ public class VirtualRoutingResource implements Manager { } else if (cmd instanceof CheckS2SVpnConnectionsCommand) { return execute((CheckS2SVpnConnectionsCommand)cmd); } else if (cmd instanceof SetMonitorServiceCommand) { - return execute((SetMonitorServiceCommand) cmd); + return execute((SetMonitorServiceCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return execute((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetNetworkACLCommand) { + return execute((SetNetworkACLCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return execute((SetSourceNatCommand)cmd); + } else if (cmd instanceof IpAssocVpcCommand) { + return execute((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return execute((IpAssocCommand)cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } } catch (final IllegalArgumentException e) { return new Answer(cmd, false, e.getMessage()); + } finally { + ExecutionResult rc = _vrDeployer.cleanupCommand((NetworkElementCommand)cmd); + if (!rc.isSuccess()) { + s_logger.error("Failed to cleanup VR command due to " + rc.getDetails()); + } } } @@ -177,9 +182,9 @@ public class VirtualRoutingResource implements Manager { args += "-u "; args += userpwd.getUsernamePassword(); } - String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result != null) { - return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername()); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpn_l2tp.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername() + ":" + result.getDetails()); } } return new Answer(cmd); @@ -204,22 +209,16 @@ public class VirtualRoutingResource implements Manager { } args += " -C " + cmd.getLocalCidr(); args += " -i " + cmd.getPublicInterface(); - String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result != null) { - return new Answer(cmd, false, "Configure VPN failed"); - } - return new Answer(cmd); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpn_l2tp.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } private Answer execute(SetFirewallRulesCommand cmd) { String[] results = new String[cmd.getRules().length]; - for (int i = 0; i < cmd.getRules().length; i++) { - results[i] = "Failed"; - } - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String routerAccessIp = cmd.getRouterAccessIp(); String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); - if (routerIp == null) { + if (routerAccessIp == null) { return new SetFirewallRulesAnswer(cmd, false, results); } @@ -230,7 +229,7 @@ public class VirtualRoutingResource implements Manager { String args = " -F"; if (trafficType == FirewallRule.TrafficType.Egress) { - args += "-E"; + args += " -E"; if (egressDefault.equals("true")) { args += " -P 1"; } else if (egressDefault.equals("System")) { @@ -249,23 +248,26 @@ public class VirtualRoutingResource implements Manager { args += " -a " + sb.toString(); } - String result = null; + ExecutionResult result; if (trafficType == FirewallRule.TrafficType.Egress) { - result = routerProxy("firewall_egress.sh", routerIp, args); + result = _vrDeployer.executeInVR(routerAccessIp, "firewall_egress.sh", args); } else { - result = routerProxy("firewall_ingress.sh", routerIp, args); + result = _vrDeployer.executeInVR(routerAccessIp, "firewall_ingress.sh", args); } - if (result != null) { + if (!result.isSuccess()) { + //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails + for (int i = 0; i < results.length; i++) { + results[i] = "Failed: " + result.getDetails(); + } return new SetFirewallRulesAnswer(cmd, false, results); } - return new SetFirewallRulesAnswer(cmd, true, null); + return new SetFirewallRulesAnswer(cmd, true, results); } private Answer execute(SetPortForwardingRulesCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; int i = 0; boolean endResult = true; @@ -278,9 +280,9 @@ public class VirtualRoutingResource implements Manager { args.append(" -r ").append(rule.getDstIp()); args.append(" -d ").append(rule.getStringDstPortRange()); - String result = routerProxy("firewall_nat.sh", routerIp, args.toString()); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "firewall_nat.sh", args.toString()); - if (result == null || result.isEmpty()) { + if (!result.isSuccess()) { results[i++] = "Failed"; endResult = false; } else { @@ -291,8 +293,7 @@ public class VirtualRoutingResource implements Manager { return new SetPortForwardingRulesAnswer(cmd, results, endResult); } - protected Answer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + protected SetStaticNatRulesAnswer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { String[] results = new String[cmd.getRules().length]; int i = 0; boolean endResult = true; @@ -302,9 +303,9 @@ public class VirtualRoutingResource implements Manager { args += " -l " + rule.getSrcIp(); args += " -r " + rule.getDstIp(); - String result = routerProxy("vpc_staticnat.sh", routerIp, args); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_staticnat.sh", args); - if (result == null) { + if (!result.isSuccess()) { results[i++] = null; } else { results[i++] = "Failed"; @@ -315,11 +316,10 @@ public class VirtualRoutingResource implements Manager { } - private Answer execute(SetStaticNatRulesCommand cmd) { + private SetStaticNatRulesAnswer execute(SetStaticNatRulesCommand cmd) { if (cmd.getVpcId() != null) { return SetVPCStaticNatRules(cmd); } - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; int i = 0; boolean endResult = true; @@ -337,9 +337,9 @@ public class VirtualRoutingResource implements Manager { args.append(" -d ").append(rule.getStringSrcPortRange()); args.append(" -G "); - String result = routerProxy("firewall_nat.sh", routerIp, args.toString()); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "firewall_nat.sh", args.toString()); - if (result == null || result.isEmpty()) { + if (!result.isSuccess()) { results[i++] = "Failed"; endResult = false; } else { @@ -350,19 +350,6 @@ public class VirtualRoutingResource implements Manager { return new SetStaticNatRulesAnswer(cmd, results, endResult); } - protected boolean createFileInVR(String routerIp, String path, String filename, String content) { - File permKey = new File("/root/.ssh/id_rsa.cloud"); - boolean result = true; - - try { - SshHelper.scpTo(routerIp, 3922, "root", permKey, null, path, content.getBytes(), filename, null); - } catch (Exception e) { - s_logger.warn("Fail to create file " + path + filename + " in VR " + routerIp, e); - result = false; - } - return result; - } - private Answer execute(LoadBalancerConfigCommand cmd) { String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); @@ -378,67 +365,60 @@ public class VirtualRoutingResource implements Manager { tmpCfgFileContents += "\n"; } - if (!createFileInVR(routerIp, "/etc/haproxy/", "haproxy.cfg.new", tmpCfgFileContents)) { + String tmpCfgFilePath = "/etc/haproxy/"; + String tmpCfgFileName = "haproxy.cfg.new"; + ExecutionResult result = _vrDeployer.createFileInVR(cmd.getRouterAccessIp(), tmpCfgFilePath, tmpCfgFileName, tmpCfgFileContents); + + if (!result.isSuccess()) { return new Answer(cmd, false, "Fail to copy LB config file to VR"); } - try { - String[][] rules = cfgtr.generateFwRules(cmd); + String[][] rules = cfgtr.generateFwRules(cmd); - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; + String[] addRules = rules[LoadBalancerConfigurator.ADD]; + String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; + String[] statRules = rules[LoadBalancerConfigurator.STATS]; - String args = ""; - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - args += " -a " + sb.toString(); + String args = ""; + StringBuilder sb = new StringBuilder(); + if (addRules.length > 0) { + for (int i = 0; i < addRules.length; i++) { + sb.append(addRules[i]).append(','); } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - - args += " -d " + sb.toString(); - } - - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); - } - - String result; - - if (cmd.getVpcId() == null) { - args = " -i " + routerIp + args; - result = routerProxy("loadbalancer.sh", routerIp, args); - } else { - args = " -i " + cmd.getNic().getIp() + args; - result = routerProxy("vpc_loadbalancer.sh", routerIp, args); - } - - if (result != null) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed"); - } - return new Answer(cmd); - - } catch (Exception e) { - return new Answer(cmd, e); + args += " -a " + sb.toString(); } + + sb = new StringBuilder(); + if (removeRules.length > 0) { + for (int i = 0; i < removeRules.length; i++) { + sb.append(removeRules[i]).append(','); + } + + args += " -d " + sb.toString(); + } + + sb = new StringBuilder(); + if (statRules.length > 0) { + for (int i = 0; i < statRules.length; i++) { + sb.append(statRules[i]).append(','); + } + + args += " -s " + sb.toString(); + } + + if (cmd.getVpcId() == null) { + args = " -i " + routerIp + args; + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "loadbalancer.sh", args); + } else { + args = " -i " + cmd.getNic().getIp() + args; + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_loadbalancer.sh", args); + } + + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(VmDataCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); Map> data = new HashMap>(); data.put(cmd.getVmIpAddress(), cmd.getVmData()); @@ -449,32 +429,8 @@ public class VirtualRoutingResource implements Manager { String args = "-d " + json; - final String result = routerProxy("vmdata.py", routerIp, args); - if (result != null) { - return new Answer(cmd, false, "VmDataCommand failed, check agent logs"); - } - return new Answer(cmd); - } - - protected Answer execute(final IpAssocCommand cmd) { - IpAddressTO[] ips = cmd.getIpAddresses(); - String[] results = new String[cmd.getIpAddresses().length]; - int i = 0; - String result = null; - String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - for (IpAddressTO ip : ips) { - result = - assignPublicIpAddress(routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), ip.getVlanGateway(), - ip.getVlanNetmask(), ip.getVifMacAddress(), 2, false); - if (result != null) { - results[i++] = IpAssocAnswer.errorResult; - } else { - results[i++] = ip.getPublicIp() + " - success"; - ; - } - } - return new IpAssocAnswer(cmd, results); + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vmdata.py", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final SavePasswordCommand cmd) { @@ -485,11 +441,8 @@ public class VirtualRoutingResource implements Manager { String args = "-v " + vmIpAddress; args += " -p " + password; - String result = routerProxy("savepassword.sh", routerPrivateIPAddress, args); - if (result != null) { - return new Answer(cmd, false, "Unable to save password to DomR."); - } - return new Answer(cmd); + ExecutionResult result = _vrDeployer.executeInVR(routerPrivateIPAddress, "savepassword.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final DhcpEntryCommand cmd) { @@ -520,65 +473,44 @@ public class VirtualRoutingResource implements Manager { args += " -N"; } - final String result = routerProxy("edithosts.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - return new Answer(cmd, result == null, result); + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "edithosts.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final CreateIpAliasCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); List ipAliasTOs = cmd.getIpAliasList(); String args = ""; for (IpAliasTO ipaliasto : ipAliasTOs) { args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; } - final String result = routerProxy("createipAlias.sh", routerIp, args); - return new Answer(cmd, result == null, result); + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "createipAlias.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final DeleteIpAliasCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String args = ""; List revokedIpAliasTOs = cmd.getDeleteIpAliasTos(); for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; } + //this is to ensure that thre is some argument passed to the deleteipAlias script when there are no revoked rules. args = args + "- "; List activeIpAliasTOs = cmd.getCreateIpAliasTos(); for (IpAliasTO ipAliasTO : activeIpAliasTOs) { args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; } - final String result = routerProxy("deleteipAlias.sh", routerIp, args); - return new Answer(cmd, result == null, result); + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "deleteipAlias.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final DnsMasqConfigCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); List dhcpTos = cmd.getIps(); String args = ""; for (DhcpTO dhcpTo : dhcpTos) { args = args + dhcpTo.getRouterIp() + ":" + dhcpTo.getGateway() + ":" + dhcpTo.getNetmask() + ":" + dhcpTo.getStartIpOfSubnet() + "-"; } - final String result = routerProxy("dnsmasq.sh", routerIp, args); - return new Answer(cmd, result == null, result); - } - - public String getRouterStatus(String routerIP) { - return routerProxyWithParser("checkrouter.sh", routerIP, null); - } - - public String routerProxyWithParser(String script, String routerIP, String args) { - final Script command = new Script(_routerProxyPath, _timeout, s_logger); - final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); - command.add(script); - command.add(routerIP); - if (args != null) { - command.add(args); - } - String result = command.execute(parser); - if (result == null) { - return parser.getLine(); - } - return null; + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "dnsmasq.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) { @@ -586,74 +518,46 @@ public class VirtualRoutingResource implements Manager { String args = ""; for (String ip : cmd.getVpnIps()) { - args += " " + ip; + args += ip + " "; } - final String result = routerProxy("checkbatchs2svpn.sh", routerIP, args); - if (result == null || result.isEmpty()) { - return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed"); - } - return new CheckS2SVpnConnectionsAnswer(cmd, true, result); - } - - public String routerProxy(String script, String routerIP, String args) { - final Script command = new Script(_routerProxyPath, _timeout, s_logger); - command.add(script); - command.add(routerIP); - if (args != null) { - command.add(args); - } - return command.execute(); + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "checkbatchs2svpn.sh", args); + return new CheckS2SVpnConnectionsAnswer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(CheckRouterCommand cmd) { final String routerPrivateIPAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - final String result = getRouterStatus(routerPrivateIPAddress); - if (result == null || result.isEmpty()) { - return new CheckRouterAnswer(cmd, "CheckRouterCommand failed"); + final ExecutionResult result = _vrDeployer.executeInVR(routerPrivateIPAddress, "checkrouter.sh", null); + if (!result.isSuccess()) { + return new CheckRouterAnswer(cmd, result.getDetails()); } - return new CheckRouterAnswer(cmd, result, true); + return new CheckRouterAnswer(cmd, result.getDetails(), true); } protected Answer execute(BumpUpPriorityCommand cmd) { - String result = routerProxy("bumpup_priority.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), null); - if (result != null) { - return new Answer(cmd, false, "BumpUpPriorityCommand failed due to " + result); - } - return new Answer(cmd, true, null); - } - - protected String getDomRVersion(String routerIP) { - return routerProxyWithParser("get_template_version.sh", routerIP, null); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "bumpup_priority.sh", null); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(GetDomRVersionCmd cmd) { final String routerPrivateIPAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - final String result = getDomRVersion(routerPrivateIPAddress); - if (result == null || result.isEmpty()) { + final ExecutionResult result = _vrDeployer.executeInVR(routerPrivateIPAddress, "get_template_version.sh", null); + if (!result.isSuccess()) { return new GetDomRVersionAnswer(cmd, "GetDomRVersionCmd failed"); } - String[] lines = result.split("&"); + String[] lines = result.getDetails().split("&"); if (lines.length != 2) { - return new GetDomRVersionAnswer(cmd, result); + return new GetDomRVersionAnswer(cmd, result.getDetails()); } - return new GetDomRVersionAnswer(cmd, result, lines[0], lines[1]); - } - - protected Answer execute(final CheckConsoleProxyLoadCommand cmd) { - return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort()); - } - - protected Answer execute(final WatchConsoleProxyLoadCommand cmd) { - return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort()); + return new GetDomRVersionAnswer(cmd, result.getDetails(), lines[0], lines[1]); } protected Answer execute(Site2SiteVpnCfgCommand cmd) { - String args; + String args = ""; if (cmd.isCreate()) { - args = "-A"; + args += "-A"; args += " -l "; args += cmd.getLocalPublicIp(); args += " -n "; @@ -684,7 +588,7 @@ public class VirtualRoutingResource implements Manager { args += " -p "; } } else { - args = "-D"; + args += "-D"; args += " -r "; args += cmd.getPeerGatewayIp(); args += " -n "; @@ -692,59 +596,45 @@ public class VirtualRoutingResource implements Manager { args += " -N "; args += cmd.getPeerGuestCidrList(); } - String result = routerProxy("ipsectunnel.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result != null) { - return new Answer(cmd, false, "Configure site to site VPN failed due to " + result); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "ipsectunnel.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "Configure site to site VPN failed due to " + result.getDetails()); } return new Answer(cmd); } - private Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) { - String result = null; - - final StringBuffer sb = new StringBuffer(); - sb.append("http://").append(proxyManagementIp).append(":" + cmdPort).append("/cmd/getstatus"); - - boolean success = true; - try { - final URL url = new URL(sb.toString()); - final URLConnection conn = url.openConnection(); - - final InputStream is = conn.getInputStream(); - final BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - final StringBuilder sb2 = new StringBuilder(); - String line = null; - try { - while ((line = reader.readLine()) != null) { - sb2.append(line + "\n"); - } - result = sb2.toString(); - } catch (final IOException e) { - success = false; - } finally { - try { - is.close(); - } catch (final IOException e) { - s_logger.warn("Exception when closing , console proxy address : " + proxyManagementIp); - success = false; - } - } - } catch (final IOException e) { - s_logger.warn("Unable to open console proxy command port url, console proxy address : " + proxyManagementIp); - success = false; - } - - return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result); - } - - public String configureMonitor(final String routerIP, final String config) { + protected Answer execute(SetMonitorServiceCommand cmd) { + String config = cmd.getConfiguration(); String args = " -c " + config; - return routerProxy("monitor_service.sh", routerIP, args); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "monitor_service.sh", args); + + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); + } + return new Answer(cmd); } - public String assignGuestNetwork(final String dev, final String routerIP, final String routerGIP, final String gateway, final String cidr, final String netmask, - final String dns, final String domainName) { + protected SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + NicTO nic = cmd.getNic(); + String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String routerGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); + String gateway = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); + String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); + String domainName = cmd.getNetworkDomain(); + String dns = cmd.getDefaultDns1(); + + if (dns == null || dns.isEmpty()) { + dns = cmd.getDefaultDns2(); + } else { + String dns2 = cmd.getDefaultDns2(); + if (dns2 != null && !dns2.isEmpty()) { + dns += "," + dns2; + } + } + + String dev = "eth" + nic.getDeviceId(); + String netmask = NetUtils.getSubNet(routerGIP, nic.getNetmask()); String args = " -C"; args += " -d " + dev; @@ -758,33 +648,74 @@ public class VirtualRoutingResource implements Manager { if (domainName != null && !domainName.isEmpty()) { args += " -e " + domainName; } - return routerProxy("vpc_guestnw.sh", routerIP, args); + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "vpc_guestnw.sh", args); + + if (!result.isSuccess()) { + return new SetupGuestNetworkAnswer(cmd, false, "Creating guest network failed due to " + result.getDetails()); + } + return new SetupGuestNetworkAnswer(cmd, true, "success"); } - public String assignNetworkACL(final String routerIP, final String dev, final String routerGIP, final String netmask, final String rule, String privateGw) { - String args = " -d " + dev; - if (privateGw != null) { - args += " -a " + rule; - return routerProxy("vpc_privategw_acl.sh", routerIP, args); - } else { - args += " -i " + routerGIP; - args += " -m " + netmask; - args += " -a " + rule; - return routerProxy("vpc_acl.sh", routerIP, args); + private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { + String[] results = new String[cmd.getRules().length]; + + String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); + + try { + String[][] rules = cmd.generateFwRules(); + String[] aclRules = rules[0]; + NicTO nic = cmd.getNic(); + String dev = "eth" + nic.getDeviceId(); + String netmask = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < aclRules.length; i++) { + sb.append(aclRules[i]).append(','); + } + + String rule = sb.toString(); + ExecutionResult result; + + String args = " -d " + dev; + if (privateGw != null) { + args += " -a " + rule; + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_privategw_acl.sh", args); + } else { + args += " -i " + nic.getIp(); + args += " -m " + netmask; + args += " -a " + rule; + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_acl.sh", args); + } + + if (!result.isSuccess()) { + for (int i = 0; i < results.length; i++) { + results[i] = "Failed"; + } + return new SetNetworkACLAnswer(cmd, false, results); + } + + return new SetNetworkACLAnswer(cmd, true, results); + } catch (Exception e) { + String msg = "SetNetworkACL failed due to " + e.toString(); + s_logger.error(msg, e); + return new SetNetworkACLAnswer(cmd, false, results); } } - public String assignSourceNat(final String routerIP, final String pubIP, final String dev) { + protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + IpAddressTO pubIP = cmd.getIpAddress(); + String dev = "eth" + pubIP.getNicDevId(); String args = " -A "; args += " -l "; - args += pubIP; + args += pubIP.getPublicIp(); args += " -c "; args += dev; - return routerProxy("vpc_snat.sh", routerIP, args); + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "vpc_snat.sh", args); + return new SetSourceNatAnswer(cmd, result.isSuccess(), result.getDetails()); } private SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; int i = 0; @@ -797,9 +728,9 @@ public class VirtualRoutingResource implements Manager { args += " -r " + rule.getDstIp(); args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - String result = routerProxy("vpc_portforwarding.sh", routerIp, args); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_portforwarding.sh", args); - if (result != null) { + if (!result.isSuccess()) { results[i++] = "Failed"; endResult = false; } else { @@ -809,44 +740,56 @@ public class VirtualRoutingResource implements Manager { return new SetPortForwardingRulesAnswer(cmd, results, endResult); } - public void assignVpcIpToRouter(final String routerIP, final boolean add, final String pubIP, final String nicname, final String gateway, final String netmask, - final String subnet, boolean sourceNat) throws InternalErrorException { + public IpAssocAnswer execute(IpAssocVpcCommand cmd) { + String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String[] results = new String[cmd.getIpAddresses().length]; String args = ""; String snatArgs = ""; - - if (add) { - args += " -A "; - snatArgs += " -A "; - } else { - args += " -D "; - snatArgs += " -D "; + for (int i = 0; i < cmd.getIpAddresses().length; i ++) { + results[i] = "Failed"; } - args += " -l "; - args += pubIP; - args += " -c "; - args += nicname; - args += " -g "; - args += gateway; - args += " -m "; - args += netmask; - args += " -n "; - args += subnet; - - String result = routerProxy("vpc_ipassoc.sh", routerIP, args); - if (result != null) { - throw new InternalErrorException("KVM plugin \"vpc_ipassoc\" failed:" + result); - } - if (sourceNat) { - snatArgs += " -l " + pubIP; - snatArgs += " -c " + nicname; - - result = routerProxy("vpc_privateGateway.sh", routerIP, snatArgs); - if (result != null) { - throw new InternalErrorException("KVM plugin \"vpc_privateGateway\" failed:" + result); + int i = 0; + for (IpAddressTO ip : cmd.getIpAddresses()) { + if (ip.isAdd()) { + args += " -A "; + snatArgs += " -A "; + } else { + args += " -D "; + snatArgs += " -D "; } + args += " -l "; + args += ip.getPublicIp(); + String nicName = "eth" + ip.getNicDevId(); + args += " -c "; + args += nicName; + args += " -g "; + args += ip.getVlanGateway(); + args += " -m "; + args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); + args += " -n "; + args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); + + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "vpc_ipassoc.sh", args); + if (!result.isSuccess()) { + results[i++] = ip.getPublicIp() + " - vpc_ipassoc failed:" + result.getDetails(); + break; + } + + if (ip.isSourceNat()) { + snatArgs += " -l " + ip.getPublicIp(); + snatArgs += " -c " + nicName; + + result = _vrDeployer.executeInVR(routerIP, "vpc_privateGateway.sh", snatArgs); + if (result != null) { + results[i++] = ip.getPublicIp() + " - vpc_privateGateway failed:" + result.getDetails(); + break; + } + } + results[i++] = ip.getPublicIp() + " - success "; } + return new IpAssocAnswer(cmd, results); } private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) { @@ -862,9 +805,9 @@ public class VirtualRoutingResource implements Manager { } String args = " -a " + sb.toString(); - String result = routerProxy("vpc_staticroute.sh", routerIP, args); + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "vpc_staticroute.sh", args); - if (result != null) { + if (!result.isSuccess()) { for (int i = 0; i < results.length; i++) { results[i] = "Failed"; } @@ -879,161 +822,56 @@ public class VirtualRoutingResource implements Manager { } } - private Answer execute(SetMonitorServiceCommand cmd) { - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String config = cmd.getConfiguration(); - - String result = configureMonitor(routerIp, config); - - if (result != null) { - return new Answer(cmd, false, "SetMonitorServiceCommand failed"); - } - return new Answer(cmd); - - } - - public String assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP, - final boolean sourceNat, final String broadcastUri, final String vlanGateway, final String vlanNetmask, final String vifMacAddress, int nicNum, boolean newNic) { - - String args = ""; - if (add) { - args += "-A"; - } else { - args += "-D"; - } - String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask)); - if (sourceNat) { - args += " -s"; - } - if (firstIP) { - args += " -f"; - } - args += " -l "; - args += publicIpAddress + "/" + cidrSize; - - String publicNic = "eth" + nicNum; - args += " -c "; - args += publicNic; - - args += " -g "; - args += vlanGateway; - - if (newNic) { - args += " -n"; + public Answer execute(IpAssocCommand cmd) { + String[] results = new String[cmd.getIpAddresses().length]; + for (int i = 0; i < results.length; i++) { + results[i] = IpAssocAnswer.errorResult; } - return routerProxy("ipassoc.sh", privateIpAddress, args); - } + int i = 0; + for (IpAddressTO ip: cmd.getIpAddresses()) { + String args = ""; + if (ip.isAdd()) { + args += "-A"; + } else { + args += "-D"; + } + String cidrSize = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); + if (ip.isSourceNat()) { + args += " -s"; + } + if (ip.isFirstIP()) { + args += " -f"; + } + args += " -l "; + args += ip.getPublicIp() + "/" + cidrSize; - private void deleteBridge(String brName) { - Script cmd = new Script("/bin/sh", _timeout); - cmd.add("-c"); - cmd.add("ifconfig " + brName + " down;brctl delbr " + brName); - cmd.execute(); - } + String publicNic = "eth" + ip.getNicDevId(); + args += " -c "; + args += publicNic; - private boolean isDNSmasqRunning(String dnsmasqName) { - Script cmd = new Script("/bin/sh", _timeout); - cmd.add("-c"); - cmd.add("ls -l /var/run/libvirt/network/" + dnsmasqName + ".pid"); - String result = cmd.execute(); - if (result != null) { - return false; - } else { - return true; + args += " -g "; + args += ip.getVlanGateway(); + + if (ip.isNewNic()) { + args += " -n"; + } + + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "ipassoc.sh", args); + if (result.isSuccess()) { + results[i++] = ip.getPublicIp() + " - success"; + } else { + results[i++] = ip.getPublicIp() + " - failed:" + result.getDetails(); + break; + } } + return new IpAssocAnswer(cmd, results); } - private void stopDnsmasq(String dnsmasqName) { - Script cmd = new Script("/bin/sh", _timeout); - cmd.add("-c"); - cmd.add("kill -9 `cat /var/run/libvirt/network/" + dnsmasqName + ".pid`"); - cmd.execute(); - } - - // protected Answer execute(final SetFirewallRuleCommand cmd) { - // String args; - // if(cmd.getProtocol().toLowerCase().equals(NetUtils.NAT_PROTO)){ - // //1:1 NAT needs instanceip;publicip;domrip;op - // if(cmd.isCreate()) { - // args = "-A"; - // } else { - // args = "-D"; - // } - // - // args += " -l " + cmd.getPublicIpAddress(); - // args += " -i " + cmd.getRouterIpAddress(); - // args += " -r " + cmd.getPrivateIpAddress(); - // args += " -G " + cmd.getProtocol(); - // }else{ - // if (cmd.isEnable()) { - // args = "-A"; - // } else { - // args = "-D"; - // } - // - // args += " -P " + cmd.getProtocol().toLowerCase(); - // args += " -l " + cmd.getPublicIpAddress(); - // args += " -p " + cmd.getPublicPort(); - // args += " -n " + cmd.getRouterName(); - // args += " -i " + cmd.getRouterIpAddress(); - // args += " -r " + cmd.getPrivateIpAddress(); - // args += " -d " + cmd.getPrivatePort(); - // args += " -N " + cmd.getVlanNetmask(); - // - // String oldPrivateIP = cmd.getOldPrivateIP(); - // String oldPrivatePort = cmd.getOldPrivatePort(); - // - // if (oldPrivateIP != null) { - // args += " -w " + oldPrivateIP; - // } - // - // if (oldPrivatePort != null) { - // args += " -x " + oldPrivatePort; - // } - // } - // - // final Script command = new Script(_firewallPath, _timeout, s_logger); - // String [] argsArray = args.split(" "); - // for (String param : argsArray) { - // command.add(param); - // } - // String result = command.execute(); - // return new Answer(cmd, result == null, result); - // } - - protected String getDefaultScriptsDir() { - return "scripts/network/domr/dom0"; - } - - protected String findScript(final String script) { - return Script.findScript(_scriptsDir, script); - } - - @Override public boolean configure(final String name, final Map params) throws ConfigurationException { _name = name; - _scriptsDir = (String)params.get("domr.scripts.dir"); - if (_scriptsDir == null) { - if (s_logger.isInfoEnabled()) { - s_logger.info("VirtualRoutingResource _scriptDir can't be initialized from domr.scripts.dir param, use default"); - } - _scriptsDir = getDefaultScriptsDir(); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("VirtualRoutingResource _scriptDir to use: " + _scriptsDir); - } - - String value = (String)params.get("scripts.timeout"); - _timeout = NumbersUtil.parseInt(value, 120) * 1000; - - value = (String)params.get("start.script.timeout"); - _startTimeout = NumbersUtil.parseInt(value, 360) * 1000; - - value = (String)params.get("ssh.sleep"); + String value = (String)params.get("ssh.sleep"); _sleep = NumbersUtil.parseInt(value, 10) * 1000; value = (String)params.get("ssh.retry"); @@ -1042,26 +880,8 @@ public class VirtualRoutingResource implements Manager { value = (String)params.get("ssh.port"); _port = NumbersUtil.parseInt(value, 3922); - _publicIpAddress = (String)params.get("public.ip.address"); - if (_publicIpAddress != null) { - s_logger.warn("Incoming public ip address is overriden. Will always be using the same ip address: " + _publicIpAddress); - } - - _publicEthIf = (String)params.get("public.network.device"); - if (_publicEthIf == null) { - _publicEthIf = "xenbr1"; - } - _publicEthIf = _publicEthIf.toLowerCase(); - - _privateEthIf = (String)params.get("private.network.device"); - if (_privateEthIf == null) { - _privateEthIf = "xenbr0"; - } - _privateEthIf = _privateEthIf.toLowerCase(); - - _routerProxyPath = findScript("router_proxy.sh"); - if (_routerProxyPath == null) { - throw new ConfigurationException("Unable to find router_proxy.sh"); + if (_vrDeployer == null) { + throw new ConfigurationException("Unable to find the resource for VirtualRouterDeployer!"); } return true; } @@ -1141,50 +961,4 @@ public class VirtualRoutingResource implements Manager { return false; } - - @Override - public String getName() { - return _name; - } - - @Override - public void setName(String name) { - _name = name; - } - - @Override - public boolean start() { - return true; - } - - @Override - public boolean stop() { - return true; - } - - @Override - public int getRunLevel() { - return ComponentLifecycle.RUN_LEVEL_COMPONENT; - } - - public void setRunLevel() { - } - - @Override - public void setConfigParams(Map params) { - // TODO Auto-generated method stub - - } - - @Override - public Map getConfigParams() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setRunLevel(int level) { - // TODO Auto-generated method stub - - } } diff --git a/debian/control b/debian/control index c756dcd0d8e..ab4644badd2 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: cloudstack Section: libs Priority: extra Maintainer: Wido den Hollander -Build-Depends: debhelper (>= 7), openjdk-6-jdk | openjdk-7-jdk, tomcat6, genisoimage, +Build-Depends: debhelper (>= 7), openjdk-7-jdk, tomcat6, genisoimage, python-mysqldb, maven3 | maven (>= 3), python (>= 2.6.6-3~) Standards-Version: 3.8.1 Homepage: http://www.cloudstack.org/ @@ -22,7 +22,7 @@ Description: CloudStack server library Package: cloudstack-agent Architecture: all -Depends: openjdk-6-jre | openjdk-7-jre, cloudstack-common (= ${source:Version}), lsb-base (>= 3.2), libcommons-daemon-java, openssh-client, libvirt0, sysvinit-utils, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, perl-base, perl-modules, ebtables, vlan, wget, jsvc, ipset, python-libvirt, ethtool, iptables +Depends: openjdk-7-jre, cloudstack-common (= ${source:Version}), lsb-base (>= 3.2), libcommons-daemon-java, openssh-client, libvirt0, sysvinit-utils, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, perl-base, perl-modules, ebtables, vlan, wget, jsvc, ipset, python-libvirt, ethtool, iptables Conflicts: cloud-agent, cloud-agent-libs, cloud-agent-deps, cloud-agent-scripts Description: CloudStack agent The CloudStack agent is in charge of managing shared computing resources in @@ -31,7 +31,7 @@ Description: CloudStack agent Package: cloudstack-usage Architecture: all -Depends: openjdk-6-jre | openjdk-7-jre, cloudstack-common (= ${source:Version}), jsvc +Depends: openjdk-7-jre, cloudstack-common (= ${source:Version}), jsvc Description: CloudStack usage monitor The CloudStack usage monitor provides usage accounting across the entire cloud for cloud operators to charge based on usage parameters. diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 8fd542b9669..f3e3c36c57c 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1525,6 +1525,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } protected boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId, String reservationId) throws NoTransitionException { + // if there are active vm snapshots task, state change is not allowed + if (_vmSnapshotMgr.hasActiveVMSnapshotTasks(vm.getId())) { + s_logger.error("State transit with event: " + e + " failed due to: " + vm.getInstanceName() + " has active VM snapshots tasks"); + return false; + } vm.setReservationId(reservationId); return _stateMachine.transitTo(vm, e, new Pair(vm.getHostId(), hostId), _vmDao); } @@ -4317,7 +4322,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4368,7 +4373,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4421,7 +4426,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4470,7 +4475,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4525,7 +4530,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4578,7 +4583,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4630,7 +4635,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4679,7 +4684,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4728,7 +4733,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4777,7 +4782,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4828,7 +4833,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4918,7 +4923,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac NicProfile nic = orchestrateAddVmToNetwork(vm, network, work.getRequestedNicProfile()); - return new Pair(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(new Long(nic.getId()))); + return new Pair(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(nic.getId())); } private Pair orchestrateRemoveNicFromVm(VmWorkRemoveNicFromVm work) throws Exception { diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index 1a400e049e0..08efb8345f5 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -36,7 +36,7 @@ - + @@ -45,7 +45,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -72,7 +72,7 @@ - + @@ -81,7 +81,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -99,7 +99,7 @@ - + @@ -109,7 +109,7 @@ - + @@ -172,12 +172,12 @@ - - - - + + + + - + @@ -331,6 +331,8 @@ + + diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 9a22466c99e..aab32560717 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -28,6 +28,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.template.VirtualMachineTemplate; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -147,7 +148,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sb.and("format", sb.entity().getFormat(), SearchCriteria.Op.EQ); sb.and("type", sb.entity().getTemplateType(), SearchCriteria.Op.EQ); sb.and("bootable", sb.entity().isBootable(), SearchCriteria.Op.EQ); - sb.and("removed", sb.entity().getRemoved(), SearchCriteria.Op.EQ); + sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); SearchBuilder tagSearch = _tagsDao.createSearchBuilder(); for (int count = 0; count < tags.size(); count++) { @@ -170,7 +171,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } if (!listRemoved) { - sc.setParameters("removed", (Object)null); + sc.setParameters("state", VirtualMachineTemplate.State.Active); } if (tags != null && !tags.isEmpty()) { @@ -197,7 +198,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sc.setParameters("type", TemplateType.USER.toString()); if (!listRemoved) { - sc.setParameters("removed", (Object)null); + sc.setParameters("state", VirtualMachineTemplate.State.Active); } return listBy(sc); @@ -217,7 +218,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem String sql = "select * from template_host_ref as thr INNER JOIN vm_template as t ON t.id=thr.template_id " - + "where thr.host_id=? and t.public=0 and t.featured=0 and t.type='USER' and t.removed is NULL"; + + "where thr.host_id=? and t.public=0 and t.featured=0 and t.type='USER' and t.state='Active'"; List l = new ArrayList(); @@ -265,6 +266,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem public List listByAccountId(long accountId) { SearchCriteria sc = AccountIdSearch.create(); sc.setParameters("accountId", accountId); + sc.setParameters("state", VirtualMachineTemplate.State.Active); return listBy(sc); } @@ -312,12 +314,12 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem PublicIsoSearch.and("format", PublicIsoSearch.entity().getFormat(), SearchCriteria.Op.EQ); PublicIsoSearch.and("type", PublicIsoSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); PublicIsoSearch.and("bootable", PublicIsoSearch.entity().isBootable(), SearchCriteria.Op.EQ); - PublicIsoSearch.and("removed", PublicIsoSearch.entity().getRemoved(), SearchCriteria.Op.EQ); + PublicIsoSearch.and("state", PublicIsoSearch.entity().getState(), SearchCriteria.Op.EQ); UserIsoSearch = createSearchBuilder(); UserIsoSearch.and("format", UserIsoSearch.entity().getFormat(), SearchCriteria.Op.EQ); UserIsoSearch.and("type", UserIsoSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); - UserIsoSearch.and("removed", UserIsoSearch.entity().getRemoved(), SearchCriteria.Op.EQ); + UserIsoSearch.and("state", UserIsoSearch.entity().getState(), SearchCriteria.Op.EQ); tmpltTypeHyperSearch = createSearchBuilder(); tmpltTypeHyperSearch.and("templateType", tmpltTypeHyperSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); @@ -332,7 +334,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem tmpltTypeHyperSearch.done(); readySystemTemplateSearch = createSearchBuilder(); - readySystemTemplateSearch.and("removed", readySystemTemplateSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + readySystemTemplateSearch.and("state", readySystemTemplateSearch.entity().getState(), SearchCriteria.Op.EQ); readySystemTemplateSearch.and("templateType", readySystemTemplateSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); SearchBuilder templateDownloadSearch = _templateDataStoreDao.createSearchBuilder(); templateDownloadSearch.and("downloadState", templateDownloadSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); @@ -355,13 +357,13 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem tmpltTypeHyperSearch2.and("templateName", tmpltTypeHyperSearch2.entity().getName(), SearchCriteria.Op.EQ); tmpltTypeSearch = createSearchBuilder(); - tmpltTypeSearch.and("removed", tmpltTypeSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + tmpltTypeSearch.and("state", tmpltTypeSearch.entity().getState(), SearchCriteria.Op.EQ); tmpltTypeSearch.and("templateType", tmpltTypeSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); AccountIdSearch = createSearchBuilder(); AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountIdSearch.and("publicTemplate", AccountIdSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ); - AccountIdSearch.and("removed", AccountIdSearch.entity().getRemoved(), SearchCriteria.Op.NULL); // only list not removed templates for this account + AccountIdSearch.and("state", AccountIdSearch.entity().getState(), SearchCriteria.Op.EQ); // only list not removed templates for this account AccountIdSearch.done(); SearchBuilder tmpltZoneSearch = _templateZoneDao.createSearchBuilder(); @@ -369,7 +371,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem tmpltZoneSearch.and("zoneId", tmpltZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ); TmpltsInZoneSearch = createSearchBuilder(); - TmpltsInZoneSearch.and("removed", TmpltsInZoneSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + TmpltsInZoneSearch.and("state", TmpltsInZoneSearch.entity().getState(), SearchCriteria.Op.EQ); TmpltsInZoneSearch.and().op("avoidtype", TmpltsInZoneSearch.entity().getTemplateType(), SearchCriteria.Op.NEQ); TmpltsInZoneSearch.or("templateType", TmpltsInZoneSearch.entity().getTemplateType(), SearchCriteria.Op.NULL); TmpltsInZoneSearch.cp(); @@ -378,12 +380,12 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem TmpltsInZoneSearch.done(); ActiveTmpltSearch = createSearchBuilder(); - ActiveTmpltSearch.and("removed", ActiveTmpltSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + ActiveTmpltSearch.and("state", ActiveTmpltSearch.entity().getState(), SearchCriteria.Op.EQ); CountTemplatesByAccount = createSearchBuilder(Long.class); CountTemplatesByAccount.select(null, Func.COUNT, null); CountTemplatesByAccount.and("account", CountTemplatesByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); - CountTemplatesByAccount.and("removed", CountTemplatesByAccount.entity().getRemoved(), SearchCriteria.Op.NULL); + CountTemplatesByAccount.and("state", CountTemplatesByAccount.entity().getState(), SearchCriteria.Op.EQ); CountTemplatesByAccount.done(); // updateStateSearch = this.createSearchBuilder(); @@ -774,6 +776,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem public List listAllInZone(long dataCenterId) { SearchCriteria sc = TmpltsInZoneSearch.create(); sc.setParameters("avoidtype", TemplateType.PERHOST.toString()); + sc.setParameters("state", VirtualMachineTemplate.State.Active); sc.setJoinParameters("tmpltzone", "zoneId", dataCenterId); return listBy(sc); } @@ -781,6 +784,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem @Override public List listAllActive() { SearchCriteria sc = ActiveTmpltSearch.create(); + sc.setParameters("state", VirtualMachineTemplate.State.Active.toString()); return listBy(sc); } @@ -788,6 +792,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem public List listDefaultBuiltinTemplates() { SearchCriteria sc = tmpltTypeSearch.create(); sc.setParameters("templateType", Storage.TemplateType.BUILTIN); + sc.setParameters("state", VirtualMachineTemplate.State.Active); return listBy(sc); } @@ -813,6 +818,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem public VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType) { SearchCriteria sc = readySystemTemplateSearch.create(); sc.setParameters("templateType", Storage.TemplateType.SYSTEM); + sc.setParameters("state", VirtualMachineTemplate.State.Active); sc.setJoinParameters("tmplHyper", "type", Host.Type.Routing); sc.setJoinParameters("tmplHyper", "zoneId", zoneId); sc.setJoinParameters("vmTemplateJoinTemplateStoreRef", "downloadState", VMTemplateStorageResourceAssoc.Status.DOWNLOADED); @@ -873,6 +879,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem public Long countTemplatesForAccount(long accountId) { SearchCriteria sc = CountTemplatesByAccount.create(); sc.setParameters("account", accountId); + sc.setParameters("state", VirtualMachineTemplate.State.Active.toString()); return customSearch(sc, null).get(0); } diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java index 3158905b876..dc89a15c112 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java @@ -172,43 +172,17 @@ public class Upgrade430to440 implements DbUpgrade { } } - - - if (networkRs != null) { - try { networkRs.close(); - } catch (SQLException e) { - } - } - - - if (pstmtNw != null) { - try { + networkRs = null; pstmtNw.close(); - - } catch (SQLException e) { - } - } - + pstmtNw = null; } } //if - - if (vmRs != null) { - try { + pstmtVm.close(); + pstmtVm = null; vmRs.close(); - } catch (SQLException e) { - } - } - - if (networkRs != null) { - try { - networkRs.close(); - } catch (SQLException e) { - } - } - - + vmRs = null; } // while @@ -225,22 +199,6 @@ public class Upgrade430to440 implements DbUpgrade { } - if (pstmtVm != null) { - try { - pstmtVm.close(); - } catch (SQLException e) { - } - } - - - if (pstmtNw != null) { - try { - pstmtNw.close(); - - } catch (SQLException e) { - } - } - if (rs1 != null) { try { rs1.close(); @@ -248,6 +206,15 @@ public class Upgrade430to440 implements DbUpgrade { } } + + + if (pstmtVm != null) { + try { + pstmtVm.close(); + } catch (SQLException e) { + } + } + if (vmRs != null) { try { vmRs.close(); @@ -255,6 +222,17 @@ public class Upgrade430to440 implements DbUpgrade { } } + + + if (pstmtNw != null) { + try { + pstmtNw.close(); + + } catch (SQLException e) { + } + } + + if (networkRs != null) { try { networkRs.close(); diff --git a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java index 9fbfa279089..39b8470b8c2 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java +++ b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java @@ -51,4 +51,6 @@ public interface NicSecondaryIpDao extends GenericDao { NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp); List getSecondaryIpAddressesForNic(long nicId); + + Long countByNicId(long nicId); } diff --git a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java index 2f3cc290b40..29af0198b47 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java @@ -35,6 +35,7 @@ import com.cloud.utils.db.SearchCriteria.Op; public class NicSecondaryIpDaoImpl extends GenericDaoBase implements NicSecondaryIpDao { private final SearchBuilder AllFieldsSearch; private final GenericSearchBuilder IpSearch; + protected GenericSearchBuilder CountByNicId; protected NicSecondaryIpDaoImpl() { super(); @@ -50,6 +51,11 @@ public class NicSecondaryIpDaoImpl extends GenericDaoBase sc = CountByNicId.create(); + sc.setParameters("nic", nicId); + return customSearch(sc, null).get(0); + } } diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmGroupDetailVO.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmGroupDetailVO.java new file mode 100644 index 00000000000..a657caa7d98 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmGroupDetailVO.java @@ -0,0 +1,81 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.resourcedetail; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "autoscale_vmgroup_details") +public class AutoScaleVmGroupDetailVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "autoscale_vmgroup_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value", length = 1024) + private String value; + + @Column(name = "display") + private boolean display; + + public AutoScaleVmGroupDetailVO() { + } + + public AutoScaleVmGroupDetailVO(long id, String name, String value) { + this.resourceId = id; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public boolean isDisplay() { + return display; + } +} \ No newline at end of file diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmProfileDetailVO.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmProfileDetailVO.java new file mode 100644 index 00000000000..06d7296fe13 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmProfileDetailVO.java @@ -0,0 +1,81 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.resourcedetail; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "autoscale_vmprofile_details") +public class AutoScaleVmProfileDetailVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "autoscale_vmprofile_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value", length = 1024) + private String value; + + @Column(name = "display") + private boolean display; + + public AutoScaleVmProfileDetailVO() { + } + + public AutoScaleVmProfileDetailVO(long id, String name, String value) { + this.resourceId = id; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public boolean isDisplay() { + return display; + } +} \ No newline at end of file diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDao.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDao.java new file mode 100644 index 00000000000..6e20e5ae2ca --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDao.java @@ -0,0 +1,26 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.resourcedetail.dao; + +import org.apache.cloudstack.resourcedetail.AutoScaleVmGroupDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +import com.cloud.utils.db.GenericDao; + +public interface AutoScaleVmGroupDetailsDao extends GenericDao, ResourceDetailsDao { + +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDaoImpl.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDaoImpl.java new file mode 100644 index 00000000000..b4c82bc06a1 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDaoImpl.java @@ -0,0 +1,33 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.resourcedetail.dao; + +import javax.ejb.Local; + +import org.apache.cloudstack.resourcedetail.AutoScaleVmGroupDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.springframework.stereotype.Component; + +@Component +@Local(value = {AutoScaleVmGroupDetailsDao.class}) +public class AutoScaleVmGroupDetailsDaoImpl extends ResourceDetailsDaoBase implements AutoScaleVmGroupDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value) { + super.addDetail(new AutoScaleVmGroupDetailVO(resourceId, key, value)); + } +} \ No newline at end of file diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDao.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDao.java new file mode 100644 index 00000000000..9da313a85a7 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDao.java @@ -0,0 +1,26 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.resourcedetail.dao; + +import org.apache.cloudstack.resourcedetail.AutoScaleVmProfileDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +import com.cloud.utils.db.GenericDao; + +public interface AutoScaleVmProfileDetailsDao extends GenericDao, ResourceDetailsDao { + +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDaoImpl.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDaoImpl.java new file mode 100644 index 00000000000..17e0316bc98 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDaoImpl.java @@ -0,0 +1,33 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.resourcedetail.dao; + +import javax.ejb.Local; + +import org.apache.cloudstack.resourcedetail.AutoScaleVmProfileDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.springframework.stereotype.Component; + +@Component +@Local(value = {AutoScaleVmProfileDetailsDao.class}) +public class AutoScaleVmProfileDetailsDaoImpl extends ResourceDetailsDaoBase implements AutoScaleVmProfileDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value) { + super.addDetail(new AutoScaleVmProfileDetailVO(resourceId, key, value)); + } +} \ No newline at end of file diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 2c829141a1e..166b523e387 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -75,6 +75,7 @@ import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.ResourceAllocationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.StoragePool; import com.cloud.storage.VMTemplateStorageResourceAssoc; @@ -721,6 +722,13 @@ public class TemplateServiceImpl implements TemplateService { @Override public AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, DataStore destStore) { + // for vmware template, we need to check if ova packing is needed, since template created from snapshot does not have .ova file + // we invoke createEntityExtractURL to trigger ova packing. Ideally, we can directly use extractURL to pass to following createTemplate. + // Need to understand what is the background to use two different urls for copy and extract. + if (srcTemplate.getFormat() == ImageFormat.OVA){ + ImageStoreEntity tmpltStore = (ImageStoreEntity)srcTemplate.getDataStore(); + tmpltStore.createEntityExtractUrl(srcTemplate.getInstallPath(), srcTemplate.getFormat(), srcTemplate); + } // generate a URL from source template ssvm to download to destination data store String url = generateCopyUrl(srcTemplate); if (url == null) { diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 3e5a5466fd0..3e315da4b48 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -420,12 +420,12 @@ public class VolumeServiceImpl implements VolumeService { } else { if (s_logger.isDebugEnabled()) { s_logger.debug("Found template " + template.getUniqueName() + " in storage pool " + dataStore.getId() + " with VMTemplateStoragePool id: " + - templatePoolRef.getId()); + templatePoolRef.getId()); } } long templatePoolRefId = templatePoolRef.getId(); CreateBaseImageContext context = - new CreateBaseImageContext(null, volume, dataStore, template, future, templateOnPrimaryStoreObj, templatePoolRefId); + new CreateBaseImageContext(null, volume, dataStore, template, future, templateOnPrimaryStoreObj, templatePoolRefId); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null)).setContext(context); @@ -440,9 +440,9 @@ public class VolumeServiceImpl implements VolumeService { s_logger.info("Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId); } templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId()); - if (templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) { + if (templatePoolRef != null && templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) { s_logger.info("Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId + ", But Template " + template.getUniqueName() + - " is already copied to primary storage, skip copying"); + " is already copied to primary storage, skip copying"); createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future); return; } @@ -523,7 +523,7 @@ public class VolumeServiceImpl implements VolumeService { volumeOnPrimaryStorage.processEvent(Event.CreateOnlyRequested); CreateVolumeFromBaseImageContext context = - new CreateVolumeFromBaseImageContext(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null); + new CreateVolumeFromBaseImageContext(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null)); caller.setContext(context); @@ -534,7 +534,7 @@ public class VolumeServiceImpl implements VolumeService { @DB protected Void createVolumeFromBaseImageCallBack(AsyncCallbackDispatcher callback, - CreateVolumeFromBaseImageContext context) { + CreateVolumeFromBaseImageContext context) { DataObject vo = context.vo; DataObject tmplOnPrimary = context.templateOnStore; CopyCommandResult result = callback.getResult(); @@ -615,7 +615,7 @@ public class VolumeServiceImpl implements VolumeService { volumeOnStore.processEvent(Event.CreateOnlyRequested); snapshot.processEvent(Event.CopyingRequested); CreateVolumeFromBaseImageContext context = - new CreateVolumeFromBaseImageContext(null, volume, store, volumeOnStore, future, snapshot); + new CreateVolumeFromBaseImageContext(null, volume, store, volumeOnStore, future, snapshot); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null)).setContext(context); motionSrv.copyAsync(snapshot, volumeOnStore, caller); @@ -630,7 +630,7 @@ public class VolumeServiceImpl implements VolumeService { } protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher callback, - CreateVolumeFromBaseImageContext context) { + CreateVolumeFromBaseImageContext context) { CopyCommandResult result = callback.getResult(); VolumeInfo volume = (VolumeInfo)context.templateOnStore; SnapshotInfo snapshot = context.snapshot; @@ -716,7 +716,7 @@ public class VolumeServiceImpl implements VolumeService { } protected Void - copyVolumeFromImageToPrimaryCallback(AsyncCallbackDispatcher callback, CopyVolumeContext context) { + copyVolumeFromImageToPrimaryCallback(AsyncCallbackDispatcher callback, CopyVolumeContext context) { VolumeInfo srcVolume = context.srcVolume; VolumeInfo destVolume = context.destVolume; CopyCommandResult result = callback.getResult(); @@ -770,7 +770,7 @@ public class VolumeServiceImpl implements VolumeService { } protected Void - copyVolumeFromPrimaryToImageCallback(AsyncCallbackDispatcher callback, CopyVolumeContext context) { + copyVolumeFromPrimaryToImageCallback(AsyncCallbackDispatcher callback, CopyVolumeContext context) { VolumeInfo srcVolume = context.srcVolume; VolumeInfo destVolume = context.destVolume; CopyCommandResult result = callback.getResult(); @@ -988,7 +988,7 @@ public class VolumeServiceImpl implements VolumeService { } protected Void - migrateVmWithVolumesCallBack(AsyncCallbackDispatcher callback, MigrateVmWithVolumesContext context) { + migrateVmWithVolumesCallBack(AsyncCallbackDispatcher callback, MigrateVmWithVolumesContext context) { Map volumeToPool = context.volumeToPool; CopyCommandResult result = callback.getResult(); AsyncCallFuture future = context.future; @@ -1065,20 +1065,20 @@ public class VolumeServiceImpl implements VolumeService { physicalSize = volStore.getPhysicalSize(); } else { s_logger.warn("No entry found in volume_store_ref for volume id: " + vo.getId() + " and image store id: " + ds.getId() + - " at the end of uploading volume!"); + " at the end of uploading volume!"); } Scope dsScope = ds.getScope(); if (dsScope.getScopeType() == ScopeType.ZONE) { if (dsScope.getScopeId() != null) { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_UPLOAD, vo.getAccountId(), dsScope.getScopeId(), vo.getId(), vo.getName(), null, - null, physicalSize, vo.getSize(), Volume.class.getName(), vo.getUuid()); + null, physicalSize, vo.getSize(), Volume.class.getName(), vo.getUuid()); } else { s_logger.warn("Zone scope image store " + ds.getId() + " has a null scope id"); } } else if (dsScope.getScopeType() == ScopeType.REGION) { // publish usage event for region-wide image store using a -1 zoneId for 4.2, need to revisit post-4.2 UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_UPLOAD, vo.getAccountId(), -1, vo.getId(), vo.getName(), null, null, physicalSize, - vo.getSize(), Volume.class.getName(), vo.getUuid()); + vo.getSize(), Volume.class.getName(), vo.getUuid()); _resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, vo.getSize()); } @@ -1173,7 +1173,7 @@ public class VolumeServiceImpl implements VolumeService { VolumeVO volume = _volumeDao.findById(volumeStore.getVolumeId()); if (volume == null) { s_logger.warn("Volume_store_ref shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId + - ", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark it as destroyed"); + ", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark it as destroyed"); volumeStore.setDestroyed(true); _volumeStoreDao.update(volumeStore.getId(), volumeStore); continue; @@ -1193,7 +1193,7 @@ public class VolumeServiceImpl implements VolumeService { s_logger.info("msg"); if (volumeStore.getDownloadUrl() == null) { msg = - "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + + "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + "is corrupted, please check in image store: " + volumeStore.getDataStoreId(); s_logger.warn(msg); } else { @@ -1221,15 +1221,15 @@ public class VolumeServiceImpl implements VolumeService { if (volInfo.getSize() > 0) { try { _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), - com.cloud.configuration.Resource.ResourceType.secondary_storage, volInfo.getSize() - volInfo.getPhysicalSize()); + com.cloud.configuration.Resource.ResourceType.secondary_storage, volInfo.getSize() - volInfo.getPhysicalSize()); } catch (ResourceAllocationException e) { s_logger.warn(e.getMessage()); _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(), - e.getMessage(), - e.getMessage()); + e.getMessage(), + e.getMessage()); } finally { _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), - com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); + com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); } } } @@ -1238,7 +1238,7 @@ public class VolumeServiceImpl implements VolumeService { // Volume is not on secondary but we should download. if (volumeStore.getDownloadState() != Status.DOWNLOADED) { s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + - ", will request download to start/resume shortly"); + ", will request download to start/resume shortly"); toBeDownloaded.add(volumeStore); } } diff --git a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java index 503d7591135..f282428b8de 100755 --- a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java +++ b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java @@ -658,9 +658,21 @@ public abstract class GenericDaoBase extends Compone } } + /** + * Get a value from a result set. + * + * @param type + * the expected type of the result + * @param rs + * the result set + * @param index + * the index of the column + * @return the result in the requested type + * @throws SQLException + */ @DB() @SuppressWarnings("unchecked") - protected M getObject(Class type, ResultSet rs, int index) throws SQLException { + protected static M getObject(Class type, ResultSet rs, int index) throws SQLException { if (type == String.class) { byte[] bytes = rs.getBytes(index); if (bytes != null) { @@ -681,12 +693,12 @@ public abstract class GenericDaoBase extends Compone return (M)new Integer(rs.getInt(index)); } } else if (type == long.class) { - return (M)new Long(rs.getLong(index)); + return (M) (Long) rs.getLong(index); } else if (type == Long.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Long(rs.getLong(index)); + return (M) (Long) rs.getLong(index); } } else if (type == Date.class) { final Object data = rs.getDate(index); @@ -696,44 +708,44 @@ public abstract class GenericDaoBase extends Compone return (M)DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)); } } else if (type == short.class) { - return (M)new Short(rs.getShort(index)); + return (M) (Short) rs.getShort(index); } else if (type == Short.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Short(rs.getShort(index)); + return (M) (Short) rs.getShort(index); } } else if (type == boolean.class) { - return (M)new Boolean(rs.getBoolean(index)); + return (M) (Boolean) rs.getBoolean(index); } else if (type == Boolean.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Boolean(rs.getBoolean(index)); + return (M) (Boolean) rs.getBoolean(index); } } else if (type == float.class) { - return (M)new Float(rs.getFloat(index)); + return (M) (Float) rs.getFloat(index); } else if (type == Float.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Float(rs.getFloat(index)); + return (M) (Float) rs.getFloat(index); } } else if (type == double.class) { - return (M)new Double(rs.getDouble(index)); + return (M) (Double) rs.getDouble(index); } else if (type == Double.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Double(rs.getDouble(index)); + return (M) (Double) rs.getDouble(index); } } else if (type == byte.class) { - return (M)new Byte(rs.getByte(index)); + return (M) (Byte) rs.getByte(index); } else if (type == Byte.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Byte(rs.getByte(index)); + return (M) (Byte) rs.getByte(index); } } else if (type == Calendar.class) { final Object data = rs.getDate(index); diff --git a/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java b/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java new file mode 100644 index 00000000000..b7febcb8994 --- /dev/null +++ b/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java @@ -0,0 +1,134 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.utils.db; + +import java.sql.ResultSet; +import java.sql.SQLException; + +import junit.framework.Assert; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class GenericDaoBaseTest { + @Mock + ResultSet resultSet; + + @Test + public void getObjectBoolean() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(false); + Mockito.when(resultSet.getBoolean(1)).thenReturn(false); + Assert.assertFalse(GenericDaoBase + .getObject(Boolean.class, resultSet, 1)); + Mockito.verify(resultSet).getBoolean(1); + } + + @Test + public void getObjectPrimitiveBoolean() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(false); + Mockito.when(resultSet.getBoolean(1)).thenReturn(false); + Assert.assertFalse(GenericDaoBase + .getObject(boolean.class, resultSet, 1)); + Mockito.verify(resultSet).getBoolean(1); + } + + @Test + public void getObjectPrimitiveShort() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn((short) 1); + Mockito.when(resultSet.getShort(1)).thenReturn((short) 1); + Assert.assertEquals(Short.valueOf((short) 1), + GenericDaoBase.getObject(short.class, resultSet, 1)); + Mockito.verify(resultSet).getShort(1); + } + + @Test + public void getObjectShort() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn((short) 1); + Mockito.when(resultSet.getShort(1)).thenReturn((short) 1); + Assert.assertEquals(Short.valueOf((short) 1), + GenericDaoBase.getObject(Short.class, resultSet, 1)); + Mockito.verify(resultSet).getShort(1); + } + + @Test + public void getObjectFloat() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(0.1f); + Mockito.when(resultSet.getFloat(1)).thenReturn(0.1f); + Assert.assertEquals(0.1f, + GenericDaoBase.getObject(Float.class, resultSet, 1)); + Mockito.verify(resultSet).getFloat(1); + } + + @Test + public void getObjectPrimitiveFloat() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(0.1f); + Mockito.when(resultSet.getFloat(1)).thenReturn(0.1f); + Assert.assertEquals(0.1f, + GenericDaoBase.getObject(float.class, resultSet, 1)); + Mockito.verify(resultSet).getFloat(1); + } + + @Test + public void getObjectPrimitiveDouble() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(0.1d); + Mockito.when(resultSet.getDouble(1)).thenReturn(0.1d); + Assert.assertEquals(0.1d, + GenericDaoBase.getObject(double.class, resultSet, 1)); + Mockito.verify(resultSet).getDouble(1); + } + + @Test + public void getObjectDouble() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(0.1d); + Mockito.when(resultSet.getDouble(1)).thenReturn(0.1d); + Assert.assertEquals(0.1d, + GenericDaoBase.getObject(Double.class, resultSet, 1)); + Mockito.verify(resultSet).getDouble(1); + } + + @Test + public void getObjectLong() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(1l); + Mockito.when(resultSet.getLong(1)).thenReturn(1l); + Assert.assertEquals((Long) 1l, + GenericDaoBase.getObject(Long.class, resultSet, 1)); + Mockito.verify(resultSet).getLong(1); + } + + @Test + public void getObjectPrimitiveLong() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(1l); + Mockito.when(resultSet.getLong(1)).thenReturn(1l); + Assert.assertEquals((Long) 1l, + GenericDaoBase.getObject(long.class, resultSet, 1)); + Mockito.verify(resultSet).getLong(1); + } + + @Test + public void getObjectPrimitiveByte() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn((byte) 1); + Mockito.when(resultSet.getByte(1)).thenReturn((byte) 1); + Assert.assertTrue((byte) 1 == GenericDaoBase.getObject(byte.class, + resultSet, 1)); + Mockito.verify(resultSet).getByte(1); + } + +} diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec index 8029b61cc31..83c598b07a7 100644 --- a/packaging/centos63/cloud.spec +++ b/packaging/centos63/cloud.spec @@ -43,7 +43,7 @@ Group: System Environment/Libraries Source0: %{name}-%{_maventag}.tgz BuildRoot: %{_tmppath}/%{name}-%{_maventag}-%{release}-build -BuildRequires: java-1.6.0-openjdk-devel +BuildRequires: java-1.7.0-openjdk-devel BuildRequires: tomcat6 BuildRequires: ws-commons-util BuildRequires: jpackage-utils @@ -60,7 +60,7 @@ intelligent IaaS cloud implementation. %package management Summary: CloudStack management server UI Requires: tomcat6 -Requires: java >= 1.6.0 +Requires: java >= 1.7.0 Requires: python Requires: bash Requires: bzip2 @@ -112,7 +112,7 @@ The Apache CloudStack files shared between agent and management server %package agent Summary: CloudStack Agent for KVM hypervisors Requires: openssh-clients -Requires: java >= 1.6.0 +Requires: java >= 1.7.0 Requires: %{name}-common = %{_ver} Requires: libvirt Requires: bridge-utils @@ -138,7 +138,7 @@ The CloudStack agent for KVM hypervisors %package usage Summary: CloudStack Usage calculation server -Requires: java >= 1.6.0 +Requires: java >= 1.7.0 Requires: jsvc Requires: jakarta-commons-daemon Requires: jakarta-commons-daemon-jsvc diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.Designer.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.Designer.cs index 854427732aa..4bf424fa4b9 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.Designer.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.Designer.cs @@ -45,7 +45,7 @@ namespace CloudStack.Plugin.AgentShell private void InitializeComponent() { components = new System.ComponentModel.Container(); - this.ServiceName = "CloudStack ServerResource"; + this.ServiceName = Program.serviceName; } #endregion diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config index 68ab80ee555..3ec08bd29c9 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config @@ -10,9 +10,9 @@ - + - + @@ -25,13 +25,14 @@ + - + @@ -95,7 +96,7 @@ 2048 - 10.102.192.150 + 0.0.0.0 diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs index 847380cb115..c336a3821e3 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs @@ -254,7 +254,7 @@ namespace HypervResource // Assert if (result.dataStore == null || (result.primaryDataStore == null && result.nfsDataStore == null)) { - String errMsg = "VolumeObjectTO missing dataStore in spec " + volumeObjectTOJson.ToString(); + String errMsg = "VolumeObjectTO missing dataStore in spec " + Utils.CleanString(volumeObjectTOJson.ToString()); logger.Error(errMsg); throw new ArgumentNullException(errMsg); } @@ -292,7 +292,7 @@ namespace HypervResource } else { - String errMsg = "VolumeObjectTO missing dataStore in spec " + volInfo.ToString(); + String errMsg = "VolumeObjectTO missing dataStore in spec " + Utils.CleanString(volInfo.ToString()); logger.Error(errMsg); throw new ArgumentNullException(errMsg); } @@ -690,6 +690,20 @@ namespace HypervResource public String entityType; } + public class NicDetails + { + [JsonProperty("macAddress")] + public string macaddress; + [JsonProperty("vlanid")] + public int vlanid; + public NicDetails() { } + public NicDetails(String macaddress, int vlanid) + { + this.macaddress = macaddress; + this.vlanid = vlanid; + } + } + /// /// Fully qualified named for a number of types used in CloudStack. Used to specify the intended type for JSON serialised objects. /// @@ -738,6 +752,10 @@ namespace HypervResource public const string GetVmDiskStatsCommand = "com.cloud.agent.api.GetVmDiskStatsCommand"; public const string GetVmStatsAnswer = "com.cloud.agent.api.GetVmStatsAnswer"; public const string GetVmStatsCommand = "com.cloud.agent.api.GetVmStatsCommand"; + public const string GetVmConfigCommand = "com.cloud.agent.api.GetVmConfigCommand"; + public const string GetVmConfigAnswer = "com.cloud.agent.api.GetVmConfigAnswer"; + public const string ModifyVmNicConfigCommand = "com.cloud.agent.api.ModifyVmNicConfigCommand"; + public const string ModifyVmNicConfigAnswer = "com.cloud.agent.api.ModifyVmNicConfigAnswer"; public const string GetVncPortAnswer = "com.cloud.agent.api.GetVncPortAnswer"; public const string GetVncPortCommand = "com.cloud.agent.api.GetVncPortCommand"; public const string HostStatsEntry = "com.cloud.agent.api.HostStatsEntry"; diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index a1c91a5b642..ebb3bce2cf8 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -207,7 +207,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.AttachCommand + cmd.ToString()); + logger.Info(CloudStackTypes.AttachCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; @@ -268,7 +268,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.DettachCommand + cmd.ToString()); + logger.Info(CloudStackTypes.DettachCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; @@ -485,7 +485,7 @@ namespace HypervResource { JObject ansObj = Utils.CreateCloudStackObject(ansType, ansContent); JArray answer = new JArray(ansObj); - logger.Info(ansObj.ToString()); + logger.Info(Utils.CleanString(ansObj.ToString())); return answer; } @@ -496,7 +496,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.CreateCommand + cmd.ToString()); + logger.Info(CloudStackTypes.CreateCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; @@ -603,7 +603,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.PrimaryStorageDownloadCommand + cmd.ToString()); + logger.Info(CloudStackTypes.PrimaryStorageDownloadCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; long size = 0; @@ -871,7 +871,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.CreateStoragePoolCommand + cmd.ToString()); + logger.Info(CloudStackTypes.CreateStoragePoolCommand + Utils.CleanString(cmd.ToString())); object ansContent = new { result = true, @@ -889,7 +889,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.ModifyStoragePoolCommand + cmd.ToString()); + logger.Info(CloudStackTypes.ModifyStoragePoolCommand + Utils.CleanString(cmd.ToString())); string details = null; string localPath; StoragePoolType poolType; @@ -982,6 +982,24 @@ namespace HypervResource return true; } + // POST api/HypervResource/PlugNicCommand + [HttpPost] + [ActionName(CloudStackTypes.PlugNicCommand)] + public JContainer PlugNicCommand([FromBody]dynamic cmd) + { + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.PlugNicCommand + cmd.ToString()); + object ansContent = new + { + result = true, + details = "instead of plug, change he network settings", + contextMap = contextMap + }; + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.PlugNicAnswer); + } + } + // POST api/HypervResource/CleanupNetworkRulesCmd [HttpPost] @@ -1045,7 +1063,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.StartCommand + cmd.ToString()); // TODO: Security hole? VM data printed to log + logger.Info(CloudStackTypes.StartCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; @@ -1144,7 +1162,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.CreateObjectCommand + cmd.ToString()); + logger.Info(CloudStackTypes.CreateObjectCommand + Utils.CleanString(cmd.ToString())); bool result = false; string details = null; @@ -1264,6 +1282,88 @@ namespace HypervResource } } + // POST api/HypervResource/ModifyVmVnicVlanCommand + [HttpPost] + [ActionName(CloudStackTypes.ModifyVmNicConfigCommand)] + public JContainer ModifyVmNicConfigCommand([FromBody]dynamic cmd) + { + + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.ModifyVmNicConfigCommand + cmd.ToString()); + bool result = false; + String vmName = cmd.vmName; + uint vlan = (uint)cmd.vlan; + string macAddress = cmd.macAddress; + wmiCallsV2.ModifyVmVLan(vmName, vlan, macAddress); + + result = true; + + object ansContent = new + { + vmName = vmName, + result = result, + contextMap = contextMap + }; + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.ModifyVmNicConfigAnswer); + } + + } + + // POST api/HypervResource/GetVmConfigCommand + [HttpPost] + [ActionName(CloudStackTypes.GetVmConfigCommand)] + public JContainer GetVmConfigCommand([FromBody]dynamic cmd) + { + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.GetVmConfigCommand + cmd.ToString()); + bool result = false; + String vmName = cmd.vmName; + ComputerSystem vm = wmiCallsV2.GetComputerSystem(vmName); + List nicDetails = new List(); + var nicSettingsViaVm = wmiCallsV2.GetEthernetPortSettings(vm); + NicDetails nic = null; + String[] macAddress = new String[nicSettingsViaVm.Length]; + int index = 0; + foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm) + { + macAddress[index++] = item.Address; + } + + index = 0; + var ethernetConnections = wmiCallsV2.GetEthernetConnections(vm); + int vlanid = 1; + foreach (EthernetPortAllocationSettingData item in ethernetConnections) + { + EthernetSwitchPortVlanSettingData vlanSettings = wmiCallsV2.GetVlanSettings(item); + if (vlanSettings == null) + { + vlanid = -1; + } + else + { + vlanid = vlanSettings.AccessVlanId; + } + nic = new NicDetails(macAddress[index++], vlanid); + nicDetails.Add(nic); + } + + result = true; + + object ansContent = new + { + vmName = vmName, + nics = nicDetails, + result = result, + contextMap = contextMap + }; + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVmConfigAnswer); + } + } + + + // POST api/HypervResource/GetVmStatsCommand [HttpPost] [ActionName(CloudStackTypes.GetVmStatsCommand)] @@ -1315,7 +1415,7 @@ namespace HypervResource using (log4net.NDC.Push(Guid.NewGuid().ToString())) { // Log command *after* we've removed security details from the command. - logger.Info(CloudStackTypes.CopyCommand + cmd.ToString()); + logger.Info(CloudStackTypes.CopyCommand + Utils.CleanString(cmd.ToString())); bool result = false; string details = null; @@ -1691,7 +1791,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.GetStorageStatsCommand + cmd.ToString()); + logger.Info(CloudStackTypes.GetStorageStatsCommand + Utils.CleanString(cmd.ToString())); bool result = false; string details = null; long capacity = 0; @@ -1921,6 +2021,7 @@ namespace HypervResource string productVersion = System.Environment.OSVersion.Version.Major.ToString() + "." + System.Environment.OSVersion.Version.Minor.ToString(); details.Add("product_version", productVersion); + details.Add("rdp.server.port", 2179); } // Detect CPUs, speed, memory @@ -2000,6 +2101,45 @@ namespace HypervResource } } + // POST api/HypervResource/GetVncPortCommand + [HttpPost] + [ActionName(CloudStackTypes.GetVncPortCommand)] + public JContainer GetVncPortCommand([FromBody]dynamic cmd) + { + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.GetVncPortCommand + cmd.ToString()); + + string details = null; + bool result = false; + string address = null; + int port = -9; + + try + { + string vmName = (string)cmd.name; + var sys = wmiCallsV2.GetComputerSystem(vmName); + address = "instanceId=" + sys.Name ; + result = true; + } + catch (Exception sysEx) + { + details = CloudStackTypes.GetVncPortAnswer + " failed due to " + sysEx.Message; + logger.Error(details, sysEx); + } + + object ansContent = new + { + result = result, + details = details, + address = address, + port = port + }; + + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVncPortAnswer); + } + } + public static System.Net.NetworkInformation.NetworkInterface GetNicInfoFromIpAddress(string ipAddress, out string subnet) { System.Net.NetworkInformation.NetworkInterface[] nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces(); diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs index 5f814c59535..9042d7c5e12 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs @@ -66,5 +66,6 @@ namespace HypervResource void patchSystemVmIso(string vmName, string systemVmIso); void SetState(ComputerSystem vm, ushort requiredState); Dictionary GetVmSync(String privateIpAddress); + void ModifyVmVLan(string vmName, uint vlanid, string mac); } } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs index c4b39ba24c2..6ebc5bf7f23 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs @@ -164,6 +164,16 @@ namespace HypervResource capacity = totalNumberOfBytes > 0 ? (long)totalNumberOfBytes : 0; } + public static string CleanString(string stringToClean) + { + string cleanString = null; + string regexQueryString = "(&|%26)?(password|accesskey|secretkey)(=|%3D).*?(?=(%26|[&'\"]))"; + string regexJson = "\"(password|accesskey|secretkey)\":\".*?\",?"; + cleanString = System.Text.RegularExpressions.Regex.Replace(stringToClean, regexQueryString, ""); + cleanString = System.Text.RegularExpressions.Regex.Replace(cleanString, regexJson, ""); + return cleanString; + } + // from http://stackoverflow.com/a/2541569/939250 #region imports [DllImport("advapi32.dll", SetLastError = true)] diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs index 2e3aca59675..b9694f00eca 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs @@ -443,6 +443,7 @@ namespace HypervResource nicCount++; } + // pass the boot args for the VM using KVP component. // We need to pass the boot args to system vm's to get them configured with cloudstack configuration. // Add new user data @@ -909,6 +910,37 @@ namespace HypervResource return new ResourceAllocationSettingData((ManagementBaseObject)defaultDiskDriveSettings.LateBoundObject.Clone()); } + + // Modify the systemvm nic's VLAN id + public void ModifyVmVLan(string vmName, uint vlanid, String mac) + { + ComputerSystem vm = GetComputerSystem(vmName); + SyntheticEthernetPortSettingData[] nicSettingsViaVm = GetEthernetPortSettings(vm); + // Obtain controller for Hyper-V virtualisation subsystem + VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService(); + string normalisedMAC = string.Join("", (mac.Split(new char[] { ':' }))); + int index = 0; + foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm) + { + if (normalisedMAC.ToLower().Equals(item.Address.ToLower())) + { + break; + } + index++; + } + + //TODO: make sure the index wont be out of range. + + EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm); + EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[index]); + + //Assign configuration to new NIC + vlanSettings.LateBoundObject["AccessVlanId"] = vlanid; + vlanSettings.LateBoundObject["OperationMode"] = 1; + ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] { + vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)}); + } + public void AttachIso(string displayName, string iso) { logger.DebugFormat("Got request to attach iso {0} to vm {1}", iso, displayName); @@ -1420,6 +1452,36 @@ namespace HypervResource return vSwitch; } + + private static void ModifyFeatureVmResources(VirtualSystemManagementService vmMgmtSvc, ComputerSystem vm, string[] resourceSettings) + { + // Resource settings are changed through the management service + System.Management.ManagementPath jobPath; + System.Management.ManagementPath[] results; + + var ret_val = vmMgmtSvc.ModifyFeatureSettings( + resourceSettings, + out jobPath, + out results); + + // If the Job is done asynchronously + if (ret_val == ReturnCode.Started) + { + JobCompleted(jobPath); + } + else if (ret_val != ReturnCode.Completed) + { + var errMsg = string.Format( + "Failed to update VM {0} (GUID {1}) due to {2} (ModifyVirtualSystem call), existing VM not deleted", + vm.ElementName, + vm.Name, + ReturnCode.ToString(ret_val)); + var ex = new WmiException(errMsg); + logger.Error(errMsg, ex); + throw ex; + } + } + private static void ModifyVmResources(VirtualSystemManagementService vmMgmtSvc, ComputerSystem vm, string[] resourceSettings) { // Resource settings are changed through the management service diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java index 5845038bbff..1d9e7f619f9 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java @@ -16,15 +16,30 @@ // under the License. package com.cloud.hypervisor.hyperv.guru; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + import javax.ejb.Local; import javax.inject.Inject; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuru; import com.cloud.hypervisor.HypervisorGuruBase; import com.cloud.storage.GuestOSVO; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.hypervisor.hyperv.manager.HypervManager; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.NicProfile; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; /** @@ -35,6 +50,9 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru { @Inject private GuestOSDao _guestOsDao; + @Inject HypervManager _hypervMgr; + @Inject NetworkDao _networkDao; + @Inject NetworkModel _networkMgr; @Override public final HypervisorType getHypervisorType() { @@ -51,6 +69,78 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru { @Override public final VirtualMachineTO implement(VirtualMachineProfile vm) { VirtualMachineTO to = toVirtualMachineTO(vm); + List nicProfiles = vm.getNics(); + + if(vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) { + + NicProfile publicNicProfile = null; + for(NicProfile nicProfile : nicProfiles) { + if(nicProfile.getTrafficType() == TrafficType.Public) { + publicNicProfile = nicProfile; + break; + } + } + + if(publicNicProfile != null) { + NicTO[] nics = to.getNics(); + + // reserve extra NICs + NicTO[] expandedNics = new NicTO[nics.length + _hypervMgr.getRouterExtraPublicNics()]; + int i = 0; + int deviceId = -1; + for(i = 0; i < nics.length; i++) { + expandedNics[i] = nics[i]; + if(nics[i].getDeviceId() > deviceId) + deviceId = nics[i].getDeviceId(); + } + deviceId++; + + long networkId = publicNicProfile.getNetworkId(); + NetworkVO network = _networkDao.findById(networkId); + + for(; i < nics.length + _hypervMgr.getRouterExtraPublicNics(); i++) { + NicTO nicTo = new NicTO(); + nicTo.setDeviceId(deviceId++); + nicTo.setBroadcastType(publicNicProfile.getBroadcastType()); + nicTo.setType(publicNicProfile.getTrafficType()); + nicTo.setIp("0.0.0.0"); + nicTo.setNetmask("255.255.255.255"); + nicTo.setName(publicNicProfile.getName()); + + try { + String mac = _networkMgr.getNextAvailableMacAddressInNetwork(networkId); + nicTo.setMac(mac); + } catch (InsufficientAddressCapacityException e) { + throw new CloudRuntimeException("unable to allocate mac address on network: " + networkId); + } + nicTo.setDns1(publicNicProfile.getDns1()); + nicTo.setDns2(publicNicProfile.getDns2()); + if (publicNicProfile.getGateway() != null) { + nicTo.setGateway(publicNicProfile.getGateway()); + } else { + nicTo.setGateway(network.getGateway()); + } + nicTo.setDefaultNic(false); + nicTo.setBroadcastUri(publicNicProfile.getBroadCastUri()); + nicTo.setIsolationuri(publicNicProfile.getIsolationUri()); + + Integer networkRate = _networkMgr.getNetworkRate(network.getId(), null); + nicTo.setNetworkRateMbps(networkRate); + + expandedNics[i] = nicTo; + } + to.setNics(expandedNics); + } + + StringBuffer sbMacSequence = new StringBuffer(); + for(NicTO nicTo : sortNicsByDeviceId(to.getNics())) { + sbMacSequence.append(nicTo.getMac()).append("|"); + } + sbMacSequence.deleteCharAt(sbMacSequence.length() - 1); + String bootArgs = to.getBootArgs(); + to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString()); + + } // Determine the VM's OS description GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId()); @@ -59,6 +149,29 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru { return to; } + private NicTO[] sortNicsByDeviceId(NicTO[] nics) { + + List listForSort = new ArrayList(); + for (NicTO nic : nics) { + listForSort.add(nic); + } + Collections.sort(listForSort, new Comparator() { + + @Override + public int compare(NicTO arg0, NicTO arg1) { + if (arg0.getDeviceId() < arg1.getDeviceId()) { + return -1; + } else if (arg0.getDeviceId() == arg1.getDeviceId()) { + return 0; + } + + return 1; + } + }); + + return listForSort.toArray(new NicTO[0]); + } + @Override public final boolean trackVmHostChange() { return false; diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java index 9030e29e7a4..5821fe4dcae 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java @@ -21,4 +21,5 @@ import com.cloud.utils.component.Manager; public interface HypervManager extends Manager { public String prepareSecondaryStorageStore(long zoneId); + int getRouterExtraPublicNics(); } diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java index a30eb7df005..71a619a0ad5 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java @@ -45,6 +45,8 @@ import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; +import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.VMInstanceDao; @Local(value = {HypervManager.class}) public class HypervManagerImpl implements HypervManager { @@ -60,10 +62,11 @@ public class HypervManagerImpl implements HypervManager { Map _storageMounts = new HashMap(); StorageLayer _storage; - @Inject - ConfigurationDao _configDao; - @Inject - DataStoreManager _dataStoreMgr; + @Inject ConfigurationDao _configDao; + @Inject DataStoreManager _dataStoreMgr; + @Inject VMInstanceDao _vminstanceDao; + @Inject NicDao _nicDao; + int _routerExtraPublicNics = 2; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -77,7 +80,7 @@ public class HypervManagerImpl implements HypervManager { _storage = new JavaStorageLayer(); _storage.configure("StorageLayer", params); } - + _routerExtraPublicNics = NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2); return true; } @@ -373,4 +376,9 @@ public class HypervManagerImpl implements HypervManager { } } } -} + + @Override + public int getRouterExtraPublicNics() { + return _routerExtraPublicNics; + } +} \ No newline at end of file diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java index d6ffa1db5c2..2f645906317 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java @@ -36,13 +36,13 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; import javax.annotation.PostConstruct; import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringEscapeUtils; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; @@ -71,7 +71,12 @@ import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.GetDomRVersionAnswer; import com.cloud.agent.api.GetDomRVersionCmd; +import com.cloud.agent.api.GetVmConfigAnswer; +import com.cloud.agent.api.GetVmConfigAnswer.NicDetails; +import com.cloud.agent.api.GetVmConfigCommand; import com.cloud.agent.api.HostVmStateReportEntry; +import com.cloud.agent.api.ModifyVmNicConfigAnswer; +import com.cloud.agent.api.ModifyVmNicConfigCommand; import com.cloud.agent.api.NetworkUsageAnswer; import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.PingCommand; @@ -117,11 +122,13 @@ import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.exception.InternalErrorException; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.hyperv.manager.HypervManager; import com.cloud.network.HAProxyConfigurator; import com.cloud.network.LoadBalancerConfigurator; +import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.RouterPrivateIpStrategy; import com.cloud.network.rules.FirewallRule; import com.cloud.resource.ServerResource; @@ -133,6 +140,8 @@ import com.cloud.utils.net.NetUtils; import com.cloud.utils.ssh.SshHelper; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineName; + + /** * Implementation of dummy resource to be returned from discoverer. **/ @@ -706,65 +715,6 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S } } - // - // find mac address of a specified ethx device - // ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2 - // returns - // eth0:xx.xx.xx.xx - - // - // list IP with eth devices - // ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' - // | awk -F: '{ print $1 ": " $3 }' - // - // returns - // eth0:xx.xx.xx.xx - // - // - - private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception { - - s_logger.info("findRouterEthDeviceIndex. mac: " + mac); - - // TODO : this is a temporary very inefficient solution, will refactor it later - Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "ls /proc/sys/net/ipv4/conf"); - - // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS - // we use a waiting loop here as a workaround to synchronize activities in systems - long startTick = System.currentTimeMillis(); - while (System.currentTimeMillis() - startTick < 15000) { - if (result.first()) { - String[] tokens = result.second().split("\\s+"); - for (String token : tokens) { - if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) { - String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); - - if (s_logger.isDebugEnabled()) - s_logger.debug("Run domr script " + cmd); - Pair result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, - // TODO need to find the dev index inside router based on IP address - cmd); - if (s_logger.isDebugEnabled()) - s_logger.debug("result: " + result2.first() + ", output: " + result2.second()); - - if (result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim())) - return Integer.parseInt(token.substring(3)); - } - } - } - - s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry..."); - - try { - Thread.currentThread(); - Thread.sleep(1000); - } catch (InterruptedException e) { - } - } - - return -1; - } - protected Answer execute(SetPortForwardingRulesCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource SetPortForwardingRulesCommand: " + s_gson.toJson(cmd)); @@ -1170,74 +1120,35 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource VmDataCommand: " + s_gson.toJson(cmd)); } - - String routerPrivateIpAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String controlIp = getRouterSshControlIp(cmd); + Map> data = new HashMap>(); + data.put(cmd.getVmIpAddress(), cmd.getVmData()); - String vmIpAddress = cmd.getVmIpAddress(); - List vmData = cmd.getVmData(); - String[] vmDataArgs = new String[vmData.size() * 2 + 4]; - vmDataArgs[0] = "routerIP"; - vmDataArgs[1] = routerPrivateIpAddress; - vmDataArgs[2] = "vmIP"; - vmDataArgs[3] = vmIpAddress; - int i = 4; - for (String[] vmDataEntry : vmData) { - String folder = vmDataEntry[0]; - String file = vmDataEntry[1]; - String contents = (vmDataEntry[2] != null) ? vmDataEntry[2] : "none"; + String json = new Gson().toJson(data); + s_logger.debug("VM data JSON IS:" + json); - vmDataArgs[i] = folder + "," + file; - vmDataArgs[i + 1] = contents; - i += 2; - } + json = Base64.encodeBase64String(json.getBytes()); - String content = encodeDataArgs(vmDataArgs); - String tmpFileName = UUID.randomUUID().toString(); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run vm_data command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", data: " + content); - } + String args = "-d " + json; try { - SshHelper.scpTo(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/tmp", content.getBytes(), tmpFileName, null); - - try { - Pair result = - SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/userdata.py " + tmpFileName); - - if (!result.first()) { - s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second()); - return new Answer(cmd, false, "VmDataCommand failed due to " + result.second()); - } - } finally { - - SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "rm /tmp/" + tmpFileName); + Pair result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/vmdata.py " + args); + if (!result.first()) { + s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second()); + return new Answer(cmd, false, "VmDataCommand failed due to " + result.second()); } if (s_logger.isInfoEnabled()) { s_logger.info("vm_data command on domain router " + controlIp + " completed"); } - } catch (Throwable e) { - String msg = "VmDataCommand failed due to " + e; + String msg = "VmDataCommand failed due to " + e.getMessage(); s_logger.error(msg, e); return new Answer(cmd, false, msg); } return new Answer(cmd); } - private String encodeDataArgs(String[] dataArgs) { - StringBuilder sb = new StringBuilder(); - - for (String arg : dataArgs) { - sb.append(arg); - sb.append("\n"); - } - - return sb.toString(); - } - protected Answer execute(DhcpEntryCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource DhcpEntryCommand: " + s_gson.toJson(cmd)); @@ -1386,6 +1297,102 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S return new Answer(cmd); } + // + // find mac address of a specified ethx device + // ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2 + // returns + // eth0:xx.xx.xx.xx + + // + // list IP with eth devices + // ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' + // | awk -F: '{ print $1 ": " $3 }' + // + // returns + // eth0:xx.xx.xx.xx + // + // + + private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception { + + s_logger.info("findRouterEthDeviceIndex. mac: " + mac); + + // TODO : this is a temporary very inefficient solution, will refactor it later + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, + "ls /proc/sys/net/ipv4/conf"); + + // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS + // we use a waiting loop here as a workaround to synchronize activities in systems + long startTick = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTick < 15000) { + if (result.first()) { + String[] tokens = result.second().split("\\s+"); + for (String token : tokens) { + if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) { + String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); + + if (s_logger.isDebugEnabled()) + s_logger.debug("Run domr script " + cmd); + Pair result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, + // TODO need to find the dev index inside router based on IP address + cmd); + if (s_logger.isDebugEnabled()) + s_logger.debug("result: " + result2.first() + ", output: " + result2.second()); + + if (result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim())) + return Integer.parseInt(token.substring(3)); + } + } + } + + s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry..."); + + } + + return -1; + } + + private Pair findRouterFreeEthDeviceIndex(String routerIp) throws Exception { + + s_logger.info("findRouterFreeEthDeviceIndex. mac: "); + + // TODO : this is a temporary very inefficient solution, will refactor it later + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, + "ip address | grep DOWN| cut -f2 -d :"); + + // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS + // we use a waiting loop here as a workaround to synchronize activities in systems + long startTick = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTick < 15000) { + if (result.first() && !result.second().isEmpty()) { + String[] tokens = result.second().split("\\n"); + for (String token : tokens) { + if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) { + //String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); + //TODO: don't check for eth0,1,2, as they will be empty by default. + //String cmd = String.format("ip address show %s ", token); + String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); + if (s_logger.isDebugEnabled()) + s_logger.debug("Run domr script " + cmd); + Pair result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, + // TODO need to find the dev index inside router based on IP address + cmd); + if (s_logger.isDebugEnabled()) + s_logger.debug("result: " + result2.first() + ", output: " + result2.second()); + + if (result2.first() && result2.second().trim().length() > 0) + return new Pair(Integer.parseInt(token.trim().substring(3)), result2.second().trim()) ; + } + } + } + + //s_logger.warn("can not find intereface associated with mac: , guest OS may still at loading state, retry..."); + + } + + return new Pair(-1, ""); + } + protected Answer execute(IpAssocCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource IPAssocCommand: " + s_gson.toJson(cmd)); @@ -1401,7 +1408,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S String controlIp = getRouterSshControlIp(cmd); for (IpAddressTO ip : ips) { assignPublicIpAddress(routerName, controlIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), ip.getVlanGateway(), - ip.getVlanNetmask(), ip.getVifMacAddress()); + ip.getVlanNetmask(), ip.getVifMacAddress()); results[i++] = ip.getPublicIp() + " - success"; } @@ -1419,16 +1426,97 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S return new IpAssocAnswer(cmd, results); } + protected int getVmNics(String vmName, int vlanid) { + GetVmConfigCommand vmConfig = new GetVmConfigCommand(vmName); + URI agentUri = null; + int nicposition = -1; + try { + String cmdName = GetVmConfigCommand.class.getName(); + agentUri = + new URI("https", null, _agentIp, _port, + "/api/HypervResource/" + cmdName, null, null); + } catch (URISyntaxException e) { + String errMsg = "Could not generate URI for Hyper-V agent"; + s_logger.error(errMsg, e); + } + String ansStr = postHttpRequest(s_gson.toJson(vmConfig), agentUri); + Answer[] result = s_gson.fromJson(ansStr, Answer[].class); + s_logger.debug("executeRequest received response " + + s_gson.toJson(result)); + if (result.length > 0) { + GetVmConfigAnswer ans = ((GetVmConfigAnswer)result[0]); + List nics = ans.getNics(); + for (NicDetails nic : nics) { + if (nic.getVlanid() == vlanid) { + nicposition = nics.indexOf(nic); + break; + } + } + } + return nicposition; + } + + protected void modifyNicVlan(String vmName, int vlanId, String macAddress) { + ModifyVmNicConfigCommand modifynic = new ModifyVmNicConfigCommand(vmName, vlanId, macAddress); + URI agentUri = null; + try { + String cmdName = ModifyVmNicConfigCommand.class.getName(); + agentUri = + new URI("https", null, _agentIp, _port, + "/api/HypervResource/" + cmdName, null, null); + } catch (URISyntaxException e) { + String errMsg = "Could not generate URI for Hyper-V agent"; + s_logger.error(errMsg, e); + } + String ansStr = postHttpRequest(s_gson.toJson(modifynic), agentUri); + Answer[] result = s_gson.fromJson(ansStr, Answer[].class); + s_logger.debug("executeRequest received response " + + s_gson.toJson(result)); + if (result.length > 0) { + ModifyVmNicConfigAnswer ans = ((ModifyVmNicConfigAnswer)result[0]); + } + } + protected void assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP, - final boolean sourceNat, final String vlanId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws Exception { + final boolean sourceNat, final String broadcastId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws Exception { + + URI broadcastUri = BroadcastDomainType.fromString(broadcastId); + if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { + throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + broadcastId); + } + int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri)); + + int publicNicInfo = -1; + publicNicInfo = getVmNics(vmName, vlanId); boolean addVif = false; - if (add) { + if (add && publicNicInfo == -1) { if (s_logger.isDebugEnabled()) { s_logger.debug("Plug new NIC to associate" + privateIpAddress + " to " + publicIpAddress); } addVif = true; } else if (!add && firstIP) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unplug NIC " + publicNicInfo); + } + } + + if (addVif) { + Pair nicdevice = findRouterFreeEthDeviceIndex(privateIpAddress); + publicNicInfo = nicdevice.first(); + if (publicNicInfo > 0) { + modifyNicVlan(vmName, vlanId, nicdevice.second()); + // After modifying the vnic on VR, check the VR VNics config in the host and get the device position + publicNicInfo = getVmNics(vmName, vlanId); + // As a new nic got activated in the VR. add the entry in the NIC's table. + networkUsage(privateIpAddress, "addVif", "eth" + publicNicInfo); + } + else { + // we didn't find any eth device available in VR to configure the ip range with new VLAN + String msg = "No Nic is available on DomR VIF to associate/disassociate IP with."; + s_logger.error(msg); + throw new InternalErrorException(msg); + } } String args = null; @@ -1450,8 +1538,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S args += publicIpAddress + "/" + cidrSize; args += " -c "; - args += "eth" + "2"; // currently hardcoding to eth 2 (which is default public ipd)//publicNicInfo.first(); + args += "eth" + publicNicInfo; args += " -g "; args += vlanGateway; @@ -1464,7 +1552,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S } Pair result = - SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/ipassoc.sh " + args); + SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/ipassoc.sh " + args); if (!result.first()) { s_logger.error("ipassoc command on domain router " + privateIpAddress + " failed. message: " + result.second()); @@ -1840,7 +1928,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S sch.connect(addr); return null; } catch (IOException e) { - s_logger.info("Could not connect to " + ipAddress + " due to " + e.toString()); + s_logger.info("Could] not connect to " + ipAddress + " due to " + e.toString()); if (e instanceof ConnectException) { // if connection is refused because of VM is being started, // we give it more sleep time diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index c40cd75c831..fd0078c6970 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -16,73 +16,12 @@ // under the License. package com.cloud.hypervisor.kvm.resource; -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.text.DateFormat; -import java.text.MessageFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.commons.io.FileUtils; -import org.apache.log4j.Logger; -import org.libvirt.Connect; -import org.libvirt.Domain; -import org.libvirt.DomainBlockStats; -import org.libvirt.DomainInfo; -import org.libvirt.DomainInterfaceStats; -import org.libvirt.DomainSnapshot; -import org.libvirt.LibvirtException; -import org.libvirt.NodeInfo; - import com.ceph.rados.IoCTX; import com.ceph.rados.Rados; import com.ceph.rados.RadosException; import com.ceph.rbd.Rbd; import com.ceph.rbd.RbdException; import com.ceph.rbd.RbdImage; - -import org.apache.cloudstack.storage.command.StorageSubSystemCommand; -import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; -import org.apache.cloudstack.storage.to.VolumeObjectTO; -import org.apache.cloudstack.utils.qemu.QemuImg; -import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; -import org.apache.cloudstack.utils.qemu.QemuImgException; -import org.apache.cloudstack.utils.qemu.QemuImgFile; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeAnswer; @@ -155,7 +94,6 @@ import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.SecurityGroupRulesCmd; -import com.cloud.agent.api.SetupGuestNetworkAnswer; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; @@ -174,13 +112,9 @@ import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; -import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.NetworkElementCommand; -import com.cloud.agent.api.routing.SetNetworkACLAnswer; -import com.cloud.agent.api.routing.SetNetworkACLCommand; -import com.cloud.agent.api.routing.SetSourceNatAnswer; import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CopyVolumeCommand; @@ -201,6 +135,7 @@ import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; +import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.dc.Vlan; import com.cloud.exception.InternalErrorException; @@ -250,17 +185,77 @@ import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.QCOW2Processor; import com.cloud.storage.template.TemplateLocation; import com.cloud.storage.template.TemplateProp; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.PropertiesUtil; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.utils.script.OutputInterpreter; +import com.cloud.utils.script.OutputInterpreter.AllLinesParser; import com.cloud.utils.script.Script; +import com.cloud.utils.ssh.SshHelper; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachine.State; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.cloudstack.utils.qemu.QemuImg; +import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; +import org.apache.cloudstack.utils.qemu.QemuImgException; +import org.apache.cloudstack.utils.qemu.QemuImgFile; +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.Domain; +import org.libvirt.DomainBlockStats; +import org.libvirt.DomainInfo; +import org.libvirt.DomainInterfaceStats; +import org.libvirt.DomainSnapshot; +import org.libvirt.LibvirtException; +import org.libvirt.NodeInfo; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.InetAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.text.DateFormat; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * LibvirtComputingResource execute requests on the computing/routing host using @@ -285,7 +280,7 @@ import com.cloud.vm.VirtualMachine.State; * pool | the parent of the storage pool hierarchy * } **/ @Local(value = {ServerResource.class}) -public class LibvirtComputingResource extends ServerResourceBase implements ServerResource { +public class LibvirtComputingResource extends ServerResourceBase implements ServerResource, VirtualRouterDeployer { private static final Logger s_logger = Logger.getLogger(LibvirtComputingResource.class); private String _modifyVlanPath; @@ -322,6 +317,59 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected static final String DEFAULT_OVS_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.OvsVifDriver"; protected static final String DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.BridgeVifDriver"; + @Override + public ExecutionResult executeInVR(String routerIp, String script, String args) { + final Script command = new Script(_routerProxyPath, _timeout, s_logger); + final AllLinesParser parser = new AllLinesParser(); + command.add(script); + command.add(routerIp); + if (args != null) { + command.add(args); + } + String details = command.execute(parser); + if (details == null) { + details = parser.getLines(); + } + return new ExecutionResult(command.getExitValue() == 0, details); + } + + @Override + public ExecutionResult createFileInVR(String routerIp, String path, String filename, String content) { + File permKey = new File("/root/.ssh/id_rsa.cloud"); + String error = null; + + try { + SshHelper.scpTo(routerIp, 3922, "root", permKey, null, path, content.getBytes(), filename, null); + } catch (Exception e) { + s_logger.warn("Fail to create file " + path + filename + " in VR " + routerIp, e); + error = e.getMessage(); + } + return new ExecutionResult(error == null, error); + } + + @Override + public ExecutionResult prepareCommand(NetworkElementCommand cmd) { + //Update IP used to access router + cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + assert cmd.getRouterAccessIp() != null; + + if (cmd instanceof IpAssocVpcCommand) { + return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return prepareNetworkElementCommand((IpAssocCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return prepareNetworkElementCommand((SetSourceNatCommand)cmd); + } + return new ExecutionResult(true, null); + } + + @Override + public ExecutionResult cleanupCommand(NetworkElementCommand cmd) { + return new ExecutionResult(true, null); + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -376,6 +424,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private boolean _canBridgeFirewall; protected String _localStoragePath; protected String _localStorageUUID; + protected boolean _noMemBalloon = false; protected String _guestCpuMode; protected String _guestCpuModel; private final Map _pifs = new HashMap(); @@ -537,7 +586,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv params.put("domr.scripts.dir", domrScriptsDir); - _virtRouterResource = new VirtualRoutingResource(); + _virtRouterResource = new VirtualRoutingResource(this); success = _virtRouterResource.configure(name, params); if (!success) { @@ -723,6 +772,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv value = (String)params.get("cmds.timeout"); _cmdsTimeout = NumbersUtil.parseInt(value, 7200) * 1000; + value = (String) params.get("vm.memballoon.disable"); + if (Boolean.parseBoolean(value)) { + _noMemBalloon = true; + } + value = (String)params.get("host.reserved.mem.mb"); _dom0MinMem = NumbersUtil.parseInt(value, 0) * 1024 * 1024; @@ -1258,16 +1312,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((PlugNicCommand)cmd); } else if (cmd instanceof UnPlugNicCommand) { return execute((UnPlugNicCommand)cmd); - } else if (cmd instanceof SetupGuestNetworkCommand) { - return execute((SetupGuestNetworkCommand)cmd); - } else if (cmd instanceof SetNetworkACLCommand) { - return execute((SetNetworkACLCommand)cmd); - } else if (cmd instanceof SetSourceNatCommand) { - return execute((SetSourceNatCommand)cmd); - } else if (cmd instanceof IpAssocVpcCommand) { - return execute((IpAssocVpcCommand)cmd); - } else if (cmd instanceof IpAssocCommand) { - return execute((IpAssocCommand)cmd); } else if (cmd instanceof NetworkElementCommand) { return _virtRouterResource.executeRequest(cmd); } else if (cmd instanceof CheckSshCommand) { @@ -1977,25 +2021,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + private ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) { Connect conn; NicTO nic = cmd.getNic(); - String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String routerGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String gateway = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); - String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - String domainName = cmd.getNetworkDomain(); - String dns = cmd.getDefaultDns1(); - - if (dns == null || dns.isEmpty()) { - dns = cmd.getDefaultDns2(); - } else { - String dns2 = cmd.getDefaultDns2(); - if (dns2 != null && !dns2.isEmpty()) { - dns += "," + dns2; - } - } try { conn = LibvirtConnection.getConnectionByVmName(routerName); @@ -2010,62 +2039,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } if (routerNic == null) { - return new SetupGuestNetworkAnswer(cmd, false, "Can not find nic with mac " + nic.getMac() + " for VM " + routerName); + return new ExecutionResult(false, "Can not find nic with mac " + nic.getMac() + " for VM " + routerName); } - String dev = "eth" + nic.getDeviceId(); - String netmask = NetUtils.getSubNet(routerGIP, nic.getNetmask()); - String result = _virtRouterResource.assignGuestNetwork(dev, routerIP, routerGIP, gateway, cidr, netmask, dns, domainName); - - if (result != null) { - return new SetupGuestNetworkAnswer(cmd, false, "Creating guest network failed due to " + result); - } - return new SetupGuestNetworkAnswer(cmd, true, "success"); + return new ExecutionResult(true, null); } catch (LibvirtException e) { String msg = "Creating guest network failed due to " + e.toString(); s_logger.warn(msg, e); - return new SetupGuestNetworkAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } } - - private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { - String[] results = new String[cmd.getRules().length]; - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); - - try { - String[][] rules = cmd.generateFwRules(); - String[] aclRules = rules[0]; - NicTO nic = cmd.getNic(); - String dev = "eth" + nic.getDeviceId(); - String netmask = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < aclRules.length; i++) { - sb.append(aclRules[i]).append(','); - } - - String rule = sb.toString(); - String result = _virtRouterResource.assignNetworkACL(routerIp, dev, nic.getIp(), netmask, rule, privateGw); - - if (result != null) { - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetNetworkACLAnswer(cmd, false, results); - } - - return new SetNetworkACLAnswer(cmd, true, results); - } catch (Exception e) { - String msg = "SetNetworkACL failed due to " + e.toString(); - s_logger.error(msg, e); - return new SetNetworkACLAnswer(cmd, false, results); - } - } - - protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) { Connect conn; String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); @@ -2086,7 +2071,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv /*skip over, no physical bridge device exists*/ } else if (pluggedVlanId == null) { /*this should only be true in the case of link local bridge*/ - return new SetSourceNatAnswer(cmd, false, "unable to find the vlan id for bridge " + pluggedVlanBr + " when attempting to set up" + pubVlan + + return new ExecutionResult(false, "unable to find the vlan id for bridge " + pluggedVlanBr + " when attempting to set up" + pubVlan + " on router " + routerName); } else if (pluggedVlanId.equals(pubVlan)) { break; @@ -2094,26 +2079,20 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv devNum++; } - String dev = "eth" + devNum; - String result = _virtRouterResource.assignSourceNat(routerIP, pubIP.getPublicIp(), dev); + pubIP.setNicDevId(devNum); - if (result != null) { - return new SetSourceNatAnswer(cmd, false, "KVM plugin \"vpc_snat\" failed:" + result); - } - return new SetSourceNatAnswer(cmd, true, "success"); + return new ExecutionResult(true, "success"); } catch (LibvirtException e) { String msg = "Ip SNAT failure due to " + e.toString(); s_logger.error(msg, e); - return new SetSourceNatAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } } - protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) { Connect conn; - String[] results = new String[cmd.getIpAddresses().length]; int i = 0; String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); try { conn = LibvirtConnection.getConnectionByVmName(routerName); @@ -2136,31 +2115,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } for (IpAddressTO ip : ips) { - String nicName = "eth" + broadcastUriToNicNum.get(ip.getBroadcastUri()); - String netmask = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); - String subnet = NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); - _virtRouterResource.assignVpcIpToRouter(routerIP, ip.isAdd(), ip.getPublicIp(), nicName, ip.getVlanGateway(), netmask, subnet, ip.isSourceNat()); - results[i++] = ip.getPublicIp() + " - success"; + ip.setNicDevId(broadcastUriToNicNum.get(ip.getBroadcastUri())); } + return new ExecutionResult(true, null); } catch (LibvirtException e) { s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; - } catch (InternalErrorException e) { - s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; + return new ExecutionResult(false, e.getMessage()); } - - return new IpAssocAnswer(cmd, results); } - public Answer execute(IpAssocCommand cmd) { + public ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) { String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String[] results = new String[cmd.getIpAddresses().length]; - for (int i = 0; i < results.length; i++) { - results[i] = IpAssocAnswer.errorResult; - } Connect conn; try { conn = LibvirtConnection.getConnectionByVmName(routerName); @@ -2182,11 +2149,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv nicPos++; } IpAddressTO[] ips = cmd.getIpAddresses(); - int i = 0; - String result = null; int nicNum = 0; - boolean newNic = false; for (IpAddressTO ip : ips) { + boolean newNic = false; if (!broadcastUriAllocatedToVM.containsKey(ip.getBroadcastUri())) { /* plug a vif into router */ VifHotPlug(conn, routerName, ip.getBroadcastUri(), ip.getVifMacAddress()); @@ -2195,21 +2160,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } nicNum = broadcastUriAllocatedToVM.get(ip.getBroadcastUri()); networkUsage(routerIp, "addVif", "eth" + nicNum); - result = - _virtRouterResource.assignPublicIpAddress(routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), - ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress(), nicNum, newNic); - if (result == null) { - results[i++] = ip.getPublicIp() + " - success"; - } + ip.setNicDevId(nicNum); + ip.setNewNic(newNic); } - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } catch (LibvirtException e) { s_logger.error("ipassoccmd failed", e); - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(false, e.getMessage()); } catch (InternalErrorException e) { s_logger.error("ipassoccmd failed", e); - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(false, e.getMessage()); } } @@ -2972,10 +2933,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv dconn = new Connect("qemu+tcp://" + cmd.getDestinationIp() + "/system"); /* - * Hard code lm flags: VIR_MIGRATE_LIVE(1<<0) and - * VIR_MIGRATE_PERSIST_DEST(1<<3) + * Hard code lm flag: VIR_MIGRATE_LIVE(1<<0) */ - destDomain = dm.migrate(dconn, (1 << 0) | (1 << 3), xmlDesc, vmName, "tcp:" + cmd.getDestinationIp(), _migrateSpeed); + destDomain = dm.migrate(dconn, (1 << 0), xmlDesc, vmName, "tcp:" + cmd.getDestinationIp(), _migrateSpeed); _storagePoolMgr.disconnectPhysicalDisksViaVmSpec(cmd.getVirtualMachine()); } catch (LibvirtException e) { @@ -3143,8 +3103,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv String[] splitResult = result.split(":"); int i = 0; while (i < splitResult.length - 1) { - stats[0] += (new Long(splitResult[i++])).longValue(); - stats[1] += (new Long(splitResult[i++])).longValue(); + stats[0] += Long.parseLong(splitResult[i++]); + stats[1] += Long.parseLong(splitResult[i++]); } } return stats; @@ -3185,8 +3145,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv String[] splitResult = result.split(":"); int i = 0; while (i < splitResult.length - 1) { - stats[0] += (new Long(splitResult[i++])).longValue(); - stats[1] += (new Long(splitResult[i++])).longValue(); + stats[0] += Long.parseLong(splitResult[i++]); + stats[1] += Long.parseLong(splitResult[i++]); } } return stats; @@ -3472,7 +3432,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv GuestResourceDef grd = new GuestResourceDef(); - if (vmTO.getMinRam() != vmTO.getMaxRam()) { + if (vmTO.getMinRam() != vmTO.getMaxRam() && !_noMemBalloon) { grd.setMemBalloning(true); grd.setCurrentMem(vmTO.getMinRam() / 1024); grd.setMemorySize(vmTO.getMaxRam() / 1024); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index 9fd058fa3eb..5aeacdafae0 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -162,6 +162,8 @@ public class LibvirtVMDef { } if (_memBalloning) { resBuidler.append("\n" + "\n" + "\n"); + } else { + resBuidler.append("\n" + "\n" + "\n"); } if (_vcpu != -1) { resBuidler.append("" + _vcpu + "\n"); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java index fafbee08e36..bbd1c24ac99 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java @@ -386,7 +386,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool; try { - StorageVol vol = this.getVolume(libvirtPool.getPool(), volumeUuid); + StorageVol vol = getVolume(libvirtPool.getPool(), volumeUuid); KVMPhysicalDisk disk; LibvirtStorageVolumeDef voldef = getStorageVolumeDef(libvirtPool.getPool().getConnect(), vol); disk = new KVMPhysicalDisk(vol.getPath(), vol.getName(), pool); @@ -471,7 +471,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { String targetPath = pdef.getTargetPath(); if (targetPath != null && targetPath.equals(path)) { s_logger.debug("Storage pool utilizing path '" + path + "' already exists as pool " + poolname + - ", undefining so we can re-define with correct name " + name); + ", undefining so we can re-define with correct name " + name); if (p.isPersistent() == 1) { p.destroy(); p.undefine(); @@ -527,8 +527,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { String error = e.toString(); if (error.contains("Storage source conflict")) { throw new CloudRuntimeException("A pool matching this location already exists in libvirt, " + - " but has a different UUID/Name. Cannot create new pool without first " + " removing it. Check for inactive pools via 'virsh pool-list --all'. " + - error); + " but has a different UUID/Name. Cannot create new pool without first " + " removing it. Check for inactive pools via 'virsh pool-list --all'. " + + error); } else { throw new CloudRuntimeException(error); } @@ -556,7 +556,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { /* * Some storage pools, like RBD also have 'secret' information stored in libvirt * Destroy them if they exist - */ + */ try { s = conn.secretLookupByUUIDString(uuid); } catch (LibvirtException e) { @@ -580,7 +580,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { if (e.toString().contains("exit status 16")) { String targetPath = _mountPoint + File.separator + uuid; s_logger.error("deleteStoragePool removed pool from libvirt, but libvirt had trouble" + "unmounting the pool. Trying umount location " + targetPath + - "again in a few seconds"); + "again in a few seconds"); String result = Script.runSimpleBashScript("sleep 5 && umount " + targetPath); if (result == null) { s_logger.error("Succeeded in unmounting " + targetPath); @@ -624,7 +624,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { IoCTX io = r.ioCtxCreate(pool.getSourceDir()); Rbd rbd = new Rbd(io); - rbd.create(name, size, this.rbdFeatures, this.rbdOrder); + rbd.create(name, size, rbdFeatures, rbdOrder); r.ioCtxDestroy(io); } catch (RadosException e) { @@ -702,7 +702,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { try { Connect conn = LibvirtConnection.getConnection(); - StoragePool pool = conn.storagePoolLookupByUUIDString(poolUuid); + conn.storagePoolLookupByUUIDString(poolUuid); deleteStoragePool(poolUuid); @@ -753,7 +753,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool; try { - StorageVol vol = this.getVolume(libvirtPool.getPool(), uuid); + StorageVol vol = getVolume(libvirtPool.getPool(), uuid); deleteVol(libvirtPool, vol); vol.free(); return true; @@ -784,7 +784,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { So for RBD we don't create the image, but let qemu-img do that for us. We then create a KVMPhysicalDisk object that we can return - */ + */ try { if (destPool.getType() != StoragePoolType.RBD) { disk = destPool.createPhysicalDisk(newUuid, format, template.getVirtualSize()); @@ -815,8 +815,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { QemuImg qemu = new QemuImg(timeout); QemuImgFile srcFile; QemuImgFile destFile = - new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(), destPool.getSourcePort(), destPool.getAuthUserName(), - destPool.getAuthSecret(), disk.getPath())); + new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(), destPool.getSourcePort(), destPool.getAuthUserName(), + destPool.getAuthSecret(), disk.getPath())); destFile.setFormat(format); if (srcPool.getType() != StoragePoolType.RBD) { @@ -850,9 +850,9 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { if (srcImage.isOldFormat()) { /* The source image is RBD format 1, we have to do a regular copy */ s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName() + - " is RBD format 1. We have to perform a regular copy (" + template.getVirtualSize() + " bytes)"); + " is RBD format 1. We have to perform a regular copy (" + template.getVirtualSize() + " bytes)"); - rbd.create(disk.getName(), template.getVirtualSize(), this.rbdFeatures, this.rbdOrder); + rbd.create(disk.getName(), template.getVirtualSize(), rbdFeatures, rbdOrder); RbdImage destImage = rbd.open(disk.getName()); s_logger.debug("Starting to copy " + srcImage.getName() + " to " + destImage.getName() + " in Ceph pool " + srcPool.getSourceDir()); @@ -862,10 +862,10 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { rbd.close(destImage); } else { s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName() + - " is RBD format 2. We will perform a RBD clone using snapshot " + this.rbdTemplateSnapName); + " is RBD format 2. We will perform a RBD clone using snapshot " + rbdTemplateSnapName); /* The source image is format 2, we can do a RBD snapshot+clone (layering) */ - rbd.clone(template.getName(), this.rbdTemplateSnapName, io, disk.getName(), this.rbdFeatures, this.rbdOrder); - s_logger.debug("Succesfully cloned " + template.getName() + "@" + this.rbdTemplateSnapName + " to " + disk.getName()); + rbd.clone(template.getName(), rbdTemplateSnapName, io, disk.getName(), rbdFeatures, rbdOrder); + s_logger.debug("Succesfully cloned " + template.getName() + "@" + rbdTemplateSnapName + " to " + disk.getName()); } rbd.close(srcImage); @@ -893,14 +893,14 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { Rbd dRbd = new Rbd(dIO); s_logger.debug("Creating " + disk.getName() + " on the destination cluster " + rDest.confGet("mon_host") + " in pool " + - destPool.getSourceDir()); - dRbd.create(disk.getName(), template.getVirtualSize(), this.rbdFeatures, this.rbdOrder); + destPool.getSourceDir()); + dRbd.create(disk.getName(), template.getVirtualSize(), rbdFeatures, rbdOrder); RbdImage srcImage = sRbd.open(template.getName()); RbdImage destImage = dRbd.open(disk.getName()); s_logger.debug("Copying " + template.getName() + " from Ceph cluster " + rSrc.confGet("mon_host") + " to " + disk.getName() + " on cluster " + - rDest.confGet("mon_host")); + rDest.confGet("mon_host")); sRbd.copy(srcImage, destImage); sRbd.close(srcImage); @@ -923,7 +923,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } if (disk == null) { - throw new CloudRuntimeException("Failed to create " + disk.getPath() + " from template " + template.getName()); + throw new CloudRuntimeException("Failed to create disk from template " + template.getName()); } return disk; @@ -942,7 +942,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { try { String[] vols = virtPool.listVolumes(); for (String volName : vols) { - KVMPhysicalDisk disk = this.getPhysicalDisk(volName, pool); + KVMPhysicalDisk disk = getPhysicalDisk(volName, pool); disks.add(disk); } return disks; @@ -1036,11 +1036,11 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } } else if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() == StoragePoolType.RBD)) { /** - * Qemu doesn't support writing to RBD format 2 directly, so we have to write to a temporary RAW file first - * which we then convert to RBD format 2. - * - * A HUGE performance gain can be achieved here if QCOW2 -> RBD format 2 can be done in one step - */ + * Qemu doesn't support writing to RBD format 2 directly, so we have to write to a temporary RAW file first + * which we then convert to RBD format 2. + * + * A HUGE performance gain can be achieved here if QCOW2 -> RBD format 2 can be done in one step + */ s_logger.debug("The source image is not RBD, but the destination is. We will convert into RBD format 2"); String sourceFile; boolean useTmpFile = false; @@ -1069,7 +1069,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { Rbd rbd = new Rbd(io); s_logger.debug("Creating RBD image " + name + " in Ceph pool " + destPool.getSourceDir() + " with RBD format 2"); - rbd.create(name, disk.getVirtualSize(), this.rbdFeatures, this.rbdOrder); + rbd.create(name, disk.getVirtualSize(), rbdFeatures, rbdOrder); RbdImage image = rbd.open(name); @@ -1098,10 +1098,10 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } /* Snapshot the image and protect that snapshot so we can clone (layer) from it */ - s_logger.debug("Creating RBD snapshot " + this.rbdTemplateSnapName + " on image " + name); - image.snapCreate(this.rbdTemplateSnapName); - s_logger.debug("Protecting RBD snapshot " + this.rbdTemplateSnapName + " on image " + name); - image.snapProtect(this.rbdTemplateSnapName); + s_logger.debug("Creating RBD snapshot " + rbdTemplateSnapName + " on image " + name); + image.snapCreate(rbdTemplateSnapName); + s_logger.debug("Protecting RBD snapshot " + rbdTemplateSnapName + " on image " + name); + image.snapProtect(rbdTemplateSnapName); rbd.close(image); r.ioCtxDestroy(io); @@ -1125,8 +1125,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { it doesn't benefit us. It's better to keep the current code in place which works */ srcFile = - new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), srcPool.getSourcePort(), srcPool.getAuthUserName(), srcPool.getAuthSecret(), - sourcePath)); + new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), srcPool.getSourcePort(), srcPool.getAuthUserName(), srcPool.getAuthSecret(), + sourcePath)); srcFile.setFormat(sourceFormat); destFile = new QemuImgFile(destPath); destFile.setFormat(destFormat); diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java new file mode 100644 index 00000000000..54036b3c848 --- /dev/null +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package com.cloud.hypervisor.kvm.resource; + +import junit.framework.TestCase; +import com.cloud.hypervisor.kvm.resource.LibvirtSecretDef.usage; + +public class LibvirtSecretDefTest extends TestCase { + + public void testVolumeSecretDef() { + String uuid = "db66f42b-a79e-4666-9910-9dfc8a024427"; + String name = "myEncryptedQCOW2"; + usage use = usage.VOLUME; + + LibvirtSecretDef def = new LibvirtSecretDef(use, uuid); + def.setVolumeVolume(name); + + String expectedXml = "\n" + uuid + "\n" + + "\n" + name + "\n\n\n"; + + assertEquals(expectedXml, def.toString()); + } + + public void testCephSecretDef() { + String uuid = "a9febe83-ac5c-467a-bf19-eb75325ec23c"; + String name = "admin"; + usage use = usage.CEPH; + + LibvirtSecretDef def = new LibvirtSecretDef(use, uuid); + def.setCephName(name); + + String expectedXml = "\n" + uuid + "\n" + + "\n" + name + "\n\n\n"; + + assertEquals(expectedXml, def.toString()); + } + +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java new file mode 100644 index 00000000000..687432b3d71 --- /dev/null +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package com.cloud.hypervisor.kvm.resource; + +import junit.framework.TestCase; +import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.poolType; +import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.authType; + +public class LibvirtStoragePoolDefTest extends TestCase { + + public void testSetGetStoragePool() { + poolType type = poolType.NETFS; + String name = "myNFSPool"; + String uuid = "d7846cb0-f610-4a5b-8d38-ee6e8d63f37b"; + String host = "127.0.0.1"; + String dir = "/export/primary"; + String targetPath = "/mnt/" + uuid; + int port = 1234; + + LibvirtStoragePoolDef pool = new LibvirtStoragePoolDef(type, name, uuid, host, port, dir, targetPath); + + assertEquals(type, pool.getPoolType()); + assertEquals(name, pool.getPoolName()); + assertEquals(host, pool.getSourceHost()); + assertEquals(port, pool.getSourcePort()); + assertEquals(dir, pool.getSourceDir()); + assertEquals(targetPath, pool.getTargetPath()); + } + + public void testNfsStoragePool() { + poolType type = poolType.NETFS; + String name = "myNFSPool"; + String uuid = "89a605bc-d470-4637-b3df-27388be452f5"; + String host = "127.0.0.1"; + String dir = "/export/primary"; + String targetPath = "/mnt/" + uuid; + + LibvirtStoragePoolDef pool = new LibvirtStoragePoolDef(type, name, uuid, host, dir, targetPath); + + String expectedXml = "\n" + name + "\n" + uuid + "\n" + + "\n\n\n\n\n" + + "" + targetPath + "\n\n\n"; + + assertEquals(expectedXml, pool.toString()); + } + + public void testRbdStoragePool() { + poolType type = poolType.RBD; + String name = "myRBDPool"; + String uuid = "921ef8b2-955a-4c18-a697-66bb9adf6131"; + String host = "127.0.0.1"; + String dir = "cloudstackrbdpool"; + String authUsername = "admin"; + String secretUuid = "08c2fa02-50d0-4a78-8903-b742d3f34934"; + authType auth = authType.CEPH; + int port = 6789; + + LibvirtStoragePoolDef pool = new LibvirtStoragePoolDef(type, name, uuid, host, port, dir, authUsername, auth, secretUuid); + + String expectedXml = "\n" + name + "\n" + uuid + "\n" + + "\n\n" + dir + "\n" + + "\n\n" + + "\n\n\n"; + + assertEquals(expectedXml, pool.toString()); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java index 85f7e856f80..0eeef82c055 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java @@ -32,6 +32,8 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.user.AccountManager; +import org.apache.cloudstack.context.CallContext; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -87,6 +89,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage MockStorageManager _storageMgr = null; @Inject ResourceManager _resourceMgr; + @Inject private AccountManager _accountMgr; SimulatorSecondaryDiscoverer discoverer; @Inject @@ -303,8 +306,10 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage @Override @DB public void run() { + CallContext.register(_accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); if (this.mode.equalsIgnoreCase("Stop")) { handleSystemVMStop(); + CallContext.unregister(); return; } @@ -359,10 +364,12 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage _resourceMgr.discoverHosts(cmd); } catch (DiscoveryException e) { s_logger.debug("Failed to discover host: " + e.toString()); + CallContext.unregister(); return; } } catch (ConfigurationException e) { s_logger.debug("Failed to load secondary storage resource: " + e.toString()); + CallContext.unregister(); return; } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index 3cd7a9f0e9e..e6ecbc9adbc 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -166,7 +166,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer _clusterDetailsDao.persist(clusterId, clusterDetails); } String updatedInventoryPath = validateCluster(url, vmwareDc); - if (url.getPath() != updatedInventoryPath) { + if (!url.getPath().equals(updatedInventoryPath)) { // If url from API doesn't specify DC then update url in database with DC associated with this zone. clusterDetails.put("url", url.getScheme() + "://" + url.getHost() + updatedInventoryPath); _clusterDetailsDao.persist(clusterId, clusterDetails); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 69543cea623..c609686efa1 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -44,7 +44,6 @@ import java.util.concurrent.TimeUnit; import javax.naming.ConfigurationException; -import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import org.apache.log4j.NDC; @@ -115,17 +114,12 @@ import com.cloud.agent.api.AttachVolumeAnswer; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.BackupSnapshotAnswer; import com.cloud.agent.api.BackupSnapshotCommand; -import com.cloud.agent.api.BumpUpPriorityCommand; import com.cloud.agent.api.CheckHealthAnswer; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkAnswer; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostAnswer; import com.cloud.agent.api.CheckOnHostCommand; -import com.cloud.agent.api.CheckRouterAnswer; -import com.cloud.agent.api.CheckRouterCommand; -import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer; -import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.CheckVirtualMachineAnswer; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.Command; @@ -139,8 +133,6 @@ import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.DeleteVMSnapshotAnswer; import com.cloud.agent.api.DeleteVMSnapshotCommand; -import com.cloud.agent.api.GetDomRVersionAnswer; -import com.cloud.agent.api.GetDomRVersionCmd; import com.cloud.agent.api.GetHostStatsAnswer; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsAnswer; @@ -186,7 +178,6 @@ import com.cloud.agent.api.ScaleVmAnswer; import com.cloud.agent.api.ScaleVmCommand; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; -import com.cloud.agent.api.SetupGuestNetworkAnswer; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; @@ -206,35 +197,11 @@ import com.cloud.agent.api.ValidateSnapshotCommand; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; -import com.cloud.agent.api.routing.CreateIpAliasCommand; -import com.cloud.agent.api.routing.DeleteIpAliasCommand; -import com.cloud.agent.api.routing.DhcpEntryCommand; -import com.cloud.agent.api.routing.DnsMasqConfigCommand; -import com.cloud.agent.api.routing.IpAliasTO; -import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; -import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; -import com.cloud.agent.api.routing.SavePasswordCommand; -import com.cloud.agent.api.routing.SetFirewallRulesAnswer; -import com.cloud.agent.api.routing.SetFirewallRulesCommand; -import com.cloud.agent.api.routing.SetMonitorServiceCommand; -import com.cloud.agent.api.routing.SetNetworkACLAnswer; import com.cloud.agent.api.routing.SetNetworkACLCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; -import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; -import com.cloud.agent.api.routing.SetSourceNatAnswer; import com.cloud.agent.api.routing.SetSourceNatCommand; -import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; -import com.cloud.agent.api.routing.SetStaticNatRulesCommand; -import com.cloud.agent.api.routing.SetStaticRouteAnswer; -import com.cloud.agent.api.routing.SetStaticRouteCommand; -import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; -import com.cloud.agent.api.routing.VmDataCommand; -import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CreateAnswer; @@ -248,17 +215,15 @@ import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.DhcpTO; import com.cloud.agent.api.to.DiskTO; -import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.NicTO; -import com.cloud.agent.api.to.PortForwardingRuleTO; -import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; +import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; +import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.configuration.Config; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.Vlan; @@ -293,13 +258,10 @@ import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHostResourceSummary; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.hypervisor.vmware.util.VmwareGuestOsMapper; import com.cloud.hypervisor.vmware.util.VmwareHelper; -import com.cloud.network.HAProxyConfigurator; -import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.VmwareTrafficLabel; -import com.cloud.network.rules.FirewallRule; import com.cloud.resource.ServerResource; import com.cloud.serializer.GsonHelper; import com.cloud.storage.Storage; @@ -312,6 +274,7 @@ import com.cloud.storage.resource.VmwareStorageProcessor; import com.cloud.storage.resource.VmwareStorageSubsystemCommandHandler; import com.cloud.storage.template.TemplateProp; import com.cloud.utils.DateUtil; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; @@ -330,7 +293,7 @@ import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineName; import com.cloud.vm.VmDetailConstants; -public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService { +public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService, VirtualRouterDeployer { private static final Logger s_logger = Logger.getLogger(VmwareResource.class); protected String _name; @@ -379,6 +342,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa protected StorageSubsystemCommandHandler storageHandler; + protected VirtualRoutingResource _vrResource; + protected static HashMap s_powerStatesTable; static { s_powerStatesTable = new HashMap(); @@ -428,26 +393,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa Class clz = cmd.getClass(); if (clz == CreateCommand.class) { answer = execute((CreateCommand)cmd); - } else if (clz == SetPortForwardingRulesCommand.class) { - answer = execute((SetPortForwardingRulesCommand)cmd); - } else if (clz == SetStaticNatRulesCommand.class) { - answer = execute((SetStaticNatRulesCommand)cmd); - } else if (clz == LoadBalancerConfigCommand.class) { - answer = execute((LoadBalancerConfigCommand)cmd); - } else if (clz == IpAssocCommand.class) { - answer = execute((IpAssocCommand)cmd); - } else if (clz == SavePasswordCommand.class) { - answer = execute((SavePasswordCommand)cmd); - } else if (clz == DhcpEntryCommand.class) { - answer = execute((DhcpEntryCommand)cmd); - } else if (clz == CreateIpAliasCommand.class) { - return execute((CreateIpAliasCommand)cmd); - } else if (clz == DnsMasqConfigCommand.class) { - return execute((DnsMasqConfigCommand)cmd); - } else if (clz == DeleteIpAliasCommand.class) { - return execute((DeleteIpAliasCommand)cmd); - } else if (clz == VmDataCommand.class) { - answer = execute((VmDataCommand)cmd); + } else if (cmd instanceof NetworkElementCommand) { + return _vrResource.executeRequest(cmd); } else if (clz == ReadyCommand.class) { answer = execute((ReadyCommand)cmd); } else if (clz == GetHostStatsCommand.class) { @@ -524,62 +471,32 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa answer = execute((NetworkUsageCommand)cmd); } else if (clz == StartCommand.class) { answer = execute((StartCommand)cmd); - } else if (clz == RemoteAccessVpnCfgCommand.class) { - answer = execute((RemoteAccessVpnCfgCommand)cmd); - } else if (clz == VpnUsersCfgCommand.class) { - answer = execute((VpnUsersCfgCommand)cmd); } else if (clz == CheckSshCommand.class) { answer = execute((CheckSshCommand)cmd); - } else if (clz == CheckRouterCommand.class) { - answer = execute((CheckRouterCommand)cmd); - } else if (clz == SetFirewallRulesCommand.class) { - answer = execute((SetFirewallRulesCommand)cmd); - } else if (clz == BumpUpPriorityCommand.class) { - answer = execute((BumpUpPriorityCommand)cmd); - } else if (clz == GetDomRVersionCmd.class) { - answer = execute((GetDomRVersionCmd)cmd); } else if (clz == CheckNetworkCommand.class) { answer = execute((CheckNetworkCommand)cmd); - } else if (clz == SetupGuestNetworkCommand.class) { - answer = execute((SetupGuestNetworkCommand)cmd); - } else if (clz == IpAssocVpcCommand.class) { - answer = execute((IpAssocVpcCommand)cmd); } else if (clz == PlugNicCommand.class) { answer = execute((PlugNicCommand)cmd); } else if (clz == UnPlugNicCommand.class) { answer = execute((UnPlugNicCommand)cmd); - } else if (clz == SetSourceNatCommand.class) { - answer = execute((SetSourceNatCommand)cmd); - } else if (clz == SetNetworkACLCommand.class) { - answer = execute((SetNetworkACLCommand)cmd); } else if (cmd instanceof CreateVMSnapshotCommand) { return execute((CreateVMSnapshotCommand)cmd); } else if (cmd instanceof DeleteVMSnapshotCommand) { return execute((DeleteVMSnapshotCommand)cmd); } else if (cmd instanceof RevertToVMSnapshotCommand) { return execute((RevertToVMSnapshotCommand)cmd); - } else if (clz == SetPortForwardingRulesVpcCommand.class) { - answer = execute((SetPortForwardingRulesVpcCommand)cmd); - } else if (clz == Site2SiteVpnCfgCommand.class) { - answer = execute((Site2SiteVpnCfgCommand)cmd); - } else if (clz == CheckS2SVpnConnectionsCommand.class) { - answer = execute((CheckS2SVpnConnectionsCommand)cmd); } else if (clz == ResizeVolumeCommand.class) { return execute((ResizeVolumeCommand)cmd); } else if (clz == UnregisterVMCommand.class) { - return execute((UnregisterVMCommand)cmd); + return execute((UnregisterVMCommand) cmd); } else if (cmd instanceof StorageSubSystemCommand) { - return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); + return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd); } else if (clz == ScaleVmCommand.class) { return execute((ScaleVmCommand)cmd); } else if (clz == PvlanSetupCommand.class) { return execute((PvlanSetupCommand)cmd); - } else if (clz == SetStaticRouteCommand.class) { - answer = execute((SetStaticRouteCommand)cmd); } else if (clz == UnregisterNicCommand.class) { answer = execute((UnregisterNicCommand)cmd); - } else if (clz == SetMonitorServiceCommand.class) { - answer = execute((SetMonitorServiceCommand)cmd); } else { answer = Answer.createUnsupportedCommandAnswer(cmd); } @@ -695,52 +612,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return answer; } - private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetStaticRouteCommand: " + _gson.toJson(cmd)); - } - - boolean endResult = true; - - String controlIp = getRouterSshControlIp(cmd); - String args = ""; - String[] results = new String[cmd.getStaticRoutes().length]; - int i = 0; - - // Extract and build the arguments for the command to be sent to the VR. - String[][] rules = cmd.generateSRouteRules(); - StringBuilder sb = new StringBuilder(); - String[] srRules = rules[0]; - for (int j = 0; j < srRules.length; j++) { - sb.append(srRules[j]).append(','); - } - args += " -a " + sb.toString(); - - // Send over the command for execution, via ssh, to the VR. - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_staticroute.sh " + args); - - if (s_logger.isDebugEnabled()) - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/vpc_staticroute.sh " + args); - - if (!result.first()) { - s_logger.error("SetStaticRouteCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Throwable e) { - s_logger.error("SetStaticRouteCommand(args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); - results[i++] = "Failed"; - endResult = false; - } - return new SetStaticRouteAnswer(cmd, endResult, results); - - } - protected NetworkUsageAnswer VPCNetworkUsage(NetworkUsageCommand cmd) { String privateIp = cmd.getPrivateIP(); String option = cmd.getOption(); @@ -762,284 +633,34 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } else { return new NetworkUsageAnswer(cmd, "success", 0L, 0L); } - try { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Executing /opt/cloud/bin/vpc_netusage.sh " + args + " on DomR " + privateIp); + + ExecutionResult callResult = executeInVR(privateIp, "vpc_netusage.sh", args); + + if (!callResult.isSuccess()) { + s_logger.error("Unable to execute NetworkUsage command on DomR (" + privateIp + "), domR may not be ready yet. failure due to " + callResult.getDetails()); + } + + if (option.equals("get") || option.equals("vpn")) { + String result = callResult.getDetails(); + if (result == null || result.isEmpty()) { + s_logger.error(" vpc network usage get returns empty "); } - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - Pair resultPair = - SshHelper.sshExecute(privateIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_netusage.sh " + args); - - if (!resultPair.first()) { - throw new Exception(" vpc network usage plugin call failed "); - - } - - if (option.equals("get") || option.equals("vpn")) { - String result = resultPair.second(); - if (result == null || result.isEmpty()) { - throw new Exception(" vpc network usage get returns empty "); - } - long[] stats = new long[2]; - if (result != null) { - String[] splitResult = result.split(":"); - int i = 0; - while (i < splitResult.length - 1) { - stats[0] += (new Long(splitResult[i++])).longValue(); - stats[1] += (new Long(splitResult[i++])).longValue(); - } - return new NetworkUsageAnswer(cmd, "success", stats[0], stats[1]); + long[] stats = new long[2]; + if (result != null) { + String[] splitResult = result.split(":"); + int i = 0; + while (i < splitResult.length - 1) { + stats[0] += (new Long(splitResult[i++])).longValue(); + stats[1] += (new Long(splitResult[i++])).longValue(); } + return new NetworkUsageAnswer(cmd, "success", stats[0], stats[1]); } - return new NetworkUsageAnswer(cmd, "success", 0L, 0L); - } catch (Throwable e) { - - s_logger.error( - "Unable to execute NetworkUsage command on DomR (" + privateIp + "), domR may not be ready yet. failure due to " + VmwareHelper.getExceptionMessage(e), e); } return new NetworkUsageAnswer(cmd, "success", 0L, 0L); } - protected Answer execute(SetMonitorServiceCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetMonitorServiceCommand: " + _gson.toJson(cmd)); - } - - String controlIp = getRouterSshControlIp(cmd); - String config = cmd.getConfiguration(); - - String args = ""; - - args += " -c " + config; - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/monitor_service.sh " + args); - - if (!result.first()) { - String msg = "monitor_service.sh failed on domain router " + controlIp + " failed " + result.second(); - s_logger.error(msg); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd); - - } catch (Throwable e) { - s_logger.error("Unexpected exception: " + e.toString(), e); - return new Answer(cmd, false, "SetMonitorServiceCommand failed due to " + VmwareHelper.getExceptionMessage(e)); - } - } - - protected Answer execute(SetPortForwardingRulesCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetPortForwardingRulesCommand: " + _gson.toJson(cmd)); - } - - String controlIp = getRouterSshControlIp(cmd); - String args = ""; - String[] results = new String[cmd.getRules().length]; - int i = 0; - - boolean endResult = true; - for (PortForwardingRuleTO rule : cmd.getRules()) { - args += rule.revoked() ? " -D " : " -A "; - args += " -P " + rule.getProtocol().toLowerCase(); - args += " -l " + rule.getSrcIp(); - args += " -p " + rule.getStringSrcPortRange(); - args += " -r " + rule.getDstIp(); - args += " -d " + rule.getStringDstPortRange(); - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/firewall_nat.sh " + args); - - if (s_logger.isDebugEnabled()) - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/firewall_nat.sh " + args); - - if (!result.first()) { - s_logger.error("SetPortForwardingRulesCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Throwable e) { - s_logger.error("SetPortForwardingRulesCommand(args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); - results[i++] = "Failed"; - endResult = false; - } - } - - return new SetPortForwardingRulesAnswer(cmd, results, endResult); - } - - protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) { - String controlIp = getRouterSshControlIp(cmd); - String[] results = new String[cmd.getRules().length]; - FirewallRuleTO[] allrules = cmd.getRules(); - FirewallRule.TrafficType trafficType = allrules[0].getTrafficType(); - String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); - - String[][] rules = cmd.generateFwRules(); - String args = ""; - args += " -F "; - if (trafficType == FirewallRule.TrafficType.Egress) { - args += " -E "; - if (egressDefault.equals("true")) { - args += " -P 1 "; - } else if (egressDefault.equals("System")) { - args += " -P 2 "; - } else { - args += " -P 0 "; - } - } - - StringBuilder sb = new StringBuilder(); - String[] fwRules = rules[0]; - if (fwRules.length > 0) { - for (int i = 0; i < fwRules.length; i++) { - sb.append(fwRules[i]).append(','); - } - args += " -a " + sb.toString(); - } - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - Pair result = null; - - if (trafficType == FirewallRule.TrafficType.Egress) { - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/firewall_egress.sh " + args); - } else { - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/firewall_ingress.sh " + args); - } - - if (s_logger.isDebugEnabled()) { - if (trafficType == FirewallRule.TrafficType.Egress) { - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/firewall_egress.sh " + args); - } else { - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/firewall_ingress.sh " + args); - } - } - - if (!result.first()) { - s_logger.error("SetFirewallRulesCommand failure on setting one rule. args: " + args); - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - - return new SetFirewallRulesAnswer(cmd, false, results); - } - } catch (Throwable e) { - s_logger.error("SetFirewallRulesCommand(args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetFirewallRulesAnswer(cmd, false, results); - } - - return new SetFirewallRulesAnswer(cmd, true, results); - } - - protected SetStaticNatRulesAnswer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetVPCStaticNatRulesCommand: " + _gson.toJson(cmd)); - } - - String[] results = new String[cmd.getRules().length]; - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - - int i = 0; - boolean endResult = true; - for (StaticNatRuleTO rule : cmd.getRules()) { - // Prepare command to be send to VPC VR - String args = ""; - args += rule.revoked() ? " -D" : " -A"; - args += " -l " + rule.getSrcIp(); - args += " -r " + rule.getDstIp(); - - // Invoke command on VPC VR. - try { - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_staticnat.sh " + args); - - if (s_logger.isDebugEnabled()) - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/vpc_staticnat.sh " + args); - - if (!result.first()) { - s_logger.error("SetVPCStaticNatRulesCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Throwable e) { - s_logger.error("SetVPCStaticNatRulesCommand (args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); - results[i++] = "Failed"; - endResult = false; - } - } - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - protected Answer execute(SetStaticNatRulesCommand cmd) { - - if (cmd.getVpcId() != null) { - return SetVPCStaticNatRules(cmd); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetFirewallRuleCommand: " + _gson.toJson(cmd)); - } - - String args = null; - String[] results = new String[cmd.getRules().length]; - int i = 0; - boolean endResult = true; - for (StaticNatRuleTO rule : cmd.getRules()) { - // 1:1 NAT needs instanceip;publicip;domrip;op - args = rule.revoked() ? " -D " : " -A "; - - args += " -l " + rule.getSrcIp(); - args += " -r " + rule.getDstIp(); - - if (rule.getProtocol() != null) { - args += " -P " + rule.getProtocol().toLowerCase(); - } - - args += " -d " + rule.getStringSrcPortRange(); - args += " -G "; - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/firewall_nat.sh " + args); - - if (s_logger.isDebugEnabled()) - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/firewall_nat.sh " + args); - - if (!result.first()) { - s_logger.error("SetStaticNatRulesCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Throwable e) { - s_logger.error("SetStaticNatRulesCommand (args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); - results[i++] = "Failed"; - endResult = false; - } - } - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - protected boolean createFileInVR(String routerIp, String filePath, String fileName, String content) { + @Override + public ExecutionResult createFileInVR(String routerIp, String filePath, String fileName, String content) { VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); File keyFile = mgr.getSystemVMKeyFile(); boolean result = true; @@ -1048,95 +669,34 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa SshHelper.scpTo(routerIp, 3922, "root", keyFile, null, filePath, content.getBytes(), fileName, null); } catch (Exception e) { s_logger.warn("Fail to create file " + filePath + fileName + " in VR " + routerIp, e); - result = false; + return new ExecutionResult(false, e.getMessage()); } - return result; + return new ExecutionResult(true, null); } - protected Answer execute(final LoadBalancerConfigCommand cmd) { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + @Override + public ExecutionResult prepareCommand(NetworkElementCommand cmd) { + //Update IP used to access router + cmd.setRouterAccessIp(getRouterSshControlIp(cmd)); + assert cmd.getRouterAccessIp() != null; - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String controlIp = getRouterSshControlIp(cmd); - - assert (controlIp != null); - - LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); - String[] config = cfgtr.generateConfiguration(cmd); - - String tmpCfgFileContents = ""; - String tmpCfgFileName = "haproxy.cfg.new"; - String tmpCfgFilePath = "/etc/haproxy/"; - for (int i = 0; i < config.length; i++) { - tmpCfgFileContents += config[i]; - tmpCfgFileContents += "\n"; + if (cmd instanceof IpAssocVpcCommand) { + return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return prepareNetworkElementCommand((IpAssocCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return prepareNetworkElementCommand((SetSourceNatCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetNetworkACLCommand) { + return prepareNetworkElementCommand((SetNetworkACLCommand)cmd); } + return new ExecutionResult(true, null); + } - if (!createFileInVR(controlIp, tmpCfgFilePath, tmpCfgFileName, tmpCfgFileContents)) { - return new Answer(cmd, false, "Fail to create LB config file in VR"); - } - - try { - - String[][] rules = cfgtr.generateFwRules(cmd); - - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; - - String args = ""; - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - - args += " -a " + sb.toString(); - } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - - args += " -d " + sb.toString(); - } - - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); - } - - Pair result; - if (cmd.getVpcId() == null) { - args = " -i " + routerIp + args; - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/loadbalancer.sh " + args); - } else { - args = " -i " + cmd.getNic().getIp() + args; - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_loadbalancer.sh " + args); - } - // Invoke the command - - if (!result.first()) { - String msg = "LoadBalancerConfigCommand on domain router " + routerIp + " failed. message: " + result.second(); - s_logger.error(msg); - - return new Answer(cmd, false, msg); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("LoadBalancerConfigCommand on domain router " + routerIp + " completed"); - } - return new Answer(cmd); - } catch (Throwable e) { - s_logger.error("Unexpected exception: " + e.toString(), e); - return new Answer(cmd, false, "LoadBalancerConfigCommand failed due to " + VmwareHelper.getExceptionMessage(e)); - } + @Override + public ExecutionResult cleanupCommand(NetworkElementCommand cmd) { + return new ExecutionResult(true, null); } // @@ -1204,77 +764,26 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return null; } - private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { - - s_logger.info("Executing resource SetupGuestNetworkCommand " + _gson.toJson(cmd)); - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - + protected ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) { NicTO nic = cmd.getNic(); - String routerIp = getRouterSshControlIp(cmd); - String domrGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); - String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String gw = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); - String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - String domainName = cmd.getNetworkDomain(); - String dns = cmd.getDefaultDns1(); - if (dns == null || dns.isEmpty()) { - dns = cmd.getDefaultDns2(); - } else { - String dns2 = cmd.getDefaultDns2(); - if (dns2 != null && !dns2.isEmpty()) { - dns += "," + dns2; - } - } + String domrName = + cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); try { - int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, nic.getMac()); - s_logger.info("find interface index. routerIp: " + routerIp + ", mac: " + nic.getMac() + ", index: " + ethDeviceNum); - - String args = (cmd.isAdd() ? "-C" : "-D"); - String dev = "eth" + ethDeviceNum; - args += " -d " + dev; - args += " -i " + domrGIP; - args += " -g " + gw; - args += " -m " + cidr; - args += " -n " + NetUtils.getSubNet(domrGIP, nic.getNetmask()); - if (dns != null && !dns.isEmpty()) { - args += " -s " + dns; - } - if (domainName != null && !domainName.isEmpty()) { - args += " -e " + domainName; - } - - Pair result = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_guestnw.sh " + args); - - if (!result.first()) { - String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.second(); - s_logger.error(msg); - - return new SetupGuestNetworkAnswer(cmd, false, msg); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("SetupGuestNetworkCommand on domain router " + routerIp + " completed"); - } - - return new SetupGuestNetworkAnswer(cmd, true, "success"); + int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, + nic.getMac()); + nic.setDeviceId(ethDeviceNum); } catch (Exception e) { - String msg = "SetupGuestNetwork failed due to " + e.toString(); + String msg = "Prepare SetupGuestNetwork failed due to " + e.toString(); s_logger.warn(msg, e); - return new SetupGuestNetworkAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } - protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource IpAssocVpcCommand " + _gson.toJson(cmd)); - } - String[] results = new String[cmd.getIpAddresses().length]; - int i = 0; + private ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) { String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = getRouterSshControlIp(cmd); @@ -1282,229 +791,58 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa IpAddressTO[] ips = cmd.getIpAddresses(); for (IpAddressTO ip : ips) { - assignVPCPublicIpAddress(routerName, routerIp, ip); - results[i++] = ip.getPublicIp() + " - success"; + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, ip.getVifMacAddress()); + if (ethDeviceNum < 0) { + if (ip.isAdd()) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } else { + s_logger.debug("VIF to deassociate IP with does not exist, return success"); + continue; + } + } + + ip.setNicDevId(ethDeviceNum); } } catch (Exception e) { - s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; + s_logger.error("Prepare Ip Assoc failure on applying one ip due to exception: ", e); + return new ExecutionResult(false, e.toString()); } - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } - protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetSourceNatCommand " + _gson.toJson(cmd)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - + protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) { String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = getRouterSshControlIp(cmd); IpAddressTO pubIp = cmd.getIpAddress(); + try { int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress()); - String args = ""; - args += " -A "; - args += " -l "; - args += pubIp.getPublicIp(); - - args += " -c "; - args += "eth" + ethDeviceNum; - - Pair result = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_snat.sh " + args); - - if (!result.first()) { - String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.second(); - s_logger.error(msg); - - return new SetSourceNatAnswer(cmd, false, msg); - } - - return new SetSourceNatAnswer(cmd, true, "success"); + pubIp.setNicDevId(ethDeviceNum); } catch (Exception e) { - String msg = "Ip SNAT failure due to " + e.toString(); + String msg = "Prepare Ip SNAT failure due to " + e.toString(); s_logger.error(msg, e); - return new SetSourceNatAnswer(cmd, false, msg); + return new ExecutionResult(false, e.toString()); } + return new ExecutionResult(true, null); } - private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetNetworkACLCommand " + _gson.toJson(cmd)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); + private ExecutionResult prepareNetworkElementCommand(SetNetworkACLCommand cmd) { + NicTO nic = cmd.getNic(); + String routerName = + cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = getRouterSshControlIp(cmd); - String[] results = new String[cmd.getRules().length]; try { - String[][] rules = cmd.generateFwRules(); - StringBuilder sb = new StringBuilder(); - String[] aclRules = rules[0]; - if (aclRules.length == 0) { - return new SetNetworkACLAnswer(cmd, true, results); - } - - for (int i = 0; i < aclRules.length; i++) { - sb.append(aclRules[i]).append(','); - } - - NicTO nic = cmd.getNic(); - int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, nic.getMac()); - String args = ""; - Pair result; - - if (privateGw != null) { - s_logger.debug("Private gateway configuration is set"); - args += " -d " + "eth" + ethDeviceNum; - args += " -a " + sb.toString(); - result = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_privategw_acl.sh " + args); - - if (!result.first()) { - String msg = "SetNetworkACLAnswer on domain router " + routerIp + " failed. message: " + result.second(); - s_logger.error(msg); - return new SetNetworkACLAnswer(cmd, false, results); - } - } else { - args = ""; - args += " -d " + "eth" + ethDeviceNum; - args += " -i " + nic.getIp(); - args += " -m " + Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - args += " -a " + sb.toString(); - - result = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_acl.sh " + args); - - if (!result.first()) { - String msg = "SetNetworkACLAnswer on domain router " + routerIp + " failed. message: " + result.second(); - s_logger.error(msg); - - return new SetNetworkACLAnswer(cmd, false, results); - } - } - - return new SetNetworkACLAnswer(cmd, true, results); + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, + nic.getMac()); + nic.setDeviceId(ethDeviceNum); } catch (Exception e) { - String msg = "SetNetworkACL failed due to " + e.toString(); + String msg = "Prepare SetNetworkACL failed due to " + e.toString(); s_logger.error(msg, e); - return new SetNetworkACLAnswer(cmd, false, results); + return new ExecutionResult(false, msg); } - } - - protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetPortForwardingRulesVpcCommand " + _gson.toJson(cmd)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - String routerIp = getRouterSshControlIp(cmd); - - String[] results = new String[cmd.getRules().length]; - int i = 0; - - boolean endResult = true; - for (PortForwardingRuleTO rule : cmd.getRules()) { - String args = ""; - args += rule.revoked() ? " -D" : " -A"; - args += " -P " + rule.getProtocol().toLowerCase(); - args += " -l " + rule.getSrcIp(); - args += " -p " + rule.getStringSrcPortRange(); - args += " -r " + rule.getDstIp(); - args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - - try { - Pair sshResult = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_portforwarding.sh " + args); - - if (!sshResult.first()) { - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Exception e) { - results[i++] = "Failed"; - endResult = false; - } - } - return new SetPortForwardingRulesAnswer(cmd, results, endResult); - } - - protected Answer execute(Site2SiteVpnCfgCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource Site2SiteVpnCfgCommand " + _gson.toJson(cmd)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - String routerIp = getRouterSshControlIp(cmd); - - String args = ""; - if (cmd.isCreate()) { - args += " -A"; - args += " -l "; - args += cmd.getLocalPublicIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -g "; - args += cmd.getLocalPublicGateway(); - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - args += " -e "; - args += "\"" + cmd.getEspPolicy() + "\""; - args += " -i "; - args += "\"" + cmd.getIkePolicy() + "\""; - args += " -t "; - args += Long.toString(cmd.getIkeLifetime()); - args += " -T "; - args += Long.toString(cmd.getEspLifetime()); - args += " -s "; - args += "\"" + cmd.getIpsecPsk() + "\""; - args += " -d "; - if (cmd.getDpd()) { - args += "1"; - } else { - args += "0"; - } - if (cmd.isPassive()) { - args += " -p "; - } - } else { - args += " -D"; - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - } - - Pair result; - try { - result = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/ipsectunnel.sh " + args); - - if (!result.first()) { - s_logger.error("Setup site2site VPN " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); - - return new Answer(cmd, false, "Setup site2site VPN falied due to " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("setup site 2 site vpn on router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "Setup site2site VPN falied due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, "Setup site2site VPN failed due to " + VmwareHelper.getExceptionMessage(e)); - } - return new Answer(cmd, true, result.second()); + return new ExecutionResult(true, null); } private PlugNicAnswer execute(PlugNicCommand cmd) { @@ -1644,185 +982,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - protected void assignVPCPublicIpAddress(String domrName, String routerIp, IpAddressTO ip) throws Exception { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource assignVPCPublicIpAddress. domrName: " + domrName + ", routerIp: " + routerIp + ", ip: " + _gson.toJson(ip)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, ip.getVifMacAddress()); - if (ethDeviceNum < 0) { - if (ip.isAdd()) { - throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); - } else { - s_logger.debug("VIF to deassociate IP with does not exist, return success"); - return; - } - } - - String args = ""; - String snatArgs = ""; - - if (ip.isAdd()) { - args += " -A "; - snatArgs += " -A "; - } else { - args += " -D "; - snatArgs += " -D "; - } - - args += " -l "; - args += ip.getPublicIp(); - - args += " -c "; - args += "eth" + ethDeviceNum; - - args += " -g "; - args += ip.getVlanGateway(); - - args += " -m "; - args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); - - args += " -n "; - args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); - - Pair result = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_ipassoc.sh " + args); - - if (!result.first()) { - throw new InternalErrorException("Unable to assign public IP address"); - } - - if (ip.isSourceNat()) { - snatArgs += " -l "; - snatArgs += ip.getPublicIp(); - snatArgs += " -c "; - snatArgs += "eth" + ethDeviceNum; - - Pair result_gateway = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_privateGateway.sh " + snatArgs); - - if (!result_gateway.first()) { - throw new InternalErrorException("Unable to configure source NAT for public IP address."); - } - } - } - - protected void assignPublicIpAddress(VirtualMachineMO vmMo, final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, - final boolean firstIP, final boolean sourceNat, final String broadcastId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) - throws Exception { - - /** - * TODO support other networks - */ - URI broadcastUri = BroadcastDomainType.fromString(broadcastId); - if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { - throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + broadcastId); - } - String vlanId = BroadcastDomainType.getValue(broadcastUri); - - String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId); - Pair publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo.first()); - } - - boolean addVif = false; - boolean removeVif = false; - if (add && publicNicInfo.first().intValue() == -1) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Plug new NIC to associate" + privateIpAddress + " to " + publicIpAddress); - } - - addVif = true; - } else if (!add && firstIP) { - removeVif = true; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unplug NIC " + publicNicInfo.first()); - } - } - - if (addVif) { - plugPublicNic(vmMo, vlanId, vifMacAddress); - publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); - if (publicNicInfo.first().intValue() >= 0) { - networkUsage(privateIpAddress, "addVif", "eth" + publicNicInfo.first()); - } - } - - if (publicNicInfo.first().intValue() < 0) { - String msg = "Failed to find DomR VIF to associate/disassociate IP with."; - s_logger.error(msg); - throw new InternalErrorException(msg); - } - - String args = null; - - if (add) { - args = " -A "; - } else { - args = " -D "; - } - - if (sourceNat) { - args += " -s "; - } - if (firstIP) { - args += " -f "; - } - String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask)); - args += " -l "; - args += publicIpAddress + "/" + cidrSize; - - args += " -c "; - args += "eth" + publicNicInfo.first(); - - args += " -g "; - args += vlanGateway; - - if (addVif) { - args += " -n "; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domain router " + privateIpAddress + ", /opt/cloud/bin/ipassoc.sh " + args); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = - SshHelper.sshExecute(privateIpAddress, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/ipassoc.sh " + args); - - if (!result.first()) { - s_logger.error("ipassoc command on domain router " + privateIpAddress + " failed. message: " + result.second()); - throw new Exception("ipassoc failed due to " + result.second()); - } - - if (removeVif) { - - String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK); - int nicMasks = Integer.parseInt(nicMasksStr); - nicMasks &= ~(1 << publicNicInfo.first().intValue()); - vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks)); - - HostMO hostMo = vmMo.getRunningHost(); - List networks = vmMo.getNetworksWithDetails(); - for (NetworkDetails netDetails : networks) { - if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) { - if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) { - cleanupNetwork(hostMo, netDetails); - } - } - } - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("ipassoc command on domain router " + privateIpAddress + " completed"); - } - } - private void plugPublicNic(VirtualMachineMO vmMo, final String vlanId, final String vifMacAddress) throws Exception { // TODO : probably need to set traffic shaping Pair networkInfo = null; @@ -1905,11 +1064,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa throw new Exception("Could not allocate a free public NIC"); } - protected Answer execute(IpAssocCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource IPAssocCommand: " + _gson.toJson(cmd)); - } - + private ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) { int i = 0; String[] results = new String[cmd.getIpAddresses().length]; @@ -1939,413 +1094,158 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } for (IpAddressTO ip : ips) { - assignPublicIpAddress(vmMo, routerName, controlIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), - ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress()); - results[i++] = ip.getPublicIp() + " - success"; + /** + * TODO support other networks + */ + URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { + throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + ip.getBroadcastUri()); + } + String vlanId = BroadcastDomainType.getValue(broadcastUri); + + String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId); + Pair publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo.first()); + } + + boolean addVif = false; + if (ip.isAdd() && publicNicInfo.first().intValue() == -1) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Plug new NIC to associate" + controlIp + " to " + ip.getPublicIp()); + } + addVif = true; + } + + if (addVif) { + plugPublicNic(vmMo, vlanId, ip.getVifMacAddress()); + publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); + if (publicNicInfo.first().intValue() >= 0) { + networkUsage(controlIp, "addVif", "eth" + publicNicInfo.first()); + } + } + + if (publicNicInfo.first().intValue() < 0) { + String msg = "Failed to find DomR VIF to associate/disassociate IP with."; + s_logger.error(msg); + throw new InternalErrorException(msg); + } + ip.setNicDevId(publicNicInfo.first().intValue()); + ip.setNewNic(addVif); } } catch (Throwable e) { s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e); - - for (; i < cmd.getIpAddresses().length; i++) { - results[i++] = IpAssocAnswer.errorResult; - } + return new ExecutionResult(false, e.toString()); } - - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } - protected Answer execute(SavePasswordCommand cmd) { - if (s_logger.isInfoEnabled()) { - - s_logger.info("Executing resource SavePasswordCommand. vmName: " + cmd.getVmName() + ", vmIp: " + cmd.getVmIpAddress() + ", password: " + - StringUtils.getMaskedPasswordForDisplay(cmd.getPassword())); - } - - String controlIp = getRouterSshControlIp(cmd); - final String password = cmd.getPassword(); - final String vmIpAddress = cmd.getVmIpAddress(); - - // Run save_password_to_domr.sh - String args = " -v " + vmIpAddress; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domain router " + controlIp + ", /opt/cloud/bin/savepassword.sh " + args + " -p " + - StringUtils.getMaskedPasswordForDisplay(cmd.getPassword())); - } - - args += " -p " + password; + private ExecutionResult NetworkElementCommandnup(IpAssocCommand cmd) { + String[] results = new String[cmd.getIpAddresses().length]; + VmwareContext context = getServiceContext(); try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/savepassword.sh " + args); + VmwareHypervisorHost hyperHost = getHyperHost(context); - if (!result.first()) { - s_logger.error("savepassword command on domain router " + controlIp + " failed, message: " + result.second()); + IpAddressTO[] ips = cmd.getIpAddresses(); + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String controlIp = VmwareResource.getRouterSshControlIp(cmd); - return new Answer(cmd, false, "SavePassword failed due to " + result.second()); + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(routerName); + + // command may sometimes be redirect to a wrong host, we relax + // the check and will try to find it within cluster + if (vmMo == null) { + if (hyperHost instanceof HostMO) { + ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO)hyperHost).getParentMor()); + vmMo = clusterMo.findVmOnHyperHost(routerName); + } } - if (s_logger.isInfoEnabled()) { - s_logger.info("savepassword command on domain router " + controlIp + " completed"); + if (vmMo == null) { + String msg = "Router " + routerName + " no longer exists to execute IPAssoc command"; + s_logger.error(msg); + throw new Exception(msg); } - } catch (Throwable e) { - String msg = "SavePasswordCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - return new Answer(cmd); - } + for (IpAddressTO ip : ips) { + /** + * TODO support other networks + */ + URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { + throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + ip.getBroadcastUri()); + } + String vlanId = BroadcastDomainType.getValue(broadcastUri); - protected Answer execute(DhcpEntryCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource DhcpEntryCommand: " + _gson.toJson(cmd)); - } + String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId); + Pair publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); - // ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/root/edithosts.sh $mac $ip $vm $dfltrt $ns $staticrt" >/dev/null + if (s_logger.isDebugEnabled()) { + s_logger.debug("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo.first()); + } - String args = " -m " + cmd.getVmMac(); - if (cmd.getVmIpAddress() != null) { - args += " -4 " + cmd.getVmIpAddress(); - } - args += " -h " + cmd.getVmName(); + boolean removeVif = false; + if (!ip.isAdd() && ip.isFirstIP()) { + removeVif = true; - if (cmd.getDefaultRouter() != null) { - args += " -d " + cmd.getDefaultRouter(); - } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unplug NIC " + publicNicInfo.first()); + } + } - if (cmd.getDefaultDns() != null) { - args += " -n " + cmd.getDefaultDns(); - } + if (publicNicInfo.first().intValue() < 0) { + String msg = "Failed to find DomR VIF to associate/disassociate IP with."; + s_logger.error(msg); + throw new InternalErrorException(msg); + } - if (cmd.getStaticRoutes() != null) { - args += " -s " + cmd.getStaticRoutes(); - } + if (removeVif) { + String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK); + int nicMasks = Integer.parseInt(nicMasksStr); + nicMasks &= ~(1 << publicNicInfo.first().intValue()); + vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks)); - if (cmd.getVmIp6Address() != null) { - args += " -6 " + cmd.getVmIp6Address(); - args += " -u " + cmd.getDuid(); - } - - if (!cmd.isDefault()) { - args += " -N"; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/edithosts.sh " + args); - } - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/edithosts.sh " + args); - - if (!result.first()) { - s_logger.error("dhcp_entry command on domR " + controlIp + " failed, message: " + result.second()); - - return new Answer(cmd, false, "DhcpEntry failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("dhcp_entry command on domain router " + controlIp + " completed"); - } - - } catch (Throwable e) { - String msg = "DhcpEntryCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd); - } - - protected Answer execute(final CreateIpAliasCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing createIpAlias command: " + _gson.toJson(cmd)); - } - cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List ipAliasTOs = cmd.getIpAliasList(); - String args = ""; - for (IpAliasTO ipaliasto : ipAliasTOs) { - args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/createIpAlias " + args); - } - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/createIpAlias.sh " + args); - - if (!result.first()) { - s_logger.error("CreateIpAlias command on domr " + controlIp + " failed, message: " + result.second()); - - return new Answer(cmd, false, "createipAlias failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("createIpAlias command on domain router " + controlIp + " completed"); - } - - } catch (Throwable e) { - String msg = "createIpAlias failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd); - } - - protected Answer execute(final DeleteIpAliasCommand cmd) { - cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List revokedIpAliasTOs = cmd.getDeleteIpAliasTos(); - List activeIpAliasTOs = cmd.getCreateIpAliasTos(); - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing deleteIpAlias command: " + _gson.toJson(cmd)); - } - String args = ""; - for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { - args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; - } - args = args + "- "; - for (IpAliasTO ipAliasTO : activeIpAliasTOs) { - args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/deleteIpAlias " + args); - } - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/deleteIpAlias.sh " + args); - - if (!result.first()) { - s_logger.error("deleteIpAlias command on domr " + controlIp + " failed, message: " + result.second()); - - return new Answer(cmd, false, "deleteIpAlias failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("deleteIpAlias command on domain router " + controlIp + " completed"); - } - - } catch (Throwable e) { - String msg = "deleteIpAlias failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd); - } - - protected Answer execute(final DnsMasqConfigCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing dnsmasqConfig command: " + _gson.toJson(cmd)); - } - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String controlIp = getRouterSshControlIp(cmd); - - assert (controlIp != null); - - List dhcpTos = cmd.getIps(); - String args = ""; - for (DhcpTO dhcpTo : dhcpTos) { - args = args + dhcpTo.getRouterIp() + ":" + dhcpTo.getGateway() + ":" + dhcpTo.getNetmask() + ":" + dhcpTo.getStartIpOfSubnet() + "-"; - } - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - mgr.getSystemVMKeyFile(); - - try { - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/dnsmasq.sh " + args); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domain router " + routerIp + ", /opt/cloud/bin/dnsmasq.sh"); - } - - if (!result.first()) { - s_logger.error("Unable update dnsmasq config file"); - return new Answer(cmd, false, "dnsmasq config update failed due to: " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("dnsmasq config command on domain router " + routerIp + " completed"); + HostMO hostMo = vmMo.getRunningHost(); + List networks = vmMo.getNetworksWithDetails(); + for (NetworkDetails netDetails : networks) { + if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) { + if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) { + cleanupNetwork(hostMo, netDetails); + } + } + } + } } } catch (Throwable e) { - String msg = "Dnsmasqconfig command failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); + s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e); + return new ExecutionResult(false, e.toString()); } - - return new Answer(cmd); + return new ExecutionResult(true, null); } - protected CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing resource CheckS2SVpnConnectionsCommand: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/checkbatchs2svpn.sh "); - } - + @Override + public ExecutionResult executeInVR(String routerIP, String script, String args) { Pair result; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - String cmdline = "/opt/cloud/bin/checkbatchs2svpn.sh "; - for (String ip : cmd.getVpnIps()) { - cmdline += " " + ip; - } - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, cmdline); - - if (!result.first()) { - s_logger.error("check site-to-site vpn connections command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + - result.second()); - - return new CheckS2SVpnConnectionsAnswer(cmd, false, result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("check site-to-site vpn connections command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "CheckS2SVpnConnectionsCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed"); - } - return new CheckS2SVpnConnectionsAnswer(cmd, true, result.second()); - } - - protected Answer execute(CheckRouterCommand cmd) { + //TODO: Password should be masked, cannot output to log directly if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing resource CheckRouterCommand: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/checkrouter.sh "); + s_logger.debug("Run command on VR: " + routerIP + ", script: " + script + " with args: " + args); } - Pair result; try { VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/checkrouter.sh "); - - if (!result.first()) { - s_logger.error("check router command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); - - return new CheckRouterAnswer(cmd, "CheckRouter failed due to " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("check router command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "CheckRouterCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new CheckRouterAnswer(cmd, msg); + result = SshHelper.sshExecute(routerIP, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/" + script + " " + args); + } catch (Exception e) { + String msg = "Command failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg); + result = new Pair(false, msg); } - return new CheckRouterAnswer(cmd, result.second(), true); - } - - protected Answer execute(GetDomRVersionCmd cmd) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing resource GetDomRVersionCmd: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/get_template_version.sh "); + s_logger.debug(script + " execution result: " + result.first().toString()); } - - Pair result; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/get_template_version.sh "); - - if (!result.first()) { - s_logger.error("GetDomRVersionCmd on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); - - return new GetDomRVersionAnswer(cmd, "GetDomRVersionCmd failed due to " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("GetDomRVersionCmd on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "GetDomRVersionCmd failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new GetDomRVersionAnswer(cmd, msg); - } - String[] lines = result.second().split("&"); - if (lines.length != 2) { - return new GetDomRVersionAnswer(cmd, result.second()); - } - return new GetDomRVersionAnswer(cmd, result.second(), lines[0], lines[1]); - } - - protected Answer execute(BumpUpPriorityCommand cmd) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing resource BumpUpPriorityCommand: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/bumpup_priority.sh "); - } - - Pair result; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/bumpup_priority.sh "); - - if (!result.first()) { - s_logger.error("BumpUpPriority command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); - - return new Answer(cmd, false, "BumpUpPriorityCommand failed due to " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("BumpUpPriorityCommand on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "BumpUpPriorityCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - if (result.second() == null || result.second().isEmpty()) { - return new Answer(cmd, true, result.second()); - } - return new Answer(cmd, false, result.second()); - } - - protected Answer execute(VmDataCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource VmDataCommand: " + _gson.toJson(cmd)); - } - - String controlIp = getRouterSshControlIp(cmd); - Map> data = new HashMap>(); - data.put(cmd.getVmIpAddress(), cmd.getVmData()); - - String json = new Gson().toJson(data); - s_logger.debug("VM data JSON IS:" + json); - - json = Base64.encodeBase64String(json.getBytes()); - - String args = "-d " + json; - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - try { - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vmdata.py " + args); - if (!result.first()) { - s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second()); - return new Answer(cmd, false, "VmDataCommand failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("vm_data command on domain router " + controlIp + " completed"); - } - } catch (Throwable e) { - String msg = "VmDataCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - return new Answer(cmd); + return new ExecutionResult(result.first(), result.second()); } protected CheckSshAnswer execute(CheckSshCommand cmd) { @@ -3317,7 +2217,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa public int compare(DiskTO arg0, DiskTO arg1) { if (arg0.getDiskSeq() < arg1.getDiskSeq()) { return -1; - } else if (arg0.getDiskSeq() == arg1.getDiskSeq()) { + } else if (arg0.getDiskSeq().equals(arg1.getDiskSeq())) { return 0; } @@ -3570,101 +2470,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - protected Answer execute(final RemoteAccessVpnCfgCommand cmd) { - String controlIp = getRouterSshControlIp(cmd); - StringBuffer argsBuf = new StringBuffer(); - if (cmd.isCreate()) { - argsBuf.append(" -r ") - .append(cmd.getIpRange()) - .append(" -p ") - .append(cmd.getPresharedKey()) - .append(" -s ") - .append(cmd.getVpnServerIp()) - .append(" -l ") - .append(cmd.getLocalIp()) - .append(" -c "); - - } else { - argsBuf.append(" -d ").append(" -s ").append(cmd.getVpnServerIp()); - } - argsBuf.append(" -C ").append(cmd.getLocalCidr()); - argsBuf.append(" -i ").append(cmd.getPublicInterface()); - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing /opt/cloud/bin/vpn_lt2p.sh "); - } - - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpn_l2tp.sh " + argsBuf.toString()); - - if (!result.first()) { - s_logger.error("RemoteAccessVpnCfg command on domR failed, message: " + result.second()); - - return new Answer(cmd, false, "RemoteAccessVpnCfg command failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("RemoteAccessVpnCfg command on domain router " + argsBuf.toString() + " completed"); - } - - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String msg = "RemoteAccessVpnCfg command failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd); - } - - protected Answer execute(final VpnUsersCfgCommand cmd) { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - String controlIp = getRouterSshControlIp(cmd); - for (VpnUsersCfgCommand.UsernamePassword userpwd : cmd.getUserpwds()) { - StringBuffer argsBuf = new StringBuffer(); - if (!userpwd.isAdd()) { - argsBuf.append(" -U ").append(userpwd.getUsername()); - } else { - argsBuf.append(" -u ").append(userpwd.getUsernamePassword()); - } - - try { - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing /opt/cloud/bin/vpn_lt2p.sh "); - } - - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpn_l2tp.sh " + argsBuf.toString()); - - if (!result.first()) { - s_logger.error("VpnUserCfg command on domR failed, message: " + result.second()); - - return new Answer(cmd, false, "VpnUserCfg command failed due to " + result.second()); - } - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String msg = "VpnUserCfg command failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - } - - return new Answer(cmd); - } - private VirtualMachineMO takeVmFromOtherHyperHost(VmwareHypervisorHost hyperHost, String vmName) throws Exception { VirtualMachineMO vmMo = hyperHost.findVmOnPeerHyperHost(vmName); @@ -4182,7 +2987,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa volume = entry.getKey(); filerTo = entry.getValue(); - volume.getPoolUuid().replace("-", ""); tgtDsName = filerTo.getUuid().replace("-", ""); tgtDsNfsHost = filerTo.getHost(); tgtDsNfsPath = filerTo.getPath(); @@ -6486,11 +5290,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (vals.get(vi) instanceof PerfMetricIntSeries) { PerfMetricIntSeries val = (PerfMetricIntSeries)vals.get(vi); List perfValues = val.getValue(); + Long sumRate = 0L; + for (int j = 0; j < infos.size(); j++) { // Size of the array matches the size as the PerfSampleInfo + sumRate += perfValues.get(j); + } + Long averageRate = sumRate / infos.size(); if (vals.get(vi).getId().getCounterId() == rxPerfCounterInfo.getKey()) { - networkReadKBs = sampleDuration * perfValues.get(3); //get the average RX rate multiplied by sampled duration + networkReadKBs = sampleDuration * averageRate; //get the average RX rate multiplied by sampled duration } if (vals.get(vi).getId().getCounterId() == txPerfCounterInfo.getKey()) { - networkWriteKBs = sampleDuration * perfValues.get(3);//get the average TX rate multiplied by sampled duration + networkWriteKBs = sampleDuration * averageRate;//get the average TX rate multiplied by sampled duration } } } @@ -6522,28 +5331,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += ethName; } - try { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Executing /opt/cloud/bin/netusage.sh " + args + " on DomR " + privateIpAddress); - } + ExecutionResult result = executeInVR(privateIpAddress, "netusage.sh", args); - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - Pair result = - SshHelper.sshExecute(privateIpAddress, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/netusage.sh " + args); - - if (!result.first()) { - return null; - } - - return result.second(); - } catch (Throwable e) { - s_logger.error( - "Unable to execute NetworkUsage command on DomR (" + privateIpAddress + "), domR may not be ready yet. failure due to " + - VmwareHelper.getExceptionMessage(e), e); + if (!result.isSuccess()) { + return null; } - return null; + return result.getDetails(); } private long[] getNetworkStats(String privateIP) { @@ -6788,6 +5582,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr, timeout, this, _shutdownWaitMs, null); storageHandler = new VmwareStorageSubsystemCommandHandler(storageProcessor); + _vrResource = new VirtualRoutingResource(this); + if (!_vrResource.configure(name, params)) { + throw new ConfigurationException("Unable to configure VirtualRoutingResource"); + } return true; } finally { recycleServiceContext(); diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java index 0ed09c4c82b..6157bd681c4 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -957,7 +957,7 @@ public class VmwareStorageProcessor implements StorageProcessor { String backupUuid = UUID.randomUUID().toString(); Pair snapshotInfo = exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName); - return new Ternary(backupUuid + "/" + backupUuid, snapshotInfo.first(), snapshotInfo.second()); + return new Ternary(backupUuid, snapshotInfo.first(), snapshotInfo.second()); } @Override @@ -1040,8 +1040,25 @@ public class VmwareStorageProcessor implements StorageProcessor { answer = new CopyCmdAnswer(details); } else { details = "Successfully backedUp the snapshot with Uuid: " + snapshotUuid + " to secondary storage."; + + // Get snapshot physical size + long physicalSize = 0l; + String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl); + String snapshotDir = destSnapshot.getPath() + "/" + snapshotBackupUuid; + File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles(); + if(files != null) { + for(File file : files) { + String fileName = file.getName(); + if(fileName.toLowerCase().startsWith(snapshotBackupUuid) && fileName.toLowerCase().endsWith(".vmdk")) { + physicalSize = new File(secondaryMountPoint + "/" + snapshotDir + "/" + fileName).length(); + break; + } + } + } + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); - newSnapshot.setPath(destSnapshot.getPath() + "/" + snapshotBackupUuid); + newSnapshot.setPath(snapshotDir + "/" + snapshotBackupUuid); + newSnapshot.setPhysicalSize(physicalSize); answer = new CopyCmdAnswer(newSnapshot); } } finally { diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java index 3930d8ec68d..e1527f96b15 100644 --- a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java +++ b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java @@ -99,7 +99,7 @@ public class VmwareStorageMotionStrategy implements DataMotionStrategy { try { VMInstanceVO instance = instanceDao.findById(vmTo.getId()); if (instance != null) { - if (srcHost.getClusterId() == destHost.getClusterId()) { + if (srcHost.getClusterId().equals(destHost.getClusterId())) { answer = migrateVmWithVolumesWithinCluster(instance, vmTo, srcHost, destHost, volumeMap); } else { answer = migrateVmWithVolumesAcrossCluster(instance, vmTo, srcHost, destHost, volumeMap); @@ -119,7 +119,7 @@ public class VmwareStorageMotionStrategy implements DataMotionStrategy { } private Answer migrateVmWithVolumesAcrossCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) - throws AgentUnavailableException { + throws AgentUnavailableException { // Initiate migration of a virtual machine with it's volumes. try { @@ -157,7 +157,7 @@ public class VmwareStorageMotionStrategy implements DataMotionStrategy { } private Answer migrateVmWithVolumesWithinCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) - throws AgentUnavailableException { + throws AgentUnavailableException { // Initiate migration of a virtual machine with it's volumes. try { diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index ed9eec1dda3..200a72ff219 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -16,22 +16,84 @@ // under the License. package com.cloud.hypervisor.xen.resource; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Queue; +import java.util.Random; +import java.util.Set; +import java.util.UUID; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +import com.trilead.ssh2.SCPClient; +import com.xensource.xenapi.Bond; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Console; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.HostCpu; +import com.xensource.xenapi.HostMetrics; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.PBD; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Pool; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Session; +import com.xensource.xenapi.Task; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.BadServerResponse; +import com.xensource.xenapi.Types.VmPowerState; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VBDMetrics; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VIF; +import com.xensource.xenapi.VLAN; +import com.xensource.xenapi.VM; +import com.xensource.xenapi.VMGuestMetrics; +import com.xensource.xenapi.XenAPIObject; + +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; + import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeAnswer; import com.cloud.agent.api.AttachVolumeCommand; -import com.cloud.agent.api.BumpUpPriorityCommand; import com.cloud.agent.api.CheckHealthAnswer; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkAnswer; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostAnswer; import com.cloud.agent.api.CheckOnHostCommand; -import com.cloud.agent.api.CheckRouterAnswer; -import com.cloud.agent.api.CheckRouterCommand; -import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer; -import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.CheckVirtualMachineAnswer; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; @@ -44,8 +106,6 @@ import com.cloud.agent.api.CreateVMSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.DeleteVMSnapshotAnswer; import com.cloud.agent.api.DeleteVMSnapshotCommand; -import com.cloud.agent.api.GetDomRVersionAnswer; -import com.cloud.agent.api.GetDomRVersionCmd; import com.cloud.agent.api.GetHostStatsAnswer; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsAnswer; @@ -105,7 +165,6 @@ import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; -import com.cloud.agent.api.SetupGuestNetworkAnswer; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; @@ -125,35 +184,11 @@ import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; -import com.cloud.agent.api.routing.CreateIpAliasCommand; -import com.cloud.agent.api.routing.DeleteIpAliasCommand; -import com.cloud.agent.api.routing.DhcpEntryCommand; -import com.cloud.agent.api.routing.DnsMasqConfigCommand; -import com.cloud.agent.api.routing.IpAliasTO; -import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; -import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; -import com.cloud.agent.api.routing.SavePasswordCommand; -import com.cloud.agent.api.routing.SetFirewallRulesAnswer; -import com.cloud.agent.api.routing.SetFirewallRulesCommand; -import com.cloud.agent.api.routing.SetMonitorServiceCommand; -import com.cloud.agent.api.routing.SetNetworkACLAnswer; import com.cloud.agent.api.routing.SetNetworkACLCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; -import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; -import com.cloud.agent.api.routing.SetSourceNatAnswer; import com.cloud.agent.api.routing.SetSourceNatCommand; -import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; -import com.cloud.agent.api.routing.SetStaticNatRulesCommand; -import com.cloud.agent.api.routing.SetStaticRouteAnswer; -import com.cloud.agent.api.routing.SetStaticRouteCommand; -import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; -import com.cloud.agent.api.routing.VmDataCommand; -import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.DestroyCommand; @@ -163,28 +198,23 @@ import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; -import com.cloud.agent.api.to.DhcpTO; import com.cloud.agent.api.to.DiskTO; -import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.NicTO; -import com.cloud.agent.api.to.PortForwardingRuleTO; -import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; +import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; +import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.exception.InternalErrorException; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.HAProxyConfigurator; -import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetworkSetupInfo; -import com.cloud.network.rules.FirewallRule; import com.cloud.resource.ServerResource; import com.cloud.resource.hypervisor.HypervisorResource; import com.cloud.storage.Storage; @@ -195,6 +225,7 @@ import com.cloud.storage.resource.StorageSubsystemCommandHandler; import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase; import com.cloud.storage.template.TemplateProp; import com.cloud.template.VirtualMachineTemplate.BootloaderType; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; @@ -207,71 +238,6 @@ import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.snapshot.VMSnapshot; -import com.google.gson.Gson; -import com.trilead.ssh2.SCPClient; -import com.xensource.xenapi.Bond; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Console; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.HostCpu; -import com.xensource.xenapi.HostMetrics; -import com.xensource.xenapi.Network; -import com.xensource.xenapi.PBD; -import com.xensource.xenapi.PIF; -import com.xensource.xenapi.Pool; -import com.xensource.xenapi.SR; -import com.xensource.xenapi.Session; -import com.xensource.xenapi.Task; -import com.xensource.xenapi.Types; -import com.xensource.xenapi.Types.BadServerResponse; -import com.xensource.xenapi.Types.VmPowerState; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VBD; -import com.xensource.xenapi.VBDMetrics; -import com.xensource.xenapi.VDI; -import com.xensource.xenapi.VIF; -import com.xensource.xenapi.VLAN; -import com.xensource.xenapi.VM; -import com.xensource.xenapi.VMGuestMetrics; -import com.xensource.xenapi.XenAPIObject; -import org.apache.cloudstack.storage.command.StorageSubSystemCommand; -import org.apache.cloudstack.storage.to.TemplateObjectTO; -import org.apache.cloudstack.storage.to.VolumeObjectTO; -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; -import org.apache.xmlrpc.XmlRpcException; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; -import javax.xml.parsers.DocumentBuilderFactory; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Queue; -import java.util.Random; -import java.util.Set; -import java.util.UUID; /** @@ -287,7 +253,7 @@ import java.util.UUID; * */ @Local(value = ServerResource.class) -public abstract class CitrixResourceBase implements ServerResource, HypervisorResource { +public abstract class CitrixResourceBase implements ServerResource, HypervisorResource, VirtualRouterDeployer { private static final Logger s_logger = Logger.getLogger(CitrixResourceBase.class); protected static final XenServerConnectionPool ConnPool = XenServerConnectionPool.getInstance(); protected String _name; @@ -334,6 +300,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected StorageSubsystemCommandHandler storageHandler; protected int _maxNics = 7; + protected VirtualRoutingResource _vrResource; + public enum SRType { NFS, LVM, ISCSI, ISO, LVMOISCSI, LVMOHBA, EXT, FILE; @@ -443,30 +411,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Class clazz = cmd.getClass(); if (clazz == CreateCommand.class) { return execute((CreateCommand)cmd); - } else if (clazz == SetPortForwardingRulesCommand.class) { - return execute((SetPortForwardingRulesCommand)cmd); - } else if (clazz == SetStaticNatRulesCommand.class) { - return execute((SetStaticNatRulesCommand)cmd); - } else if (clazz == LoadBalancerConfigCommand.class) { - return execute((LoadBalancerConfigCommand)cmd); - } else if (clazz == IpAssocCommand.class) { - return execute((IpAssocCommand)cmd); + } else if (cmd instanceof NetworkElementCommand) { + return _vrResource.executeRequest(cmd); } else if (clazz == CheckConsoleProxyLoadCommand.class) { return execute((CheckConsoleProxyLoadCommand)cmd); } else if (clazz == WatchConsoleProxyLoadCommand.class) { return execute((WatchConsoleProxyLoadCommand)cmd); - } else if (clazz == SavePasswordCommand.class) { - return execute((SavePasswordCommand)cmd); - } else if (clazz == DhcpEntryCommand.class) { - return execute((DhcpEntryCommand)cmd); - } else if (clazz == CreateIpAliasCommand.class) { - return execute((CreateIpAliasCommand)cmd); - } else if (clazz == DnsMasqConfigCommand.class) { - return execute((DnsMasqConfigCommand)cmd); - } else if (clazz == DeleteIpAliasCommand.class) { - return execute((DeleteIpAliasCommand)cmd); - } else if (clazz == VmDataCommand.class) { - return execute((VmDataCommand)cmd); } else if (clazz == ReadyCommand.class) { return execute((ReadyCommand)cmd); } else if (clazz == GetHostStatsCommand.class) { @@ -525,10 +475,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return execute((PoolEjectCommand)cmd); } else if (clazz == StartCommand.class) { return execute((StartCommand)cmd); - } else if (clazz == RemoteAccessVpnCfgCommand.class) { - return execute((RemoteAccessVpnCfgCommand)cmd); - } else if (clazz == VpnUsersCfgCommand.class) { - return execute((VpnUsersCfgCommand)cmd); } else if (clazz == CheckSshCommand.class) { return execute((CheckSshCommand)cmd); } else if (clazz == SecurityGroupRulesCmd.class) { @@ -555,54 +501,28 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return execute((OvsDestroyTunnelCommand)cmd); } else if (clazz == UpdateHostPasswordCommand.class) { return execute((UpdateHostPasswordCommand)cmd); - } else if (cmd instanceof CheckRouterCommand) { - return execute((CheckRouterCommand)cmd); - } else if (cmd instanceof SetFirewallRulesCommand) { - return execute((SetFirewallRulesCommand)cmd); - } else if (cmd instanceof BumpUpPriorityCommand) { - return execute((BumpUpPriorityCommand)cmd); } else if (cmd instanceof ClusterSyncCommand) { return execute((ClusterSyncCommand)cmd); - } else if (cmd instanceof GetDomRVersionCmd) { - return execute((GetDomRVersionCmd)cmd); } else if (clazz == CheckNetworkCommand.class) { return execute((CheckNetworkCommand)cmd); - } else if (clazz == SetupGuestNetworkCommand.class) { - return execute((SetupGuestNetworkCommand)cmd); } else if (clazz == PlugNicCommand.class) { return execute((PlugNicCommand)cmd); } else if (clazz == UnPlugNicCommand.class) { return execute((UnPlugNicCommand)cmd); - } else if (clazz == IpAssocVpcCommand.class) { - return execute((IpAssocVpcCommand)cmd); - } else if (clazz == SetSourceNatCommand.class) { - return execute((SetSourceNatCommand)cmd); - } else if (clazz == SetNetworkACLCommand.class) { - return execute((SetNetworkACLCommand)cmd); - } else if (clazz == SetPortForwardingRulesVpcCommand.class) { - return execute((SetPortForwardingRulesVpcCommand)cmd); - } else if (clazz == SetStaticRouteCommand.class) { - return execute((SetStaticRouteCommand)cmd); - } else if (clazz == Site2SiteVpnCfgCommand.class) { - return execute((Site2SiteVpnCfgCommand)cmd); - } else if (clazz == CheckS2SVpnConnectionsCommand.class) { - return execute((CheckS2SVpnConnectionsCommand)cmd); } else if (cmd instanceof StorageSubSystemCommand) { - return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); + return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd); } else if (clazz == CreateVMSnapshotCommand.class) { - return execute((CreateVMSnapshotCommand)cmd); + return execute((CreateVMSnapshotCommand) cmd); } else if (clazz == DeleteVMSnapshotCommand.class) { - return execute((DeleteVMSnapshotCommand)cmd); + return execute((DeleteVMSnapshotCommand) cmd); } else if (clazz == RevertToVMSnapshotCommand.class) { - return execute((RevertToVMSnapshotCommand)cmd); + return execute((RevertToVMSnapshotCommand) cmd); } else if (clazz == NetworkRulesVmSecondaryIpCommand.class) { - return execute((NetworkRulesVmSecondaryIpCommand)cmd); + return execute((NetworkRulesVmSecondaryIpCommand) cmd); } else if (clazz == ScaleVmCommand.class) { return execute((ScaleVmCommand)cmd); } else if (clazz == PvlanSetupCommand.class) { return execute((PvlanSetupCommand)cmd); - } else if (clazz == SetMonitorServiceCommand.class) { - return execute((SetMonitorServiceCommand)cmd); } else if (clazz == PerformanceMonitorCommand.class) { return execute((PerformanceMonitorCommand)cmd); } else { @@ -610,10 +530,48 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - public String routerProxy(String script, String routerIP, String args) { + @Override + public ExecutionResult executeInVR(String routerIP, String script, String args) { Connection conn = getConnection(); - String proxyArgs = script + " " + routerIP + " " + args; - return callHostPlugin(conn, "vmops", "routerProxy", "args", proxyArgs); + String rc = callHostPlugin(conn, "vmops", "routerProxy", "args", script + " " + routerIP + " " + args); + // Fail case would be start with "fail#" + return new ExecutionResult(rc.startsWith("succ#"), rc.substring(5)); + } + + @Override + public ExecutionResult createFileInVR(String routerIp, String path, String filename, String content) { + Connection conn = getConnection(); + String rc = callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "filepath", path + filename, "filecontents", content); + // Fail case would be start with "fail#" + return new ExecutionResult(rc.startsWith("succ#"), rc.substring(5)); + } + + @Override + public ExecutionResult prepareCommand(NetworkElementCommand cmd) { + //Update IP used to access router + cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + assert cmd.getRouterAccessIp() != null; + + if (cmd instanceof IpAssocVpcCommand) { + return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return prepareNetworkElementCommand((IpAssocCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return prepareNetworkElementCommand((SetSourceNatCommand)cmd); + } else if (cmd instanceof SetNetworkACLCommand) { + return prepareNetworkElementCommand((SetNetworkACLCommand)cmd); + } + return new ExecutionResult(true, null); + } + + @Override + public ExecutionResult cleanupCommand(NetworkElementCommand cmd) { + if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand)) { + cleanupNetworkElementCommand((IpAssocCommand)cmd); + } + return new ExecutionResult(true, null); } private Answer execute(PerformanceMonitorCommand cmd) { @@ -626,11 +584,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } private String getPerfMon(Connection conn, Map params, - int wait) { + int wait) { String result = null; try { result = callHostPluginAsync(conn, "vmopspremium", "asmonitor", 60, - params); + params); if (result != null) return result; } catch (Exception e) { @@ -640,7 +598,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected String callHostPluginAsync(Connection conn, String plugin, - String cmd, int wait, Map params) { + String cmd, int wait, Map params) { int timeout = wait * 1000; Map args = new HashMap(); Task task = null; @@ -650,7 +608,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (s_logger.isTraceEnabled()) { s_logger.trace("callHostPlugin executing for command " + cmd - + " with " + getArgsString(args)); + + " with " + getArgsString(args)); } Host host = Host.getByUuid(conn, _host.uuid); task = host.callPluginAsync(conn, plugin, cmd, args); @@ -662,29 +620,29 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.trace("callHostPlugin Result: " + result); } return result.replace("", "").replace("", "") - .replace("\n", ""); + .replace("\n", ""); } catch (Types.HandleInvalid e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd - + " with args " + getArgsString(args) - + " due to HandleInvalid clazz:" + e.clazz + ", handle:" - + e.handle); + + " with args " + getArgsString(args) + + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + + e.handle); } catch (XenAPIException e) { s_logger.warn( - "callHostPlugin failed for cmd: " + cmd + " with args " - + getArgsString(args) + " due to " + e.toString(), - e); + "callHostPlugin failed for cmd: " + cmd + " with args " + + getArgsString(args) + " due to " + e.toString(), + e); } catch (XmlRpcException e) { s_logger.warn( - "callHostPlugin failed for cmd: " + cmd + " with args " - + getArgsString(args) + " due to " + e.getMessage(), - e); + "callHostPlugin failed for cmd: " + cmd + " with args " + + getArgsString(args) + " due to " + e.getMessage(), + e); } finally { if (task != null) { try { task.destroy(conn); } catch (Exception e1) { s_logger.warn("unable to destroy task(" + task.toString() - + ") on host(" + _host.uuid + ") due to ", e1); + + ") on host(" + _host.uuid + ") due to ", e1); } } } @@ -699,7 +657,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Long newDynamicMemoryMax = vmSpec.getMaxRam(); if (staticMemoryMin > newDynamicMemoryMin || newDynamicMemoryMax > staticMemoryMax) { throw new CloudRuntimeException("Cannot scale up the vm because of memory constraint violation: " + "0 <= memory-static-min(" + staticMemoryMin + - ") <= memory-dynamic-min(" + newDynamicMemoryMin + ") <= memory-dynamic-max(" + newDynamicMemoryMax + ") <= memory-static-max(" + staticMemoryMax + ")"); + ") <= memory-dynamic-min(" + newDynamicMemoryMin + ") <= memory-dynamic-max(" + newDynamicMemoryMax + ") <= memory-static-max(" + staticMemoryMax + ")"); } vm.setMemoryDynamicRange(conn, newDynamicMemoryMin, newDynamicMemoryMax); @@ -739,7 +697,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe // If DMC is not enable then don't execute this command. if (!isDmcEnabled(conn, host)) { throw new CloudRuntimeException("Unable to scale the vm: " + vmName + " as DMC - Dynamic memory control is not enabled for the XenServer:" + _host.uuid + - " ,check your license and hypervisor version."); + " ,check your license and hypervisor version."); } // stop vm which is running on this host or is in halted state @@ -749,7 +707,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe VM.Record vmr = vm.getRecord(conn); if ((vmr.powerState == VmPowerState.HALTED) || - (vmr.powerState == VmPowerState.RUNNING && !isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(_host.uuid))) { + (vmr.powerState == VmPowerState.RUNNING && !isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(_host.uuid))) { iter.remove(); } } @@ -856,11 +814,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } private String revertToSnapshot(Connection conn, VM vmSnapshot, String vmName, String oldVmUuid, Boolean snapshotMemory, String hostUUID) throws XenAPIException, - XmlRpcException { + XmlRpcException { String results = - callHostPluginAsync(conn, "vmopsSnapshot", "revert_memory_snapshot", 10 * 60 * 1000, "snapshotUUID", vmSnapshot.getUuid(conn), "vmName", vmName, "oldVmUuid", - oldVmUuid, "snapshotMemory", snapshotMemory.toString(), "hostUUID", hostUUID); + callHostPluginAsync(conn, "vmopsSnapshot", "revert_memory_snapshot", 10 * 60 * 1000, "snapshotUUID", vmSnapshot.getUuid(conn), "vmName", vmName, "oldVmUuid", + oldVmUuid, "snapshotMemory", snapshotMemory.toString(), "hostUUID", hostUUID); String errMsg = null; if (results == null || results.isEmpty()) { errMsg = "revert_memory_snapshot return null"; @@ -1040,9 +998,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (!is_xcp()) enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + key); String result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge, - "key", String.valueOf(key), - "xs_nw_uuid", nw.getUuid(conn), - "cs_host_id", ((Long)hostId).toString()); + "key", String.valueOf(key), + "xs_nw_uuid", nw.getUuid(conn), + "cs_host_id", ((Long)hostId).toString()); //Note down the fact that the ovs bridge has been setup String[] res = result.split(":"); if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) { @@ -1690,8 +1648,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String result = null; if (cmd.getType() == PvlanSetupCommand.Type.DHCP) { result = - callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-dhcp", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, - "dhcp-name", dhcpName, "dhcp-ip", dhcpIp, "dhcp-mac", dhcpMac); + callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-dhcp", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, + "dhcp-name", dhcpName, "dhcp-ip", dhcpIp, "dhcp-mac", dhcpMac); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program pvlan for dhcp server with mac " + dhcpMac); return new Answer(cmd, false, result); @@ -1700,8 +1658,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } else if (cmd.getType() == PvlanSetupCommand.Type.VM) { result = - callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, - "vm-mac", vmMac); + callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, + "vm-mac", vmMac); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program pvlan for vm with mac " + vmMac); return new Answer(cmd, false, result); @@ -1776,7 +1734,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vswitch) { HashMap args = parseDefaultOvsRuleComamnd(BroadcastDomainType.getValue(nic.getBroadcastUri())); OvsSetTagAndFlowCommand flowCmd = - new OvsSetTagAndFlowCommand(args.get("vmName"), args.get("tag"), args.get("vlans"), args.get("seqno"), Long.parseLong(args.get("vmId"))); + new OvsSetTagAndFlowCommand(args.get("vmName"), args.get("tag"), args.get("vlans"), args.get("seqno"), Long.parseLong(args.get("vmId"))); OvsSetTagAndFlowAnswer r = execute(flowCmd); if (!r.getResult()) { s_logger.warn("Failed to set flow for VM " + r.getVmId()); @@ -1795,7 +1753,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe boolean secGrpEnabled = false; for (NicTO nic : nics) { if (nic.isSecurityGroupEnabled() || - (nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString()))) { + (nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString()))) { secGrpEnabled = true; break; } @@ -1814,7 +1772,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe NicTO[] nics = vmSpec.getNics(); for (NicTO nic : nics) { if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && - nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { + nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { List nicSecIps = nic.getNicSecIps(); String secIpsStr; StringBuilder sb = new StringBuilder(); @@ -1827,8 +1785,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe secIpsStr = "0:"; } result = - callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), "vmID", - Long.toString(vmSpec.getId()), "secIps", secIpsStr); + callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), "vmID", + Long.toString(vmSpec.getId()), "secIps", secIpsStr); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program default network rules for " + vmName + " on nic with ip:" + nic.getIp() + " mac:" + nic.getMac()); @@ -1959,48 +1917,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new Answer(cmd); } - private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) { - String args = ""; - for (String ip : cmd.getVpnIps()) { - args += ip + " "; - } - String result = routerProxy("checkbatchs2svpn.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed"); - } - return new CheckS2SVpnConnectionsAnswer(cmd, true, result); - } - - private CheckRouterAnswer execute(CheckRouterCommand cmd) { - String result = routerProxy("checkrouter.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), null); - if (result == null || result.isEmpty()) { - return new CheckRouterAnswer(cmd, "CheckRouterCommand failed"); - } - return new CheckRouterAnswer(cmd, result, true); - } - - private GetDomRVersionAnswer execute(GetDomRVersionCmd cmd) { - String result = routerProxy("get_template_version.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), null); - if (result == null || result.isEmpty()) { - return new GetDomRVersionAnswer(cmd, "getDomRVersionCmd failed"); - } - String[] lines = result.split("&"); - if (lines.length != 2) { - return new GetDomRVersionAnswer(cmd, result); - } - return new GetDomRVersionAnswer(cmd, result, lines[0], lines[1]); - } - - private Answer execute(BumpUpPriorityCommand cmd) { - Connection conn = getConnection(); - String args = "bumpup_priority.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "BumpUpPriorityCommand failed"); - } - return new Answer(cmd, true, result); - } - protected MaintainAnswer execute(MaintainCommand cmd) { Connection conn = getConnection(); try { @@ -2026,518 +1942,87 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesCommand cmd) { - Connection conn = getConnection(); - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String[] results = new String[cmd.getRules().length]; - int i = 0; - - boolean endResult = true; - for (PortForwardingRuleTO rule : cmd.getRules()) { - StringBuilder args = new StringBuilder(); - args.append(rule.revoked() ? " -D " : " -A "); - args.append(" -P ").append(rule.getProtocol().toLowerCase()); - args.append(" -l ").append(rule.getSrcIp()); - args.append(" -p ").append(rule.getStringSrcPortRange()); - args.append(" -r ").append(rule.getDstIp()); - args.append(" -d ").append(rule.getStringDstPortRange()); - - String result = routerProxy("firewall_nat.sh", routerIp, args.toString()); - - if (result == null || result.isEmpty()) { - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } - - return new SetPortForwardingRulesAnswer(cmd, results, endResult); - } - - protected SetStaticNatRulesAnswer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { - //String args = routerIp; - String[] results = new String[cmd.getRules().length]; - int i = 0; - boolean endResult = true; - for (StaticNatRuleTO rule : cmd.getRules()) { - String args = rule.revoked() ? "-D" : "-A"; - args += " -l " + rule.getSrcIp(); - args += " -r " + rule.getDstIp(); - String result = routerProxy("vpc_staticnat.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - - if (result == null || result.isEmpty()) { - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - protected SetStaticNatRulesAnswer execute(SetStaticNatRulesCommand cmd) { - if (cmd.getVpcId() != null) { - return SetVPCStaticNatRules(cmd); - } - Connection conn = getConnection(); - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String[] results = new String[cmd.getRules().length]; - int i = 0; - boolean endResult = true; - for (StaticNatRuleTO rule : cmd.getRules()) { - //1:1 NAT needs instanceip;publicip;domrip;op - StringBuilder args = new StringBuilder(); - args.append(rule.revoked() ? " -D " : " -A "); - args.append(" -l ").append(rule.getSrcIp()); - args.append(" -r ").append(rule.getDstIp()); - - if (rule.getProtocol() != null) { - args.append(" -P ").append(rule.getProtocol().toLowerCase()); - } - - args.append(" -d ").append(rule.getStringSrcPortRange()); - args.append(" -G "); - - String result = routerProxy("firewall_nat.sh", routerIp, args.toString()); - - if (result == null || result.isEmpty()) { - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } - - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - protected Answer execute(final CreateIpAliasCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List ipAliasTOs = cmd.getIpAliasList(); - String args = ""; - for (IpAliasTO ipaliasto : ipAliasTOs) { - args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; - } - String result = routerProxy("createipAlias.sh", routerIp, args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "CreateIPAliasCommand failed\n"); - } - - return new Answer(cmd); - } - - protected Answer execute(final DeleteIpAliasCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List revokedIpAliasTOs = cmd.getDeleteIpAliasTos(); - String args = ""; - for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { - args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; - } - //this is to ensure that thre is some argument passed to the deleteipAlias script when there are no revoked rules. - args = args + "- "; - List activeIpAliasTOs = cmd.getCreateIpAliasTos(); - for (IpAliasTO ipAliasTO : activeIpAliasTOs) { - args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; - } - String result = routerProxy("deleteipAlias", routerIp, args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "DeleteipAliasCommand failed\n"); - } - - return new Answer(cmd); - } - - protected Answer execute(final DnsMasqConfigCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List dhcpTos = cmd.getIps(); - String args = ""; - for (DhcpTO dhcpTo : dhcpTos) { - args = args + dhcpTo.getRouterIp() + ":" + dhcpTo.getGateway() + ":" + dhcpTo.getNetmask() + ":" + dhcpTo.getStartIpOfSubnet() + "-"; - } - - String result = routerProxy("dnsmasq.sh", routerIp, args); - - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "DnsMasqconfigCommand failed"); - } - - return new Answer(cmd); - - } - - protected String createFileInVR(String routerIp, String path, String content) { - Connection conn = getConnection(); - return callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "filepath", path, "filecontents", content); - } - - protected Answer execute(final LoadBalancerConfigCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - - if (routerIp == null) { - return new Answer(cmd); - } - - LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); - String[] config = cfgtr.generateConfiguration(cmd); - String tmpCfgFileContents = ""; - for (int i = 0; i < config.length; i++) { - tmpCfgFileContents += config[i]; - tmpCfgFileContents += "\n"; - } - String tmpCfgFilePath = "/etc/haproxy/haproxy.cfg.new"; - String result = createFileInVR(routerIp, tmpCfgFilePath, tmpCfgFileContents); - - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed to create HA proxy cfg file."); - } - - String[][] rules = cfgtr.generateFwRules(cmd); - - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; - - String ip = cmd.getNic().getIp(); - String args = " -i " + ip; - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - - args += " -a " + sb.toString(); - } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - - args += " -d " + sb.toString(); - } - - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); - } - - if (cmd.getVpcId() == null) { - args = " -i " + routerIp + args; - result = routerProxy("loadbalancer.sh", routerIp, args); - } else { - args = " -i " + cmd.getNic().getIp() + args; - result = routerProxy("vpc_loadbalancer.sh", routerIp, args); - } - - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed"); - } - return new Answer(cmd); - } - - protected synchronized Answer execute(final DhcpEntryCommand cmd) { - String args = " -m " + cmd.getVmMac(); - if (cmd.getVmIpAddress() != null) { - args += " -4 " + cmd.getVmIpAddress(); - } - args += " -h " + cmd.getVmName(); - - if (cmd.getDefaultRouter() != null) { - args += " -d " + cmd.getDefaultRouter(); - } - - if (cmd.getDefaultDns() != null) { - args += " -n " + cmd.getDefaultDns(); - } - - if (cmd.getStaticRoutes() != null) { - args += " -s " + cmd.getStaticRoutes(); - } - - if (cmd.getVmIp6Address() != null) { - args += " -6 " + cmd.getVmIp6Address(); - args += " -u " + cmd.getDuid(); - } - - if (!cmd.isDefault()) { - args += " -N"; - } - - String result = routerProxy("edithosts.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "DhcpEntry failed"); - } - return new Answer(cmd); - } - - protected synchronized Answer execute(final RemoteAccessVpnCfgCommand cmd) { - String args = ""; - if (cmd.isCreate()) { - args += " -r " + cmd.getIpRange(); - args += " -p " + cmd.getPresharedKey(); - args += " -s " + cmd.getVpnServerIp(); - args += " -l " + cmd.getLocalIp(); - args += " -c "; - } else { - args += " -d "; - args += " -s " + cmd.getVpnServerIp(); - } - args += " -C " + cmd.getLocalCidr(); - args += " -i " + cmd.getPublicInterface(); - String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "Configure VPN failed"); - } - return new Answer(cmd); - } - - protected synchronized Answer execute(final VpnUsersCfgCommand cmd) { - for (VpnUsersCfgCommand.UsernamePassword userpwd: cmd.getUserpwds()) { - String args = ""; - if (!userpwd.isAdd()) { - args += " -U " + userpwd.getUsername(); - } else { - args += " -u " + userpwd.getUsernamePassword(); - } - String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername()); - } - } - - return new Answer(cmd); - } - - protected Answer execute(final VmDataCommand cmd) { - Map> data = new HashMap>(); - data.put(cmd.getVmIpAddress(), cmd.getVmData()); - String json = new Gson().toJson(data); - json = Base64.encodeBase64String(json.getBytes()); - - String args = "-d " + json; - - String result = routerProxy("vmdata.py", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "vm_data failed"); - } else { - return new Answer(cmd); - } - - } - - protected Answer execute(final SavePasswordCommand cmd) { - final String password = cmd.getPassword(); - final String vmIpAddress = cmd.getVmIpAddress(); - - String args = " -v " + vmIpAddress; - args += " -p " + password; - String result = routerProxy("savepassword.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "savePassword failed"); - } - return new Answer(cmd); - } - - protected void assignPublicIpAddress(Connection conn, String vmName, String privateIpAddress, String publicIpAddress, boolean add, boolean firstIP, - boolean sourceNat, String vlanId, String vlanGateway, String vlanNetmask, String vifMacAddress, Integer networkRate, TrafficType trafficType, String name) - throws InternalErrorException { - - try { - VM router = getVM(conn, vmName); - - NicTO nic = new NicTO(); - nic.setMac(vifMacAddress); - nic.setType(trafficType); - if (vlanId == null) { - nic.setBroadcastType(BroadcastDomainType.Native); - } else { - URI uri = BroadcastDomainType.fromString(vlanId); - nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); - nic.setBroadcastUri(uri); - } - nic.setDeviceId(0); - nic.setNetworkRateMbps(networkRate); - nic.setName(name); - - Network network = getNetwork(conn, nic); - - // Determine the correct VIF on DomR to associate/disassociate the - // IP address with - VIF correctVif = getCorrectVif(conn, router, network); - - // If we are associating an IP address and DomR doesn't have a VIF - // for the specified vlan ID, we need to add a VIF - // If we are disassociating the last IP address in the VLAN, we need - // to remove a VIF - boolean addVif = false; - boolean removeVif = false; - if (add && correctVif == null) { - addVif = true; - } - - if (addVif) { - // Add a new VIF to DomR - String vifDeviceNum = getLowestAvailableVIFDeviceNum(conn, router); - - if (vifDeviceNum == null) { - throw new InternalErrorException("There were no more available slots for a new VIF on router: " + router.getNameLabel(conn)); - } - - nic.setDeviceId(Integer.parseInt(vifDeviceNum)); - - correctVif = createVif(conn, vmName, router, null, nic); - correctVif.plug(conn); - // Add iptables rule for network usage - networkUsage(conn, privateIpAddress, "addVif", "eth" + correctVif.getDevice(conn)); - } - - if (correctVif == null) { - throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); - } - - String args = ""; - - if (add) { - args += " -A "; - } else { - args += " -D "; - } - - if (sourceNat) { - args += " -s"; - } - if (firstIP) { - args += " -f"; - } - - String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask)); - args += " -l "; - args += publicIpAddress + "/" + cidrSize; - - args += " -c "; - args += "eth" + correctVif.getDevice(conn); - - args += " -g "; - args += vlanGateway; - - if (addVif) { - //To indicate this is new interface created - args += " -n"; - } - - String result = routerProxy("ipassoc.sh", privateIpAddress, args); - - if (result == null || result.isEmpty()) { - throw new InternalErrorException("Xen plugin \"ipassoc\" failed."); - } - - if (removeVif) { - network = correctVif.getNetwork(conn); - - // Mark this vif to be removed from network usage - networkUsage(conn, privateIpAddress, "deleteVif", "eth" + correctVif.getDevice(conn)); - - // Remove the VIF from DomR - correctVif.unplug(conn); - correctVif.destroy(conn); - - // Disable the VLAN network if necessary - disableVlanNetwork(conn, network); - } - - } catch (XenAPIException e) { - String msg = "Unable to assign public IP address due to " + e.toString(); - s_logger.warn(msg, e); - throw new InternalErrorException(msg); - } catch (final XmlRpcException e) { - String msg = "Unable to assign public IP address due to " + e.getMessage(); - s_logger.warn(msg, e); - throw new InternalErrorException(msg); - } - } - - protected void assignVPCPublicIpAddress(Connection conn, String vmName, String routerIp, IpAddressTO ip) throws Exception { - - try { - VM router = getVM(conn, vmName); - - VIF correctVif = getVifByMac(conn, router, ip.getVifMacAddress()); - if (correctVif == null) { - if (ip.isAdd()) { - throw new InternalErrorException("Failed to find DomR VIF to associate IP with."); - } else { - s_logger.debug("VIF to deassociate IP with does not exist, return success"); - return; - } - } - - String args = ""; - String snatArgs = ""; - - if (ip.isAdd()) { - args += " -A "; - snatArgs += " -A "; - } else { - args += " -D "; - snatArgs += " -D "; - } - - args += " -l "; - args += ip.getPublicIp(); - - args += " -c "; - args += "eth" + correctVif.getDevice(conn); - - args += " -g "; - args += ip.getVlanGateway(); - - args += " -m "; - args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); - - args += " -n "; - args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); - - String result = routerProxy("vpc_ipassoc.sh", routerIp, args); - if (result == null || result.isEmpty()) { - throw new InternalErrorException("Xen plugin \"vpc_ipassoc\" failed."); - } - - if (ip.isSourceNat()) { - snatArgs += " -l " + ip.getPublicIp(); - snatArgs += " -c " + "eth" + correctVif.getDevice(conn); - - result = routerProxy("vpc_privateGateway.sh", routerIp, snatArgs); - if (result == null || result.isEmpty()) { - throw new InternalErrorException("Xen plugin \"vpc_privateGateway\" failed."); - } - } - - } catch (Exception e) { - String msg = "Unable to assign public IP address due to " + e.toString(); - s_logger.warn(msg, e); - throw new Exception(msg); - } - } - protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) { - if (option.equals("get")) { return "0:0"; } return null; } - protected Answer execute(IpAssocCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) { + Connection conn = getConnection(); + int i = 0; + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + + try { + IpAddressTO[] ips = cmd.getIpAddresses(); + for (IpAddressTO ip : ips) { + + VM router = getVM(conn, routerName); + + NicTO nic = new NicTO(); + nic.setMac(ip.getVifMacAddress()); + nic.setType(ip.getTrafficType()); + if (ip.getBroadcastUri()== null) { + nic.setBroadcastType(BroadcastDomainType.Native); + } else { + URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); + nic.setBroadcastUri(uri); + } + nic.setDeviceId(0); + nic.setNetworkRateMbps(ip.getNetworkRate()); + nic.setName(ip.getNetworkName()); + + Network network = getNetwork(conn, nic); + + // Determine the correct VIF on DomR to associate/disassociate the + // IP address with + VIF correctVif = getCorrectVif(conn, router, network); + + // If we are associating an IP address and DomR doesn't have a VIF + // for the specified vlan ID, we need to add a VIF + // If we are disassociating the last IP address in the VLAN, we need + // to remove a VIF + boolean addVif = false; + if (ip.isAdd() && correctVif == null) { + addVif = true; + } + + if (addVif) { + // Add a new VIF to DomR + String vifDeviceNum = getLowestAvailableVIFDeviceNum(conn, router); + + if (vifDeviceNum == null) { + throw new InternalErrorException("There were no more available slots for a new VIF on router: " + router.getNameLabel(conn)); + } + + nic.setDeviceId(Integer.valueOf(vifDeviceNum)); + + correctVif = createVif(conn, routerName, router, null, nic); + correctVif.plug(conn); + // Add iptables rule for network usage + networkUsage(conn, routerIp, "addVif", "eth" + correctVif.getDevice(conn)); + } + + if (correctVif == null) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } + + ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); + ip.setNewNic(addVif); + } + } catch (InternalErrorException e) { + s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); + return new ExecutionResult(false, e.getMessage()); + } catch (Exception e) { + return new ExecutionResult(false, e.getMessage()); + } + return new ExecutionResult(true, null); + } + + protected ExecutionResult cleanupNetworkElementCommand(IpAssocCommand cmd) { Connection conn = getConnection(); String[] results = new String[cmd.getIpAddresses().length]; int i = 0; @@ -2547,16 +2032,57 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe IpAddressTO[] ips = cmd.getIpAddresses(); for (IpAddressTO ip : ips) { - assignPublicIpAddress(conn, routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), - ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress(), ip.getNetworkRate(), ip.getTrafficType(), ip.getNetworkName()); - results[i++] = ip.getPublicIp() + " - success"; + VM router = getVM(conn, routerName); + + NicTO nic = new NicTO(); + nic.setMac(ip.getVifMacAddress()); + nic.setType(ip.getTrafficType()); + if (ip.getBroadcastUri()== null) { + nic.setBroadcastType(BroadcastDomainType.Native); + } else { + URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); + nic.setBroadcastUri(uri); + } + nic.setDeviceId(0); + nic.setNetworkRateMbps(ip.getNetworkRate()); + nic.setName(ip.getNetworkName()); + + Network network = getNetwork(conn, nic); + + // Determine the correct VIF on DomR to associate/disassociate the + // IP address with + VIF correctVif = getCorrectVif(conn, router, network); + + // If we are disassociating the last IP address in the VLAN, we need + // to remove a VIF + boolean removeVif = false; + + if (correctVif == null) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } + + if (removeVif) { + network = correctVif.getNetwork(conn); + + // Mark this vif to be removed from network usage + networkUsage(conn, routerIp, "deleteVif", "eth" + correctVif.getDevice(conn)); + + // Remove the VIF from DomR + correctVif.unplug(conn); + correctVif.destroy(conn); + + // Disable the VLAN network if necessary + disableVlanNetwork(conn, network); + } } } catch (InternalErrorException e) { s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; + return new ExecutionResult(false, e.getMessage()); + } catch (Exception e) { + return new ExecutionResult(false, e.getMessage()); } - - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } protected GetVncPortAnswer execute(GetVncPortCommand cmd) { @@ -2941,7 +2467,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String startTime = String.valueOf(currentDate.getTime() / 1000 - 1000); return callHostPlugin(conn, "vmops", "gethostvmstats", "collectHostStats", String.valueOf("true"), "consolidationFunction", _consolidationFunction, "interval", - String.valueOf(_pollingIntervalInSeconds), "startTime", startTime); + String.valueOf(_pollingIntervalInSeconds), "startTime", startTime); } protected String getVmStatsRawXML(Connection conn) { @@ -2949,7 +2475,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String startTime = String.valueOf(currentDate.getTime() / 1000 - 1000); return callHostPlugin(conn, "vmops", "gethostvmstats", "collectHostStats", String.valueOf("false"), "consolidationFunction", _consolidationFunction, "interval", - String.valueOf(_pollingIntervalInSeconds), "startTime", startTime); + String.valueOf(_pollingIntervalInSeconds), "startTime", startTime); } protected State convertToState(Types.VmPowerState ps) { @@ -3163,8 +2689,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String createTemplateFromSnapshot(Connection conn, String templatePath, String snapshotPath, int wait) { String tmpltLocalDir = UUID.randomUUID().toString(); String results = - callHostPluginAsync(conn, "vmopspremium", "create_privatetemplate_from_snapshot", wait, "templatePath", templatePath, "snapshotPath", snapshotPath, - "tmpltLocalDir", tmpltLocalDir); + callHostPluginAsync(conn, "vmopspremium", "create_privatetemplate_from_snapshot", wait, "templatePath", templatePath, "snapshotPath", snapshotPath, + "tmpltLocalDir", tmpltLocalDir); String errMsg = null; if (results == null || results.isEmpty()) { errMsg = "create_privatetemplate_from_snapshot return null"; @@ -3215,7 +2741,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String copy_vhd_from_secondarystorage(Connection conn, String mountpoint, String sruuid, int wait) { String nameLabel = "cloud-" + UUID.randomUUID().toString(); String results = - callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", wait, "mountpoint", mountpoint, "sruuid", sruuid, "namelabel", nameLabel); + callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", wait, "mountpoint", mountpoint, "sruuid", sruuid, "namelabel", nameLabel); String errMsg = null; if (results == null || results.isEmpty()) { errMsg = "copy_vhd_from_secondarystorage return null"; @@ -3400,7 +2926,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Set vbds = vm.getVBDs(conn); for (VBD vbd : vbds) { VBD.Record vbdRec = vbd.getRecord(conn); - if (vbdRec.type.equals(Types.VbdType.CD.toString()) && !vbdRec.empty) { + if (vbdRec.type.equals(Types.VbdType.CD) && !vbdRec.empty) { vbd.eject(conn); break; } @@ -3668,7 +3194,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe long beginTime = System.currentTimeMillis(); if (s_logger.isTraceEnabled()) { s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout + - "ms timeout"); + "ms timeout"); } while (task.getStatus(c) == Types.TaskStatusType.PENDING) { try { @@ -3911,7 +3437,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return result.replace("", "").replace("", "").replace("\n", ""); } catch (Types.HandleInvalid e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + - e.handle); + e.handle); } catch (XenAPIException e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e); } catch (XmlRpcException e) { @@ -4194,7 +3720,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (rec.management) { if (rec.VLAN != null && rec.VLAN != -1) { String msg = - new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) + new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) .append("; pif=") .append(rec.uuid) .append("; vlan=") @@ -4219,7 +3745,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Bond bond = mgmtPifRec.bondSlaveOf; if (!isRefNull(bond)) { String msg = - "Management interface is on slave(" + mgmtPifRec.uuid + ") of bond(" + bond.getUuid(conn) + ") on host(" + _host.uuid + + "Management interface is on slave(" + mgmtPifRec.uuid + ") of bond(" + bond.getUuid(conn) + ") on host(" + _host.uuid + "), please move management interface to bond!"; s_logger.warn(msg); throw new CloudRuntimeException(msg); @@ -4986,6 +4512,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (_securityGroupEnabled) { _canBridgeFirewall = can_bridge_firewall(conn); + if (!_canBridgeFirewall) { + String msg = "Failed to configure brige firewall"; + s_logger.warn(msg); + s_logger.warn("Check host " + _host.ip +" for CSP is installed or not and check network mode for bridge"); + return new SetupAnswer(cmd, msg); + } + } String result = callHostPluginPremium(conn, "heartbeat", "host", _host.uuid, "interval", Integer.toString(_heartbeatInterval)); @@ -5019,7 +4552,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (rec.management) { if (rec.VLAN != null && rec.VLAN != -1) { String msg = - new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) + new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) .append("; pif=") .append(rec.uuid) .append("; vlan=") @@ -5053,7 +4586,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (pr.VLAN != null && pr.VLAN != -1) { String msg = - new StringBuilder("Unsupported configuration. Network cloud-private is on a VLAN. Network=").append(network.uuid) + new StringBuilder("Unsupported configuration. Network cloud-private is on a VLAN. Network=").append(network.uuid) .append(" ; pif=") .append(pr.uuid) .toString(); @@ -5063,7 +4596,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (!pr.management && pr.bondMasterOf != null && pr.bondMasterOf.size() > 0) { if (pr.bondMasterOf.size() > 1) { String msg = - new StringBuilder("Unsupported configuration. Network cloud-private has more than one bond. Network=").append(network.uuid) + new StringBuilder("Unsupported configuration. Network cloud-private has more than one bond. Network=").append(network.uuid) .append("; pif=") .append(pr.uuid) .toString(); @@ -5077,8 +4610,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (spr.management) { if (!transferManagementNetwork(conn, host, slave, spr, pif)) { String msg = - new StringBuilder("Unable to transfer management network. slave=" + spr.uuid + "; master=" + pr.uuid + "; host=" + - _host.uuid).toString(); + new StringBuilder("Unable to transfer management network. slave=" + spr.uuid + "; master=" + pr.uuid + "; host=" + + _host.uuid).toString(); s_logger.warn(msg); return new SetupAnswer(cmd, msg); } @@ -5236,22 +4769,22 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe for (PhysicalNetworkSetupInfo info : infoList) { if (!isNetworkSetupByName(info.getGuestNetworkName())) { msg = - "For Physical Network id:" + info.getPhysicalNetworkId() + ", Guest Network is not configured on the backend by name " + - info.getGuestNetworkName(); + "For Physical Network id:" + info.getPhysicalNetworkId() + ", Guest Network is not configured on the backend by name " + + info.getGuestNetworkName(); errorout = true; break; } if (!isNetworkSetupByName(info.getPrivateNetworkName())) { msg = - "For Physical Network id:" + info.getPhysicalNetworkId() + ", Private Network is not configured on the backend by name " + - info.getPrivateNetworkName(); + "For Physical Network id:" + info.getPhysicalNetworkId() + ", Private Network is not configured on the backend by name " + + info.getPrivateNetworkName(); errorout = true; break; } if (!isNetworkSetupByName(info.getPublicNetworkName())) { msg = - "For Physical Network id:" + info.getPhysicalNetworkId() + ", Public Network is not configured on the backend by name " + - info.getPublicNetworkName(); + "For Physical Network id:" + info.getPhysicalNetworkId() + ", Public Network is not configured on the backend by name " + + info.getPublicNetworkName(); errorout = true; break; } @@ -5420,8 +4953,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new Answer(cmd, true, "success"); } catch (Exception e) { String msg = - "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" + _host.uuid + " pool: " + - pool.getHost() + pool.getPath(); + "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" + _host.uuid + " pool: " + + pool.getHost() + pool.getPath(); s_logger.warn(msg, e); return new Answer(cmd, false, msg); } @@ -5451,7 +4984,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return result.replace("\n", ""); } catch (Types.HandleInvalid e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + - e.handle); + e.handle); } catch (XenAPIException e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e); } catch (XmlRpcException e) { @@ -5610,8 +5143,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getFrom(), cmd.getKey()); bridge = nw.getBridge(conn); String result = - callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(), "key", cmd.getKey().toString(), "from", - cmd.getFrom().toString(), "to", cmd.getTo().toString()); + callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(), "key", cmd.getKey().toString(), "from", + cmd.getFrom().toString(), "to", cmd.getTo().toString()); String[] res = result.split(":"); if (res.length == 2 && res[0].equalsIgnoreCase("SUCCESS")) { return new OvsCreateTunnelAnswer(cmd, true, result, res[1], bridge); @@ -5684,8 +5217,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe * plugin side */ String result = - callHostPlugin(conn, "ovsgre", "ovs_set_tag_and_flow", "bridge", bridge, "vmName", cmd.getVmName(), "tag", cmd.getTag(), "vlans", cmd.getVlans(), - "seqno", cmd.getSeqNo()); + callHostPlugin(conn, "ovsgre", "ovs_set_tag_and_flow", "bridge", bridge, "vmName", cmd.getVmName(), "tag", cmd.getTag(), "vlans", cmd.getVlans(), + "seqno", cmd.getSeqNo()); s_logger.debug("set flow for " + cmd.getVmName() + " " + result); if (result.equalsIgnoreCase("SUCCESS")) { @@ -5742,8 +5275,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe bridge = nw.getBridge(conn); String result = - callHostPlugin(conn, "ovsgre", "ovs_create_gre", "bridge", bridge, "remoteIP", cmd.getRemoteIp(), "greKey", cmd.getKey(), "from", - Long.toString(cmd.getFrom()), "to", Long.toString(cmd.getTo())); + callHostPlugin(conn, "ovsgre", "ovs_create_gre", "bridge", bridge, "remoteIP", cmd.getRemoteIp(), "greKey", cmd.getKey(), "from", + Long.toString(cmd.getFrom()), "to", Long.toString(cmd.getTo())); String[] res = result.split(":"); if (res.length != 2 || (res.length == 2 && res[1].equalsIgnoreCase("[]"))) { return new OvsCreateGreTunnelAnswer(cmd, false, result, _host.ip, bridge); @@ -5770,20 +5303,20 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (!_canBridgeFirewall) { s_logger.warn("Host " + _host.ip + " cannot do bridge firewalling"); return new SecurityGroupRuleAnswer(cmd, false, "Host " + _host.ip + " cannot do bridge firewalling", - SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); + SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); } String result = - callHostPlugin(conn, "vmops", "network_rules", "vmName", cmd.getVmName(), "vmIP", cmd.getGuestIp(), "vmMAC", cmd.getGuestMac(), "vmID", - Long.toString(cmd.getVmId()), "signature", cmd.getSignature(), "seqno", Long.toString(cmd.getSeqNum()), "deflated", "true", "rules", - cmd.compressStringifiedRules(), "secIps", cmd.getSecIpsString()); + callHostPlugin(conn, "vmops", "network_rules", "vmName", cmd.getVmName(), "vmIP", cmd.getGuestIp(), "vmMAC", cmd.getGuestMac(), "vmID", + Long.toString(cmd.getVmId()), "signature", cmd.getSignature(), "seqno", Long.toString(cmd.getSeqNum()), "deflated", "true", "rules", + cmd.compressStringifiedRules(), "secIps", cmd.getSecIpsString()); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program network rules for vm " + cmd.getVmName()); return new SecurityGroupRuleAnswer(cmd, false, "programming network rules failed"); } else { s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", ingress numrules=" + cmd.getIngressRuleSet().length + - ", egress numrules=" + cmd.getEgressRuleSet().length); + ", egress numrules=" + cmd.getEgressRuleSet().length); return new SecurityGroupRuleAnswer(cmd); } } @@ -5999,8 +5532,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe CheckXenHostInfo(); storageHandler = getStorageHandler(); - return true; + _vrResource = new VirtualRoutingResource(this); + if (!_vrResource.configure(name, params)) { + throw new ConfigurationException("Unable to configure VirtualRoutingResource"); + } + return true; } protected StorageSubsystemCommandHandler getStorageHandler() { @@ -6066,7 +5603,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.debug("Succesfully created VDI for " + cmd + ". Uuid = " + vdir.uuid); VolumeTO vol = - new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), vdir.nameLabel, pool.getPath(), vdir.uuid, vdir.virtualSize, null); + new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), vdir.nameLabel, pool.getPath(), vdir.uuid, vdir.virtualSize, null); return new CreateAnswer(cmd, vol); } catch (Exception e) { s_logger.warn("Unable to create volume; Pool=" + pool + "; Disk: " + dskch, e); @@ -6136,8 +5673,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Host host = Host.getByUuid(conn, _host.uuid); SR sr = - SR.create(conn, host, deviceConfig, new Long(0), name, uri.getHost() + uri.getPath(), SRType.NFS.toString(), "user", shared, - new HashMap()); + SR.create(conn, host, deviceConfig, new Long(0), name, uri.getHost() + uri.getPath(), SRType.NFS.toString(), "user", shared, + new HashMap()); if (!checkSR(conn, sr)) { throw new Exception("no attached PBD"); } @@ -6226,7 +5763,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected SR getIscsiSR(Connection conn, String srNameLabel, String target, String path, String chapInitiatorUsername, String chapInitiatorPassword, - boolean ignoreIntroduceException) { + boolean ignoreIntroduceException) { synchronized (srNameLabel.intern()) { Map deviceConfig = new HashMap(); try { @@ -6269,7 +5806,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (target.equals(dc.get("target")) && targetiqn.equals(dc.get("targetIQN")) && lunid.equals(dc.get("lunid"))) { throw new CloudRuntimeException("There is a SR using the same configuration target:" + dc.get("target") + ", targetIQN:" + dc.get("targetIQN") + - ", lunid:" + dc.get("lunid") + " for pool " + srNameLabel + "on host:" + _host.uuid); + ", lunid:" + dc.get("lunid") + " for pool " + srNameLabel + "on host:" + _host.uuid); } } deviceConfig.put("target", target); @@ -6400,7 +5937,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (server.equals(dc.get("server")) && serverpath.equals(dc.get("serverpath"))) { throw new CloudRuntimeException("There is a SR using the same configuration server:" + dc.get("server") + ", serverpath:" + dc.get("serverpath") + - " for pool " + pool.getUuid() + "on host:" + _host.uuid); + " for pool " + pool.getUuid() + "on host:" + _host.uuid); } } @@ -6408,8 +5945,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe deviceConfig.put("serverpath", serverpath); Host host = Host.getByUuid(conn, _host.uuid); SR sr = - SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), Long.toString(pool.getId()), SRType.NFS.toString(), "user", true, - new HashMap()); + SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), Long.toString(pool.getId()), SRType.NFS.toString(), "user", true, + new HashMap()); sr.scan(conn); return sr; } catch (XenAPIException e) { @@ -6527,7 +6064,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (cmd.getAttach() && cmd.isManaged()) { SR sr = - getIscsiSR(conn, cmd.get_iScsiName(), cmd.getStorageHost(), cmd.get_iScsiName(), cmd.getChapInitiatorUsername(), cmd.getChapInitiatorPassword(), true); + getIscsiSR(conn, cmd.get_iScsiName(), cmd.getStorageHost(), cmd.get_iScsiName(), cmd.getChapInitiatorUsername(), cmd.getChapInitiatorPassword(), true); vdi = getVDIbyUuid(conn, cmd.getVolumePath(), false); @@ -6555,7 +6092,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (isHVM && !pvDrvInstalled) { s_logger.warn(errorMsg + ": You attempted an operation on a VM which requires PV drivers to be installed but the drivers were not detected"); return new AttachVolumeAnswer(cmd, - "You attempted an operation that requires PV drivers to be installed on the VM. Please install them by inserting xen-pv-drv.iso."); + "You attempted an operation that requires PV drivers to be installed on the VM. Please install them by inserting xen-pv-drv.iso."); } if (attach) { // Figure out the disk number to attach the VM to @@ -6802,11 +6339,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } private VM createWorkingVM(Connection conn, String vmName, String guestOSType, List listVolumeTo) throws BadServerResponse, Types.VmBadPowerState, Types.SrFull, - Types.OperationNotAllowed, XenAPIException, XmlRpcException { + Types.OperationNotAllowed, XenAPIException, XmlRpcException { String guestOsTypeName = getGuestOsType(guestOSType, false); if (guestOsTypeName == null) { String msg = - " Hypervisor " + this.getClass().getName() + " doesn't support guest OS type " + guestOSType + ". you can choose 'Other install media' to run it as HVM"; + " Hypervisor " + this.getClass().getName() + " doesn't support guest OS type " + guestOSType + ". you can choose 'Other install media' to run it as HVM"; s_logger.warn(msg); throw new CloudRuntimeException(msg); } @@ -7197,7 +6734,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected boolean postCreatePrivateTemplate(Connection conn, String templatePath, String tmpltFilename, String templateName, String templateDescription, - String checksum, long size, long virtualSize, long templateId) { + String checksum, long size, long virtualSize, long templateId) { if (templateDescription == null) { templateDescription = ""; @@ -7208,9 +6745,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } String result = - callHostPlugin(conn, "vmopsSnapshot", "post_create_private_template", "templatePath", templatePath, "templateFilename", tmpltFilename, "templateName", - templateName, "templateDescription", templateDescription, "checksum", checksum, "size", String.valueOf(size), "virtualSize", String.valueOf(virtualSize), - "templateId", String.valueOf(templateId)); + callHostPlugin(conn, "vmopsSnapshot", "post_create_private_template", "templatePath", templatePath, "templateFilename", tmpltFilename, "templateName", + templateName, "templateDescription", templateDescription, "checksum", checksum, "size", String.valueOf(size), "virtualSize", String.valueOf(virtualSize), + "templateId", String.valueOf(templateId)); boolean success = false; if (result != null && !result.isEmpty()) { @@ -7229,8 +6766,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected String getVhdParent(Connection conn, String primaryStorageSRUuid, String snapshotUuid, Boolean isISCSI) { String parentUuid = - callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", - isISCSI.toString()); + callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", + isISCSI.toString()); if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) { s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid); @@ -7244,8 +6781,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe // If anybody modifies the formatting below again, I'll skin them String result = - callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "dcId", dcId.toString(), "accountId", accountId.toString(), - "volumeId", volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath); + callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "dcId", dcId.toString(), "accountId", accountId.toString(), + "volumeId", volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath); return result; } @@ -7461,8 +6998,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Connection conn = getConnection(); String result = - callHostPlugin(conn, "vmops", "network_rules_vmSecondaryIp", "vmName", cmd.getVmName(), "vmMac", cmd.getVmMac(), "vmSecIp", cmd.getVmSecIp(), "action", - cmd.getAction()); + callHostPlugin(conn, "vmops", "network_rules_vmSecondaryIp", "vmName", cmd.getVmName(), "vmMac", cmd.getVmMac(), "vmSecIp", cmd.getVmSecIp(), "action", + cmd.getAction()); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { success = false; } @@ -7470,76 +7007,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new Answer(cmd, success, ""); } - private Answer execute(SetMonitorServiceCommand cmd) { - boolean success = true; - - String config = cmd.getConfiguration(); - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - if (routerIp == null) { - return new Answer(cmd); - } - - String args = " -c " + config; - - String result = routerProxy("monitor_service.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "SetMonitorServiceCommand failed to create cfg file."); - } - - return new Answer(cmd, success, ""); - - } - - protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) { - String[] results = new String[cmd.getRules().length]; - String callResult; - Connection conn = getConnection(); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); - FirewallRuleTO[] allrules = cmd.getRules(); - FirewallRule.TrafficType trafficType = allrules[0].getTrafficType(); - if (routerIp == null) { - return new SetFirewallRulesAnswer(cmd, false, results); - } - - String[][] rules = cmd.generateFwRules(); - String args = " -F"; - if (trafficType == FirewallRule.TrafficType.Egress) { - args += " -E"; - if (egressDefault.equals("true")) { - args += " -P 1"; - } else if (egressDefault.equals("System")) { - args += " -P 2"; - } else { - args += " -P 0"; - } - } - StringBuilder sb = new StringBuilder(); - String[] fwRules = rules[0]; - if (fwRules.length > 0) { - for (int i = 0; i < fwRules.length; i++) { - sb.append(fwRules[i]).append(','); - } - args += " -a " + sb.toString(); - } - - if (trafficType == FirewallRule.TrafficType.Egress) { - callResult = routerProxy("firewall_egress.sh", routerIp, args); - } else { - callResult = routerProxy("firewall_ingress.sh", routerIp, args); - } - - if (callResult == null || callResult.isEmpty()) { - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetFirewallRulesAnswer(cmd, false, results); - } - return new SetFirewallRulesAnswer(cmd, true, results); - } - protected Answer execute(final ClusterSyncCommand cmd) { Connection conn = getConnection(); //check if this is master @@ -7783,28 +7250,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe * @param cmd * @return */ - private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + private ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) { Connection conn = getConnection(); NicTO nic = cmd.getNic(); - String domrIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String domrGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String gw = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); - String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - String domainName = cmd.getNetworkDomain(); - String dns = cmd.getDefaultDns1(); - if (dns == null || dns.isEmpty()) { - dns = cmd.getDefaultDns2(); - } else { - String dns2 = cmd.getDefaultDns2(); - if (dns2 != null && !dns2.isEmpty()) { - dns += "," + dns2; - } - } try { Set vms = VM.getByNameLabel(conn, domrName); if (vms == null || vms.isEmpty()) { - return new SetupGuestNetworkAnswer(cmd, false, "Can not find VM " + domrName); + return new ExecutionResult(false, "Can not find VM " + domrName); } VM vm = vms.iterator().next(); String mac = nic.getMac(); @@ -7817,105 +7270,46 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } if (domrVif == null) { - return new SetupGuestNetworkAnswer(cmd, false, "Can not find vif with mac " + mac + " for VM " + domrName); + return new ExecutionResult(false, "Can not find vif with mac " + mac + " for VM " + domrName); } - String args = (cmd.isAdd()?" -C":" -D"); - String dev = "eth" + domrVif.getDevice(conn); - args += " -d " + dev; - args += " -i " + domrGIP; - args += " -g " + gw; - args += " -m " + cidr; - args += " -n " + NetUtils.getSubNet(domrGIP, nic.getNetmask()); - if (dns != null && !dns.isEmpty()) { - args += " -s " + dns; - } - if (domainName != null && !domainName.isEmpty()) { - args += " -e " + domainName; - } - String result = routerProxy("vpc_guestnw.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new SetupGuestNetworkAnswer(cmd, false, "creating guest network failed due to " + ((result == null) ? "null" : result)); - } - return new SetupGuestNetworkAnswer(cmd, true, "success"); + nic.setDeviceId(Integer.valueOf(domrVif.getDevice(conn))); } catch (Exception e) { String msg = "Creating guest network failed due to " + e.toString(); s_logger.warn(msg, e); - return new SetupGuestNetworkAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } - protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) { Connection conn = getConnection(); - String[] results = new String[cmd.getIpAddresses().length]; - int i = 0; String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); try { IpAddressTO[] ips = cmd.getIpAddresses(); for (IpAddressTO ip : ips) { - assignVPCPublicIpAddress(conn, routerName, routerIp, ip); - results[i++] = ip.getPublicIp() + " - success"; + VM router = getVM(conn, routerName); + + VIF correctVif = getVifByMac(conn, router, ip.getVifMacAddress()); + if (correctVif == null) { + if (ip.isAdd()) { + throw new InternalErrorException("Failed to find DomR VIF to associate IP with."); + } else { + s_logger.debug("VIF to deassociate IP with does not exist, return success"); + } + } + ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); } } catch (Exception e) { s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; + return new ExecutionResult(false, e.getMessage()); } - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } - protected Answer execute(Site2SiteVpnCfgCommand cmd) { - String args = ""; - if (cmd.isCreate()) { - args += " -A"; - args += " -l "; - args += cmd.getLocalPublicIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -g "; - args += cmd.getLocalPublicGateway(); - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - args += " -e "; - args += "\"" + cmd.getEspPolicy() + "\""; - args += " -i "; - args += "\"" + cmd.getIkePolicy() + "\""; - args += " -t "; - args += Long.toString(cmd.getIkeLifetime()); - args += " -T "; - args += Long.toString(cmd.getEspLifetime()); - args += " -s "; - args += "\"" + cmd.getIpsecPsk() + "\""; - args += " -d "; - if (cmd.getDpd()) { - args += "1"; - } else { - args += "0"; - } - if (cmd.isPassive()) { - args += " -p "; - } - } else { - args += " -D"; - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - } - String result = routerProxy("ipsectunnel.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "Configure site to site VPN failed! "); - } - return new Answer(cmd); - } - - protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) { Connection conn = getConnection(); String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); IpAddressTO pubIp = cmd.getIpAddress(); @@ -7924,139 +7318,33 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe VIF correctVif = getCorrectVif(conn, router, pubIp); - String args = ""; + pubIp.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); - args += " -A "; - args += " -l "; - args += pubIp.getPublicIp(); - - args += " -c "; - args += "eth" + correctVif.getDevice(conn); - - String result = routerProxy("vpc_snat.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - throw new InternalErrorException("Xen plugin \"vpc_snat\" failed."); - } - return new SetSourceNatAnswer(cmd, true, "success"); } catch (Exception e) { String msg = "Ip SNAT failure due to " + e.toString(); s_logger.error(msg, e); - return new SetSourceNatAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } - private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { - String[] results = new String[cmd.getRules().length]; - String callResult; + protected ExecutionResult prepareNetworkElementCommand(SetNetworkACLCommand cmd) { Connection conn = getConnection(); String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); try { VM router = getVM(conn, routerName); - String[][] rules = cmd.generateFwRules(); - StringBuilder sb = new StringBuilder(); - String[] aclRules = rules[0]; - for (int i = 0; i < aclRules.length; i++) { - sb.append(aclRules[i]).append(','); - } - - if (privateGw != null) { - s_logger.debug("Private gateway configuration is set"); - } NicTO nic = cmd.getNic(); VIF vif = getVifByMac(conn, router, nic.getMac()); - if (privateGw != null) { - s_logger.debug("Private gateway configuration is set"); - String args = ""; - args += " -d " + "eth" + vif.getDevice(conn); - args += " -a " + sb.toString(); - - callResult = routerProxy("vpc_privategw_acl.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (callResult == null || callResult.isEmpty()) { - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetNetworkACLAnswer(cmd, false, results); - } - } else { - String args = ""; - args += " -d " + "eth" + vif.getDevice(conn); - args += " -i " + nic.getIp(); - args += " -m " + Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - args += " -a " + sb.toString(); - - callResult = routerProxy("vpc_acl.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (callResult == null || callResult.isEmpty()) { - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetNetworkACLAnswer(cmd, false, results); - } - } - return new SetNetworkACLAnswer(cmd, true, results); + nic.setDeviceId(Integer.valueOf(vif.getDevice(conn))); } catch (Exception e) { - String msg = "SetNetworkACL failed due to " + e.toString(); + String msg = "Prepare SetNetworkACL failed due to " + e.toString(); s_logger.error(msg, e); - return new SetNetworkACLAnswer(cmd, false, results); - } - } - - protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { - String[] results = new String[cmd.getRules().length]; - int i = 0; - - boolean endResult = true; - for (PortForwardingRuleTO rule : cmd.getRules()) { - String args = ""; - args += rule.revoked() ? " -D" : " -A"; - args += " -P " + rule.getProtocol().toLowerCase(); - args += " -l " + rule.getSrcIp(); - args += " -p " + rule.getStringSrcPortRange(); - args += " -r " + rule.getDstIp(); - args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - - String result = routerProxy("vpc_portforwarding.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - - if (result == null || result.isEmpty()) { - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } - return new SetPortForwardingRulesAnswer(cmd, results, endResult); - } - - private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) { - String callResult; - try { - String[] results = new String[cmd.getStaticRoutes().length]; - String[][] rules = cmd.generateSRouteRules(); - StringBuilder sb = new StringBuilder(); - String[] srRules = rules[0]; - for (int i = 0; i < srRules.length; i++) { - sb.append(srRules[i]).append(','); - } - String args = "-a " + sb.toString(); - callResult = routerProxy("vpc_staticroute.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (callResult == null || callResult.isEmpty()) { - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetStaticRouteAnswer(cmd, false, results); - } - return new SetStaticRouteAnswer(cmd, true, results); - } catch (Exception e) { - String msg = "SetStaticRoute failed due to " + e.toString(); - s_logger.error(msg, e); - return new SetStaticRouteAnswer(cmd, false, null); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } @Override diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java index df43430d481..7e26a5cdb22 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java @@ -16,25 +16,6 @@ // under the License. package com.cloud.hypervisor.xen.resource; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import javax.ejb.Local; - -import org.apache.log4j.Logger; -import org.apache.xmlrpc.XmlRpcException; - -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.Network; -import com.xensource.xenapi.PIF; -import com.xensource.xenapi.Types.IpConfigurationMode; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VLAN; -import com.xensource.xenapi.VM; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckOnHostAnswer; import com.cloud.agent.api.CheckOnHostCommand; @@ -47,6 +28,22 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.resource.ServerResource; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Types.IpConfigurationMode; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VLAN; +import com.xensource.xenapi.VM; +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import javax.ejb.Local; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; @Local(value = ServerResource.class) public class XenServer56Resource extends CitrixResourceBase { @@ -127,7 +124,7 @@ public class XenServer56Resource extends CitrixResourceBase { @Override protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) { - String args = "netusage.sh " + privateIpAddress + " "; + String args = ""; if (option.equals("get")) { args += "-g"; } else if (option.equals("create")) { @@ -142,7 +139,7 @@ public class XenServer56Resource extends CitrixResourceBase { args += vif; } - return callHostPlugin(conn, "vmops", "routerProxy", "args", args); + return executeInVR(privateIpAddress, "netusage.sh", args).getDetails(); } protected NetworkUsageAnswer VPCNetworkUsage(NetworkUsageCommand cmd) { @@ -151,8 +148,7 @@ public class XenServer56Resource extends CitrixResourceBase { String option = cmd.getOption(); String publicIp = cmd.getGatewayIP(); - String args = "vpc_netusage.sh " + cmd.getPrivateIP(); - args += " -l " + publicIp + " "; + String args = " -l " + publicIp + " "; if (option.equals("get")) { args += "-g"; } else if (option.equals("create")) { @@ -169,7 +165,7 @@ public class XenServer56Resource extends CitrixResourceBase { return new NetworkUsageAnswer(cmd, "success", 0L, 0L); } - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + String result = executeInVR(cmd.getPrivateIP(), "vpc_netusage.sh", args).getDetails(); if (option.equals("get") || option.equals("vpn")) { long[] stats = new long[2]; if (result != null) { diff --git a/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java b/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java index f2bf47262ca..e8217f7216f 100644 --- a/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java +++ b/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java @@ -106,7 +106,7 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { try { VMInstanceVO instance = instanceDao.findById(vmTo.getId()); if (instance != null) { - if (srcHost.getClusterId() == destHost.getClusterId()) { + if (srcHost.getClusterId().equals(destHost.getClusterId())) { answer = migrateVmWithVolumesWithinCluster(instance, vmTo, srcHost, destHost, volumeMap); } else { answer = migrateVmWithVolumesAcrossCluster(instance, vmTo, srcHost, destHost, volumeMap); @@ -126,7 +126,7 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { } private Answer migrateVmWithVolumesAcrossCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) - throws AgentUnavailableException { + throws AgentUnavailableException { // Initiate migration of a virtual machine with it's volumes. try { @@ -153,7 +153,7 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { } MigrateWithStorageSendCommand sendCmd = - new MigrateWithStorageSendCommand(to, receiveAnswer.getVolumeToSr(), receiveAnswer.getNicToNetwork(), receiveAnswer.getToken()); + new MigrateWithStorageSendCommand(to, receiveAnswer.getVolumeToSr(), receiveAnswer.getNicToNetwork(), receiveAnswer.getToken()); MigrateWithStorageSendAnswer sendAnswer = (MigrateWithStorageSendAnswer)agentMgr.send(srcHost.getId(), sendCmd); if (sendAnswer == null) { s_logger.error("Migration with storage of vm " + vm + " to host " + destHost + " failed."); @@ -184,7 +184,7 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { } private Answer migrateVmWithVolumesWithinCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) - throws AgentUnavailableException { + throws AgentUnavailableException { // Initiate migration of a virtual machine with it's volumes. try { diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml index ae6961e10a2..8c6877dfb90 100644 --- a/plugins/network-elements/juniper-contrail/pom.xml +++ b/plugins/network-elements/juniper-contrail/pom.xml @@ -82,6 +82,12 @@ cloud-framework-events ${project.version} + + org.apache.cloudstack + cloud-framework-spring-lifecycle + ${project.version} + test + com.google.guava guava diff --git a/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/module.properties b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/module.properties new file mode 100644 index 00000000000..ced0f3addc7 --- /dev/null +++ b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=contrail +parent=network \ No newline at end of file diff --git a/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml new file mode 100644 index 00000000000..99ab02ea84b --- /dev/null +++ b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java index 092e4bc7365..05723b04447 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java @@ -26,7 +26,6 @@ import java.util.Set; import javax.ejb.Local; import javax.inject.Inject; -import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -90,12 +89,6 @@ public class ContrailElementImpl extends AdapterBase ServerDBSync _dbSync; private static final Logger s_logger = Logger.getLogger(ContrailElement.class); - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - s_logger.debug("configure"); - return true; - } - // PluggableService @Override public List> getCommands() { diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java index 704dedd4a3c..0bb95dd81cb 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.network.contrail.management; import java.io.IOException; import java.net.URI; +import java.util.List; import javax.inject.Inject; import javax.ejb.Local; @@ -54,6 +55,8 @@ import com.cloud.network.guru.NetworkGuru; import com.cloud.network.PhysicalNetwork; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.addr.PublicIp; import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; @@ -94,7 +97,7 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru { private boolean canHandle(NetworkOffering offering, NetworkType networkType, PhysicalNetwork physicalNetwork) { if (networkType == NetworkType.Advanced - && offering.getId() == _manager.getRouterOffering().getId() + && (offering.getId() == _manager.getRouterOffering().getId() || offering.getId() == _manager.getVpcRouterOffering().getId()) && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated && physicalNetwork.getIsolationMethods().contains("L3VPN")) @@ -148,6 +151,25 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru { return network; } _manager.getDatabase().getVirtualNetworks().add(vnModel); + + if (network.getVpcId() != null) { + List ips = _ipAddressDao.listByAssociatedVpc(network.getVpcId(), true); + if (ips.isEmpty()) { + s_logger.debug("Creating a source nat ip for network " + network); + Account owner = _accountMgr.getAccount(network.getAccountId()); + try { + PublicIp publicIp = _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network); + IPAddressVO ip = publicIp.ip(); + ip.setVpcId(network.getVpcId()); + _ipAddressDao.acquireInLockTable(ip.getId()); + _ipAddressDao.update(ip.getId(), ip); + _ipAddressDao.releaseFromLockTable(ip.getId()); + } catch (Exception e) { + s_logger.error("Unable to allocate source nat ip: " + e); + } + } + } + return network; } diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java index 6853d1efd55..1fe13035fb1 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java @@ -38,12 +38,19 @@ import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.offering.NetworkOffering; import com.cloud.projects.ProjectVO; import com.cloud.network.vpc.NetworkACLVO; +import com.cloud.network.vpc.VpcOffering; +import com.cloud.network.vpc.VpcVO; public interface ContrailManager { public static final String routerOfferingName = "Juniper Contrail Network Offering"; public static final String routerOfferingDisplayText = "Juniper Contrail Network Offering"; public static final String routerPublicOfferingName = "Juniper Contrail Public Network Offering"; public static final String routerPublicOfferingDisplayText = "Juniper Contrail Public Network Offering"; + public static final String vpcRouterOfferingName = "Juniper Contrail VPC Network Offering"; + public static final String vpcRouterOfferingDisplayText = "Juniper Contrail VPC Network Offering"; + public static final String juniperVPCOfferingName = "Juniper Contrail VPC Offering"; + public static final String juniperVPCOfferingDisplayText = "Juniper Contrail VPC Offering"; + public static final int DB_SYNC_INTERVAL_DEFAULT = 600000; public static final String VNC_ROOT_DOMAIN = "default-domain"; public static final String VNC_DEFAULT_PROJECT = "default-project"; @@ -51,6 +58,8 @@ public interface ContrailManager { public NetworkOffering getRouterOffering(); public NetworkOffering getPublicRouterOffering(); + public NetworkOffering getVpcRouterOffering(); + public VpcOffering getVpcOffering(); public void syncNetworkDB(short syncMode) throws IOException; @@ -116,6 +125,8 @@ public interface ContrailManager { public List findManagedPublicIps(); + public List findManagedVpcs(); + public List findManagedACLs(); public VirtualNetwork findDefaultVirtualNetwork(TrafficType trafficType) throws IOException; diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java index ef76e4cee49..616a8c5c85a 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java @@ -81,6 +81,12 @@ import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.projects.ProjectVO; import com.cloud.network.vpc.dao.NetworkACLDao; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.network.vpc.dao.VpcOfferingDao; +import com.cloud.network.vpc.VpcOffering; +import com.cloud.network.vpc.VpcOfferingVO; +import com.cloud.network.vpc.VpcProvisioningService; +import com.cloud.network.vpc.VpcVO; import com.cloud.network.vpc.NetworkACLVO; import com.cloud.projects.dao.ProjectDao; import com.cloud.user.Account; @@ -132,6 +138,12 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager @Inject UserVmDao _vmDao; @Inject + VpcOfferingDao _vpcOffDao; + @Inject + VpcProvisioningService _vpcProvSvc; + @Inject + VpcDao _vpcDao; + @Inject NetworkACLDao _networkAclDao; private static final Logger s_logger = Logger.getLogger(ContrailManager.class); @@ -141,6 +153,9 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager private NetworkOffering _offering; private NetworkOffering _routerOffering; private NetworkOffering _routerPublicOffering; + private NetworkOffering _vpcRouterOffering; + private VpcOffering _vpcOffering; + private Timer _dbSyncTimer; private int _dbSyncInterval = DB_SYNC_INTERVAL_DEFAULT; private final String configuration = "contrail.properties"; @@ -175,7 +190,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return _database; } - private NetworkOffering LocatePublicNetworkOffering(String offeringName, + private NetworkOffering locatePublicNetworkOffering(String offeringName, String offeringDisplayText, Provider provider) { List offerList = _configService.listNetworkOfferings(TrafficType.Public, false); for (NetworkOffering offer: offerList) { @@ -210,7 +225,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return _networkOfferingDao.findById(id); } - private NetworkOffering LocateNetworkOffering(String offeringName, + private NetworkOffering locateNetworkOffering(String offeringName, String offeringDisplayText, Provider provider) { List offerList = _configService.listNetworkOfferings(TrafficType.Guest, false); for (NetworkOffering offer : offerList) { @@ -239,6 +254,38 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return _networkOfferingDao.findById(id); } + private VpcOffering locateVpcOffering() { + VpcOffering vpcOffer = _vpcOffDao.findByUniqueName(juniperVPCOfferingName); + if (vpcOffer != null) { + if (((VpcOfferingVO)vpcOffer).getState() == VpcOffering.State.Enabled) { + return vpcOffer; + } + ((VpcOfferingVO)vpcOffer).setState(VpcOffering.State.Enabled); + long id = vpcOffer.getId(); + _vpcOffDao.update(id, (VpcOfferingVO)vpcOffer); + return vpcOffer; + } + Map> serviceProviderMap = new HashMap>(); + List providerSet = new ArrayList(); + providerSet.add(Provider.JuniperContrailVpcRouter.getName()); + final List services = new ArrayList(); + services.add(Service.Connectivity.getName()); + services.add(Service.Dhcp.getName()); + services.add(Service.NetworkACL.getName()); + services.add(Service.StaticNat.getName()); + services.add(Service.SourceNat.getName()); + services.add(Service.Gateway.getName()); + + for (String svc: services) { + serviceProviderMap.put(svc, providerSet); + } + vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null); + ((VpcOfferingVO)vpcOffer).setState(VpcOffering.State.Enabled); + long id = vpcOffer.getId(); + _vpcOffDao.update(id, (VpcOfferingVO)vpcOffer); + return _vpcOffDao.findById(id); + } + private NetworkOffering EnableNetworkOffering(long id) { NetworkOfferingVO offering = _networkOfferingDao.createForUpdate(id); offering.setState(NetworkOffering.State.Enabled); @@ -281,10 +328,13 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager _controller = new ModelController(this, _api, _vmDao, _networksDao, _nicDao, _vlanDao, _ipAddressDao); - _routerOffering = LocateNetworkOffering(routerOfferingName, routerOfferingDisplayText, + _routerOffering = locateNetworkOffering(routerOfferingName, routerOfferingDisplayText, Provider.JuniperContrailRouter); - _routerPublicOffering = LocatePublicNetworkOffering(routerPublicOfferingName, routerPublicOfferingDisplayText, + _routerPublicOffering = locatePublicNetworkOffering(routerPublicOfferingName, routerPublicOfferingDisplayText, Provider.JuniperContrailRouter); + _vpcRouterOffering = locateNetworkOffering(vpcRouterOfferingName, vpcRouterOfferingDisplayText, + Provider.JuniperContrailVpcRouter); + _vpcOffering = locateVpcOffering(); _eventHandler.subscribe(); @@ -303,6 +353,16 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return _routerOffering; } + @Override + public NetworkOffering getVpcRouterOffering() { + return _vpcRouterOffering; + } + + @Override + public VpcOffering getVpcOffering() { + return _vpcOffering; + } + @Override public String getPhysicalNetworkName(PhysicalNetworkVO physNet) { String physname = physNet.getName(); @@ -465,7 +525,8 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager public boolean isManagedPhysicalNetwork(Network network) { List net_list = _physicalNetworkDao.listByZone(network.getDataCenterId()); for (PhysicalNetworkVO phys : net_list) { - if (_physProviderDao.findByServiceProvider(phys.getId(), Network.Provider.JuniperContrailRouter.getName()) != null) { + if(_physProviderDao.findByServiceProvider(phys.getId(), Provider.JuniperContrailRouter.getName()) != null || + _physProviderDao.findByServiceProvider(phys.getId(), Provider.JuniperContrailVpcRouter.getName()) != null) { return true; } } @@ -564,6 +625,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager SearchCriteria sc = searchBuilder.create(); List offerings = new ArrayList(); offerings.add(getRouterOffering().getId()); + offerings.add(getVpcRouterOffering().getId()); offerings.add(getPublicRouterOffering().getId()); sc.setParameters("networkOfferingId", offerings.toArray()); @@ -585,9 +647,11 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager List phys_list = _physicalNetworkDao.listAll(); final String provider = Network.Provider.JuniperContrailRouter.getName(); + final String vpcProvider = Provider.JuniperContrailVpcRouter.getName(); for (Iterator iter = phys_list.iterator(); iter.hasNext();) { PhysicalNetworkVO phys = iter.next(); - if (_physProviderDao.findByServiceProvider(phys.getId(), provider) != null) { + if (_physProviderDao.findByServiceProvider(phys.getId(), provider) != null || + _physProviderDao.findByServiceProvider(phys.getId(), vpcProvider) != null) { List infraNets = new ArrayList(); findInfrastructureNetworks(phys, infraNets); for (NetworkVO net : infraNets) { @@ -611,10 +675,51 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return dbNets; } + @Override + public List findManagedVpcs() { + SearchBuilder searchBuilder = _vpcDao.createSearchBuilder(); + searchBuilder.and("vpcOffering", searchBuilder.entity().getVpcOfferingId(), Op.EQ); + SearchCriteria sc = searchBuilder.create(); + sc.setParameters("vpcOffering", getVpcOffering().getId()); + List vpcs = _vpcDao.search(sc, null); + if (vpcs == null || vpcs.size() == 0) { + s_logger.debug("no vpcs found"); + return null; + } + return vpcs; + } + @Override public List findManagedACLs() { - /* contrail vpc is not yet implemented */ - return null; + List vpcs = findManagedVpcs(); + if (vpcs == null || vpcs.isEmpty()) { + return null; + } + List vpcIds = new ArrayList(); + /* default-allow, default-deny ACLs will be under vpcId '0', so include it*/ + vpcIds.add((long)0); + for (VpcVO vpc:vpcs) { + vpcIds.add(vpc.getId()); + } + SearchBuilder searchBuilder = _networkAclDao.createSearchBuilder(); + searchBuilder.and("vpcId", searchBuilder.entity().getVpcId(), Op.IN); + SearchCriteria sc = searchBuilder.create(); + sc.setParameters("vpcId", vpcIds.toArray()); + List acls = _networkAclDao.search(sc, null); + if (acls == null || acls.size() == 0) { + s_logger.debug("no acls found"); + return null; + } + /* only return if acl is associated to any network */ + List jnprAcls = new ArrayList(); + for (NetworkACLVO acl:acls) { + List nets = _networksDao.listByAclId(acl.getId()); + if (nets == null || nets.isEmpty()) { + continue; + } + jnprAcls.add(acl); + } + return jnprAcls; } /* diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java new file mode 100644 index 00000000000..4a72fcb6697 --- /dev/null +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java @@ -0,0 +1,199 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.cloudstack.network.contrail.management; + +import java.io.IOException; +import java.util.List; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel; +import org.apache.cloudstack.network.contrail.model.NetworkPolicyModel; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.Network.Provider; +import com.cloud.network.element.NetworkACLServiceProvider; +import com.cloud.network.element.VpcProvider; +import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.network.vpc.NetworkACLVO; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRouteProfile; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.dao.NetworkACLDao; +import com.cloud.vm.ReservationContext; + +@Component +@Local(value = {NetworkACLServiceProvider.class, VpcProvider.class, ContrailElementImpl.class}) +public class ContrailVpcElementImpl extends ContrailElementImpl implements NetworkACLServiceProvider, VpcProvider { + private static final Logger s_logger = + Logger.getLogger(ContrailElement.class); + + @Inject + NetworkACLDao _networkACLDao; + + // NetworkElement API + @Override + public Provider getProvider() { + return Provider.JuniperContrailVpcRouter; + } + + @Override + public boolean implementVpc(Vpc vpc, DeployDestination dest, + ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + // TODO Auto-generated method stub + s_logger.debug("NetworkElement implementVpc"); + return true; + } + + @Override + public boolean shutdownVpc(Vpc vpc, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + s_logger.debug("NetworkElement shutdownVpc"); + return true; + } + + @Override + public boolean createPrivateGateway(PrivateGateway gateway) + throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + s_logger.debug("NetworkElement createPrivateGateway"); + return false; + } + + @Override + public boolean deletePrivateGateway(PrivateGateway privateGateway) + throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + s_logger.debug("NetworkElement deletePrivateGateway"); + return false; + } + + @Override + public boolean applyStaticRoutes(Vpc vpc, List routes) + throws ResourceUnavailableException { + // TODO Auto-generated method stub + s_logger.debug("NetworkElement applyStaticRoutes"); + return true; + } + + @Override + public boolean applyNetworkACLs(Network net, + List rules) + throws ResourceUnavailableException { + s_logger.debug("NetworkElement applyNetworkACLs"); + if (rules == null || rules.isEmpty()) { + s_logger.debug("no rules to apply"); + return true; + } + + Long aclId = rules.get(0).getAclId(); + NetworkACLVO acl = _networkACLDao.findById(aclId); + NetworkPolicyModel policyModel = _manager.getDatabase().lookupNetworkPolicy(acl.getUuid()); + if (policyModel == null) { + /* + * For the first time, when a CS ACL applied to a network, create a network-policy in VNC + * and when there are no networks associated to CS ACL, delete it from VNC. + */ + policyModel = new NetworkPolicyModel(acl.getUuid(), acl.getName()); + net.juniper.contrail.api.types.Project project; + try { + project = _manager.getVncProject(net.getDomainId(), net.getAccountId()); + if (project == null) { + project = _manager.getDefaultVncProject(); + } + } catch (IOException ex) { + s_logger.warn("read project", ex); + return false; + } + policyModel.setProject(project); + } + + VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(net.getUuid(), + _manager.getCanonicalName(net), net.getTrafficType()); + NetworkPolicyModel oldPolicyModel = null; + /* this method is called when network is destroyed too, hence vn model might have been deleted already */ + if (vnModel != null) { + oldPolicyModel = vnModel.getNetworkPolicyModel(); + vnModel.addToNetworkPolicy(policyModel); + } + + try { + policyModel.build(_manager.getModelController(), rules); + } catch (Exception e) { + s_logger.error(e); + e.printStackTrace(); + return false; + } + + try { + if (!policyModel.verify(_manager.getModelController())) { + policyModel.update(_manager.getModelController()); + } + _manager.getDatabase().getNetworkPolicys().add(policyModel); + } catch (Exception ex) { + s_logger.error("network-policy update: ", ex); + ex.printStackTrace(); + return false; + } + + if (!policyModel.hasPolicyRules()) { + try { + policyModel.delete(_manager.getModelController()); + _manager.getDatabase().getNetworkPolicys().remove(policyModel); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + /* + * if no other VNs are associated with the old policy, + * we could delete it from the Contrail VNC + */ + if (policyModel != oldPolicyModel && oldPolicyModel != null && !oldPolicyModel.hasDescendents()) { + try { + oldPolicyModel.delete(_manager.getModelController()); + _manager.getDatabase().getNetworkPolicys().remove(oldPolicyModel); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + return true; + } + + @Override + public boolean applyACLItemsToPrivateGw(PrivateGateway privateGateway, + List rules) + throws ResourceUnavailableException { + // TODO Auto-generated method stub + s_logger.debug("NetworkElement applyACLItemsToPrivateGw"); + return true; + } + +} diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java index b1f47187ed8..b9a3ed3b034 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java @@ -68,6 +68,8 @@ import com.cloud.network.vpc.NetworkACLItemDao; import com.cloud.network.vpc.NetworkACLItemVO; import com.cloud.network.vpc.NetworkACLVO; import com.cloud.network.vpc.dao.NetworkACLDao; +import com.cloud.network.vpc.VpcVO; +import com.cloud.network.vpc.dao.VpcDao; import com.cloud.projects.ProjectVO; import com.cloud.projects.dao.ProjectDao; import com.cloud.vm.NicVO; @@ -97,6 +99,8 @@ public class ServerDBSyncImpl implements ServerDBSync { @Inject ContrailManager _manager; @Inject + VpcDao _vpcDao; + @Inject NetworkACLItemDao _networkACLItemDao; @Inject NetworkACLDao _networkACLDao; @@ -990,7 +994,12 @@ public class ServerDBSyncImpl implements ServerDBSync { NetworkPolicyModel policyModel = new NetworkPolicyModel(db.getUuid(), db.getName()); net.juniper.contrail.api.types.Project project = null; try { - project = _manager.getDefaultVncProject(); + VpcVO vpc = _vpcDao.findById(db.getVpcId()); + if (vpc != null) { + project = _manager.getVncProject(vpc.getDomainId(), vpc.getAccountId()); + } else { + project = _manager.getDefaultVncProject(); + } } catch (IOException ex) { s_logger.warn("read project", ex); throw ex; @@ -1055,7 +1064,12 @@ public class ServerDBSyncImpl implements ServerDBSync { NetworkPolicyModel policyModel = new NetworkPolicyModel(db.getUuid(), db.getName()); net.juniper.contrail.api.types.Project project = null; try { - project = _manager.getDefaultVncProject(); + VpcVO vpc = _vpcDao.findById(db.getVpcId()); + if (vpc != null) { + project = _manager.getVncProject(vpc.getDomainId(), vpc.getAccountId()); + } else { + project = _manager.getDefaultVncProject(); + } } catch (IOException ex) { s_logger.warn("read project", ex); } diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java index 8ec2ff7187a..3092cad4ff6 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java @@ -73,7 +73,7 @@ public class NetworkPolicyModel extends ModelObjectBase { SearchCriteria sc = searchBuilder.create(); - sc.setParameters("networkOfferingId", controller.getManager().getRouterOffering().getId()); + sc.setParameters("networkOfferingId", controller.getManager().getVpcRouterOffering().getId()); sc.setParameters("cidr", cidr); sc.setParameters("trafficType", Networks.TrafficType.Guest); diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java index 416653d0a53..1a53c173d9f 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java @@ -45,14 +45,17 @@ import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDaoImpl; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDaoImpl; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.DcDetailsDaoImpl; +import org.apache.cloudstack.engine.orchestration.NetworkOrchestrator; import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.engine.service.api.OrchestrationService; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigDepotAdmin; import org.apache.cloudstack.framework.config.dao.ConfigurationDaoImpl; @@ -65,6 +68,7 @@ import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl; import org.apache.cloudstack.framework.jobs.impl.AsyncJobMonitor; import org.apache.cloudstack.framework.jobs.impl.SyncQueueManager; import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDaoImpl; +import org.apache.cloudstack.network.element.InternalLoadBalancerElement; import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService; import org.apache.cloudstack.network.lb.InternalLoadBalancerVMManager; import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService; @@ -73,6 +77,9 @@ import org.apache.cloudstack.region.PortableIpDaoImpl; import org.apache.cloudstack.region.PortableIpRangeDaoImpl; import org.apache.cloudstack.region.RegionManager; import org.apache.cloudstack.region.dao.RegionDaoImpl; +import org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry; +import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; import org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl; import org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl; @@ -120,6 +127,7 @@ import com.cloud.dc.dao.AccountVlanMapDaoImpl; import com.cloud.dc.dao.ClusterDaoImpl; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterDaoImpl; +import com.cloud.dc.dao.DataCenterDetailsDaoImpl; import com.cloud.dc.dao.DataCenterIpAddressDaoImpl; import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDaoImpl; import com.cloud.dc.dao.DataCenterVnetDaoImpl; @@ -141,11 +149,11 @@ import com.cloud.host.dao.HostDetailsDaoImpl; import com.cloud.host.dao.HostTagsDaoImpl; import com.cloud.hypervisor.HypervisorGuruManagerImpl; import com.cloud.hypervisor.dao.HypervisorCapabilitiesDaoImpl; +import com.cloud.hypervisor.XenServerGuru; import com.cloud.network.ExternalDeviceUsageManager; import com.cloud.network.IpAddress; import com.cloud.network.IpAddressManagerImpl; import com.cloud.network.Ipv6AddressManagerImpl; -import com.cloud.network.NetworkModelImpl; import com.cloud.network.NetworkServiceImpl; import com.cloud.network.NetworkUsageService; import com.cloud.network.StorageNetworkManager; @@ -161,6 +169,7 @@ import com.cloud.network.as.dao.CounterDaoImpl; import com.cloud.network.dao.AccountGuestVlanMapDaoImpl; import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; import com.cloud.network.dao.FirewallRulesDaoImpl; +import com.cloud.network.dao.IPAddressDaoImpl; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LBHealthCheckPolicyDaoImpl; import com.cloud.network.dao.LBStickinessPolicyDaoImpl; @@ -183,7 +192,11 @@ import com.cloud.network.dao.Site2SiteVpnGatewayDaoImpl; import com.cloud.network.dao.UserIpv6AddressDaoImpl; import com.cloud.network.dao.VirtualRouterProviderDaoImpl; import com.cloud.network.dao.VpnUserDaoImpl; +import com.cloud.network.element.FirewallServiceProvider; +import com.cloud.network.element.NetworkACLServiceProvider; +import com.cloud.network.element.PortForwardingServiceProvider; import com.cloud.network.element.Site2SiteVpnServiceProvider; +import com.cloud.network.element.VpcProvider; import com.cloud.network.firewall.FirewallManagerImpl; import com.cloud.network.lb.LoadBalancingRulesManagerImpl; import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl; @@ -234,7 +247,7 @@ import com.cloud.storage.VolumeApiService; import com.cloud.storage.dao.DiskOfferingDaoImpl; import com.cloud.storage.dao.GuestOSCategoryDaoImpl; import com.cloud.storage.dao.GuestOSDaoImpl; -import com.cloud.storage.dao.LaunchPermissionDao; +import com.cloud.storage.dao.LaunchPermissionDaoImpl; import com.cloud.storage.dao.SnapshotDaoImpl; import com.cloud.storage.dao.SnapshotPolicyDaoImpl; import com.cloud.storage.dao.StoragePoolDetailsDaoImpl; @@ -271,10 +284,13 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.TransactionStatus; import com.cloud.vm.ItWorkDaoImpl; +import com.cloud.vm.UserVmManagerImpl; +import com.cloud.vm.VirtualMachineManagerImpl; import com.cloud.vm.dao.ConsoleProxyDaoImpl; import com.cloud.vm.dao.DomainRouterDaoImpl; import com.cloud.vm.dao.InstanceGroupDaoImpl; import com.cloud.vm.dao.InstanceGroupVMMapDaoImpl; +import com.cloud.vm.dao.NicDaoImpl; import com.cloud.vm.dao.NicIpAliasDaoImpl; import com.cloud.vm.dao.NicSecondaryIpDaoImpl; import com.cloud.vm.dao.SecondaryStorageVmDaoImpl; @@ -291,19 +307,19 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; AsyncJobJournalDaoImpl.class, AsyncJobManagerImpl.class, AutoScalePolicyConditionMapDaoImpl.class, AutoScalePolicyDaoImpl.class, AutoScaleVmGroupDaoImpl.class, AutoScaleVmGroupPolicyMapDaoImpl.class, AutoScaleVmProfileDaoImpl.class, CapacityDaoImpl.class, ClusterDaoImpl.class, ClusterDetailsDaoImpl.class, ConditionDaoImpl.class, ConfigurationDaoImpl.class, ConfigurationManagerImpl.class, ConfigurationServerImpl.class, ConsoleProxyDaoImpl.class, - ContrailElementImpl.class, ContrailGuru.class, ContrailManagerImpl.class, CounterDaoImpl.class, DataCenterDaoImpl.class, DataCenterIpAddressDaoImpl.class, + ContrailElementImpl.class, ContrailGuru.class, ContrailManagerImpl.class, CounterDaoImpl.class, DataCenterDaoImpl.class, DataCenterDetailsDaoImpl.class, DataCenterIpAddressDaoImpl.class, DataCenterJoinDaoImpl.class, DataCenterLinkLocalIpAddressDaoImpl.class, DataCenterVnetDaoImpl.class, DcDetailsDaoImpl.class, DedicatedResourceDaoImpl.class, DiskOfferingDaoImpl.class, DiskOfferingJoinDaoImpl.class, DomainDaoImpl.class, DomainManagerImpl.class, DomainRouterDaoImpl.class, DomainRouterJoinDaoImpl.class, - EventDaoImpl.class, EventJoinDaoImpl.class, EventUtils.class, EventUtils.class, FirewallManagerImpl.class, FirewallRulesCidrsDaoImpl.class, + EventDaoImpl.class, EventJoinDaoImpl.class, EventUtils.class, ExtensionRegistry.class, FirewallManagerImpl.class, FirewallRulesCidrsDaoImpl.class, FirewallRulesDaoImpl.class, GuestOSCategoryDaoImpl.class, GuestOSDaoImpl.class, HostDaoImpl.class, HostDetailsDaoImpl.class, HostJoinDaoImpl.class, HostPodDaoImpl.class, HostTagsDaoImpl.class, HostTransferMapDaoImpl.class, HypervisorCapabilitiesDaoImpl.class, HypervisorGuruManagerImpl.class, ImageStoreDaoImpl.class, ImageStoreJoinDaoImpl.class, InstanceGroupDaoImpl.class, InstanceGroupJoinDaoImpl.class, - InstanceGroupVMMapDaoImpl.class, IpAddressManagerImpl.class, Ipv6AddressManagerImpl.class, ItWorkDaoImpl.class, LBHealthCheckPolicyDaoImpl.class, - LBStickinessPolicyDaoImpl.class, LaunchPermissionDao.class, LoadBalancerDaoImpl.class, LoadBalancerVMMapDaoImpl.class, LoadBalancingRulesManagerImpl.class, + InstanceGroupVMMapDaoImpl.class, InternalLoadBalancerElement.class, IPAddressDaoImpl.class, IpAddressManagerImpl.class, Ipv6AddressManagerImpl.class, ItWorkDaoImpl.class, LBHealthCheckPolicyDaoImpl.class, + LBStickinessPolicyDaoImpl.class, LaunchPermissionDaoImpl.class, LoadBalancerDaoImpl.class, LoadBalancerVMMapDaoImpl.class, LoadBalancingRulesManagerImpl.class, ManagementServerHostDaoImpl.class, MockAccountManager.class, NetworkACLDaoImpl.class, NetworkACLItemDaoImpl.class, NetworkACLManagerImpl.class, - NetworkAccountDaoImpl.class, NetworkDaoImpl.class, NetworkDomainDaoImpl.class, NetworkModelImpl.class, NetworkOfferingDaoImpl.class, - NetworkOfferingDetailsDaoImpl.class, NetworkOfferingServiceMapDaoImpl.class, NetworkOpDaoImpl.class, NetworkRuleConfigDaoImpl.class, NetworkServiceImpl.class, - NetworkServiceMapDaoImpl.class, NicIpAliasDaoImpl.class, NicSecondaryIpDaoImpl.class, PhysicalNetworkDaoImpl.class, PhysicalNetworkServiceProviderDaoImpl.class, + NetworkAccountDaoImpl.class, NetworkDaoImpl.class, NetworkDomainDaoImpl.class, NetworkOfferingDaoImpl.class, + NetworkOfferingDetailsDaoImpl.class, NetworkOfferingServiceMapDaoImpl.class, NetworkOpDaoImpl.class, NetworkOrchestrator.class, NetworkRuleConfigDaoImpl.class, NetworkServiceImpl.class, + NetworkServiceMapDaoImpl.class, NicDaoImpl.class, NicIpAliasDaoImpl.class, NicSecondaryIpDaoImpl.class, PhysicalNetworkDaoImpl.class, PhysicalNetworkServiceProviderDaoImpl.class, PhysicalNetworkTrafficTypeDaoImpl.class, PlannerHostReservationDaoImpl.class, PodVlanDaoImpl.class, PodVlanMapDaoImpl.class, PortForwardingRulesDaoImpl.class, PortableIpDaoImpl.class, PortableIpRangeDaoImpl.class, PrimaryDataStoreDaoImpl.class, PrivateIpDaoImpl.class, ProjectAccountDaoImpl.class, ProjectAccountJoinDaoImpl.class, ProjectInvitationDaoImpl.class, ProjectDaoImpl.class, ProjectInvitationJoinDaoImpl.class, ProjectJoinDaoImpl.class, @@ -315,11 +331,11 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; SnapshotDaoImpl.class, SnapshotPolicyDaoImpl.class, StaticRouteDaoImpl.class, StatsCollector.class, StoragePoolDetailsDaoImpl.class, StoragePoolHostDaoImpl.class, StoragePoolJoinDaoImpl.class, SyncQueueItemDaoImpl.class, TemplateDataStoreDaoImpl.class, TemplateJoinDaoImpl.class, UploadDaoImpl.class, UsageEventDaoImpl.class, UserAccountJoinDaoImpl.class, UserDaoImpl.class, UserIpv6AddressDaoImpl.class, UserStatisticsDaoImpl.class, UserStatsLogDaoImpl.class, - UserVmCloneSettingDaoImpl.class, UserVmDaoImpl.class, UserVmDetailsDaoImpl.class, UserVmJoinDaoImpl.class, VMInstanceDaoImpl.class, VMSnapshotDaoImpl.class, - VMTemplateDaoImpl.class, VMTemplateDetailsDaoImpl.class, VMTemplateHostDaoImpl.class, VMTemplateZoneDaoImpl.class, VirtualRouterProviderDaoImpl.class, + UserVmCloneSettingDaoImpl.class, UserVmDaoImpl.class, UserVmDetailsDaoImpl.class, UserVmJoinDaoImpl.class, UserVmManagerImpl.class, VMInstanceDaoImpl.class, VMSnapshotDaoImpl.class, + VMTemplateDaoImpl.class, VMTemplateDetailsDaoImpl.class, VMTemplateHostDaoImpl.class, VMTemplateZoneDaoImpl.class, VirtualMachineManagerImpl.class, VirtualRouterProviderDaoImpl.class, VlanDaoImpl.class, VmDiskStatisticsDaoImpl.class, VmRulesetLogDaoImpl.class, VolumeDaoImpl.class, VolumeHostDaoImpl.class, VolumeJoinDaoImpl.class, VpcDaoImpl.class, VpcGatewayDaoImpl.class, VpcManagerImpl.class, VpcOfferingDaoImpl.class, VpcOfferingServiceMapDaoImpl.class, VpcServiceMapDaoImpl.class, - VpcVirtualNetworkApplianceManagerImpl.class, VpnUserDaoImpl.class}, includeFilters = {@Filter(value = IntegrationTestConfiguration.ComponentFilter.class, + VpcVirtualNetworkApplianceManagerImpl.class, VpnUserDaoImpl.class, XenServerGuru.class}, includeFilters = {@Filter(value = IntegrationTestConfiguration.ComponentFilter.class, type = FilterType.CUSTOM)}, useDefaultFilters = false) @Configuration public class IntegrationTestConfiguration { @@ -711,5 +727,36 @@ public class IntegrationTestConfiguration { public VolumeOrchestrationService volumeOrchestrationService() { return Mockito.mock(VolumeOrchestrationService.class); } - + @Bean + public FirewallServiceProvider firewallServiceProvider() { + return Mockito.mock(FirewallServiceProvider.class); + } + @Bean + public PortForwardingServiceProvider portForwardingServiceProvider() { + return Mockito.mock(PortForwardingServiceProvider.class); + } + @Bean + public NetworkACLServiceProvider networkACLServiceProvider() { + return Mockito.mock(NetworkACLServiceProvider.class); + } + @Bean + public VpcProvider vpcProvier() { + return Mockito.mock(VpcProvider.class); + } + @Bean + public VolumeService volumeService() { + return Mockito.mock(VolumeService.class); + } + @Bean + public PrimaryDataStoreProviderManager privateDataStoreProviderManager() { + return Mockito.mock(PrimaryDataStoreProviderManager.class); + } + @Bean + public ImageStoreProviderManager imageStoreProviderManager() { + return Mockito.mock(ImageStoreProviderManager.class); + } + @Bean + public DataStoreProvider dataStoreProvider() { + return Mockito.mock(DataStoreProvider.class); + } } diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java index e16eedbe6b6..50419ea1b36 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java @@ -327,7 +327,7 @@ public class ManagementServerMock { _znet = _networkService.getPhysicalNetwork(id); List nets = _physicalNetworkDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public); if (nets == null || nets.isEmpty()) { - _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), null, null, null, null, null, null); + _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null); } } catch (InvalidParameterValueException e) { List isolationMethods = new ArrayList(); @@ -337,7 +337,7 @@ public class ManagementServerMock { "znet"); List nets = _physicalNetworkDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public); if (nets == null || nets.isEmpty()) { - _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), null, null, null, null, null, null); + _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null); } } if (_znet.getState() != PhysicalNetwork.State.Enabled) { @@ -353,7 +353,7 @@ public class ManagementServerMock { } } if (!found) { - _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Guest.toString(), null, null, null, null, null, null); + _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Guest.toString(), "vlan", null, null, null, null, null, null); } Pair, Integer> providers = diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java index 67dd406be7a..6e2d70db359 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java @@ -34,7 +34,6 @@ import org.apache.cloudstack.api.command.admin.user.RegisterCmd; import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; import org.apache.cloudstack.context.CallContext; -import com.cloud.api.query.dao.AccountJoinDao; import com.cloud.configuration.ResourceLimit; import com.cloud.configuration.dao.ResourceCountDao; import com.cloud.domain.Domain; @@ -68,8 +67,6 @@ public class MockAccountManager extends ManagerBase implements AccountManager { @Inject ResourceCountDao _resourceCountDao; - @Inject - AccountJoinDao _accountJoinDao; @Inject UserDao _userDao; diff --git a/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml b/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml index eef908ff15b..6f46f6dde4e 100644 --- a/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml +++ b/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml @@ -23,6 +23,7 @@ + - - - + + + + + - + + - - - - - - - - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + class="org.apache.cloudstack.network.contrail.management.IntegrationTestConfiguration"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java index d398844d344..83d00752665 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java @@ -102,11 +102,11 @@ public class NiciraNvpApi { private final Gson gson; - protected static Map prefixMap; + protected final static Map prefixMap; - protected static Map listTypeMap; + protected final static Map listTypeMap; - protected static Map defaultListParams; + protected final static Map defaultListParams; static { prefixMap = new HashMap(); diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java index 3ab5204be0e..4d0be2d207b 100644 --- a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java +++ b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java @@ -17,26 +17,33 @@ package org.apache.cloudstack.network.element; import java.io.IOException; +import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Arrays; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpConnectionManager; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; -import org.apache.commons.httpclient.URIException; -import org.apache.commons.httpclient.cookie.CookiePolicy; -import org.apache.commons.httpclient.methods.DeleteMethod; -import org.apache.commons.httpclient.methods.EntityEnclosingMethod; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.PutMethod; -import org.apache.commons.httpclient.methods.RequestEntity; -import org.apache.commons.httpclient.methods.StringRequestEntity; -import org.apache.commons.httpclient.params.HttpClientParams; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.params.ClientPNames; +import org.apache.http.client.params.CookiePolicy; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.params.CoreConnectionPNames; import org.apache.log4j.Logger; import com.google.gson.Gson; +import com.google.gson.JsonIOException; +import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.SerializedName; /** @@ -44,117 +51,75 @@ import com.google.gson.annotations.SerializedName; */ public class SspClient { private static final Logger s_logger = Logger.getLogger(SspClient.class); - private static final HttpConnectionManager s_httpclient_manager = new MultiThreadedHttpConnectionManager(); - private static final HttpClientParams s_httpclient_params = new HttpClientParams(); + private static final HttpClient s_client = new DefaultHttpClient( + new PoolingClientConnectionManager()); static { - s_httpclient_params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); + s_client.getParams() + .setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY) + .setParameter(CoreConnectionPNames.SO_TIMEOUT, 10000); } private final String apiUrl; private final String username; private final String password; - protected HttpClient client; - protected PostMethod postMethod; - protected DeleteMethod deleteMethod; - protected PutMethod putMethod; - public SspClient(String apiUrl, String username, String password) { super(); this.apiUrl = apiUrl; this.username = username; this.password = password; - client = new HttpClient(s_httpclient_params, s_httpclient_manager); - postMethod = new PostMethod(apiUrl); - deleteMethod = new DeleteMethod(apiUrl); - putMethod = new PutMethod(apiUrl); + } + + protected HttpClient getHttpClient() { // for mock test + return s_client; + } + + private HttpResponse innerExecuteMethod(HttpRequestBase req, String path) { + try { + URI base = new URI(apiUrl); + req.setURI(new URI(base.getScheme(), base.getUserInfo(), base.getHost(), + base.getPort(), path, null, null)); + } catch (URISyntaxException e) { + s_logger.error("invalid API URL " + apiUrl + " path " + path, e); + return null; + } + HttpResponse res = null; + try { + res = getHttpClient().execute(req); + s_logger.info("ssp api call:" + req + " status=" + res.getStatusLine()); + } catch (IOException e) { + s_logger.error("ssp api call failed: " + req, e); + } + return res; + } + + private HttpResponse executeMethod(HttpRequestBase req, String path) { + HttpResponse res = innerExecuteMethod(req, path); + if (res.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED && login()) { + req.reset(); + res = innerExecuteMethod(req, path); + } + return res; } public boolean login() { - PostMethod method = postMethod; - method.setPath("/ws.v1/login"); // NOTE: /ws.v1/login is correct - method.addParameter("username", username); - method.addParameter("password", password); + HttpPost method = new HttpPost(); + try { + method.setEntity(new UrlEncodedFormEntity(Arrays.asList( + new BasicNameValuePair("username", username), + new BasicNameValuePair("password", password)))); + } catch (UnsupportedEncodingException e) { + s_logger.error("invalid username or password", e); + return false; + } - try { - client.executeMethod(method); - } catch (HttpException e) { - s_logger.info("Login " + username + " to " + apiUrl + " failed", e); - return false; - } catch (IOException e) { - s_logger.info("Login " + username + " to " + apiUrl + " failed", e); - return false; - } finally { - method.releaseConnection(); - } - String apiCallPath = null; - try { - apiCallPath = method.getName() + " " + method.getURI().toString(); - } catch (URIException e) { - s_logger.error("method getURI failed", e); - } - s_logger.info("ssp api call:" + apiCallPath + " user=" + username + " status=" + method.getStatusLine()); - if (method.getStatusCode() == HttpStatus.SC_OK) { + HttpResponse res = this.innerExecuteMethod(method, "/ws.v1/login"); + if (res != null && res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { return true; } return false; } - private String executeMethod(HttpMethod method) { - String apiCallPath = null; - try { - apiCallPath = method.getName() + " " + method.getURI().toString(); - } catch (URIException e) { - s_logger.error("method getURI failed", e); - } - - String response = null; - try { - client.executeMethod(method); - response = method.getResponseBodyAsString(); - } catch (HttpException e) { - s_logger.error("ssp api call failed " + apiCallPath, e); - return null; - } catch (IOException e) { - s_logger.error("ssp api call failed " + apiCallPath, e); - return null; - } finally { - method.releaseConnection(); - } - - if (method.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { - if (!login()) { - return null; - } - - try { - client.executeMethod(method); - response = method.getResponseBodyAsString(); - } catch (HttpException e) { - s_logger.error("ssp api call failed " + apiCallPath, e); - return null; - } catch (IOException e) { - s_logger.error("ssp api call failed " + apiCallPath, e); - return null; - } finally { - method.releaseConnection(); - } - } - s_logger.info("ssp api call:" + apiCallPath + " user=" + username + " status=" + method.getStatusLine()); - if (method instanceof EntityEnclosingMethod) { - EntityEnclosingMethod emethod = (EntityEnclosingMethod)method; - RequestEntity reqEntity = emethod.getRequestEntity(); - if (reqEntity instanceof StringRequestEntity) { - StringRequestEntity strReqEntity = (StringRequestEntity)reqEntity; - s_logger.debug("ssp api request body:" + strReqEntity.getContent()); - } else { - s_logger.debug("ssp api request body:" + emethod.getRequestEntity()); - } - } - s_logger.debug("ssp api response body:" + response); - return response; - } - public class TenantNetwork { public String uuid; public String name; @@ -167,30 +132,31 @@ public class SspClient { req.name = networkName; req.tenantUuid = tenantUuid; - PostMethod method = postMethod; - method.setPath("/ssp.v1/tenant-networks"); - StringRequestEntity entity = null; - try { - entity = new StringRequestEntity(new Gson().toJson(req), "application/json", "UTF-8"); - } catch (UnsupportedEncodingException e) { - s_logger.error("failed creating http request body", e); + HttpPost method = new HttpPost(); + method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON)); + HttpResponse res = executeMethod(method, "/ssp.v1/tenant-networks"); + if (res == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) { return null; } - method.setRequestEntity(entity); - - String response = executeMethod(method); - if (response != null && method.getStatusCode() == HttpStatus.SC_CREATED) { - return new Gson().fromJson(response, TenantNetwork.class); + try { + return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent(), "UTF-8"), + TenantNetwork.class); + } catch (JsonSyntaxException e) { + s_logger.error("reading response body failed", e); + } catch (JsonIOException e) { + s_logger.error("reading response body failed", e); + } catch (IllegalStateException e) { + s_logger.error("reading response body failed", e); + } catch (IOException e) { + s_logger.error("reading response body failed", e); } return null; } public boolean deleteTenantNetwork(String tenantNetworkUuid) { - DeleteMethod method = deleteMethod; - method.setPath("/ssp.v1/tenant-networks/" + tenantNetworkUuid); - - executeMethod(method); - if (method.getStatusCode() == HttpStatus.SC_NO_CONTENT) { + HttpDelete method = new HttpDelete(); + HttpResponse res = executeMethod(method, "/ssp.v1/tenant-networks/" + tenantNetworkUuid); + if (res != null && res.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) { return true; } return false; @@ -214,30 +180,33 @@ public class SspClient { req.networkUuid = tenantNetworkUuid; req.attachmentType = "NoAttachment"; - PostMethod method = postMethod; - method.setPath("/ssp.v1/tenant-ports"); - StringRequestEntity entity = null; - try { - entity = new StringRequestEntity(new Gson().toJson(req), "application/json", "UTF-8"); - } catch (UnsupportedEncodingException e) { - s_logger.error("failed creating http request body", e); + HttpPost method = new HttpPost(); + method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON)); + HttpResponse res = executeMethod(method, "/ssp.v1/tenant-ports"); + + if (res == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) { return null; } - method.setRequestEntity(entity); - - String response = executeMethod(method); - if (response != null && method.getStatusCode() == HttpStatus.SC_CREATED) { - return new Gson().fromJson(response, TenantPort.class); + try { + return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent(), "UTF-8"), + TenantPort.class); + } catch (JsonSyntaxException e) { + s_logger.error("reading response body failed", e); + } catch (JsonIOException e) { + s_logger.error("reading response body failed", e); + } catch (IllegalStateException e) { + s_logger.error("reading response body failed", e); + } catch (IOException e) { + s_logger.error("reading response body failed", e); } return null; } public boolean deleteTenantPort(String tenantPortUuid) { - DeleteMethod method = deleteMethod; - method.setPath("/ssp.v1/tenant-ports/" + tenantPortUuid); + HttpDelete method = new HttpDelete(); + HttpResponse res = executeMethod(method, "/ssp.v1/tenant-ports/" + tenantPortUuid); - executeMethod(method); - if (method.getStatusCode() == HttpStatus.SC_NO_CONTENT) { + if (res != null && res.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) { return true; } return false; @@ -252,20 +221,23 @@ public class SspClient { req.attachmentType = "NoAttachment"; } - PutMethod method = putMethod; - method.setPath("/ssp.v1/tenant-ports/" + portUuid); - StringRequestEntity entity = null; - try { - entity = new StringRequestEntity(new Gson().toJson(req), "application/json", "UTF-8"); - } catch (UnsupportedEncodingException e) { - s_logger.error("failed creating http request body", e); + HttpPut method = new HttpPut(); + method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON)); + HttpResponse res = executeMethod(method, "/ssp.v1/tenant-ports/" + portUuid); + if (res == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { return null; } - method.setRequestEntity(entity); - - String response = executeMethod(method); - if (response != null && method.getStatusCode() == HttpStatus.SC_OK) { - return new Gson().fromJson(response, TenantPort.class); + try { + return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent(), "UTF-8"), + TenantPort.class); + } catch (JsonSyntaxException e) { + s_logger.error("reading response body failed", e); + } catch (JsonIOException e) { + s_logger.error("reading response body failed", e); + } catch (IllegalStateException e) { + s_logger.error("reading response body failed", e); + } catch (IOException e) { + s_logger.error("reading response body failed", e); } return null; } diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java index 173d6f0de9e..b41be40b4e9 100644 --- a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java +++ b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java @@ -92,6 +92,7 @@ import com.cloud.vm.dao.NicDao; public class SspElement extends AdapterBase implements ConnectivityProvider, SspManager, SspService, NetworkMigrationResponder { private static final Logger s_logger = Logger.getLogger(SspElement.class); public static final String s_SSP_NAME = "StratosphereSsp"; + private static final Provider s_ssp_provider = new Provider(s_SSP_NAME, false); @Inject NetworkServiceMapDao _ntwkSrvcDao; @@ -134,15 +135,7 @@ public class SspElement extends AdapterBase implements ConnectivityProvider, Ssp @Override public Provider getProvider() { - Provider provider = null; - synchronized (s_SSP_NAME) { - provider = Provider.getProvider(s_SSP_NAME); - if (provider == null) { - provider = new Provider(s_SSP_NAME, true); - s_logger.debug("registering Network.Provider " + s_SSP_NAME); - } - } - return provider; + return s_ssp_provider; } private List fetchSspClients(Long physicalNetworkId, Long dataCenterId, boolean enabledOnly) { @@ -187,14 +180,10 @@ public class SspElement extends AdapterBase implements ConnectivityProvider, Ssp public boolean isReady(PhysicalNetworkServiceProvider provider) { PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(provider.getPhysicalNetworkId()); assert (physicalNetwork != null); - if (physicalNetwork != null) { - if (fetchSspClients(physicalNetwork.getId(), physicalNetwork.getDataCenterId(), false).size() > 0) { - return true; - } - s_logger.warn("Ssp api endpoint not found. " + physicalNetwork.toString()); - } else { - s_logger.warn("PhysicalNetwork is NULL."); + if (fetchSspClients(physicalNetwork.getId(), physicalNetwork.getDataCenterId(), false).size() > 0) { + return true; } + s_logger.warn("Ssp api endpoint not found. " + physicalNetwork.toString()); return false; } diff --git a/plugins/network-elements/stratosphere-ssp/sspmock/sspmock.py b/plugins/network-elements/stratosphere-ssp/sspmock/sspmock.py index 5e7e61067c6..9ac646e244e 100644 --- a/plugins/network-elements/stratosphere-ssp/sspmock/sspmock.py +++ b/plugins/network-elements/stratosphere-ssp/sspmock/sspmock.py @@ -17,7 +17,8 @@ import json import uuid -from flask import Flask +from flask import Flask,request,make_response +from beaker.middleware import SessionMiddleware app = Flask(__name__) tenant_networks = [] @@ -25,50 +26,59 @@ tenant_ports = [] @app.route("/ws.v1/login", methods=["POST",]) def login(): - response.content_type = "application/json" - return "" + assert "username" in request.form + assert "password" in request.form + request.environ["beaker.session"]["login"] = True + res = make_response("", 200) + res.headers["Content-type"] = "application/json" + return res @app.route("/ssp.v1/tenant-networks", methods=["POST",]) def create_tenant_network(): - response.content_type = "application/json" - response.status = 201 + if "login" not in request.environ["beaker.session"]: + return make_response("", 401) obj = request.json obj["uuid"] = str(uuid.uuid1()) tenant_networks.append(obj) - return json.dumps(obj) + res = make_response(json.dumps(obj), 201) + res.headers["Content-type"] = "application/json" + return res @app.route("/ssp.v1/tenant-networks/", methods=["DELETE",]) def delete_tenant_network(tenant_net_uuid): + if "login" not in request.environ["beaker.session"]: + return make_response("", 401) for net in tenant_networks: if net["uuid"] == tenant_net_uuid: tenant_networks.remove(net) - response.status = 204 - return "" - response.status = 404 - return "" + return make_response("", 204) + return make_response("", 404) @app.route("/ssp.v1/tenant-ports", methods=["POST",]) def create_tenant_port(): - response.content_type = "application/json" - response.status = 201 + if "login" not in request.environ["beaker.session"]: + return make_response("", 401) obj = request.json obj["uuid"] = str(uuid.uuid1()) tenant_ports.append(obj) - return json.dumps(obj) + res = make_response(json.dumps(obj), 201) + res.headers["Content-type"] = "application/json" + return res @app.route("/ssp.v1/tenant-ports/", methods=["DELETE",]) def delete_tenant_port(tenant_port_uuid): + if "login" not in request.environ["beaker.session"]: + return make_response("", 401) for port in tenant_ports: if port["uuid"] == tenant_port_uuid: tenant_ports.remove(port) - response.status = 204 - return "" - response.status = 404 - return "" + return make_response("", 204) + return make_response("", 404) @app.route("/ssp.v1/tenant-ports/", methods=["PUT",]) def update_tenant_port(tenant_port_uuid): - response.content_type = "application/json" + if "login" not in request.environ["beaker.session"]: + return make_response("", 401) for port in tenant_ports: if port["uuid"] == tenant_port_uuid: obj = request.json @@ -76,10 +86,14 @@ def update_tenant_port(tenant_port_uuid): obj["vlan_id"] = 100 tenant_ports.remove(port) tenant_ports.append(obj) - response.status = 200 - return json.dumps(obj) - response.status = 404 - return "" + res = make_response(json.dumps(obj), 200) + res.headers["Content-type"] = "application/json" + return res + return make_response("", 404) if __name__=="__main__": + app.wsgi_app = SessionMiddleware(app.wsgi_app, { + "session.auto":True, + "session.type":"cookie", + "session.validate_key":"hoge"}) app.run(host="0.0.0.0", port=9080, debug=True) diff --git a/plugins/network-elements/stratosphere-ssp/test/org/apache/cloudstack/network/element/SspClientTest.java b/plugins/network-elements/stratosphere-ssp/test/org/apache/cloudstack/network/element/SspClientTest.java index 2cff927e287..627cc878f59 100644 --- a/plugins/network-elements/stratosphere-ssp/test/org/apache/cloudstack/network/element/SspClientTest.java +++ b/plugins/network-elements/stratosphere-ssp/test/org/apache/cloudstack/network/element/SspClientTest.java @@ -20,46 +20,37 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; +import java.io.ByteArrayInputStream; import java.util.UUID; -import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.URI; -import org.apache.commons.httpclient.methods.DeleteMethod; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.PutMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpUriRequest; import org.junit.Test; public class SspClientTest { - HttpClient _client = mock(HttpClient.class); - PostMethod _postMethod = mock(PostMethod.class); - PutMethod _putMethod = mock(PutMethod.class); - DeleteMethod _deleteMethod = mock(DeleteMethod.class); - String uuid = UUID.randomUUID().toString(); String apiUrl = "http://a.example.jp/"; String username = "foo"; String password = "bar"; - SspClient sspClient = new SspClient(apiUrl, username, password) { - { - client = _client; - postMethod = _postMethod; - putMethod = _putMethod; - deleteMethod = _deleteMethod; - } - }; - - @SuppressWarnings("deprecation") - private URI getUri() throws Exception { - return new URI(apiUrl); - } @Test public void loginTest() throws Exception { - when(_postMethod.getURI()).thenReturn(getUri()); - when(_postMethod.getStatusCode()).thenReturn(HttpStatus.SC_OK); + SspClient sspClient = spy(new SspClient(apiUrl, username, password)); + + HttpClient client = mock(HttpClient.class); + HttpResponse res = mock(HttpResponse.class, RETURNS_DEEP_STUBS); + doReturn(client).when(sspClient).getHttpClient(); + when(client.execute(any(HttpUriRequest.class))).thenReturn(res); + when(res.getStatusLine().getStatusCode()).thenReturn(HttpStatus.SC_OK); + assertTrue(sspClient.login()); assertTrue(sspClient.login()); assertTrue(sspClient.login()); @@ -69,10 +60,18 @@ public class SspClientTest { public void createNetworkTest() throws Exception { String networkName = "example network 1"; String tenant_net_uuid = UUID.randomUUID().toString(); + SspClient sspClient = spy(new SspClient(apiUrl, username, password)); + + HttpClient client = mock(HttpClient.class); + HttpResponse res = mock(HttpResponse.class, RETURNS_DEEP_STUBS); + doReturn(client).when(sspClient).getHttpClient(); + when(client.execute(any(HttpUriRequest.class))).thenReturn(res); + when(res.getStatusLine().getStatusCode()).thenReturn(HttpStatus.SC_CREATED); + String body = "{\"uuid\":\"" + tenant_net_uuid + "\",\"name\":\"" + networkName + + "\",\"tenant_uuid\":\"" + uuid + "\"}"; + when(res.getEntity().getContent()).thenReturn( + new ByteArrayInputStream(body.getBytes("UTF-8"))); - when(_postMethod.getURI()).thenReturn(getUri()); - when(_postMethod.getStatusCode()).thenReturn(HttpStatus.SC_CREATED); - when(_postMethod.getResponseBodyAsString()).thenReturn("{\"uuid\":\"" + tenant_net_uuid + "\",\"name\":\"" + networkName + "\",\"tenant_uuid\":\"" + uuid + "\"}"); SspClient.TenantNetwork tnet = sspClient.createTenantNetwork(uuid, networkName); assertEquals(tnet.name, networkName); assertEquals(tnet.uuid, tenant_net_uuid); @@ -82,9 +81,13 @@ public class SspClientTest { @Test public void deleteNetworkTest() throws Exception { String tenant_net_uuid = UUID.randomUUID().toString(); + SspClient sspClient = spy(new SspClient(apiUrl, username, password)); - when(_deleteMethod.getURI()).thenReturn(getUri()); - when(_deleteMethod.getStatusCode()).thenReturn(HttpStatus.SC_NO_CONTENT); + HttpClient client = mock(HttpClient.class); + HttpResponse res = mock(HttpResponse.class, RETURNS_DEEP_STUBS); + doReturn(client).when(sspClient).getHttpClient(); + when(client.execute(any(HttpUriRequest.class))).thenReturn(res); + when(res.getStatusLine().getStatusCode()).thenReturn(HttpStatus.SC_NO_CONTENT); sspClient.deleteTenantNetwork(tenant_net_uuid); } diff --git a/pom.xml b/pom.xml index 8fd1f54219c..1d2304ffcc6 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ - 1.6 + 1.7 UTF-8 1.2.16 @@ -469,6 +469,19 @@ + + org.codehaus.mojo + findbugs-maven-plugin + + + cloudstack-findbugs + none + + check + + + + @@ -577,6 +590,15 @@ + + org.apache.maven.plugins + maven-site-plugin + 3.3 + + 9000 + ${basedir}/target/site/tempdir + + @@ -840,9 +862,64 @@ + + org.codehaus.mojo + findbugs-maven-plugin + 2.5.3 + + Max + High + true + false + 2048 + + + + cloudstack-findbugs + + check + + + + + + + + org.codehaus.mojo + findbugs-maven-plugin + + Low + Default + + + + org.apache.maven.plugins + maven-javadoc-plugin + + 128m + 1g + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.7 + + + org.codehaus.mojo + cobertura-maven-plugin + 2.6 + + + org.apache.maven.plugins + maven-site-plugin + 3.3 + + + awsapi @@ -916,5 +993,23 @@ + + enablefindbugs + + + + org.codehaus.mojo + findbugs-maven-plugin + + + cloudstack-findbugs + process-classes + true + + + + + + diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 96b786630f2..2f0f347c783 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -230,12 +230,10 @@ def routerProxy(session, args): cmd.insert(0, "/bin/bash") try: txt = util.pread2(cmd) - if txt is None or len(txt) == 0 : - txt = 'success' + txt = 'succ#' + txt except: logging.debug("routerProxy command " + sargs + " failed " ) - txt = '' - + txt = 'fail#' + txt return txt @echo @@ -265,13 +263,12 @@ def createFileInDomr(session, args): f.write(file_contents) f.close() target = "root@" + domrip + ":" + file_path - util.pread2(['scp','-P','3922','-q','-o','StrictHostKeyChecking=no','-i','/root/.ssh/id_rsa.cloud',tmpfile, target]) + txt = util.pread2(['scp','-P','3922','-q','-o','StrictHostKeyChecking=no','-i','/root/.ssh/id_rsa.cloud',tmpfile, target]) util.pread2(['rm',tmpfile]) - txt = 'success' + txt = 'succ#' + txt except: - logging.debug(" failed to create HA proxy cfg file ") - txt = '' - + logging.debug("failed to create file " + file_path + " in VR, contain: " + file_contents) + txt = 'fail#' + txt return txt @echo diff --git a/server/src/com/cloud/acl/DomainChecker.java b/server/src/com/cloud/acl/DomainChecker.java index 8970655ffdd..6c3274dc183 100755 --- a/server/src/com/cloud/acl/DomainChecker.java +++ b/server/src/com/cloud/acl/DomainChecker.java @@ -312,7 +312,9 @@ public class DomainChecker extends AdapterBase implements SecurityChecker { } } //didn't find in upper tree - if (zoneDomainRecord.getPath().contains(accountDomainRecord.getPath())) { + if (zoneDomainRecord != null && + accountDomainRecord != null && + zoneDomainRecord.getPath().contains(accountDomainRecord.getPath())) { return true; } } diff --git a/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java b/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java index b67eccbd2d7..946eee6da49 100755 --- a/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java +++ b/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java @@ -243,35 +243,36 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat // List vms = _vmInstanceDao.listByLastHostId(hostId); List vms = null; long usedCapacity = 0; - for (VMInstanceVO vm : vms) { - if (skipCalculation(vm)) { - continue; - } - - ServiceOffering so = null; - - if (vm.getType() == VirtualMachine.Type.User) { - UserVmVO userVm = _vmDao.findById(vm.getId()); - if (userVm == null) { + if (vms != null) { + for (VMInstanceVO vm : vms) { + if (skipCalculation(vm)) { continue; } - } - so = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()); + ServiceOffering so = null; - if (capacityType == Capacity.CAPACITY_TYPE_MEMORY) { - usedCapacity += so.getRamSize() * 1024L * 1024L; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Counting memory capacity used by vm: " + vm.getId() + ", size: " + so.getRamSize() + "MB, host: " + hostId + ", currently counted: " + - usedCapacity + " Bytes"); + if (vm.getType() == VirtualMachine.Type.User) { + UserVmVO userVm = _vmDao.findById(vm.getId()); + if (userVm == null) { + continue; + } } - } else if (capacityType == Capacity.CAPACITY_TYPE_CPU) { - usedCapacity += so.getCpu() * so.getSpeed(); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Counting cpu capacity used by vm: " + vm.getId() + ", cpu: " + so.getCpu() + ", speed: " + so.getSpeed() + ", currently counted: " + - usedCapacity + " Bytes"); + so = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()); + if (capacityType == Capacity.CAPACITY_TYPE_MEMORY) { + usedCapacity += so.getRamSize() * 1024L * 1024L; + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Counting memory capacity used by vm: " + vm.getId() + ", size: " + so.getRamSize() + "MB, host: " + hostId + ", currently counted: " + + usedCapacity + " Bytes"); + } + } else if (capacityType == Capacity.CAPACITY_TYPE_CPU) { + usedCapacity += so.getCpu() * so.getSpeed(); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Counting cpu capacity used by vm: " + vm.getId() + ", cpu: " + so.getCpu() + ", speed: " + so.getSpeed() + ", currently counted: " + + usedCapacity + " Bytes"); + } } } } diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index 751706db005..9e55d6dcb1d 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -423,8 +423,8 @@ public class ApiDispatcher { } } else { DateFormat format = BaseCmd.INPUT_FORMAT; - format.setLenient(false); synchronized (format) { + format.setLenient(false); field.set(cmdObj, format.parse(paramObj.toString())); } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 5151976eddb..77381aa1d1f 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -30,8 +30,6 @@ import java.util.TimeZone; import javax.inject.Inject; -import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.affinity.AffinityGroup; @@ -148,6 +146,7 @@ import org.apache.cloudstack.region.Region; import org.apache.cloudstack.usage.Usage; import org.apache.cloudstack.usage.UsageService; import org.apache.cloudstack.usage.UsageTypes; +import org.apache.log4j.Logger; import com.cloud.api.query.ViewResponseHelper; import com.cloud.api.query.vo.AccountJoinVO; @@ -385,8 +384,9 @@ public class ApiResponseHelper implements ResponseGenerator { populateDomain(resourceLimitResponse, accountTemp.getDomainId()); } resourceLimitResponse.setResourceType(Integer.valueOf(limit.getType().getOrdinal()).toString()); + if ((limit.getType() == ResourceType.primary_storage || limit.getType() == ResourceType.secondary_storage) && limit.getMax() >= 0) { - resourceLimitResponse.setMax((long)Math.ceil(limit.getMax() / ResourceType.bytesToGiB)); + resourceLimitResponse.setMax((long)Math.ceil((double)limit.getMax() / ResourceType.bytesToGiB)); } else { resourceLimitResponse.setMax(limit.getMax()); } @@ -1816,8 +1816,6 @@ public class ApiResponseHelper implements ResponseGenerator { public SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List securityRules) { SecurityGroupResponse response = new SecurityGroupResponse(); Map securiytGroupAccounts = new HashMap(); - Map allowedSecurityGroups = new HashMap(); - Map allowedSecuriytGroupAccounts = new HashMap(); if ((securityRules != null) && !securityRules.isEmpty()) { SecurityGroupJoinVO securityGroup = ApiDBUtils.findSecurityGroupViewById(securityRules.get(0).getSecurityGroupId()).get(0); @@ -2980,7 +2978,7 @@ public class ApiResponseHelper implements ResponseGenerator { if (profile != null) { response.setProfileId(profile.getUuid()); } - FirewallRuleVO fw = ApiDBUtils.findFirewallRuleById(vmGroup.getProfileId()); + FirewallRuleVO fw = ApiDBUtils.findFirewallRuleById(vmGroup.getLoadBalancerId()); if (fw != null) { response.setLoadBalancerId(fw.getUuid()); } @@ -3019,11 +3017,10 @@ public class ApiResponseHelper implements ResponseGenerator { response.setCidr(result.getCidr()); StaticRoute.State state = result.getState(); - String stateToSet = state.toString(); - if (state.equals(FirewallRule.State.Revoke)) { - stateToSet = "Deleting"; + if (state.equals(StaticRoute.State.Revoke)) { + state = StaticRoute.State.Deleting; } - response.setState(stateToSet); + response.setState(state.toString()); populateAccount(response, result.getAccountId()); populateDomain(response, result.getDomainId()); @@ -3512,11 +3509,11 @@ public class ApiResponseHelper implements ResponseGenerator { ApplicationLoadBalancerRuleResponse ruleResponse = new ApplicationLoadBalancerRuleResponse(); ruleResponse.setInstancePort(lb.getDefaultPortStart()); ruleResponse.setSourcePort(lb.getSourcePortStart()); - String stateToSet = lb.getState().toString(); + FirewallRule.State stateToSet = lb.getState(); if (stateToSet.equals(FirewallRule.State.Revoke)) { - stateToSet = "Deleting"; + stateToSet = FirewallRule.State.Deleting; } - ruleResponse.setState(stateToSet); + ruleResponse.setState(stateToSet.toString()); ruleResponse.setObjectName("loadbalancerrule"); ruleResponses.add(ruleResponse); lbResponse.setLbRules(ruleResponses); diff --git a/server/src/com/cloud/api/ApiSerializerHelper.java b/server/src/com/cloud/api/ApiSerializerHelper.java index cd5c7e65fdc..7426d9f1675 100644 --- a/server/src/com/cloud/api/ApiSerializerHelper.java +++ b/server/src/com/cloud/api/ApiSerializerHelper.java @@ -24,7 +24,7 @@ import org.apache.cloudstack.api.ResponseObject; public class ApiSerializerHelper { public static final Logger s_logger = Logger.getLogger(ApiSerializerHelper.class.getName()); - public static String token = "/"; + private static String token = "/"; public static String toSerializedString(Object result) { if (result != null) { diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 3bd2b2a277a..158a8976cb4 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -160,11 +160,10 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer private static final Logger s_logger = Logger.getLogger(ApiServer.class.getName()); private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName()); - public static boolean encodeApiResponse = false; - public static String jsonContentType = "text/javascript"; - public static String controlCharacters = "[\000-\011\013-\014\016-\037\177]"; // Non-printable ASCII characters - numbers 0 to 31 and 127 decimal - @Inject - ApiDispatcher _dispatcher; + private static boolean encodeApiResponse = false; + private static String jsonContentType = "text/javascript"; + private static String controlCharacters = "[\000-\011\013-\014\016-\037\177]"; // Non-printable ASCII characters - numbers 0 to 31 and 127 decimal + @Inject ApiDispatcher _dispatcher; @Inject private AccountManager _accountMgr; @@ -245,7 +244,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer } - encodeApiResponse = Boolean.valueOf(_configDao.getValue(Config.EncodeApiResponse.key())); + setEncodeApiResponse(Boolean.valueOf(_configDao.getValue(Config.EncodeApiResponse.key()))); String jsonType = _configDao.getValue(Config.JavaScriptDefaultContentType.key()); if (jsonType != null) { jsonContentType = jsonType; @@ -383,7 +382,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer buildAuditTrail(auditTrailSb, command[0], response); } else { if (!command[0].equalsIgnoreCase("login") && !command[0].equalsIgnoreCase("logout")) { - String errorString = "Unknown API command: " + ((command == null) ? "null" : command[0]); + String errorString = "Unknown API command: " + command[0]; s_logger.warn(errorString); auditTrailSb.append(" " + errorString); throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, errorString); @@ -1154,4 +1153,16 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer public void setApiAccessCheckers(List apiAccessCheckers) { _apiAccessCheckers = apiAccessCheckers; } + + public static boolean isEncodeApiResponse() { + return encodeApiResponse; + } + + private static void setEncodeApiResponse(boolean encodeApiResponse) { + ApiServer.encodeApiResponse = encodeApiResponse; + } + + public static String getJsonContentType() { + return jsonContentType; + } } diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 6a33c14baaf..46f7eba8bee 100755 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -375,7 +375,7 @@ public class ApiServlet extends HttpServlet { private void writeResponse(HttpServletResponse resp, String response, int responseCode, String responseType) { try { if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - resp.setContentType(ApiServer.jsonContentType + "; charset=UTF-8"); + resp.setContentType(ApiServer.getJsonContentType() + "; charset=UTF-8"); } else { resp.setContentType("text/xml; charset=UTF-8"); } diff --git a/server/src/com/cloud/api/EncodedStringTypeAdapter.java b/server/src/com/cloud/api/EncodedStringTypeAdapter.java index cde144830aa..50dbd0d48cd 100644 --- a/server/src/com/cloud/api/EncodedStringTypeAdapter.java +++ b/server/src/com/cloud/api/EncodedStringTypeAdapter.java @@ -37,7 +37,7 @@ public class EncodedStringTypeAdapter implements JsonSerializer { } private static String encodeString(String value) { - if (!ApiServer.encodeApiResponse) { + if (!ApiServer.isEncodeApiResponse()) { return value; } try { diff --git a/server/src/com/cloud/api/doc/Alert.java b/server/src/com/cloud/api/doc/Alert.java index e73cb0e5351..3e61d0ba268 100644 --- a/server/src/com/cloud/api/doc/Alert.java +++ b/server/src/com/cloud/api/doc/Alert.java @@ -16,9 +16,15 @@ // under the License. package com.cloud.api.doc; -public class Alert { - private String type; - private int value; +import java.io.Serializable; + +public class Alert implements Serializable{ + /** + * + */ + private static final long serialVersionUID = 960408026527837920L; + private final String type; + private final int value; public Alert(String type, int value) { this.type = type; diff --git a/server/src/com/cloud/api/doc/Command.java b/server/src/com/cloud/api/doc/Command.java index 998b39fefab..549ca291ffe 100644 --- a/server/src/com/cloud/api/doc/Command.java +++ b/server/src/com/cloud/api/doc/Command.java @@ -16,10 +16,15 @@ // under the License. package com.cloud.api.doc; +import java.io.Serializable; import java.util.ArrayList; -public class Command { +public class Command implements Serializable{ + /** + * + */ + private static final long serialVersionUID = -4318310162503004975L; private String name; private String description; private String usage; @@ -85,7 +90,7 @@ public class Command { } public Argument getReqArgByName(String name) { - for (Argument a : this.getRequest()) { + for (Argument a : getRequest()) { if (a.getName().equals(name)) { return a; } @@ -94,7 +99,7 @@ public class Command { } public Argument getResArgByName(String name) { - for (Argument a : this.getResponse()) { + for (Argument a : getResponse()) { if (a.getName().equals(name)) { return a; } diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 182a5e49777..6fe65c23b3c 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -26,9 +26,6 @@ import java.util.Set; import javax.ejb.Local; import javax.inject.Inject; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO; import org.apache.cloudstack.affinity.AffinityGroupResponse; @@ -97,6 +94,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.query.QueryService; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.api.query.dao.AccountJoinDao; import com.cloud.api.query.dao.AffinityGroupJoinDao; @@ -2856,6 +2855,63 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { // search and ignore other query parameters sc.addAnd("id", SearchCriteria.Op.EQ, templateId); } else { + + DomainVO domain = null; + if (!permittedAccounts.isEmpty()) { + domain = _domainDao.findById(permittedAccounts.get(0)); + } else { + domain = _domainDao.findById(Domain.ROOT_DOMAIN); + } + + // List hypers = null; + // if (!isIso) { + // hypers = _resourceMgr.listAvailHypervisorInZone(null, null); + // } + + // add criteria for project or not + if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { + sc.addAnd("accountType", SearchCriteria.Op.NEQ, Account.ACCOUNT_TYPE_PROJECT); + } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.ListProjectResourcesOnly) { + sc.addAnd("accountType", SearchCriteria.Op.EQ, Account.ACCOUNT_TYPE_PROJECT); + } + + // add criteria for domain path in case of domain admin + if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) && + (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { + sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%"); + } + + List relatedDomainIds = new ArrayList(); + if (!permittedAccounts.isEmpty()) { + for (Long accountId : permittedAccounts) { + Account account = _accountDao.findById(accountId); + boolean publicTemplates = (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community); + + // get all parent domain ID's all the way till root domain + DomainVO domainTreeNode = null; + //if template filter is featured, or community, all child domains should be included in search + if (publicTemplates) { + domainTreeNode = _domainDao.findById(Domain.ROOT_DOMAIN); + + } else { + domainTreeNode = _domainDao.findById(account.getDomainId()); + } + relatedDomainIds.add(domainTreeNode.getId()); + while (domainTreeNode.getParent() != null) { + domainTreeNode = _domainDao.findById(domainTreeNode.getParent()); + relatedDomainIds.add(domainTreeNode.getId()); + } + + // get all child domain ID's + if (_accountMgr.isAdmin(account.getType()) || publicTemplates) { + List allChildDomains = _domainDao.findAllChildren(domainTreeNode.getPath(), domainTreeNode.getId()); + for (DomainVO childDomain : allChildDomains) { + relatedDomainIds.add(childDomain.getId()); + } + } + } + } + if (!isIso) { // add hypervisor criteria for template case if (hypers != null && !hypers.isEmpty()) { diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java index 92d6d5436fa..a5dfb16224e 100644 --- a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java @@ -104,7 +104,11 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem userVmResponse.setId(userVm.getUuid()); userVmResponse.setName(userVm.getName()); + if (userVm.getDisplayName() != null) { userVmResponse.setDisplayName(userVm.getDisplayName()); + } else { + userVmResponse.setDisplayName(userVm.getName()); + } if (userVm.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) { userVmResponse.setProjectId(userVm.getProjectUuid()); diff --git a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java index a759f3e9f2c..b0e5b32da34 100644 --- a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java +++ b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java @@ -36,8 +36,8 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume; -import com.cloud.utils.db.Encrypt; import com.cloud.utils.db.GenericDao; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; @@ -50,10 +50,10 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private long id; @Column(name = "name", updatable = false, nullable = false, length = 255) - private String name = null; + private final String name = null; @Column(name = "display_name", updatable = false, nullable = false, length = 255) - private String displayName = null; + private final String displayName = null; @Column(name = "account_id") private long accountId; @@ -62,7 +62,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private String accountUuid; @Column(name = "account_name") - private String accountName = null; + private final String accountName = null; @Column(name = "account_type") private short accountType; @@ -74,10 +74,10 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private String domainUuid; @Column(name = "domain_name") - private String domainName = null; + private final String domainName = null; @Column(name = "domain_path") - private String domainPath = null; + private final String domainPath = null; @Column(name = "instance_group_id") private long instanceGroupId; @@ -99,7 +99,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { */ @Enumerated(value = EnumType.STRING) @Column(name = "state", updatable = true, nullable = false, length = 32) - private State state = null; + private final State state = null; @Column(name = GenericDao.CREATED_COLUMN) private Date created; @@ -123,10 +123,6 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name = "ha_enabled", updatable = true, nullable = true) private boolean haEnabled; - @Encrypt - @Column(name = "vnc_password", updatable = true, nullable = false, length = 255) - protected String vncPassword; - @Column(name = "limit_cpu_use", updatable = true, nullable = true) private boolean limitCpuUse; @@ -155,7 +151,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private String dataCenterUuid; @Column(name = "data_center_name") - private String dataCenterName = null; + private final String dataCenterName = null; @Column(name = "security_group_enabled") private boolean securityGroupEnabled; @@ -240,7 +236,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private String volumeUuid; @Column(name = "volume_device_id") - private Long volumeDeviceId = null; + private final Long volumeDeviceId = null; @Column(name = "volume_type") @Enumerated(EnumType.STRING) @@ -539,10 +535,6 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { return haEnabled; } - public String getVncPassword() { - return vncPassword; - } - public String getPrivateIpAddress() { return privateIpAddress; } @@ -756,9 +748,11 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { } public String getDetail(String name) { - assert (details != null) : "Did you forget to load the details?"; + if (details == null) { + throw new CloudRuntimeException("No details to get. Did you forget to load the details?"); + } - return details != null ? details.get(name) : null; + return details.get(name); } public String getUserData() { diff --git a/server/src/com/cloud/api/response/ApiResponseSerializer.java b/server/src/com/cloud/api/response/ApiResponseSerializer.java index 97836f726c6..c254520fd2e 100644 --- a/server/src/com/cloud/api/response/ApiResponseSerializer.java +++ b/server/src/com/cloud/api/response/ApiResponseSerializer.java @@ -293,7 +293,7 @@ public class ApiResponseSerializer { } private static String encodeParam(String value) { - if (!ApiServer.encodeApiResponse) { + if (!ApiServer.isEncodeApiResponse()) { return value; } try { diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 9117bc45e9d..975eecdc117 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -402,6 +402,10 @@ public enum Config { "10", "The maximum number of subnets per customer gateway", null), + MaxNumberOfSecondaryIPsPerNIC( + "Network", ManagementServer.class, Integer.class, + "vm.network.nic.max.secondary.ipaddresses", "256", + "Specify the number of secondary ip addresses per nic per vm", null), // Console Proxy ConsoleProxyCapacityStandby( @@ -981,7 +985,6 @@ public enum Config { "FirstFitPlanner", "'FirstFitPlanner', 'UserDispersingPlanner', 'UserConcentratedPodPlanner': DeploymentPlanner heuristic that will be used for VM deployment.", null), - EndpointeUrl("Advanced", ManagementServer.class, String.class, "endpointe.url", "http://localhost:8080/client/api", "Endpointe Url", null), ElasticLoadBalancerEnabled( "Advanced", ManagementServer.class, diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index ac991d28ba6..5f02004c6ff 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -1691,7 +1691,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Storage); } catch (InvalidParameterValueException noStorage) { PhysicalNetworkTrafficTypeVO mgmtTraffic = _trafficTypeDao.findBy(mgmtPhyNetwork.getId(), TrafficType.Management); - _networkSvc.addTrafficTypeToPhysicalNetwork(mgmtPhyNetwork.getId(), TrafficType.Storage.toString(), mgmtTraffic.getXenNetworkLabel(), + _networkSvc.addTrafficTypeToPhysicalNetwork(mgmtPhyNetwork.getId(), TrafficType.Storage.toString(), "vlan", mgmtTraffic.getXenNetworkLabel(), mgmtTraffic.getKvmNetworkLabel(), mgmtTraffic.getVmwareNetworkLabel(), mgmtTraffic.getSimulatorNetworkLabel(), mgmtTraffic.getVlan(), mgmtTraffic.getHypervNetworkLabel()); s_logger.info("No storage traffic type was specified by admin, create default storage traffic on physical network " + mgmtPhyNetwork.getId() @@ -2643,8 +2643,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } return NetUtils.supersetOrSubset.neitherSubetNorSuperset; - } else if (newVlanGateway == null || newVlanGateway == null) { - throw new InvalidParameterValueException("either both netmask and gateway should be passed or both should me omited."); + } else if (newVlanGateway == null || newVlanNetmask == null) { + throw new InvalidParameterValueException( + "either both netmask and gateway should be passed or both should me omited."); } else { if (!NetUtils.sameSubnet(startIP, newVlanGateway, newVlanNetmask)) { throw new InvalidParameterValueException("The start ip and gateway do not belong to the same subnet"); @@ -4295,7 +4296,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override public boolean isOfferingForVpc(NetworkOffering offering) { - boolean vpcProvider = _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.VPCVirtualRouter); + boolean vpcProvider = _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.VPCVirtualRouter) || + _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.JuniperContrailVpcRouter); + return vpcProvider; } diff --git a/server/src/com/cloud/consoleproxy/AgentHookBase.java b/server/src/com/cloud/consoleproxy/AgentHookBase.java index 9dfffd4b98f..2e0bada3abb 100644 --- a/server/src/com/cloud/consoleproxy/AgentHookBase.java +++ b/server/src/com/cloud/consoleproxy/AgentHookBase.java @@ -49,6 +49,7 @@ import com.cloud.host.dao.HostDao; import com.cloud.servlet.ConsoleProxyPasswordBasedEncryptor; import com.cloud.servlet.ConsoleProxyServlet; import com.cloud.utils.Ternary; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.VMInstanceDao; @@ -192,7 +193,9 @@ public abstract class AgentHookBase implements AgentHook { assert (ksBits != null); if (ksBits == null) { - s_logger.error("Could not find and construct a valid SSL certificate"); + String msg = "Could not find and construct a valid SSL certificate"; + s_logger.error(msg); + throw new CloudRuntimeException(msg); } cmd = new StartConsoleProxyAgentHttpHandlerCommand(ksBits, storePassword); cmd.setEncryptorPassword(getEncryptorPassword()); diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 8d76b8ae345..813888707a3 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.consoleproxy; import java.nio.charset.Charset; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Iterator; @@ -483,7 +484,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy byte[] details = proxy.getSessionDetails(); status = gson.fromJson(details != null ? new String(details, Charset.forName("US-ASCII")) : null, ConsoleProxyStatus.class); } catch (Throwable e) { - s_logger.warn("Unable to parse proxy session details : " + proxy.getSessionDetails()); + s_logger.warn("Unable to parse proxy session details : " + Arrays.toString(proxy.getSessionDetails())); } if (status != null && status.getConnections() != null) { diff --git a/server/src/com/cloud/dc/DedicatedResourceVO.java b/server/src/com/cloud/dc/DedicatedResourceVO.java index 9948f504158..e7d7b3b282c 100644 --- a/server/src/com/cloud/dc/DedicatedResourceVO.java +++ b/server/src/com/cloud/dc/DedicatedResourceVO.java @@ -29,6 +29,11 @@ import javax.persistence.Table; @Table(name = "dedicated_resources") public class DedicatedResourceVO implements DedicatedResources { + /** + * + */ + private static final long serialVersionUID = -6659510127145101917L; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") @@ -59,7 +64,7 @@ public class DedicatedResourceVO implements DedicatedResources { private long affinityGroupId; public DedicatedResourceVO() { - this.uuid = UUID.randomUUID().toString(); + uuid = UUID.randomUUID().toString(); } public DedicatedResourceVO(Long dataCenterId, Long podId, Long clusterId, Long hostId, Long domainId, Long accountId, long affinityGroupId) { @@ -69,7 +74,7 @@ public class DedicatedResourceVO implements DedicatedResources { this.hostId = hostId; this.domainId = domainId; this.accountId = accountId; - this.uuid = UUID.randomUUID().toString(); + uuid = UUID.randomUUID().toString(); this.affinityGroupId = affinityGroupId; } @@ -115,7 +120,7 @@ public class DedicatedResourceVO implements DedicatedResources { } public DedicatedResourceVO(long dedicatedResourceId) { - this.id = dedicatedResourceId; + id = dedicatedResourceId; } @Override @@ -138,7 +143,7 @@ public class DedicatedResourceVO implements DedicatedResources { @Override public String getUuid() { - return this.uuid; + return uuid; } public void setUuid(String uuid) { @@ -153,7 +158,7 @@ public class DedicatedResourceVO implements DedicatedResources { @Override public boolean equals(Object obj) { if (obj instanceof DedicatedResourceVO) { - return ((DedicatedResourceVO)obj).getId() == this.getId(); + return ((DedicatedResourceVO)obj).getId() == getId(); } else { return false; } diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java index 28eecf1287c..ee8cc4dcf2a 100644 --- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java +++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.deploy; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -91,6 +92,7 @@ import com.cloud.org.Grouping; import com.cloud.resource.ResourceState; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.ScopeType; +import com.cloud.storage.Storage; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; @@ -163,7 +165,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } public void setStoragePoolAllocators(List storagePoolAllocators) { - this._storagePoolAllocators = storagePoolAllocators; + _storagePoolAllocators = storagePoolAllocators; } protected List _hostAllocators; @@ -173,7 +175,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } public void setHostAllocators(List hostAllocators) { - this._hostAllocators = hostAllocators; + _hostAllocators = hostAllocators; } @Inject @@ -219,7 +221,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } public void setPlanners(List planners) { - this._planners = planners; + _planners = planners; } protected List _affinityProcessors; @@ -229,7 +231,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } public void setAffinityGroupProcessors(List affinityProcessors) { - this._affinityProcessors = affinityProcessors; + _affinityProcessors = affinityProcessors; } @Override @@ -360,26 +362,40 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy " already has max Running VMs(count includes system VMs), skipping this and trying other available hosts"); } else { if (host.getStatus() == Status.Up && host.getResourceState() == ResourceState.Enabled) { + boolean hostTagsMatch = true; + if(offering.getHostTag() != null){ + _hostDao.loadHostTags(host); + if (!(host.getHostTags() != null && host.getHostTags().contains(offering.getHostTag()))) { + hostTagsMatch = false; + } + } + if (hostTagsMatch) { long cluster_id = host.getClusterId(); - ClusterDetailsVO cluster_detail_cpu = _clusterDetailsDao.findDetail(cluster_id, "cpuOvercommitRatio"); - ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao.findDetail(cluster_id, "memoryOvercommitRatio"); + ClusterDetailsVO cluster_detail_cpu = _clusterDetailsDao.findDetail(cluster_id, + "cpuOvercommitRatio"); + ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao.findDetail(cluster_id, + "memoryOvercommitRatio"); Float cpuOvercommitRatio = Float.parseFloat(cluster_detail_cpu.getValue()); Float memoryOvercommitRatio = Float.parseFloat(cluster_detail_ram.getValue()); - if (_capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, true, cpuOvercommitRatio, memoryOvercommitRatio, true) - && _capacityMgr.checkIfHostHasCpuCapability(host.getId(), offering.getCpu(), offering.getSpeed())) { + if (_capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, true, + cpuOvercommitRatio, memoryOvercommitRatio, true) + && _capacityMgr.checkIfHostHasCpuCapability(host.getId(), offering.getCpu(), + offering.getSpeed())) { s_logger.debug("The last host of this VM is UP and has enough capacity"); - s_logger.debug("Now checking for suitable pools under zone: " + host.getDataCenterId() + ", pod: " + host.getPodId() + ", cluster: " + - host.getClusterId()); - // search for storage under the zone, pod, cluster of + s_logger.debug("Now checking for suitable pools under zone: " + host.getDataCenterId() + + ", pod: " + host.getPodId() + ", cluster: " + host.getClusterId()); + // search for storage under the zone, pod, cluster + // of // the last host. - DataCenterDeployment lastPlan = - new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId(), null); - Pair>, List> result = - findSuitablePoolsForVolumes(vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL); + DataCenterDeployment lastPlan = new DataCenterDeployment(host.getDataCenterId(), + host.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId(), null); + Pair>, List> result = findSuitablePoolsForVolumes( + vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL); Map> suitableVolumeStoragePools = result.first(); List readyAndReusedVolumes = result.second(); - // choose the potential pool for this VM for this host + // choose the potential pool for this VM for this + // host if (!suitableVolumeStoragePools.isEmpty()) { List suitableHosts = new ArrayList(); suitableHosts.add(host); @@ -391,12 +407,14 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy Cluster cluster = _clusterDao.findById(host.getClusterId()); Map storageVolMap = potentialResources.second(); // remove the reused vol<->pool from - // destination, since we don't have to prepare + // destination, since we don't have to + // prepare // this volume. for (Volume vol : readyAndReusedVolumes) { storageVolMap.remove(vol); } - DeployDestination dest = new DeployDestination(dc, pod, cluster, host, storageVolMap); + DeployDestination dest = new DeployDestination(dc, pod, cluster, host, + storageVolMap); s_logger.debug("Returning Deployment Destination: " + dest); return dest; } @@ -405,6 +423,9 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy s_logger.debug("The last host of this VM does not have enough capacity"); } } else { + s_logger.debug("Service Offering host tag does not match the last host of this VM"); + } + } else { s_logger.debug("The last host of this VM is not UP or is not enabled, host status is: " + host.getStatus().name() + ", host resource state is: " + host.getResourceState()); } @@ -1140,9 +1161,9 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy List suitablePools = new ArrayList(); StoragePool pool = null; if (toBeCreated.getPoolId() != null) { - pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(toBeCreated.getPoolId()); + pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(toBeCreated.getPoolId()); } else { - pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(plan.getPoolId()); + pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(plan.getPoolId()); } if (!pool.isInMaintenance()) { @@ -1154,7 +1175,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy if (plan.getDataCenterId() == exstPoolDcId && plan.getPodId() == exstPoolPodId && plan.getClusterId() == exstPoolClusterId) { canReusePool = true; } else if (plan.getDataCenterId() == exstPoolDcId) { - DataStore dataStore = this.dataStoreMgr.getPrimaryDataStore(pool.getId()); + DataStore dataStore = dataStoreMgr.getPrimaryDataStore(pool.getId()); if (dataStore != null && dataStore.getScope() != null && dataStore.getScope().getScopeType() == ScopeType.ZONE) { canReusePool = true; } @@ -1202,8 +1223,12 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy s_logger.debug("Calling StoragePoolAllocators to find suitable pools"); DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId()); - DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType()); + if (vmProfile.getTemplate().getFormat() == Storage.ImageFormat.ISO && vmProfile.getServiceOffering().getTagsArray().length != 0) { + diskOffering.setTagsArray(Arrays.asList(vmProfile.getServiceOffering().getTagsArray())); + } + + DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType()); boolean useLocalStorage = false; if (vmProfile.getType() != VirtualMachine.Type.User) { String ssvmUseLocalStorage = _configDao.getValue(Config.SystemVMUseLocalStorage.key()); @@ -1253,9 +1278,14 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } } - if (suitableVolumeStoragePools.values() != null) { - poolsToAvoidOutput.removeAll(suitableVolumeStoragePools.values()); + HashSet toRemove = new HashSet(); + for (List lsp : suitableVolumeStoragePools.values()) { + for (StoragePool sp : lsp) { + toRemove.add(sp.getId()); + } } + poolsToAvoidOutput.removeAll(toRemove); + if (avoid.getPoolsToAvoid() != null) { avoid.getPoolsToAvoid().addAll(poolsToAvoidOutput); } diff --git a/server/src/com/cloud/event/ActionEventUtils.java b/server/src/com/cloud/event/ActionEventUtils.java index 0363a0d81dd..c332a8e32e4 100755 --- a/server/src/com/cloud/event/ActionEventUtils.java +++ b/server/src/com/cloud/event/ActionEventUtils.java @@ -25,6 +25,7 @@ import java.util.Map; import javax.annotation.PostConstruct; import javax.inject.Inject; +import com.cloud.vm.VirtualMachine; import org.apache.log4j.Logger; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -40,6 +41,8 @@ import com.cloud.user.AccountVO; import com.cloud.user.User; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; +import com.cloud.projects.dao.ProjectDao; +import com.cloud.projects.Project; import com.cloud.utils.component.ComponentContext; public class ActionEventUtils { @@ -47,6 +50,7 @@ public class ActionEventUtils { private static EventDao s_eventDao; private static AccountDao s_accountDao; + private static ProjectDao s_projectDao; protected static UserDao s_userDao; protected static EventBus s_eventBus = null; @@ -62,6 +66,8 @@ public class ActionEventUtils { AccountDao accountDao; @Inject UserDao userDao; + @Inject + ProjectDao projectDao; public ActionEventUtils() { } @@ -71,6 +77,7 @@ public class ActionEventUtils { s_eventDao = eventDao; s_accountDao = accountDao; s_userDao = userDao; + s_projectDao = projectDao; } public static Long onActionEvent(Long userId, Long accountId, Long domainId, String type, String description) { @@ -181,9 +188,10 @@ public class ActionEventUtils { } org.apache.cloudstack.framework.events.Event event = - new org.apache.cloudstack.framework.events.Event(ManagementService.Name, eventCategory, eventType, EventTypes.getEntityForEvent(eventType), null); + new org.apache.cloudstack.framework.events.Event(ManagementService.Name, eventCategory, eventType, EventTypes.getEntityForEvent(eventType), entityUuid); Map eventDescription = new HashMap(); + Project project = s_projectDao.findByProjectAccountId(accountId); Account account = s_accountDao.findById(accountId); User user = s_userDao.findById(userId); // if account has been deleted, this might be called during cleanup of resources and results in null pointer @@ -191,6 +199,8 @@ public class ActionEventUtils { return; if (user == null) return; + if (project != null) + eventDescription.put("project", project.getUuid()); eventDescription.put("user", user.getUuid()); eventDescription.put("account", account.getUuid()); eventDescription.put("event", eventType); @@ -233,6 +243,8 @@ public class ActionEventUtils { else if (eventType.startsWith("USER.")) { return User.class; + }else if (eventType.startsWith("VM.")){ + return VirtualMachine.class; } return null; diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java index da1bb88bbba..770099c65fd 100644 --- a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java @@ -28,8 +28,6 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; - import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; @@ -41,7 +39,6 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.configuration.Config; import com.cloud.dc.ClusterVO; -import com.cloud.dc.dao.ClusterDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.DiscoveredWithErrorException; import com.cloud.exception.DiscoveryException; @@ -49,10 +46,8 @@ import com.cloud.exception.OperationTimedoutException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; -import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.NetworkModel; import com.cloud.network.PhysicalNetworkSetupInfo; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; @@ -70,17 +65,9 @@ public abstract class LibvirtServerDiscoverer extends DiscovererBase implements private String _kvmPublicNic; private String _kvmGuestNic; @Inject - HostDao _hostDao = null; - @Inject - ClusterDao _clusterDao; - @Inject ResourceManager _resourceMgr; @Inject AgentManager _agentMgr; - @Inject - ConfigurationDao _configDao; - @Inject - NetworkModel _networkMgr; @Override public abstract Hypervisor.HypervisorType getHypervisorType(); diff --git a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java index c7906f52d16..17b489510aa 100644 --- a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java +++ b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java @@ -26,6 +26,8 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.api.ResourceDetail; import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; +import org.apache.cloudstack.resourcedetail.dao.AutoScaleVmGroupDetailsDao; +import org.apache.cloudstack.resourcedetail.dao.AutoScaleVmProfileDetailsDao; import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao; import org.apache.cloudstack.resourcedetail.dao.FirewallRuleDetailsDao; import org.apache.cloudstack.resourcedetail.dao.NetworkACLItemDetailsDao; @@ -107,6 +109,10 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource DiskOfferingDetailsDao _diskOfferingDetailsDao; @Inject UserDetailsDao _userDetailsDao; + @Inject + AutoScaleVmProfileDetailsDao _autoScaleVmProfileDetailsDao; + @Inject + AutoScaleVmGroupDetailsDao _autoScaleVmGroupDetailsDao; private static Map> s_daoMap = new HashMap>(); @@ -134,6 +140,8 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource s_daoMap.put(ResourceObjectType.VpnConnection, _vpnConnectionDetailsDao); s_daoMap.put(ResourceObjectType.DiskOffering, _diskOfferingDetailsDao); s_daoMap.put(ResourceObjectType.User, _userDetailsDao); + s_daoMap.put(ResourceObjectType.AutoScaleVmProfile, _autoScaleVmProfileDetailsDao); + s_daoMap.put(ResourceObjectType.AutoScaleVmGroup, _autoScaleVmGroupDetailsDao); return true; } diff --git a/server/src/com/cloud/network/ExternalIpAddressAllocator.java b/server/src/com/cloud/network/ExternalIpAddressAllocator.java index 2b84231c050..3cf358067ee 100644 --- a/server/src/com/cloud/network/ExternalIpAddressAllocator.java +++ b/server/src/com/cloud/network/ExternalIpAddressAllocator.java @@ -40,7 +40,6 @@ import com.cloud.utils.exception.CloudRuntimeException; @Local(value = IpAddrAllocator.class) public class ExternalIpAddressAllocator extends AdapterBase implements IpAddrAllocator { private static final Logger s_logger = Logger.getLogger(ExternalIpAddressAllocator.class); - String _name; @Inject ConfigurationDao _configDao = null; @Inject @@ -52,10 +51,10 @@ public class ExternalIpAddressAllocator extends AdapterBase implements IpAddrAll @Override public IpAddr getPrivateIpAddress(String macAddr, long dcId, long podId) { - if (_externalIpAllocatorUrl == null || this._externalIpAllocatorUrl.equalsIgnoreCase("")) { + if (_externalIpAllocatorUrl == null || _externalIpAllocatorUrl.equalsIgnoreCase("")) { return new IpAddr(); } - String urlString = this._externalIpAllocatorUrl + "?command=getIpAddr&mac=" + macAddr + "&dc=" + dcId + "&pod=" + podId; + String urlString = _externalIpAllocatorUrl + "?command=getIpAddr&mac=" + macAddr + "&dc=" + dcId + "&pod=" + podId; s_logger.debug("getIP:" + urlString); BufferedReader in = null; @@ -101,11 +100,11 @@ public class ExternalIpAddressAllocator extends AdapterBase implements IpAddrAll @Override public boolean releasePrivateIpAddress(String ip, long dcId, long podId) { /*TODO: call API to release the ip address from external DHCP server*/ - if (_externalIpAllocatorUrl == null || this._externalIpAllocatorUrl.equalsIgnoreCase("")) { + if (_externalIpAllocatorUrl == null || _externalIpAllocatorUrl.equalsIgnoreCase("")) { return false; } - String urlString = this._externalIpAllocatorUrl + "?command=releaseIpAddr&ip=" + ip + "&dc=" + dcId + "&pod=" + podId; + String urlString = _externalIpAllocatorUrl + "?command=releaseIpAddr&ip=" + ip + "&dc=" + dcId + "&pod=" + podId; s_logger.debug("releaseIP:" + urlString); BufferedReader in = null; diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java index e8de7f03251..5e2046cc228 100644 --- a/server/src/com/cloud/network/IpAddressManagerImpl.java +++ b/server/src/com/cloud/network/IpAddressManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.network; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -28,6 +29,8 @@ import java.util.UUID; import javax.inject.Inject; +import org.apache.log4j.Logger; + import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.context.CallContext; @@ -39,7 +42,6 @@ import org.apache.cloudstack.region.PortableIp; import org.apache.cloudstack.region.PortableIpDao; import org.apache.cloudstack.region.PortableIpVO; import org.apache.cloudstack.region.Region; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.alert.AlertManager; @@ -570,8 +572,9 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage IPAddressVO ip = markIpAsUnavailable(addrId); - assert (ip != null) : "Unable to mark the ip address id=" + addrId + " as unavailable."; if (ip == null) { + String msg = "Unable to mark the ip address id=" + addrId + " as unavailable."; + s_logger.error(msg); return true; } @@ -684,10 +687,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) { fetchFromDedicatedRange = true; sc.setParameters("vlanId", dedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + dedicatedVlanDbIds.toArray()); + errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray())); } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray()); + errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray())); } else { if (podId != null) { InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId); @@ -727,7 +730,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { fetchFromDedicatedRange = false; sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray()); + errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray())); addrs = _ipAddressDao.lockRows(sc, filter, true); } } @@ -852,6 +855,11 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage public PublicIp assignDedicateIpAddress(Account owner, final Long guestNtwkId, final Long vpcId, final long dcId, final boolean isSourceNat) throws ConcurrentOperationException, InsufficientAddressCapacityException { + if (owner == null) { + s_logger.error("No account to assign an ip to."); + return null; + } + final long ownerId = owner.getId(); PublicIp ip = null; @@ -883,13 +891,11 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage return ip; } finally { - if (owner != null) { if (s_logger.isDebugEnabled()) { s_logger.debug("Releasing lock account " + ownerId); } - _accountDao.releaseFromLockTable(ownerId); - } + if (ip == null) { s_logger.error("Unable to get source nat ip address for account " + ownerId); } @@ -1218,7 +1224,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage s_logger.debug("Associating ip " + ipToAssoc + " to network " + network); - IPAddressVO ip = _ipAddressDao.findById(ipId); + IPAddressVO ip = ipToAssoc; //_ipAddressDao.findById(ipId); //update ip address with networkId ip.setAssociatedWithNetworkId(networkId); ip.setSourceNat(isSourceNat); @@ -1235,7 +1241,6 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage return ip; } finally { if (!success && releaseOnFailure) { - if (ip != null) { try { s_logger.warn("Failed to associate ip address, so releasing ip from the database " + ip); _ipAddressDao.markAsUnavailable(ip.getId()); @@ -1250,7 +1255,6 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage } } } - } protected boolean isSharedNetworkOfferingWithServices(long networkOfferingId) { NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId); @@ -1327,7 +1331,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage PublicIp publicIp = PublicIp.createFromAddrAndVlan(ipToAssoc, _vlanDao.findById(ipToAssoc.getVlanId())); ipList.add(publicIp); Map> ipToServices = _networkModel.getIpToServices(ipList, false, true); - if (ipToServices != null & !ipToServices.isEmpty()) { + if (ipToServices != null && !ipToServices.isEmpty()) { Set services = ipToServices.get(publicIp); if (services != null && !services.isEmpty()) { throw new InvalidParameterValueException("IP " + ipToAssoc + " has services and rules associated in the network " + networkId); @@ -1368,7 +1372,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage PublicIp publicIp = PublicIp.createFromAddrAndVlan(ip, _vlanDao.findById(ip.getVlanId())); ipList.add(publicIp); Map> ipToServices = _networkModel.getIpToServices(ipList, false, true); - if (ipToServices != null & !ipToServices.isEmpty()) { + if (ipToServices != null && !ipToServices.isEmpty()) { Set ipServices = ipToServices.get(publicIp); if (ipServices != null && !ipServices.isEmpty()) { return false; @@ -1671,14 +1675,14 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override public boolean applyStaticNats(List staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException { - Network network = _networksDao.findById(staticNats.get(0).getNetworkId()); - boolean success = true; - if (staticNats == null || staticNats.size() == 0) { s_logger.debug("There are no static nat rules for the network elements"); return true; } + Network network = _networksDao.findById(staticNats.get(0).getNetworkId()); + boolean success = true; + // get the list of public ip's owned by the network List userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null); List publicIps = new ArrayList(); diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index 52a08e1480e..68807d38939 100755 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -1017,14 +1017,14 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { List map = _ntwkOfferingSrvcDao.listByNetworkOfferingId(networkOfferingId); for (NetworkOfferingServiceMapVO instance : map) { - String service = instance.getService(); + Service service = Network.Service.getService(instance.getService()); Set providers; providers = serviceProviderMap.get(service); if (providers == null) { providers = new HashSet(); } providers.add(Provider.getProvider(instance.getProvider())); - serviceProviderMap.put(Service.getService(service), providers); + serviceProviderMap.put(service, providers); } return serviceProviderMap; @@ -1533,6 +1533,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { @Override public void checkNetworkPermissions(Account owner, Network network) { + if (network == null) { + throw new CloudRuntimeException("no network to check permissions for."); + } // Perform account permission check if (network.getGuestType() != Network.GuestType.Shared || (network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Account)) { AccountVO networkOwner = _accountDao.findById(network.getAccountId()); diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 4b7195c2ab2..474f5103d84 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -671,6 +671,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Invalid network id is given"); } + int maxAllowedIpsPerNic = NumbersUtil.parseInt(_configDao.getValue(Config.MaxNumberOfSecondaryIPsPerNIC.key()), 10); + Long nicWiseIpCount = _nicSecondaryIpDao.countByNicId(nicId); + if(nicWiseIpCount.intValue() >= maxAllowedIpsPerNic) { + s_logger.error("Maximum Number of Ips \"vm.network.nic.max.secondary.ipaddresses = \"" + maxAllowedIpsPerNic + " per Nic has been crossed for the nic " + nicId + "."); + throw new InsufficientAddressCapacityException("Maximum Number of Ips per Nic has been crossed.", Nic.class, nicId); + } + + s_logger.debug("Calling the ip allocation ..."); String ipaddr = null; //Isolated network can exist in Basic zone only, so no need to verify the zone type @@ -3531,7 +3539,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_CREATE, eventDescription = "Creating Physical Network TrafficType", create = true) - public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficTypeStr, String xenLabel, String kvmLabel, String vmwareLabel, + public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficTypeStr, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan, String hypervLabel) { // verify input parameters @@ -3587,6 +3595,20 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { vlan, hypervLabel); pNetworktrafficType = _pNTrafficTypeDao.persist(pNetworktrafficType); + // For public traffic, get isolation method of physical network and update the public network accordingly + // each broadcast type will individually need to be qualified for support of public traffic + List isolationMethods = network.getIsolationMethods(); + if ((isolationMethods.size() == 1 && isolationMethods.get(0).toLowerCase().equals("vxlan")) + || (isolationMethod != null && isolationMethods.contains(isolationMethod) && isolationMethod.toLowerCase().equals("vxlan"))) { + // find row in networks table that is defined as 'Public', created when zone was deployed + NetworkVO publicNetwork = _networksDao.listByZoneAndTrafficType(network.getDataCenterId(),TrafficType.Public).get(0); + if (publicNetwork != null) { + s_logger.debug("setting public network " + publicNetwork + " to broadcast type vxlan"); + publicNetwork.setBroadcastDomainType(BroadcastDomainType.Vxlan); + _networksDao.persist(publicNetwork); + } + } + return pNetworktrafficType; } catch (Exception ex) { s_logger.warn("Exception: ", ex); @@ -3848,10 +3870,16 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { Network network = _networksDao.findById(networkId); if (network == null) { + // release the acquired IP addrress before throwing the exception + // else it will always be in allocating state + releaseIpAddress(ipId); throw new InvalidParameterValueException("Invalid network id is given"); } if (network.getVpcId() != null) { + // release the acquired IP addrress before throwing the exception + // else it will always be in allocating state + releaseIpAddress(ipId); throw new InvalidParameterValueException("Can't assign ip to the network directly when network belongs" + " to VPC.Specify vpcId to associate ip address to VPC"); } return _ipAddrMgr.associateIPToGuestNetwork(ipId, networkId, true); diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java index 367b8e6ca73..0e6a6b4ab66 100644 --- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -55,12 +55,12 @@ import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScalePolicyCmd import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmGroupCmd; import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmProfileCmd; import org.apache.cloudstack.api.command.user.vm.DeployVMCmd; +import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiDispatcher; -import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; @@ -314,7 +314,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale String apiKey = user.getApiKey(); String secretKey = user.getSecretKey(); - String csUrl = _configDao.getValue(Config.EndpointeUrl.key()); + String csUrl = ApiServiceConfiguration.ApiServletPath.value(); if (apiKey == null) { throw new InvalidParameterValueException("apiKey for user: " + user.getUsername() + " is empty. Please generate it"); @@ -439,6 +439,8 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale Long id = cmd.getId(); Long templateId = cmd.getTemplateId(); String otherDeployParams = cmd.getOtherDeployParams(); + Long serviceOffId = cmd.getServiceOfferingId(); + Long zoneId = cmd.getZoneId(); SearchWrapper searchWrapper = new SearchWrapper(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId(), "listAutoScaleVmProfiles"); @@ -446,7 +448,9 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("templateId", sb.entity().getTemplateId(), SearchCriteria.Op.EQ); + sb.and("serviceOfferingId", sb.entity().getServiceOfferingId(), SearchCriteria.Op.EQ); sb.and("otherDeployParams", sb.entity().getOtherDeployParams(), SearchCriteria.Op.LIKE); + sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); SearchCriteria sc = searchWrapper.buildSearchCriteria(); if (id != null) { @@ -458,6 +462,15 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale if (otherDeployParams != null) { sc.addAnd("otherDeployParams", SearchCriteria.Op.LIKE, "%" + otherDeployParams + "%"); } + + if (serviceOffId != null) { + sc.setParameters("serviceOfferingId", serviceOffId); + } + + if (zoneId != null) { + sc.setParameters("zoneId", zoneId); + } + return searchWrapper.search(); } diff --git a/server/src/com/cloud/network/guru/ControlNetworkGuru.java b/server/src/com/cloud/network/guru/ControlNetworkGuru.java index a6e21801586..13ff385da90 100755 --- a/server/src/com/cloud/network/guru/ControlNetworkGuru.java +++ b/server/src/com/cloud/network/guru/ControlNetworkGuru.java @@ -224,12 +224,12 @@ public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGu Map dbParams = _configDao.getConfiguration(params); - _cidr = dbParams.get(Config.ControlCidr); + _cidr = dbParams.get(Config.ControlCidr.toString()); if (_cidr == null) { _cidr = "169.254.0.0/16"; } - _gateway = dbParams.get(Config.ControlGateway); + _gateway = dbParams.get(Config.ControlGateway.toString()); if (_gateway == null) { _gateway = NetUtils.getLinkLocalGateway(); } diff --git a/server/src/com/cloud/network/guru/PublicNetworkGuru.java b/server/src/com/cloud/network/guru/PublicNetworkGuru.java index 34e97d34423..95d7790f2cb 100755 --- a/server/src/com/cloud/network/guru/PublicNetworkGuru.java +++ b/server/src/com/cloud/network/guru/PublicNetworkGuru.java @@ -103,7 +103,7 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { if (offering.getTrafficType() == TrafficType.Public) { NetworkVO ntwk = - new NetworkVO(offering.getTrafficType(), Mode.Static, BroadcastDomainType.Vlan, offering.getId(), State.Setup, plan.getDataCenterId(), + new NetworkVO(offering.getTrafficType(), Mode.Static, network.getBroadcastDomainType(), offering.getId(), State.Setup, plan.getDataCenterId(), plan.getPhysicalNetworkId()); return ntwk; } else { @@ -122,9 +122,15 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { nic.setIp4Address(ip.getAddress().toString()); nic.setGateway(ip.getGateway()); nic.setNetmask(ip.getNetmask()); - nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); - nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); - nic.setBroadcastType(BroadcastDomainType.Vlan); + if (network.getBroadcastDomainType() == BroadcastDomainType.Vxlan) { + nic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(ip.getVlanTag())); + nic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(ip.getVlanTag())); + nic.setBroadcastType(BroadcastDomainType.Vxlan); + } else { + nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastType(BroadcastDomainType.Vlan); + } nic.setFormat(AddressFormat.Ip4); nic.setReservationId(String.valueOf(ip.getVlanTag())); nic.setMacAddress(ip.getMacAddress()); diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index a0ce19dd992..d7bffb59e7e 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -30,11 +30,6 @@ import java.util.Set; import javax.ejb.Local; import javax.inject.Inject; -import org.apache.log4j.Logger; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd; import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd; @@ -44,14 +39,15 @@ import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleI import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRulesCmd; import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRuleCmd; import org.apache.cloudstack.api.response.ServiceResponse; +import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO; import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; +import org.apache.log4j.Logger; import com.cloud.agent.api.to.LoadBalancerTO; -import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; @@ -168,6 +164,8 @@ import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; @Local(value = {LoadBalancingRulesManager.class, LoadBalancingRulesService.class}) public class LoadBalancingRulesManagerImpl extends ManagerBase implements LoadBalancingRulesManager, LoadBalancingRulesService { @@ -305,7 +303,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements User user = _userDao.findByIdIncludingRemoved(autoscaleUserId); String apiKey = user.getApiKey(); String secretKey = user.getSecretKey(); - String csUrl = _configDao.getValue(Config.EndpointeUrl.key()); + String csUrl = ApiServiceConfiguration.ApiServletPath.value(); String zoneId = _dcDao.findById(autoScaleVmProfile.getZoneId()).getUuid(); String domainId = _domainDao.findById(autoScaleVmProfile.getDomainId()).getUuid(); String serviceOfferingId = _offeringsDao.findById(autoScaleVmProfile.getServiceOfferingId()).getUuid(); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index d7c7310411f..bf2516a24a9 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1834,9 +1834,17 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V defaultNic.setGateway(sourceNatIp.getGateway()); defaultNic.setNetmask(sourceNatIp.getNetmask()); defaultNic.setMacAddress(sourceNatIp.getMacAddress()); - defaultNic.setBroadcastType(BroadcastDomainType.Vlan); - defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); + // get broadcast from public network + Network pubNet = _networkDao.findById(sourceNatIp.getNetworkId()); + if (pubNet.getBroadcastDomainType() == BroadcastDomainType.Vxlan) { + defaultNic.setBroadcastType(BroadcastDomainType.Vxlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag())); + } else { + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); + } if (hasGuestNetwork) { defaultNic.setDeviceId(2); } @@ -2117,7 +2125,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V buf.append(" dnssearchorder=").append(domain_suffix); } - if (profile.getHypervisorType() == HypervisorType.VMware) { + if (profile.getHypervisorType() == HypervisorType.VMware || profile.getHypervisorType() == HypervisorType.Hyperv) { buf.append(" extra_pubnics=" + _routerExtraPublicNics); } diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index cd684407c2e..d5f9405bf59 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -40,6 +40,9 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.log4j.Logger; + import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupEgressCmd; import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupIngressCmd; import org.apache.cloudstack.api.command.user.securitygroup.CreateSecurityGroupCmd; @@ -51,8 +54,6 @@ import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationSe import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.utils.identity.ManagementServerNode; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.NetworkRulesSystemVmCommand; @@ -373,7 +374,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro protected String generateRulesetSignature(Map> ingress, Map> egress) { String ruleset = ingress.toString(); - ruleset.concat(egress.toString()); + ruleset = ruleset.concat(egress.toString()); return DigestUtils.md5Hex(ruleset); } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 2ffe510119f..3d9821dc475 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -203,7 +203,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker")); private List vpcElements = null; private final List nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall); - private final List supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler); + private final List supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler, Provider.JuniperContrailVpcRouter); int _cleanupInterval; int _maxNetworks; @@ -308,6 +308,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis // Just here for 4.1, replaced by commit 836ce6c1 in newer versions Set sdnProviders = new HashSet(); sdnProviders.add(Provider.NiciraNvp); + sdnProviders.add(Provider.JuniperContrailVpcRouter); boolean sourceNatSvc = false; boolean firewallSvs = false; @@ -424,14 +425,14 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis List map = _vpcOffSvcMapDao.listByVpcOffId(vpcOffId); for (VpcOfferingServiceMapVO instance : map) { - String service = instance.getService(); + Service service = Service.getService(instance.getService()); Set providers; providers = serviceProviderMap.get(service); if (providers == null) { providers = new HashSet(); } providers.add(Provider.getProvider(instance.getProvider())); - serviceProviderMap.put(Service.getService(service), providers); + serviceProviderMap.put(service, providers); } return serviceProviderMap; @@ -1193,6 +1194,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis if (vpcElements == null) { vpcElements = new ArrayList(); vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Provider.VPCVirtualRouter.getName())); + vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Provider.JuniperContrailVpcRouter.getName())); } if (vpcElements == null) { diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index 6e6dfd0df65..d10c059bd52 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -624,6 +624,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { domainUuid = domain.getUuid(); } ex.addProxyObject(domainUuid, "domainId"); + throw ex; } //verify permissions diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 6b4bdd9986a..74cfc31e749 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -880,7 +880,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim } _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue()); - if (oldCount != newCount) { + if (!Long.valueOf(oldCount).equals(newCount)) { s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " + newCount + ") for type " + type + " for account ID " + accountId + " is fixed during resource count recalculation."); } diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index 5a6ca78a9eb..3b5f5ff206a 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.server; +import com.cloud.host.DetailVO; import com.cloud.host.HostVO; import com.cloud.storage.GuestOSVO; import com.cloud.utils.Pair; @@ -47,6 +48,8 @@ public interface ManagementServer extends ManagementService, PluggableService { */ HostVO getHostBy(long hostId); + DetailVO findDetail(long hostId, String name); + String getConsoleAccessUrlRoot(long vmId); GuestOSVO getGuestOs(Long guestOsId); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index d72390f7052..0fe7f17f5d9 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -856,6 +856,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return _hostDao.findById(hostId); } + @Override + public DetailVO findDetail(long hostId, String name) { + return _detailsDao.findDetail(hostId, name); + } + @Override public long getId() { return MacAddress.getMacAddress().toLong(); @@ -901,7 +906,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe List events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getStartDate(), cmd.getEndDate(), permittedAccountIds); ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]); - _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEvents); + _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, false, sameOwnerEvents); if (ids != null && events.size() < ids.size()) { result = false; @@ -928,7 +933,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe List events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getStartDate(), cmd.getEndDate(), permittedAccountIds); ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]); - _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEvents); + _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, false, sameOwnerEvents); if (ids != null && events.size() < ids.size()) { result = false; diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index 95ae047cea8..548587cfa8e 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -737,7 +737,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc } String counterName = getCounternamebyCondition(conditionId.longValue()); - if (counterName == Counter.Source.memory.toString()) { + if (Counter.Source.memory.toString().equals(counterName)) { // calculate memory in percent Long profileId = asGroup.getProfileId(); AutoScaleVmProfileVO profileVo = _asProfileDao.findById(profileId); @@ -839,11 +839,11 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc Double sum = avgCounter.get(counter_count); Double avg = sum / currentVM; Operator op = conditionVO.getRelationalOperator(); - boolean bConditionCheck = ((op == com.cloud.network.as.Condition.Operator.EQ) && (thresholdPercent == avg)) - || ((op == com.cloud.network.as.Condition.Operator.GE) && (avg >= thresholdPercent)) - || ((op == com.cloud.network.as.Condition.Operator.GT) && (avg > thresholdPercent)) - || ((op == com.cloud.network.as.Condition.Operator.LE) && (avg <= thresholdPercent)) - || ((op == com.cloud.network.as.Condition.Operator.LT) && (avg < thresholdPercent)); + boolean bConditionCheck = ((op == com.cloud.network.as.Condition.Operator.EQ) && (thresholdPercent.equals(avg))) + || ((op == com.cloud.network.as.Condition.Operator.GE) && (avg.doubleValue() >= thresholdPercent.doubleValue())) + || ((op == com.cloud.network.as.Condition.Operator.GT) && (avg.doubleValue() > thresholdPercent.doubleValue())) + || ((op == com.cloud.network.as.Condition.Operator.LE) && (avg.doubleValue() <= thresholdPercent.doubleValue())) + || ((op == com.cloud.network.as.Condition.Operator.LT) && (avg.doubleValue() < thresholdPercent.doubleValue())); if (!bConditionCheck) { bValid = false; diff --git a/server/src/com/cloud/servlet/ConsoleProxyClientParam.java b/server/src/com/cloud/servlet/ConsoleProxyClientParam.java index e9793373c16..ce06a9624a9 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyClientParam.java +++ b/server/src/com/cloud/servlet/ConsoleProxyClientParam.java @@ -27,7 +27,11 @@ public class ConsoleProxyClientParam { private String clientTunnelUrl; private String clientTunnelSession; + private String hypervHost; + private String ajaxSessionId; + private String username; + private String password; public ConsoleProxyClientParam() { clientHostPort = 0; @@ -89,26 +93,51 @@ public class ConsoleProxyClientParam { this.clientTunnelSession = clientTunnelSession; } - public String getLocale() { - return this.locale; - } - - public void setLocale(String locale) { - this.locale = locale; - } - public String getAjaxSessionId() { - return this.ajaxSessionId; + return ajaxSessionId; } public void setAjaxSessionId(String ajaxSessionId) { this.ajaxSessionId = ajaxSessionId; } + public String getLocale() { + return locale; + } + + public void setLocale(String locale) { + this.locale = locale; + } + public String getClientMapKey() { if (clientTag != null && !clientTag.isEmpty()) return clientTag; return clientHostAddress + ":" + clientHostPort; } + + public void setHypervHost(String host) { + hypervHost = host; + } + + public String getHypervHost() { + return hypervHost; + } + + public void setUsername(String username) { + this.username = username; + + } + + public String getUsername() { + return username; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPassword() { + return password; + } } diff --git a/server/src/com/cloud/servlet/ConsoleProxyServlet.java b/server/src/com/cloud/servlet/ConsoleProxyServlet.java index f39dcb56ffb..60f32cf4bb0 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyServlet.java +++ b/server/src/com/cloud/servlet/ConsoleProxyServlet.java @@ -328,7 +328,8 @@ public class ConsoleProxyServlet extends HttpServlet { s_logger.info("Parse host info returned from executing GetVNCPortCommand. host info: " + hostInfo); - if (hostInfo != null && hostInfo.startsWith("consoleurl")) { + if (hostInfo != null) { + if (hostInfo.startsWith("consoleurl")) { String tokens[] = hostInfo.split("&"); if (hostInfo.length() > 19 && hostInfo.indexOf('/', 19) > 19) { @@ -338,6 +339,11 @@ public class ConsoleProxyServlet extends HttpServlet { } else { host = ""; } + } else if (hostInfo.startsWith("instanceId")) { + host = hostInfo.substring(hostInfo.indexOf('=') + 1); + } else { + host = hostInfo; + } } else { host = hostInfo; } @@ -363,7 +369,16 @@ public class ConsoleProxyServlet extends HttpServlet { String sid = vm.getVncPassword(); String tag = vm.getUuid(); - String ticket = genAccessTicket(host, String.valueOf(portInfo.second()), sid, tag); + + int port = -1; + if (portInfo.second() == -9) { + //for hyperv + port = Integer.parseInt(_ms.findDetail(hostVo.getId(), "rdp.server.port").getValue()); + } else { + port = portInfo.second(); + } + + String ticket = genAccessTicket(parsedHostInfo.first(), String.valueOf(port), sid, tag); ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(getEncryptorPassword()); ConsoleProxyClientParam param = new ConsoleProxyClientParam(); @@ -372,6 +387,12 @@ public class ConsoleProxyServlet extends HttpServlet { param.setClientHostPassword(sid); param.setClientTag(tag); param.setTicket(ticket); + if (portInfo.second() == -9) { + //For Hyperv Clinet Host Address will send Instance id + param.setHypervHost(host); + param.setUsername(_ms.findDetail(hostVo.getId(), "username").getValue()); + param.setPassword(_ms.findDetail(hostVo.getId(), "password").getValue()); + } if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) { param.setClientTunnelUrl(parsedHostInfo.second()); param.setClientTunnelSession(parsedHostInfo.third()); @@ -396,20 +417,38 @@ public class ConsoleProxyServlet extends HttpServlet { Ternary parsedHostInfo = parseHostInfo(portInfo.first()); - UserVmDetailVO details = _userVmDetailsDao.findDetail(vm.getId(), "keyboard"); + int port = -1; + if (portInfo.second() == -9) { + //for hyperv + port = Integer.parseInt(_ms.findDetail(hostVo.getId(), "rdp.server.port").getValue()); + } else { + port = portInfo.second(); + } + String sid = vm.getVncPassword(); + UserVmDetailVO details = _userVmDetailsDao.findDetail(vm.getId(), "keyboard"); + String tag = vm.getUuid(); - String ticket = genAccessTicket(host, String.valueOf(portInfo.second()), sid, tag); + + String ticket = genAccessTicket(parsedHostInfo.first(), String.valueOf(port), sid, tag); ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(getEncryptorPassword()); ConsoleProxyClientParam param = new ConsoleProxyClientParam(); param.setClientHostAddress(parsedHostInfo.first()); - param.setClientHostPort(portInfo.second()); + param.setClientHostPort(port); param.setClientHostPassword(sid); param.setClientTag(tag); param.setTicket(ticket); + if (details != null) { param.setLocale(details.getValue()); } + + if (portInfo.second() == -9) { + //For Hyperv Clinet Host Address will send Instance id + param.setHypervHost(host); + param.setUsername(_ms.findDetail(hostVo.getId(), "username").getValue()); + param.setPassword(_ms.findDetail(hostVo.getId(), "password").getValue()); + } if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) { param.setClientTunnelUrl(parsedHostInfo.second()); param.setClientTunnelSession(parsedHostInfo.third()); diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 1d78789ed4b..c7631692f89 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -449,8 +449,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic volume.setPoolId(null); volume.setDataCenterId(zoneId); volume.setPodId(null); - volume.setAccountId(owner.getAccountId()); - volume.setDomainId(owner.getDomainId()); + // to prevent a nullpointer deref I put the system account id here when no owner is given. + // TODO Decide if this is valid or whether throwing a CloudRuntimeException is more appropriate + volume.setAccountId((owner == null) ? Account.ACCOUNT_ID_SYSTEM : owner.getAccountId()); + volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId()); long diskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId(); volume.setDiskOfferingId(diskOfferingId); // volume.setSize(size); diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 991f35f7c69..6f1f5e90c4e 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -269,7 +269,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity)store).getMountPoint(), path, uuid, null); Answer ans = ep.sendMessage(cmd); if (ans == null || !ans.getResult()) { - errorString = "Unable to create a link for " + type + " id:" + template.getId() + "," + ans.getDetails(); + errorString = "Unable to create a link for " + type + " id:" + template.getId() + "," + (ans == null ? "" : ans.getDetails()); s_logger.error(errorString); throw new CloudRuntimeException(errorString); } @@ -325,7 +325,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity)secStore).getMountPoint(), path, uuid, null); Answer ans = ep.sendMessage(cmd); if (ans == null || !ans.getResult()) { - errorString = "Unable to create a link for " + type + " id:" + entityId + "," + ans.getDetails(); + errorString = "Unable to create a link for " + type + " id:" + entityId + "," + (ans == null ? "" : ans.getDetails()); s_logger.warn(errorString); throw new CloudRuntimeException(errorString); } diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index 1982af77c8b..900c822da83 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -25,12 +25,11 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; - import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.log4j.Logger; import com.cloud.api.query.dao.ResourceTagJoinDao; import com.cloud.dc.DataCenterVO; @@ -40,6 +39,8 @@ import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; +import com.cloud.network.as.AutoScaleVmGroupVO; +import com.cloud.network.as.AutoScaleVmProfileVO; import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.LoadBalancerVO; import com.cloud.network.dao.NetworkVO; @@ -116,6 +117,8 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso s_typeMap.put(ResourceObjectType.VpnConnection, Site2SiteVpnConnectionVO.class); s_typeMap.put(ResourceObjectType.User, UserVO.class); s_typeMap.put(ResourceObjectType.DiskOffering, DiskOfferingVO.class); + s_typeMap.put(ResourceObjectType.AutoScaleVmProfile, AutoScaleVmProfileVO.class); + s_typeMap.put(ResourceObjectType.AutoScaleVmGroup, AutoScaleVmGroupVO.class); } @Inject diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 96e3fcac1ea..3615c7acf17 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -393,14 +393,16 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { // find all eligible image stores for this template List iStores = templateMgr.getImageStoreByTemplate(template.getId(), null); if (iStores == null || iStores.size() == 0) { - // remove template from vm_templates table - if (_tmpltDao.remove(template.getId())) { + // Mark template as Inactive. + template.setState(VirtualMachineTemplate.State.Inactive); + _tmpltDao.update(template.getId(), template); + // Decrement the number of templates and total secondary storage // space used by the account Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); _resourceLimitMgr.decrementResourceCount(template.getAccountId(), ResourceType.template); _resourceLimitMgr.recalculateResourceCount(template.getAccountId(), account.getDomainId(), ResourceType.secondary_storage.getOrdinal()); - } + } // remove its related ACL permission diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index d111a5d2bb8..f3c16cad03c 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -171,8 +171,14 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat } boolean isAdmin = _accountMgr.isRootAdmin(templateOwner.getId()); + boolean isRegionStore = false; + List stores = _imgStoreDao.findRegionImageStores(); + if (stores != null && stores.size() > 0) { + isRegionStore = true; + } - if (!isAdmin && zoneId == null) { + if (!isAdmin && zoneId == null && !isRegionStore ) { + // domain admin and user should also be able to register template on a region store throw new InvalidParameterValueException("Please specify a valid zone Id."); } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 55443fdf29d..77dbbec12d2 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -425,7 +425,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (isISO) { desc = Upload.Type.ISO.toString(); } - eventId = eventId == null ? 0 : eventId; + eventId = (eventId == null ? 0 : eventId); if (!_accountMgr.isRootAdmin(caller.getId()) && _disableExtraction) { throw new PermissionDeniedException("Extraction has been disabled by admin"); @@ -1084,9 +1084,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("Please specify a valid template."); } - template.setState(VirtualMachineTemplate.State.Inactive); - _tmpltDao.update(template.getId(), template); - TemplateAdapter adapter = getAdapter(template.getHypervisorType()); TemplateProfile profile = adapter.prepareDelete(cmd); return adapter.delete(profile); @@ -1119,9 +1116,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("Failed to find a secondary storage store in the specified zone."); } - template.setState(VirtualMachineTemplate.State.Inactive); - _tmpltDao.update(template.getId(), template); - TemplateAdapter adapter = getAdapter(template.getHypervisorType()); TemplateProfile profile = adapter.prepareDelete(cmd); boolean result = adapter.delete(profile); @@ -1780,7 +1774,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } // Don't allow to modify system template - if (id == Long.valueOf(1)) { + if (Long.valueOf(1).equals(id)) { InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update template/iso of specified id"); ex.addProxyObject(String.valueOf(id), "templateId"); throw ex; diff --git a/server/src/com/cloud/test/IPRangeConfig.java b/server/src/com/cloud/test/IPRangeConfig.java index f4619955f4f..1d564714087 100755 --- a/server/src/com/cloud/test/IPRangeConfig.java +++ b/server/src/com/cloud/test/IPRangeConfig.java @@ -69,7 +69,7 @@ public class IPRangeConfig { long zoneId = PodZoneConfig.getZoneId(zone); result = changeRange(op, "public", -1, zoneId, startIP, endIP, null, -1); - result.replaceAll("
", "/n"); + result = result.replaceAll("
", "/n"); System.out.println(result); } else if (type.equals("private")) { if (args.length != 5 && args.length != 6) { @@ -92,7 +92,7 @@ public class IPRangeConfig { long podId = PodZoneConfig.getPodId(pod, zone); long zoneId = PodZoneConfig.getZoneId(zone); result = changeRange(op, "private", podId, zoneId, startIP, endIP, null, -1); - result.replaceAll("
", "/n"); + result = result.replaceAll("
", "/n"); System.out.println(result); } else { printError(usage()); @@ -569,31 +569,6 @@ public class IPRangeConfig { "Unable to start DB connection to read guest cidr network. Please contact Cloud Support."); } -// public static String getGuestIpNetwork() { -// return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`configuration` WHERE name = \"guest.ip.network\"", "value", -// "Unable to start DB connection to read guest IP network. Please contact Cloud Support."); -// } -// -// public static String getGuestNetmask() { -// return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`configuration` WHERE name = \"guest.netmask\"", "value", -// "Unable to start DB connection to read guest netmask. Please contact Cloud Support."); -// } - -// public static String getGuestSubnet() { -// String guestIpNetwork = getGuestIpNetwork(); -// String guestNetmask = getGuestNetmask(); -// -// if (guestIpNetwork == null || guestIpNetwork.isEmpty()) printError("Please enter a valid guest IP network address."); -// if (guestNetmask == null || guestNetmask.isEmpty()) printError("Please enter a valid guest IP network netmask"); -// -// return NetUtils.getSubNet(guestIpNetwork, guestNetmask); -// } - -// public static long getGuestCidrSize() { -// String guestNetmask = getGuestNetmask(); -// return NetUtils.getCidrSize(guestNetmask); -// } - public static boolean validCIDR(final String cidr) { if (cidr == null || cidr.isEmpty()) { return false; diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 4b9ecebfd6a..0089476bb76 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -453,7 +453,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir protected boolean _dailyOrHourly = false; private int capacityReleaseInterval; - protected String _name; protected String _instance; protected String _zone; protected boolean _instanceNameFlag; @@ -2969,6 +2968,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir long vmId = cmd.getEntityId(); Long hostId = cmd.getHostId(); UserVmVO vm = _vmDao.findById(vmId); + CallContext.current().putContextParameter(VirtualMachine.class, vm.getUuid()); Pair> vmParamPair = null; try { @@ -3754,7 +3754,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir collectVmDiskStatistics(uservm); } _itMgr.migrate(vm.getUuid(), srcHostId, dest); + VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); + if (vmInstance.getType().equals(VirtualMachine.Type.User)) { return _vmDao.findById(vmId); + } else { + return vmInstance; + } } private boolean checkIfHostIsDedicated(HostVO host) { @@ -3825,13 +3830,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir //if hosts are dedicated to different account/domains, raise an alert if (srcExplDedicated && destExplDedicated) { - if ((accountOfDedicatedHost(srcHost) != null) && (accountOfDedicatedHost(srcHost) != accountOfDedicatedHost(destHost))) { + if (!((accountOfDedicatedHost(srcHost) == null) || (accountOfDedicatedHost(srcHost).equals(accountOfDedicatedHost(destHost))))) { String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(srcHost) + " to host " + destHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(destHost); _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); s_logger.warn(msg); } - if ((domainOfDedicatedHost(srcHost) != null) && (domainOfDedicatedHost(srcHost) != domainOfDedicatedHost(destHost))) { + if (!((domainOfDedicatedHost(srcHost) == null) || (domainOfDedicatedHost(srcHost).equals(domainOfDedicatedHost(destHost))))) { String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(srcHost) + " to host " + destHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(destHost); _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index 5ca44c3761e..e9d10b89d40 100644 --- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -105,7 +105,6 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana public static final String VM_WORK_JOB_HANDLER = VMSnapshotManagerImpl.class.getSimpleName(); - String _name; @Inject VMInstanceDao _vmInstanceDao; @Inject VMSnapshotDao _vmSnapshotDao; diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index 846e2f58d8e..226788370e6 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -404,10 +404,10 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches } /* (non-Javadoc) - * @see com.cloud.network.NetworkService#addTrafficTypeToPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) + * @see com.cloud.network.NetworkService#addTrafficTypeToPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override - public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String xenLabel, String kvmLabel, String vmwareLabel, + public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan, String hypervLabel) { // TODO Auto-generated method stub return null; diff --git a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java b/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java index 061fd42ac6b..f891e70196d 100644 --- a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java +++ b/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java @@ -78,6 +78,7 @@ import com.cloud.utils.component.ComponentContext; import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.UserVmDao; +import com.cloud.projects.dao.ProjectDao; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader = AnnotationConfigContextLoader.class) @@ -110,6 +111,9 @@ public class AffinityApiUnitTest { @Inject AccountDao _accountDao; + @Inject + ProjectDao _projectDao; + @Inject EventDao _eventDao; @@ -217,6 +221,11 @@ public class AffinityApiUnitTest { return Mockito.mock(AccountDao.class); } + @Bean + public ProjectDao projectDao() { + return Mockito.mock(ProjectDao.class); + } + @Bean public AccountService accountService() { return Mockito.mock(AccountService.class); diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java index 43abb273477..9cb523137ec 100755 --- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java +++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java @@ -30,7 +30,7 @@ public class BufferedImageCanvas extends Canvas { private static final long serialVersionUID = 1L; // Offline screen buffer - private BufferedImage offlineImage; + protected BufferedImage offlineImage; // Cached Graphics2D object for offline screen buffer private Graphics2D graphics; @@ -76,4 +76,8 @@ public class BufferedImageCanvas extends Canvas { return graphics; } + public void updateFrameBuffer(int x, int y, int w, int h) { + //this method will be used to mark the dirty tiles + } + } diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java index 55ca8fdbf64..f3a73d70dbd 100755 --- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java +++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java @@ -77,13 +77,14 @@ public class AwtCanvasAdapter extends BaseElement { } private void handleCopyRect(CopyRectOrder order, ByteBuffer buf) { - // TODO Auto-generated method stub // Copy image canvas.getOfflineGraphics().copyArea(order.srcX, order.srcY, order.width, order.height, order.x - order.srcX, order.y - order.srcY); // Request update of repainted area + canvas.updateFrameBuffer(order.x, order.y, order.width, order.height); canvas.repaint(order.x, order.y, order.width, order.height); + } private void handleBitmap(BitmapOrder order, ByteBuffer buf) { @@ -137,6 +138,7 @@ public class AwtCanvasAdapter extends BaseElement { g.drawImage(rectImage, x, y, null); // Request update of repainted area + canvas.updateFrameBuffer(x, y, width, height); canvas.repaint(x, y, width, height); } diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java index afde70698e3..a3db165c2fa 100755 --- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java +++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java @@ -63,6 +63,9 @@ import common.adapter.AwtCanvasAdapter; public class RdpClient extends PipelineImpl { + AwtMouseEventSource mouseEventSource = null; + AwtKeyEventSource keyEventSource = null; + /** * Name of last OneTimePacket in handshake sequence. */ @@ -333,8 +336,8 @@ public class RdpClient extends PipelineImpl { // Main network // - AwtMouseEventSource mouseEventSource = new AwtMouseEventSource("mouse"); - AwtKeyEventSource keyEventSource = new AwtKeyEventSource("keyboard"); + mouseEventSource = new AwtMouseEventSource("mouse"); + keyEventSource = new AwtKeyEventSource("keyboard"); // Subscribe packet sender to various events canvas.addMouseListener(mouseEventSource); @@ -390,4 +393,12 @@ public class RdpClient extends PipelineImpl { link("client_x224_data_queue", "client_tpkt_queue", "client_tpkt_queue< queue"); } + + public AwtMouseEventSource getMouseEventSource() { + return mouseEventSource; + } + + public AwtKeyEventSource getKeyEventSource() { + return keyEventSource; + } } diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java index f2b19e1af49..2d1e8fca6c3 100755 --- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java +++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java @@ -343,7 +343,7 @@ public class AwtRdpKeyboardAdapter extends BaseElement { default: System.err.println("Key is not mapped: " + event + "."); - return 57; // Space + return event.getKeyCode(); } } diff --git a/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java b/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java index a40cdb8ed79..17bc4bde0c4 100755 --- a/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java +++ b/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java @@ -58,7 +58,7 @@ public class MockServerTest extends TestCase { Socket socket = SocketFactory.getDefault().createSocket(); try { - socket.connect(server.getAddress()); + socket.connect(new InetSocketAddress("127.0.0.1", server.getAddress().getPort())); InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); @@ -127,7 +127,7 @@ public class MockServerTest extends TestCase { Socket socket = SocketFactory.getDefault().createSocket(); try { - InetSocketAddress address = server.getAddress(); + InetSocketAddress address = new InetSocketAddress("127.0.0.1", server.getAddress().getPort()); socket.connect(address); // Send hello data over plain connection diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml index bc780a70fb5..5d0b3bc9565 100644 --- a/services/console-proxy/server/pom.xml +++ b/services/console-proxy/server/pom.xml @@ -44,6 +44,11 @@ cloud-utils ${project.version}
+ + rdpclient + cloudstack-service-console-proxy-rdpclient + ${project.version} + diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java index f889cdbf05b..02fda6424be 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java @@ -196,8 +196,8 @@ public class ConsoleProxy { Object result; try { result = - authMethod.invoke(ConsoleProxy.context, param.getClientHostAddress(), String.valueOf(param.getClientHostPort()), param.getClientTag(), - param.getClientHostPassword(), param.getTicket(), new Boolean(reauthentication)); + authMethod.invoke(ConsoleProxy.context, param.getClientHostAddress(), String.valueOf(param.getClientHostPort()), param.getClientTag(), + param.getClientHostPassword(), param.getTicket(), new Boolean(reauthentication)); } catch (IllegalAccessException e) { s_logger.error("Unable to invoke authenticateConsoleAccess due to IllegalAccessException" + " for vm: " + param.getClientTag(), e); authResult.setSuccess(false); @@ -407,7 +407,7 @@ public class ConsoleProxy { synchronized (connectionMap) { viewer = connectionMap.get(clientKey); if (viewer == null) { - viewer = new ConsoleProxyVncClient(); + viewer = getClient(param); viewer.initClient(param); connectionMap.put(clientKey, viewer); s_logger.info("Added viewer object " + viewer); @@ -418,7 +418,7 @@ public class ConsoleProxy { viewer.initClient(param); } else if (!param.getClientHostPassword().equals(viewer.getClientHostPassword())) { s_logger.warn("Bad sid detected(VNC port may be reused). sid in session: " + viewer.getClientHostPassword() + ", sid in request: " + - param.getClientHostPassword()); + param.getClientHostPassword()); viewer.initClient(param); } } @@ -442,7 +442,7 @@ public class ConsoleProxy { ConsoleProxyClient viewer = connectionMap.get(clientKey); if (viewer == null) { authenticationExternally(param); - viewer = new ConsoleProxyVncClient(); + viewer = getClient(param); viewer.initClient(param); connectionMap.put(clientKey, viewer); @@ -457,7 +457,7 @@ public class ConsoleProxy { } if (param.getClientHostPassword() == null || param.getClientHostPassword().isEmpty() || - !param.getClientHostPassword().equals(viewer.getClientHostPassword())) + !param.getClientHostPassword().equals(viewer.getClientHostPassword())) throw new AuthenticationException("Cannot use the existing viewer " + viewer + ": bad sid"); if (!viewer.isFrontEndAlive()) { @@ -479,6 +479,14 @@ public class ConsoleProxy { } } + private static ConsoleProxyClient getClient(ConsoleProxyClientParam param) { + if (param.getHypervHost() != null) { + return new ConsoleProxyRdpClient(); + } else { + return new ConsoleProxyVncClient(); + } + } + public static void removeViewer(ConsoleProxyClient viewer) { synchronized (connectionMap) { for (Map.Entry entry : connectionMap.entrySet()) { diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java index 18d97d250af..fa0bd06c09e 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java @@ -80,6 +80,9 @@ public class ConsoleProxyAjaxHandler implements HttpHandler { String console_url = queryMap.get("consoleurl"); String console_host_session = queryMap.get("sessionref"); String vm_locale = queryMap.get("locale"); + String hypervHost = queryMap.get("hypervHost"); + String username = queryMap.get("username"); + String password = queryMap.get("password"); if (tag == null) tag = ""; @@ -128,6 +131,9 @@ public class ConsoleProxyAjaxHandler implements HttpHandler { param.setClientTunnelUrl(console_url); param.setClientTunnelSession(console_host_session); param.setLocale(vm_locale); + param.setHypervHost(hypervHost); + param.setUsername(username); + param.setPassword(password); viewer = ConsoleProxy.getAjaxVncViewer(param, ajaxSessionIdStr); } catch (Exception e) { diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java index a04dd306960..e62ac4531b9 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java @@ -33,6 +33,10 @@ public class ConsoleProxyClientParam { private String locale; private String ajaxSessionId; + private String hypervHost; + private String username; + private String password; + public ConsoleProxyClientParam() { clientHostPort = 0; } @@ -94,7 +98,7 @@ public class ConsoleProxyClientParam { } public String getAjaxSessionId() { - return this.ajaxSessionId; + return ajaxSessionId; } public void setAjaxSessionId(String ajaxSessionId) { @@ -102,7 +106,7 @@ public class ConsoleProxyClientParam { } public String getLocale() { - return this.locale; + return locale; } public void setLocale(String locale) { @@ -115,4 +119,28 @@ public class ConsoleProxyClientParam { return clientHostAddress + ":" + clientHostPort; } + + public void setHypervHost(String hypervHost) { + this.hypervHost = hypervHost; + } + + public String getHypervHost() { + return hypervHost; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPassword() { + return password; + } } diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java index 7811d5030cf..51a703ae4b4 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java @@ -54,14 +54,29 @@ public class ConsoleProxyHttpHandlerHelper { // make sure we get information from token only guardUserInput(map); if (param != null) { - if (param.getClientHostAddress() != null) + if (param.getClientHostAddress() != null) { + s_logger.debug("decode token. host: " + param.getClientHostAddress()); map.put("host", param.getClientHostAddress()); - if (param.getClientHostPort() != 0) + } else { + s_logger.error("decode token. host info is not found!"); + } + if (param.getClientHostPort() != 0) { + s_logger.debug("decode token. port: " + param.getClientHostPort()); map.put("port", String.valueOf(param.getClientHostPort())); - if (param.getClientTag() != null) + } else { + s_logger.error("decode token. port info is not found!"); + } + if (param.getClientTag() != null) { + s_logger.debug("decode token. tag: " + param.getClientTag()); map.put("tag", param.getClientTag()); - if (param.getClientHostPassword() != null) + } else { + s_logger.error("decode token. tag info is not found!"); + } + if (param.getClientHostPassword() != null) { map.put("sid", param.getClientHostPassword()); + } else { + s_logger.error("decode token. sid info is not found!"); + } if (param.getClientTunnelUrl() != null) map.put("consoleurl", param.getClientTunnelUrl()); if (param.getClientTunnelSession() != null) @@ -70,6 +85,14 @@ public class ConsoleProxyHttpHandlerHelper { map.put("ticket", param.getTicket()); if (param.getLocale() != null) map.put("locale", param.getLocale()); + if (param.getHypervHost() != null) + map.put("hypervHost", param.getHypervHost()); + if (param.getUsername() != null) + map.put("username", param.getUsername()); + if (param.getPassword() != null) + map.put("password", param.getPassword()); + } else { + s_logger.error("Unable to decode token"); } } else { // we no longer accept information from parameter other than token @@ -88,5 +111,8 @@ public class ConsoleProxyHttpHandlerHelper { map.remove("sessionref"); map.remove("ticket"); map.remove("locale"); + map.remove("hypervHost"); + map.remove("username"); + map.remove("password"); } } diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java new file mode 100644 index 00000000000..d5a3fcd3639 --- /dev/null +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java @@ -0,0 +1,322 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.consoleproxy; + +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.net.InetSocketAddress; + +import org.apache.log4j.Logger; + +import rdpclient.RdpClient; +import streamer.Pipeline; +import streamer.PipelineImpl; +import streamer.SocketWrapper; +import streamer.apr.AprSocketWrapperImpl; +import streamer.ssl.SSLState; + +import com.cloud.consoleproxy.rdp.KeysymToKeycode; +import com.cloud.consoleproxy.rdp.RdpBufferedImageCanvas; +import com.cloud.consoleproxy.vnc.FrameBufferCanvas; + +import common.AwtKeyEventSource; +import common.AwtMouseEventSource; +import common.ScreenDescription; +import common.SizeChangeListener; + +public class ConsoleProxyRdpClient extends ConsoleProxyClientBase { + + private static final Logger s_logger = Logger.getLogger(ConsoleProxyRdpClient.class); + + private static final int SHIFT_KEY_MASK = 64; + private static final int CTRL_KEY_MASK = 128; + private static final int META_KEY_MASK = 256; + private static final int ALT_KEY_MASK = 512; + + private RdpClient _client; + private ScreenDescription _screen; + private SocketWrapper _socket = null; + private RdpBufferedImageCanvas _canvas = null; + + private Thread _worker; + private volatile boolean _workerDone = false; + + private AwtMouseEventSource _mouseEventSource = null; + private AwtKeyEventSource _keyEventSource = null; + + public RdpBufferedImageCanvas getCanvas() { + return _canvas; + } + + public void setCanvas(RdpBufferedImageCanvas canvas) { + _canvas = canvas; + } + + @Override + public void onClientConnected() { + // TODO Auto-generated method stub + } + + @Override + public void onClientClose() { + s_logger.info("Received client close indication. remove viewer from map."); + ConsoleProxy.removeViewer(this); + } + + @Override + public boolean isHostConnected() { + //FIXME + return true; + } + + @Override + public boolean isFrontEndAlive() { + if (_socket != null) { + if (_workerDone || System.currentTimeMillis() - getClientLastFrontEndActivityTime() > ConsoleProxy.VIEWER_LINGER_SECONDS * 1000) { + s_logger.info("Front end has been idle for too long"); + _socket.shutdown(); + return false; + } else { + return true; + } + } else { + return false; + } + } + + @Override + public void sendClientRawKeyboardEvent(InputEventType event, int code, int modifiers) { + if (_client == null) + return; + + updateFrontEndActivityTime(); + + KeyEvent keyEvent = map(event, code, modifiers); + switch (event) { + case KEY_DOWN: + _keyEventSource.keyPressed(keyEvent); + break; + + case KEY_UP: + _keyEventSource.keyReleased(keyEvent); + break; + + case KEY_PRESS: + break; + + default: + assert (false); + break; + } + } + + private KeyEvent map(InputEventType event, int code, int modifiers) { + int keycode = KeysymToKeycode.getKeycode(code); + char keyChar = (char)keycode; + + KeyEvent keyEvent = null; + int modifier = mapModifier(modifiers); + + switch (event) { + case KEY_DOWN: + keyEvent = new KeyEvent(_canvas, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), modifier, keycode, keyChar); + break; + + case KEY_UP: + keyEvent = new KeyEvent(_canvas, KeyEvent.KEY_RELEASED, System.currentTimeMillis(), modifier, keycode, keyChar); + break; + + case KEY_PRESS: + break; + + default: + assert (false); + break; + } + return keyEvent; + } + + @Override + public void sendClientMouseEvent(InputEventType event, int x, int y, int code, int modifiers) { + if (_client == null) + return; + updateFrontEndActivityTime(); + + int mousecode = mapMouseButton(code); + + if (event == InputEventType.MOUSE_DOWN) { + _mouseEventSource.mousePressed(new MouseEvent(_canvas, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), mapMouseDownModifier(code, modifiers), x, y, 1, false, + mousecode)); + } + + if (event == InputEventType.MOUSE_UP) { + _mouseEventSource.mouseReleased((new MouseEvent(_canvas, MouseEvent.MOUSE_RELEASED, System.currentTimeMillis(), mapMouseUpModifier(code, modifiers), x, y, 1, false, + mousecode))); + } + + if (event == InputEventType.MOUSE_MOVE) { + _mouseEventSource.mouseMoved(new MouseEvent(_canvas, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(), mapModifier(modifiers), x, y, 0, false)); + } + } + + public int mapMouseDownModifier(int code, int modifiers) { + int mod = mapModifier(modifiers); + switch (code) { + case 0: + return mod = mod | MouseEvent.BUTTON1_DOWN_MASK; + case 2: + return mod = mod | MouseEvent.BUTTON3_DOWN_MASK; + default: + } + return mod; + } + + public int mapMouseUpModifier(int code, int modifiers) { + int mod = mapModifier(modifiers); + switch (code) { + case 0: + return mod = mod | MouseEvent.BUTTON1_MASK; + case 2: + return mod = mod | MouseEvent.BUTTON3_MASK; + default: + } + return mod; + } + + private int mapModifier(int modifiers) { + int mod = 0; + + if ((modifiers & SHIFT_KEY_MASK) != 0) + mod = mod | InputEvent.SHIFT_DOWN_MASK; + + if ((modifiers & CTRL_KEY_MASK) != 0) + mod = mod | InputEvent.CTRL_DOWN_MASK; + + if ((modifiers & META_KEY_MASK) != 0) + mod = mod | InputEvent.META_DOWN_MASK; + + if ((modifiers & ALT_KEY_MASK) != 0) + mod = mod | InputEvent.ALT_DOWN_MASK; + + return mod; + } + + public int mapMouseButton(int code) { + switch (code) { + case 0: + return MouseEvent.BUTTON1; + case 2: + return MouseEvent.BUTTON3; + default: + return MouseEvent.BUTTON2; + } + + } + + @Override + public void initClient(final ConsoleProxyClientParam param) { + _workerDone = false; + + int canvasWidth = 1024; + int canvasHeight = 768; + setClientParam(param); + + final String host = param.getHypervHost(); + final String password = param.getPassword(); + final String instanceId = param.getClientHostAddress(); + final int port = param.getClientHostPort(); + + _screen = new ScreenDescription(); + _canvas = new RdpBufferedImageCanvas(this, canvasWidth, canvasHeight); + onFramebufferSizeChange(canvasWidth, canvasHeight); + + _screen.addSizeChangeListener(new SizeChangeListener() { + @Override + public void sizeChanged(int width, int height) { + if (_canvas != null) { + _canvas.setCanvasSize(width, height); + } + } + }); + + final SSLState sslState = new SSLState(); + + final String username = param.getUsername(); + String name = null; + String domain = null; + if (username.contains("\\")) { + String[] tokens = username.split("\\\\"); + name = tokens[1]; + domain = tokens[0]; + } else { + name = username; + domain = "Workgroup"; + } + + _client = new RdpClient("client", host, domain, name, password, instanceId, _screen, _canvas, + sslState); + + _mouseEventSource = _client.getMouseEventSource(); + _keyEventSource = _client.getKeyEventSource(); + + _worker = new Thread(new Runnable() { + @Override + public void run() { + _socket = new AprSocketWrapperImpl("socket", sslState); + Pipeline pipeline = new PipelineImpl("Client"); + pipeline.add(_socket, _client); + pipeline.link("socket", _client.getId(), "socket"); + pipeline.validate(); + + InetSocketAddress address = new InetSocketAddress(host, port); + ConsoleProxy.ensureRoute(host); + + try { + // Connect socket to remote server and run main loop(s) + _socket.connect(address); + } catch (IOException e) { + e.printStackTrace(); + } finally { + shutdown(); + } + + s_logger.info("Receiver thread stopped."); + _workerDone = true; + } + }); + _worker.setDaemon(true); + _worker.start(); + } + + @Override + public void closeClient() { + _workerDone = true; + shutdown(); + } + + @Override + protected FrameBufferCanvas getFrameBufferCavas() { + return _canvas; + } + + protected void shutdown() { + if (_socket != null) + _socket.shutdown(); + } +} diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java new file mode 100644 index 00000000000..f13dfe6c419 --- /dev/null +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java @@ -0,0 +1,138 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.consoleproxy.rdp; + +import java.awt.event.KeyEvent; + +public class KeysymToKeycode { + + // some of this keymap is taken from http://openwonderland.googlecode.com/svn/trunk/modules/foundation/xremwin/src/classes/org/jdesktop/wonderland/modules/xremwin/client/KeycodeToKeysym.java + private final static int[][] map = { + /* XK_BackSpace */{0xFF08, KeyEvent.VK_BACK_SPACE}, + /* XK_Tab */{0xFF09, KeyEvent.VK_TAB}, + /* XK_Clear */{0xFF0B, KeyEvent.VK_CLEAR}, + /* XK_Return */{0xFF0D, KeyEvent.VK_ENTER}, + /* XK_Pause */{0xFF13, KeyEvent.VK_PAUSE}, + /* XK_Scroll_Lock */{0xFF14, KeyEvent.VK_SCROLL_LOCK}, + /* XK_Escape */{0xFF1B, KeyEvent.VK_ESCAPE}, + /* XK_Delete */{0xFFFF, KeyEvent.VK_DELETE}, + /* XK_Home */{0xFF50, KeyEvent.VK_HOME}, + /* XK_Left */{0xFF51, KeyEvent.VK_LEFT}, + /* XK_Up */{0xFF52, KeyEvent.VK_UP}, + /* XK_Right */{0xFF53, KeyEvent.VK_RIGHT}, + /* XK_Down */{0xFF54, KeyEvent.VK_DOWN}, + /* XK_Page_Up */{0xFF55, KeyEvent.VK_PAGE_UP}, + /* XK_Page_Down */{0xFF56, KeyEvent.VK_PAGE_DOWN}, + /* XK_End */{0xFF57, KeyEvent.VK_END}, + /* XK_Print */{0xFF61, KeyEvent.VK_PRINTSCREEN}, + /* XK_Insert */{0xFF63, KeyEvent.VK_INSERT}, + /* XK_Undo */{0xFF65, KeyEvent.VK_UNDO}, + /* XK_Find */{0xFF68, KeyEvent.VK_FIND}, + /* XK_Cancel */{0xFF69, KeyEvent.VK_CANCEL}, + /* XK_Help */{0xFF6A, KeyEvent.VK_HELP}, + /* XK_Mode_switch */{0xFF7E, KeyEvent.VK_MODECHANGE}, + /* XK_Num_Lock */{0xFF7F, KeyEvent.VK_NUM_LOCK}, + /* XK_F1 */{0xFFBE, KeyEvent.VK_F1}, + /* XK_F2 */{0xFFBF, KeyEvent.VK_F2}, + /* XK_F3 */{0xFFC0, KeyEvent.VK_F3}, + /* XK_F4 */{0xFFC1, KeyEvent.VK_F4}, + /* XK_F5 */{0xFFC2, KeyEvent.VK_F5}, + /* XK_F6 */{0xFFC3, KeyEvent.VK_F6}, + /* XK_F7 */{0xFFC4, KeyEvent.VK_F7}, + /* XK_F8 */{0xFFC5, KeyEvent.VK_F8}, + /* XK_F9 */{0xFFC6, KeyEvent.VK_F9}, + /* XK_F10 */{0xFFC7, KeyEvent.VK_F10}, + /* XK_F11 */{0xFFC8, KeyEvent.VK_F11}, + /* XK_F12 */{0xFFC9, KeyEvent.VK_F12}, + /* XK_F13 */{0xFFCA, KeyEvent.VK_F13}, + /* XK_F14 */{0xFFCB, KeyEvent.VK_F14}, + /* XK_F15 */{0xFFCC, KeyEvent.VK_F15}, + /* XK_F16 */{0xFFCD, KeyEvent.VK_F16}, + /* XK_F17 */{0xFFCE, KeyEvent.VK_F17}, + /* XK_F18 */{0xFFCF, KeyEvent.VK_F18}, + /* XK_F19 */{0xFFD0, KeyEvent.VK_F19}, + /* XK_F20 */{0xFFD1, KeyEvent.VK_F20}, + /* XK_F21 */{0xFFD2, KeyEvent.VK_F21}, + /* XK_F22 */{0xFFD3, KeyEvent.VK_F22}, + /* XK_F23 */{0xFFD4, KeyEvent.VK_F23}, + /* XK_F24 */{0xFFD5, KeyEvent.VK_F24}, + /* XK_Shift_L */{0xFFE1, KeyEvent.VK_SHIFT}, + /* XK_Control_L */{0xFFE3, KeyEvent.VK_CONTROL}, + /* XK_Caps_Lock */{0xFFE5, KeyEvent.VK_CAPS_LOCK}, + /* XK_Meta_L */{0xFFE7, KeyEvent.VK_META}, + /* XK_Alt_L */{0xFFE9, KeyEvent.VK_ALT}, + /* XK_a */{0x0061, KeyEvent.VK_A}, + /* XK_b */{0x0062, KeyEvent.VK_B}, + /* XK_c */{0x0063, KeyEvent.VK_C}, + /* XK_d */{0x0064, KeyEvent.VK_D}, + /* XK_e */{0x0065, KeyEvent.VK_E}, + /* XK_f */{0x0066, KeyEvent.VK_F}, + /* XK_g */{0x0067, KeyEvent.VK_G}, + /* XK_h */{0x0068, KeyEvent.VK_H}, + /* XK_i */{0x0069, KeyEvent.VK_I}, + /* XK_j */{0x006a, KeyEvent.VK_J}, + /* XK_k */{0x006b, KeyEvent.VK_K}, + /* XK_l */{0x006c, KeyEvent.VK_L}, + /* XK_m */{0x006d, KeyEvent.VK_M}, + /* XK_n */{0x006e, KeyEvent.VK_N}, + /* XK_o */{0x006f, KeyEvent.VK_O}, + /* XK_p */{0x0070, KeyEvent.VK_P}, + /* XK_q */{0x0071, KeyEvent.VK_Q}, + /* XK_r */{0x0072, KeyEvent.VK_R}, + /* XK_s */{0x0073, KeyEvent.VK_S}, + /* XK_t */{0x0074, KeyEvent.VK_T}, + /* XK_u */{0x0075, KeyEvent.VK_U}, + /* XK_v */{0x0076, KeyEvent.VK_V}, + /* XK_w */{0x0077, KeyEvent.VK_W}, + /* XK_x */{0x0078, KeyEvent.VK_X}, + /* XK_y */{0x0079, KeyEvent.VK_Y}, + /* XK_z */{0x007a, KeyEvent.VK_Z}, + {0x0060, KeyEvent.VK_BACK_QUOTE}, + {0x007e, KeyEvent.VK_BACK_QUOTE}, + {0x0021, KeyEvent.VK_1}, + {0x0040, KeyEvent.VK_2}, + {0x0023, KeyEvent.VK_3}, + {0x0024, KeyEvent.VK_4}, + {0x0025, KeyEvent.VK_5}, + {0x005e, KeyEvent.VK_6}, + {0x0026, KeyEvent.VK_7}, + {0x002A, KeyEvent.VK_8}, + {0x0028, KeyEvent.VK_9}, + {0x0029, KeyEvent.VK_0}, + {0x005f, KeyEvent.VK_MINUS}, + {0x002b, KeyEvent.VK_EQUALS}, + {0x007b, KeyEvent.VK_OPEN_BRACKET}, + {0x007d, KeyEvent.VK_CLOSE_BRACKET}, + {0x007c, KeyEvent.VK_BACK_SLASH}, + {0x003a, KeyEvent.VK_SEMICOLON}, + {0x0027, KeyEvent.VK_QUOTE}, + {0x0022, KeyEvent.VK_QUOTE}, + {0x003c, KeyEvent.VK_COMMA}, + {0x003e, KeyEvent.VK_PERIOD}, + {0x003f, KeyEvent.VK_SLASH}, + }; + + public static int getKeycode(int keysym) { + for (int i = 0; i < (map.length); i++) { + if (map[i][0] == keysym) { + return map[i][1]; + } + } + return keysym; + } + +} diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java new file mode 100644 index 00000000000..4214574a7e5 --- /dev/null +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java @@ -0,0 +1,103 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.consoleproxy.rdp; + +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.List; + +import com.cloud.consoleproxy.ConsoleProxyRdpClient; +import com.cloud.consoleproxy.util.ImageHelper; +import com.cloud.consoleproxy.util.TileInfo; +import com.cloud.consoleproxy.vnc.FrameBufferCanvas; + +import common.BufferedImageCanvas; + +public class RdpBufferedImageCanvas extends BufferedImageCanvas implements FrameBufferCanvas { + /** + * + */ + private static final long serialVersionUID = 1L; + + private final ConsoleProxyRdpClient _rdpClient; + + public RdpBufferedImageCanvas(ConsoleProxyRdpClient client, int width, int height) { + super(width, height); + _rdpClient = client; + } + + @Override + public Image getFrameBufferScaledImage(int width, int height) { + if (offlineImage != null) + return offlineImage.getScaledInstance(width, height, Image.SCALE_DEFAULT); + return null; + } + + @Override + public byte[] getFrameBufferJpeg() { + int width = offlineImage.getWidth(); + int height = offlineImage.getHeight(); + + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); + Graphics2D g = bufferedImage.createGraphics(); + synchronized (offlineImage) { + g.drawImage(offlineImage, 0, 0, width, height, 0, 0, width, height, null); + g.dispose(); + } + + byte[] imgBits = null; + try { + imgBits = ImageHelper.jpegFromImage(bufferedImage); + } catch (IOException e) { + } + + return imgBits; + } + + @Override + public byte[] getTilesMergedJpeg(List tileList, int tileWidth, int tileHeight) { + int width = Math.max(tileWidth, tileWidth * tileList.size()); + + BufferedImage bufferedImage = new BufferedImage(width, tileHeight, BufferedImage.TYPE_3BYTE_BGR); + Graphics2D g = bufferedImage.createGraphics(); + + synchronized (offlineImage) { + int i = 0; + for (TileInfo tile : tileList) { + Rectangle rc = tile.getTileRect(); + g.drawImage(offlineImage, i * tileWidth, 0, i * tileWidth + rc.width, rc.height, rc.x, rc.y, rc.x + rc.width, rc.y + rc.height, null); + i++; + } + } + + byte[] imgBits = null; + try { + imgBits = ImageHelper.jpegFromImage(bufferedImage); + } catch (IOException e) { + } + return imgBits; + } + + @Override + public void updateFrameBuffer(int x, int y, int w, int h) { + _rdpClient.onFramebufferUpdate(x, y, w, h); + } + +} diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 30722e2fdd0..9782c2ec7c4 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -19,7 +19,6 @@ package org.apache.cloudstack.storage.resource; import static com.cloud.utils.S3Utils.mputFile; import static com.cloud.utils.S3Utils.putFile; import static com.cloud.utils.StringUtils.join; -import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock; import static java.lang.String.format; import static java.util.Arrays.asList; import static org.apache.commons.lang.StringUtils.substringAfterLast; @@ -44,7 +43,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.concurrent.Callable; import javax.naming.ConfigurationException; @@ -142,7 +140,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class); private static final String TEMPLATE_ROOT_DIR = "template/tmpl"; - private static final String SNAPSHOT_ROOT_DIR = "snapshots"; private static final String VOLUME_ROOT_DIR = "volumes"; int _timeout; @@ -180,7 +177,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private String _storageGateway; private final List nfsIps = new ArrayList(); protected String _parent = "/mnt/SecStorage"; - final private String _tmpltDir = "/var/cloudstack/template"; final private String _tmpltpp = "template.properties"; protected String createTemplateFromSnapshotXenScript; @@ -264,7 +260,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String script = srcData.getObjectType() == DataObjectType.TEMPLATE ? createTmpltScr : createVolScr; int installTimeoutPerGig = 180 * 60 * 1000; - int imgSizeGigs = (int)Math.ceil(destFile.length() * 1.0d / (1024 * 1024 * 1024)); + long imgSizeGigs = (long)Math.ceil(destFile.length() * 1.0d / (1024 * 1024 * 1024)); imgSizeGigs++; // add one just in case long timeout = imgSizeGigs * installTimeoutPerGig; @@ -279,7 +275,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String templateName = UUID.randomUUID().toString(); String templateFilename = templateName + "." + extension; Script scr = new Script(script, timeout, s_logger); - scr.add("-s", Integer.toString(imgSizeGigs)); // not used for now + scr.add("-s", Long.toString(imgSizeGigs)); // not used for now scr.add("-n", templateFilename); scr.add("-t", downloadPath); @@ -324,7 +320,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S try { String downloadPath = determineStorageTemplatePath(storagePath, destPath); final File downloadDirectory = _storage.getFile(downloadPath); - downloadDirectory.mkdirs(); + if (!downloadDirectory.mkdirs()) { + return new CopyCmdAnswer("Failed to create download directory " + downloadPath); + } File destFile = SwiftUtil.getObject(swiftTO, downloadDirectory, srcData.getPath()); return postProcessing(destFile, downloadPath, destPath, srcData, destData); } catch (Exception e) { @@ -341,9 +339,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String downloadPath = determineStorageTemplatePath(storagePath, destPath); final File downloadDirectory = _storage.getFile(downloadPath); - downloadDirectory.mkdirs(); - if (!downloadDirectory.exists()) { + if (!downloadDirectory.mkdirs()) { final String errMsg = "Unable to create directory " + downloadPath + " to copy from S3 to cache."; s_logger.error(errMsg); return new CopyCmdAnswer(errMsg); @@ -372,7 +369,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, - NfsTO destDataStore) { + NfsTO destDataStore) { String srcMountPoint = getRootDir(srcDataStore.getUrl()); String snapshotPath = srcData.getPath(); int index = snapshotPath.lastIndexOf("/"); @@ -488,6 +485,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S processor = new QCOW2Processor(); } else if (srcFormat == ImageFormat.RAW) { processor = new RawImageProcessor(); + } else { + throw new ConfigurationException("Unknown image format " + srcFormat.toString()); } Map params = new HashMap(); @@ -550,8 +549,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } else if (destDataStore instanceof SwiftTO) { //create template on the same data store CopyCmdAnswer answer = - (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, - (NfsTO)srcDataStore); + (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, + (NfsTO)srcDataStore); if (!answer.getResult()) { return answer; } @@ -585,8 +584,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } else if (destDataStore instanceof S3TO) { //create template on the same data store CopyCmdAnswer answer = - (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, - (NfsTO)srcDataStore); + (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, + (NfsTO)srcDataStore); if (!answer.getResult()) { return answer; } @@ -651,7 +650,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId, templateUniqueName), S3Utils.SEPARATOR); } - @SuppressWarnings("unchecked") private String determineS3TemplateNameFromKey(String key) { return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR); } @@ -661,12 +659,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return join(asList(VOLUME_ROOT_DIR, accountId, volId), S3Utils.SEPARATOR); } - @SuppressWarnings("unchecked") protected Long determineS3VolumeIdFromKey(String key) { return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR)); } - @SuppressWarnings("unchecked") private String determineStorageTemplatePath(final String storagePath, String dataPath) { return join(asList(getRootDir(storagePath), dataPath), File.separator); } @@ -690,8 +686,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S _storage.mkdirs(filePath); } File destFile = new File(filePath + File.separator + name); - if (!destFile.exists()) { - destFile.createNewFile(); + if (!destFile.createNewFile()) { + s_logger.warn("Reusing existing file " + destFile.getPath()); } FileOutputStream outputStream = new FileOutputStream(destFile); entity.writeTo(outputStream); @@ -744,9 +740,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } DownloadAnswer answer = - new DownloadAnswer(null, 100, null, VMTemplateStorageResourceAssoc.Status.DOWNLOADED, swiftPath, swiftPath, file.length(), file.length(), md5sum); + new DownloadAnswer(null, 100, null, VMTemplateStorageResourceAssoc.Status.DOWNLOADED, swiftPath, swiftPath, file.length(), file.length(), md5sum); return answer; - } catch (Exception e) { + } catch (IOException e) { s_logger.debug("Failed to register template into swift", e); return new DownloadAnswer(e.toString(), VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); } finally { @@ -904,7 +900,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Script command = new Script("/bin/bash", s_logger); command.add("-c"); command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + - swift.getUserName() + " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath); + swift.getUserName() + " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result != null) { @@ -916,7 +912,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String[] lines = parser.getLines().split("\\n"); for (String line : lines) { if (line.contains("Errno") || line.contains("failed")) { - String errMsg = "swiftDownload failed , err=" + lines.toString(); + String errMsg = "swiftDownload failed , err=" + parser.getLines(); s_logger.warn(errMsg); return errMsg; } @@ -930,7 +926,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Script command = new Script("/bin/bash", s_logger); command.add("-c"); command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + - swift.getUserName() + " -K " + swift.getKey() + " download " + container); + swift.getUserName() + " -K " + swift.getKey() + " download " + container); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result != null) { @@ -942,7 +938,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String[] lines = parser.getLines().split("\\n"); for (String line : lines) { if (line.contains("Errno") || line.contains("failed")) { - String errMsg = "swiftDownloadContainer failed , err=" + lines.toString(); + String errMsg = "swiftDownloadContainer failed , err=" + parser.getLines(); s_logger.warn(errMsg); return errMsg; } @@ -974,10 +970,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S command.add("-c"); if (size <= SWIFT_MAX_SIZE) { command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + - swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload " + container + " " + file); + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload " + container + " " + file); } else { command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + - swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file); + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file); } OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); @@ -990,7 +986,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String[] lines = parser.getLines().split("\\n"); for (String line : lines) { if (line.contains("Errno") || line.contains("failed")) { - String errMsg = "swiftUpload failed , err=" + lines.toString(); + String errMsg = "swiftUpload failed , err=" + parser.getLines(); s_logger.warn(errMsg); return errMsg; } @@ -1005,7 +1001,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Script command = new Script("/bin/bash", s_logger); command.add("-c"); command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + - swift.getUserName() + " -K " + swift.getKey() + " list " + container + " " + rFilename); + swift.getUserName() + " -K " + swift.getKey() + " list " + container + " " + rFilename); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result == null && parser.getLines() != null) { @@ -1027,7 +1023,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Script command = new Script("/bin/bash", s_logger); command.add("-c"); command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + - swift.getUserName() + " -K " + swift.getKey() + " delete " + container + " " + object); + swift.getUserName() + " -K " + swift.getKey() + " delete " + container + " " + object); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result != null) { @@ -1039,7 +1035,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String[] lines = parser.getLines().split("\\n"); for (String line : lines) { if (line.contains("Errno") || line.contains("failed")) { - String errMsg = "swiftDelete failed , err=" + lines.toString(); + String errMsg = "swiftDelete failed , err=" + parser.getLines(); s_logger.warn(errMsg); return errMsg; } @@ -1094,7 +1090,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket)); } catch (Exception e) { final String errorMessage = - String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); + String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); } @@ -1123,21 +1119,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - private String determineSnapshotS3Directory(final Long accountId, final Long volumeId) { - return join(S3Utils.SEPARATOR, SNAPSHOT_ROOT_DIR, accountId, volumeId); - } - - private String determineSnapshotS3Key(final Long accountId, final Long volumeId, final String snapshotFileName) { - - final String directoryName = determineSnapshotS3Directory(accountId, volumeId); - return join(S3Utils.SEPARATOR, directoryName, snapshotFileName); - - } - - private String determineSnapshotLocalDirectory(final String secondaryStorageUrl, final Long accountId, final Long volumeId) { - return join(File.pathSeparator, getRootDir(secondaryStorageUrl), SNAPSHOT_ROOT_DIR, accountId, volumeId); - } - private Answer execute(ComputeChecksumCommand cmd) { String relativeTemplatePath = cmd.getTemplatePath(); @@ -1207,7 +1188,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } else { String prvKey = certs.getPrivKey(); String pubCert = certs.getPrivCert(); - String certChain = certs.getCertChain(); try { File prvKeyFile = File.createTempFile("prvkey", null); @@ -1265,69 +1245,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - private String deleteSnapshotBackupFromLocalFileSystem(final String secondaryStorageUrl, final Long accountId, final Long volumeId, final String name, - final Boolean deleteAllFlag) { - String lPath = null; - int index = name.lastIndexOf(File.separator); - String snapshotPath = name.substring(0, index); - if (deleteAllFlag) { - lPath = getRootDir(secondaryStorageUrl) + File.separator + snapshotPath + File.separator + "*"; - } else { - lPath = getRootDir(secondaryStorageUrl) + File.separator + name + "*"; - } - - final String result = deleteLocalFile(lPath); - - if (result != null) { - return "failed to delete snapshot " + lPath + " , err=" + result; - } - - return null; - - } - - private String deleteSnapshotBackupfromS3(final S3TO s3, final Long accountId, final Long volumeId, final String name, final Boolean deleteAllFlag) { - - try { - - final String bucket = s3.getBucketName(); - - final String result = executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId), new Callable() { - - @Override - public String call() throws Exception { - - if (deleteAllFlag) { - S3Utils.deleteDirectory(s3, bucket, determineSnapshotS3Directory(accountId, volumeId)); - } else { - S3Utils.deleteObject(s3, bucket, determineSnapshotS3Key(accountId, volumeId, determineSnapshotBackupFilename(name))); - } - - return null; - - } - - }); - - return result; - - } catch (Exception e) { - - s_logger.error(String.format("Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.", accountId, volumeId), e); - return e.getMessage(); - - } - - } - - private String determineSnapshotBackupFilename(final String snapshotUuid) { - return snapshotUuid + ".vhd"; - } - - private String determineSnapshotLockId(final Long accountId, final Long volumeId) { - return join("_", "SNAPSHOT", accountId, volumeId); - } - protected Answer deleteSnapshot(final DeleteCommand cmd) { DataTO obj = cmd.getData(); DataStoreTO dstore = obj.getDataStore(); @@ -1381,7 +1298,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket)); } catch (Exception e) { final String errorMessage = - String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); + String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); } @@ -1523,7 +1440,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } DataStoreTO store = cmd.getDataStore(); if (store instanceof NfsTO) { - NfsTO nfs = (NfsTO)store; String root = getRootDir(cmd.getSecUrl()); Map templateInfos = _dlMgr.gatherVolumeInfo(root); return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos); @@ -1571,45 +1487,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } - private String setVhdParent(String lFullPath, String pFullPath) { - Script command = new Script("/bin/bash", s_logger); - command.add("-c"); - command.add("/bin/vhd-util modify -n " + lFullPath + " -p " + pFullPath); - String result = command.execute(); - if (result != null) { - String errMsg = "failed to set vhd parent, child " + lFullPath + " parent " + pFullPath + ", err=" + result; - s_logger.warn(errMsg); - return errMsg; - } - return null; - } - - private String createLocalDir(String folder) { - Script command = new Script("/bin/bash", s_logger); - command.add("-c"); - command.add("mkdir -p " + folder); - String result = command.execute(); - if (result != null) { - String errMsg = "Create local path " + folder + " failed , err=" + result; - s_logger.warn(errMsg); - return errMsg; - } - return null; - } - - private String deleteLocalDir(String folder) { - Script command = new Script("/bin/bash", s_logger); - command.add("-c"); - command.add("rmdir " + folder); - String result = command.execute(); - if (result != null) { - String errMsg = "Delete local path " + folder + " failed , err=" + result; - s_logger.warn(errMsg); - return errMsg; - } - return null; - } - private String deleteLocalFile(String fullPath) { Script command = new Script("/bin/bash", s_logger); command.add("-c"); @@ -1690,12 +1567,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, true, "Object with null install path does not exist on image store , no need to delete"); } switch (objType) { - case TEMPLATE: - return deleteTemplate(cmd); - case VOLUME: - return deleteVolume(cmd); - case SNAPSHOT: - return deleteSnapshot(cmd); + case TEMPLATE: + return deleteTemplate(cmd); + case VOLUME: + return deleteVolume(cmd); + case SNAPSHOT: + return deleteSnapshot(cmd); } return Answer.createUnsupportedCommandAnswer(cmd); } @@ -1716,7 +1593,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S parent += File.separator; } String absoluteTemplatePath = parent + relativeTemplatePath; - File tmpltParent = new File(absoluteTemplatePath).getParentFile(); + File tmpltPath = new File(absoluteTemplatePath); + File tmpltParent = null; + if(tmpltPath.exists() && tmpltPath.isDirectory()) { + tmpltParent = tmpltPath; + } else { + tmpltParent = tmpltPath.getParentFile(); + } + String details = null; if (!tmpltParent.exists()) { details = "template parent directory " + tmpltParent.getName() + " doesn't exist"; @@ -1770,7 +1654,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, true, String.format("Deleted template %1$s from bucket %2$s.", path, bucket)); } catch (Exception e) { final String errorMessage = - String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); + String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); } @@ -2354,7 +2238,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S List args = URLEncodedUtils.parse(uri, "UTF-8"); boolean foundUser = false; boolean foundPswd = false; - String extraOpts = ""; + StringBuilder extraOpts = new StringBuilder(); for (NameValuePair nvp : args) { String name = nvp.getName(); if (name.equals("user")) { @@ -2362,10 +2246,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S s_logger.debug("foundUser is" + foundUser); } else if (name.equals("password")) { foundPswd = true; - s_logger.debug("foundPswd is" + foundPswd); + s_logger.debug("password is present in uri"); } - extraOpts = extraOpts + name + "=" + nvp.getValue() + ","; + extraOpts.append(name + "=" + nvp.getValue() + ","); } if (s_logger.isDebugEnabled()) { @@ -2374,12 +2258,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S if (!foundUser || !foundPswd) { String errMsg = - "Missing user and password from URI. Make sure they" + "are in the query string and separated by '&'. E.g. " - + "cifs://example.com/some_share?user=foo&password=bar"; + "Missing user and password from URI. Make sure they" + "are in the query string and separated by '&'. E.g. " + + "cifs://example.com/some_share?user=foo&password=bar"; s_logger.error(errMsg); throw new CloudRuntimeException(errMsg); } - return extraOpts; + return extraOpts.toString(); } protected boolean mountExists(String localRootPath, URI uri) { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java index fef034dbdbd..ee5064751be 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java @@ -32,12 +32,9 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; - import com.cloud.agent.AgentManager; import com.cloud.host.HostVO; import com.cloud.host.Status.Event; -import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; @@ -66,16 +63,12 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov Random _random = new Random(System.currentTimeMillis()); @Inject - protected HostDao _hostDao = null; - @Inject protected VMTemplateDao _tmpltDao = null; @Inject protected VMTemplateZoneDao _vmTemplateZoneDao = null; @Inject protected VMTemplateDao _vmTemplateDao = null; @Inject - protected ConfigurationDao _configDao = null; - @Inject protected AgentManager _agentMgr = null; protected SecondaryStorageDiscoverer() { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java index 84daf27de7c..d45a6bbe607 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java @@ -62,6 +62,7 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.template.HttpTemplateDownloader; import com.cloud.storage.template.IsoProcessor; import com.cloud.storage.template.LocalTemplateDownloader; +import com.cloud.storage.template.OVAProcessor; import com.cloud.storage.template.Processor; import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.QCOW2Processor; @@ -75,7 +76,6 @@ import com.cloud.storage.template.TemplateDownloader.Status; import com.cloud.storage.template.TemplateLocation; import com.cloud.storage.template.TemplateProp; import com.cloud.storage.template.VhdProcessor; -import com.cloud.storage.template.OVAProcessor; import com.cloud.storage.template.VmdkProcessor; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ManagerBase; @@ -104,14 +104,12 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager private static class DownloadJob { private final TemplateDownloader td; - private final String jobId; private final String tmpltName; private final boolean hvm; private final ImageFormat format; private String tmpltPath; private final String description; private String checksum; - private final Long accountId; private final String installPathPrefix; private long templatesize; private long templatePhysicalSize; @@ -122,11 +120,9 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager String installPathPrefix, ResourceType resourceType) { super(); this.td = td; - this.jobId = jobId; this.tmpltName = tmpltName; this.format = format; this.hvm = hvm; - this.accountId = accountId; description = descr; checksum = cksum; this.installPathPrefix = installPathPrefix; @@ -135,10 +131,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager this.resourceType = resourceType; } - public TemplateDownloader getTd() { - return td; - } - public String getDescription() { return description; } @@ -151,10 +143,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return td; } - public String getJobId() { - return jobId; - } - public String getTmpltName() { return tmpltName; } @@ -167,10 +155,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return hvm; } - public Long getAccountId() { - return accountId; - } - public long getId() { return id; } @@ -232,7 +216,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager private String _volumeDir; private String createTmpltScr; private String createVolScr; - private List processors; private ExecutorService threadPool; @@ -240,7 +223,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager private String listTmpltScr; private String listVolScr; private int installTimeoutPerGig = 180 * 60 * 1000; - private boolean _sslCopy; public void setThreadPool(ExecutorService threadPool) { this.threadPool = threadPool; @@ -268,55 +250,55 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager TemplateDownloader td = dj.getTemplateDownloader(); s_logger.info("Download Completion for jobId: " + jobId + ", status=" + status); s_logger.info("local: " + td.getDownloadLocalPath() + ", bytes=" + td.getDownloadedBytes() + ", error=" + td.getDownloadError() + ", pct=" + - td.getDownloadPercent()); + td.getDownloadPercent()); switch (status) { - case ABORTED: - case NOT_STARTED: - case UNRECOVERABLE_ERROR: - // TODO - dj.cleanup(); - break; - case UNKNOWN: - return; - case IN_PROGRESS: - s_logger.info("Resuming jobId: " + jobId + ", status=" + status); - td.setResume(true); - threadPool.execute(td); - break; - case RECOVERABLE_ERROR: - threadPool.execute(td); - break; - case DOWNLOAD_FINISHED: - if (!(td instanceof S3TemplateDownloader)) { - // we currently only create template.properties for NFS by - // running some post download script - td.setDownloadError("Download success, starting install "); - String result = postDownload(jobId); - if (result != null) { - s_logger.error("Failed post download script: " + result); - td.setStatus(Status.UNRECOVERABLE_ERROR); - td.setDownloadError("Failed post download script: " + result); - } else { - td.setStatus(Status.POST_DOWNLOAD_FINISHED); - td.setDownloadError("Install completed successfully at " + new SimpleDateFormat().format(new Date())); - } + case ABORTED: + case NOT_STARTED: + case UNRECOVERABLE_ERROR: + // TODO + dj.cleanup(); + break; + case UNKNOWN: + return; + case IN_PROGRESS: + s_logger.info("Resuming jobId: " + jobId + ", status=" + status); + td.setResume(true); + threadPool.execute(td); + break; + case RECOVERABLE_ERROR: + threadPool.execute(td); + break; + case DOWNLOAD_FINISHED: + if (!(td instanceof S3TemplateDownloader)) { + // we currently only create template.properties for NFS by + // running some post download script + td.setDownloadError("Download success, starting install "); + String result = postDownload(jobId); + if (result != null) { + s_logger.error("Failed post download script: " + result); + td.setStatus(Status.UNRECOVERABLE_ERROR); + td.setDownloadError("Failed post download script: " + result); } else { - // for s3 and swift, we skip post download step and just set - // status to trigger callback. td.setStatus(Status.POST_DOWNLOAD_FINISHED); - // set template size for S3 - S3TemplateDownloader std = (S3TemplateDownloader)td; - long size = std.totalBytes; - DownloadJob dnld = jobs.get(jobId); - dnld.setTemplatesize(size); - dnld.setTemplatePhysicalSize(size); - dnld.setTmpltPath(std.getDownloadLocalPath()); // update template path to include file name. + td.setDownloadError("Install completed successfully at " + new SimpleDateFormat().format(new Date())); } - dj.cleanup(); - break; - default: - break; + } else { + // for s3 and swift, we skip post download step and just set + // status to trigger callback. + td.setStatus(Status.POST_DOWNLOAD_FINISHED); + // set template size for S3 + S3TemplateDownloader std = (S3TemplateDownloader)td; + long size = std.totalBytes; + DownloadJob dnld = jobs.get(jobId); + dnld.setTemplatesize(size); + dnld.setTemplatePhysicalSize(size); + dnld.setTmpltPath(std.getDownloadLocalPath()); // update template path to include file name. + } + dj.cleanup(); + break; + default: + break; } } @@ -360,28 +342,12 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager DownloadJob dnld = jobs.get(jobId); TemplateDownloader td = dnld.getTemplateDownloader(); String resourcePath = dnld.getInstallPathPrefix(); // path with mount - // directory + // directory String finalResourcePath = dnld.getTmpltPath(); // template download - // path on secondary - // storage + // path on secondary + // storage ResourceType resourceType = dnld.getResourceType(); - /* - // once template path is set, remove the parent dir so that the template - // is installed with a relative path - String finalResourcePath = ""; - if (resourceType == ResourceType.TEMPLATE) { - finalResourcePath += _templateDir + File.separator + dnld.getAccountId() + File.separator + dnld.getId() + File.separator; - resourcePath = dnld.getInstallPathPrefix() + dnld.getAccountId() + File.separator + dnld.getId() + File.separator;// dnld.getTmpltName(); - } else { - finalResourcePath += _volumeDir + File.separator + dnld.getId() + File.separator; - resourcePath = dnld.getInstallPathPrefix() + dnld.getId() + File.separator;// dnld.getTmpltName(); - } - - _storage.mkdirs(resourcePath); - dnld.setTmpltPath(finalResourcePath); - */ - File originalTemplate = new File(td.getDownloadLocalPath()); String checkSum = computeCheckSum(originalTemplate); if (checkSum == null) { @@ -421,7 +387,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager scr.add("-t", resourcePath); scr.add("-f", td.getDownloadLocalPath()); // this is the temporary - // template file downloaded + // template file downloaded if (dnld.getChecksum() != null && dnld.getChecksum().length() > 1) { scr.add("-c", dnld.getChecksum()); } @@ -497,7 +463,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager @Override public String downloadS3Template(S3TO s3, long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, - String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { + String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { UUID uuid = UUID.randomUUID(); String jobId = uuid.toString(); @@ -527,7 +493,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager @Override public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, - String installPathPrefix, String templatePath, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { + String installPathPrefix, String templatePath, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { UUID uuid = UUID.randomUUID(); String jobId = uuid.toString(); String tmpDir = installPathPrefix; @@ -540,52 +506,52 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } // TO DO - define constant for volume properties. File file = - ResourceType.TEMPLATE == resourceType ? _storage.getFile(tmpDir + File.separator + TemplateLocation.Filename) : _storage.getFile(tmpDir + File.separator + - "volume.properties"); - if (file.exists()) { - file.delete(); - } + ResourceType.TEMPLATE == resourceType ? _storage.getFile(tmpDir + File.separator + TemplateLocation.Filename) : _storage.getFile(tmpDir + File.separator + + "volume.properties"); + if (file.exists()) { + file.delete(); + } - if (!file.createNewFile()) { - s_logger.warn("Unable to create new file: " + file.getAbsolutePath()); - return "Unable to create new file: " + file.getAbsolutePath(); - } + if (!file.createNewFile()) { + s_logger.warn("Unable to create new file: " + file.getAbsolutePath()); + return "Unable to create new file: " + file.getAbsolutePath(); + } - URI uri; - try { - uri = new URI(url); - } catch (URISyntaxException e) { - throw new CloudRuntimeException("URI is incorrect: " + url); - } - TemplateDownloader td; - if ((uri != null) && (uri.getScheme() != null)) { - if (uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")) { - td = new HttpTemplateDownloader(_storage, url, tmpDir, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType); - } else if (uri.getScheme().equalsIgnoreCase("file")) { - td = new LocalTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId)); - } else if (uri.getScheme().equalsIgnoreCase("scp")) { - td = new ScpTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId)); - } else if (uri.getScheme().equalsIgnoreCase("nfs") || uri.getScheme().equalsIgnoreCase("cifs")) { - td = null; - // TODO: implement this. - throw new CloudRuntimeException("Scheme is not supported " + url); - } else { - throw new CloudRuntimeException("Scheme is not supported " + url); - } - } else { - throw new CloudRuntimeException("Unable to download from URL: " + url); - } - // NOTE the difference between installPathPrefix and templatePath - // here. instalPathPrefix is the absolute path for template - // including mount directory - // on ssvm, while templatePath is the final relative path on - // secondary storage. - DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType); - dj.setTmpltPath(templatePath); - jobs.put(jobId, dj); - threadPool.execute(td); + URI uri; + try { + uri = new URI(url); + } catch (URISyntaxException e) { + throw new CloudRuntimeException("URI is incorrect: " + url); + } + TemplateDownloader td; + if ((uri != null) && (uri.getScheme() != null)) { + if (uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")) { + td = new HttpTemplateDownloader(_storage, url, tmpDir, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType); + } else if (uri.getScheme().equalsIgnoreCase("file")) { + td = new LocalTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId)); + } else if (uri.getScheme().equalsIgnoreCase("scp")) { + td = new ScpTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId)); + } else if (uri.getScheme().equalsIgnoreCase("nfs") || uri.getScheme().equalsIgnoreCase("cifs")) { + td = null; + // TODO: implement this. + throw new CloudRuntimeException("Scheme is not supported " + url); + } else { + throw new CloudRuntimeException("Scheme is not supported " + url); + } + } else { + throw new CloudRuntimeException("Unable to download from URL: " + url); + } + // NOTE the difference between installPathPrefix and templatePath + // here. instalPathPrefix is the absolute path for template + // including mount directory + // on ssvm, while templatePath is the final relative path on + // secondary storage. + DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType); + dj.setTmpltPath(templatePath); + jobs.put(jobId, dj); + threadPool.execute(td); - return jobId; + return jobId; } catch (IOException e) { s_logger.warn("Unable to download to " + tmpDir, e); return null; @@ -645,24 +611,24 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager public static VMTemplateHostVO.Status convertStatus(Status tds) { switch (tds) { - case ABORTED: - return VMTemplateHostVO.Status.NOT_DOWNLOADED; - case DOWNLOAD_FINISHED: - return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS; - case IN_PROGRESS: - return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS; - case NOT_STARTED: - return VMTemplateHostVO.Status.NOT_DOWNLOADED; - case RECOVERABLE_ERROR: - return VMTemplateHostVO.Status.NOT_DOWNLOADED; - case UNKNOWN: - return VMTemplateHostVO.Status.UNKNOWN; - case UNRECOVERABLE_ERROR: - return VMTemplateHostVO.Status.DOWNLOAD_ERROR; - case POST_DOWNLOAD_FINISHED: - return VMTemplateHostVO.Status.DOWNLOADED; - default: - return VMTemplateHostVO.Status.UNKNOWN; + case ABORTED: + return VMTemplateHostVO.Status.NOT_DOWNLOADED; + case DOWNLOAD_FINISHED: + return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS; + case IN_PROGRESS: + return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS; + case NOT_STARTED: + return VMTemplateHostVO.Status.NOT_DOWNLOADED; + case RECOVERABLE_ERROR: + return VMTemplateHostVO.Status.NOT_DOWNLOADED; + case UNKNOWN: + return VMTemplateHostVO.Status.UNKNOWN; + case UNRECOVERABLE_ERROR: + return VMTemplateHostVO.Status.DOWNLOAD_ERROR; + case POST_DOWNLOAD_FINISHED: + return VMTemplateHostVO.Status.DOWNLOADED; + default: + return VMTemplateHostVO.Status.UNKNOWN; } } @@ -680,7 +646,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager if (cmd.getUrl() == null) { return new DownloadAnswer(resourceType.toString() + " is corrupted on storage due to an invalid url , cannot download", - VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); + VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); } if (cmd.getName() == null) { @@ -697,27 +663,27 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager String password = null; if (cmd.getAuth() != null) { user = cmd.getAuth().getUserName(); - password = new String(cmd.getAuth().getPassword()); + password = cmd.getAuth().getPassword(); } // TO DO - Define Volume max size as well long maxDownloadSizeInBytes = - (cmd.getMaxDownloadSizeInBytes() == null) ? TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES : (cmd.getMaxDownloadSizeInBytes()); + (cmd.getMaxDownloadSizeInBytes() == null) ? TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES : (cmd.getMaxDownloadSizeInBytes()); String jobId = null; if (dstore instanceof S3TO) { jobId = - downloadS3Template((S3TO)dstore, cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), - cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); + downloadS3Template((S3TO)dstore, cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), + cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); } else { jobId = - downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), - cmd.getChecksum(), installPathPrefix, cmd.getInstallPath(), user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); + downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), + cmd.getChecksum(), installPathPrefix, cmd.getInstallPath(), user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); } sleep(); if (jobId == null) { return new DownloadAnswer("Internal Error", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); } return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), getInstallPath(jobId), - getDownloadTemplateSize(jobId), getDownloadTemplateSize(jobId), getDownloadCheckSum(jobId)); + getDownloadTemplateSize(jobId), getDownloadTemplateSize(jobId), getDownloadCheckSum(jobId)); } private void sleep() { @@ -745,29 +711,29 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } TemplateDownloader td = dj.getTemplateDownloader(); switch (cmd.getRequest()) { - case GET_STATUS: - break; - case ABORT: - td.stopDownload(); - sleep(); - break; - case RESTART: - td.stopDownload(); - sleep(); - threadPool.execute(td); - break; - case PURGE: - td.stopDownload(); - answer = + case GET_STATUS: + break; + case ABORT: + td.stopDownload(); + sleep(); + break; + case RESTART: + td.stopDownload(); + sleep(); + threadPool.execute(td); + break; + case PURGE: + td.stopDownload(); + answer = new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), - getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId)); - jobs.remove(jobId); - return answer; - default: - break; // TODO + getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId)); + jobs.remove(jobId); + return answer; + default: + break; // TODO } return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), getInstallPath(jobId), - getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId)); + getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId)); } private String getInstallPath(String jobId) { @@ -778,16 +744,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return null; } - private String createTempDir(File rootDir, String name) throws IOException { - - File f = File.createTempFile(name, "", rootDir); - f.delete(); - f.mkdir(); - _storage.setWorldReadableAndWriteable(f); - return f.getAbsolutePath(); - - } - private List listVolumes(String rootdir) { List result = new ArrayList(); @@ -915,27 +871,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return result; } - private int deleteDownloadDirectories(File downloadPath, int deleted) { - try { - if (downloadPath.exists()) { - File[] files = downloadPath.listFiles(); - for (int i = 0; i < files.length; i++) { - if (files[i].isDirectory()) { - deleteDownloadDirectories(files[i], deleted); - files[i].delete(); - deleted++; - } else { - files[i].delete(); - deleted++; - } - } - } - } catch (Exception ex) { - s_logger.info("Failed to clean up template downloads directory " + ex.toString()); - } - return deleted; - } - public static class ZfsPathParser extends OutputInterpreter { String _parent; List paths = new ArrayList(); @@ -992,11 +927,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager throw new ConfigurationException("Unable to instantiate " + value); } } - String useSsl = (String)params.get("sslcopy"); - if (useSsl != null) { - _sslCopy = Boolean.parseBoolean(useSsl); - } String inSystemVM = (String)params.get("secondary.storage.vm"); if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) { s_logger.info("DownloadManager: starting additional services since we are inside system vm"); @@ -1081,7 +1012,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager String intf = "eth1"; command.add("-c"); command.add("iptables -A OUTPUT -o " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "80" + " -j REJECT;" + "iptables -A OUTPUT -o " + intf + - " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j REJECT;"); + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j REJECT;"); String result = command.execute(); if (result != null) { @@ -1120,7 +1051,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager command = new Script("/bin/bash", s_logger); command.add("-c"); command.add("iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j ACCEPT;" + "iptables -I INPUT -i " + intf + - " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j ACCEPT;"); + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j ACCEPT;"); result = command.execute(); if (result != null) { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java index dc0ef06b8ac..cdbc52dec5a 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java @@ -21,7 +21,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -46,7 +45,6 @@ import com.cloud.storage.StorageLayer; import com.cloud.storage.Upload; import com.cloud.storage.UploadVO; import com.cloud.storage.template.FtpTemplateUploader; -import com.cloud.storage.template.Processor; import com.cloud.storage.template.TemplateUploader; import com.cloud.storage.template.TemplateUploader.Status; import com.cloud.storage.template.TemplateUploader.UploadCompleteCallback; @@ -72,87 +70,17 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { private static class UploadJob { private final TemplateUploader tu; - private final String jobId; - private final String name; - private final ImageFormat format; - private String tmpltPath; - private String description; - private String checksum; - private Long accountId; - private String installPathPrefix; - private long templatesize; - private long id; public UploadJob(TemplateUploader tu, String jobId, long id, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix) { super(); this.tu = tu; - this.jobId = jobId; - this.name = name; - this.format = format; - this.accountId = accountId; - this.description = descr; - this.checksum = cksum; - this.installPathPrefix = installPathPrefix; - this.templatesize = 0; - this.id = id; - } - - public TemplateUploader getTd() { - return tu; - } - - public String getDescription() { - return description; - } - - public String getChecksum() { - return checksum; - } - - public UploadJob(TemplateUploader td, String jobId, UploadCommand cmd) { - this.tu = td; - this.jobId = jobId; - this.name = cmd.getName(); - this.format = cmd.getFormat(); } public TemplateUploader getTemplateUploader() { return tu; } - public String getJobId() { - return jobId; - } - - public String getTmpltName() { - return name; - } - - public ImageFormat getFormat() { - return format; - } - - public Long getAccountId() { - return accountId; - } - - public long getId() { - return id; - } - - public void setTmpltPath(String tmpltPath) { - this.tmpltPath = tmpltPath; - } - - public String getTmpltPath() { - return tmpltPath; - } - - public String getInstallPathPrefix() { - return installPathPrefix; - } - public void cleanup() { if (tu != null) { String upldPath = tu.getUploadLocalPath(); @@ -163,30 +91,19 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { } } - public void setTemplatesize(long templatesize) { - this.templatesize = templatesize; - } - - public long getTemplatesize() { - return templatesize; - } } public static final Logger s_logger = Logger.getLogger(UploadManagerImpl.class); private ExecutorService threadPool; private final Map jobs = new ConcurrentHashMap(); private String parentDir; - private List _processors; - private String publicTemplateRepo; private final String extractMountPoint = "/mnt/SecStorage/extractmnt"; private StorageLayer _storage; - private int installTimeoutPerGig; - private boolean _sslCopy; private boolean hvm; @Override public String uploadPublicTemplate(long id, String url, String name, ImageFormat format, Long accountId, String descr, String cksum, String installPathPrefix, - String userName, String passwd, long templateSizeInBytes) { + String userName, String passwd, long templateSizeInBytes) { UUID uuid = UUID.randomUUID(); String jobId = uuid.toString(); @@ -253,24 +170,24 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { public static UploadVO.Status convertStatus(Status tds) { switch (tds) { - case ABORTED: - return UploadVO.Status.NOT_UPLOADED; - case UPLOAD_FINISHED: - return UploadVO.Status.UPLOAD_IN_PROGRESS; - case IN_PROGRESS: - return UploadVO.Status.UPLOAD_IN_PROGRESS; - case NOT_STARTED: - return UploadVO.Status.NOT_UPLOADED; - case RECOVERABLE_ERROR: - return UploadVO.Status.NOT_UPLOADED; - case UNKNOWN: - return UploadVO.Status.UNKNOWN; - case UNRECOVERABLE_ERROR: - return UploadVO.Status.UPLOAD_ERROR; - case POST_UPLOAD_FINISHED: - return UploadVO.Status.UPLOADED; - default: - return UploadVO.Status.UNKNOWN; + case ABORTED: + return UploadVO.Status.NOT_UPLOADED; + case UPLOAD_FINISHED: + return UploadVO.Status.UPLOAD_IN_PROGRESS; + case IN_PROGRESS: + return UploadVO.Status.UPLOAD_IN_PROGRESS; + case NOT_STARTED: + return UploadVO.Status.NOT_UPLOADED; + case RECOVERABLE_ERROR: + return UploadVO.Status.NOT_UPLOADED; + case UNKNOWN: + return UploadVO.Status.UNKNOWN; + case UNRECOVERABLE_ERROR: + return UploadVO.Status.UPLOAD_ERROR; + case POST_UPLOAD_FINISHED: + return UploadVO.Status.UPLOADED; + default: + return UploadVO.Status.UNKNOWN; } } @@ -296,29 +213,29 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { } TemplateUploader td = uj.getTemplateUploader(); switch (cmd.getRequest()) { - case GET_STATUS: - break; - case ABORT: - td.stopUpload(); - sleep(); - break; + case GET_STATUS: + break; + case ABORT: + td.stopUpload(); + sleep(); + break; /*case RESTART: td.stopUpload(); sleep(); threadPool.execute(td); break;*/ - case PURGE: - td.stopUpload(); - answer = + case PURGE: + td.stopUpload(); + answer = new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId), - getUploadTemplateSize(jobId)); - jobs.remove(jobId); - return answer; - default: - break; // TODO + getUploadTemplateSize(jobId)); + jobs.remove(jobId); + return answer; + default: + break; // TODO } return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId), - getUploadTemplateSize(jobId)); + getUploadTemplateSize(jobId)); } @Override @@ -331,14 +248,11 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { String user = null; String password = null; String jobId = - uploadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), - cmd.getInstallPath(), user, password, cmd.getTemplateSizeInBytes()); + uploadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), + cmd.getInstallPath(), user, password, cmd.getTemplateSizeInBytes()); sleep(); - if (jobId == null) { - return new UploadAnswer(null, 0, "Internal Error", com.cloud.storage.UploadVO.Status.UPLOAD_ERROR, "", "", 0); - } return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId), - getUploadTemplateSize(jobId)); + getUploadTemplateSize(jobId)); } @Override @@ -435,13 +349,10 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { } private long getUploadTemplateSize(String jobId) { - UploadJob uj = jobs.get(jobId); - if (uj != null) { - return uj.getTemplatesize(); - } return 0; } + @SuppressWarnings("unchecked") @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -466,11 +377,7 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { throw new ConfigurationException("Unable to instantiate " + value); } } - String useSsl = (String)params.get("sslcopy"); - if (useSsl != null) { - _sslCopy = Boolean.parseBoolean(useSsl); - } String inSystemVM = (String)params.get("secondary.storage.vm"); if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) { s_logger.info("UploadManager: starting additional services since we are inside system vm"); @@ -478,9 +385,6 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { //blockOutgoingOnPrivate(); } - value = (String)params.get("install.timeout.pergig"); - this.installTimeoutPerGig = NumbersUtil.parseInt(value, 15 * 60) * 1000; - value = (String)params.get("install.numthreads"); final int numInstallThreads = NumbersUtil.parseInt(value, 10); @@ -544,43 +448,43 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { s_logger.warn("UploadedBytes=" + tu.getUploadedBytes() + ", error=" + tu.getUploadError() + ", pct=" + tu.getUploadPercent()); switch (status) { - case ABORTED: - case NOT_STARTED: - case UNRECOVERABLE_ERROR: - // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume. - if (uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1) { - uj.cleanup(); - } - break; - case UNKNOWN: - return; - case IN_PROGRESS: - s_logger.info("Resuming jobId: " + jobId + ", status=" + status); - tu.setResume(true); - threadPool.execute(tu); - break; - case RECOVERABLE_ERROR: - threadPool.execute(tu); - break; - case UPLOAD_FINISHED: - tu.setUploadError("Upload success, starting install "); - String result = postUpload(jobId); - if (result != null) { - s_logger.error("Failed post upload script: " + result); - tu.setStatus(Status.UNRECOVERABLE_ERROR); - tu.setUploadError("Failed post upload script: " + result); - } else { - s_logger.warn("Upload completed successfully at " + new SimpleDateFormat().format(new Date())); - tu.setStatus(Status.POST_UPLOAD_FINISHED); - tu.setUploadError("Upload completed successfully at " + new SimpleDateFormat().format(new Date())); - } - // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume. - if (uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1) { - uj.cleanup(); - } - break; - default: - break; + case ABORTED: + case NOT_STARTED: + case UNRECOVERABLE_ERROR: + // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume. + if (uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1) { + uj.cleanup(); + } + break; + case UNKNOWN: + return; + case IN_PROGRESS: + s_logger.info("Resuming jobId: " + jobId + ", status=" + status); + tu.setResume(true); + threadPool.execute(tu); + break; + case RECOVERABLE_ERROR: + threadPool.execute(tu); + break; + case UPLOAD_FINISHED: + tu.setUploadError("Upload success, starting install "); + String result = postUpload(jobId); + if (result != null) { + s_logger.error("Failed post upload script: " + result); + tu.setStatus(Status.UNRECOVERABLE_ERROR); + tu.setUploadError("Failed post upload script: " + result); + } else { + s_logger.warn("Upload completed successfully at " + new SimpleDateFormat().format(new Date())); + tu.setStatus(Status.POST_UPLOAD_FINISHED); + tu.setUploadError("Upload completed successfully at " + new SimpleDateFormat().format(new Date())); + } + // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume. + if (uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1) { + uj.cleanup(); + } + break; + default: + break; } } diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index ccff7c1f5b2..a0c45062736 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -299,7 +299,7 @@ CREATE VIEW `cloud`.`template_view` AS left join `cloud`.`vm_template` source_template ON source_template.id = vm_template.source_template_id left join - `cloud`.`template_store_ref` ON template_store_ref.template_id = vm_template.id and template_store_ref.store_role = 'Image' + `cloud`.`template_store_ref` ON template_store_ref.template_id = vm_template.id and template_store_ref.store_role = 'Image' and template_store_ref.destroyed=0 left join `cloud`.`image_store` ON image_store.removed is NULL AND template_store_ref.store_id is not NULL AND image_store.id = template_store_ref.store_id left join @@ -898,5 +898,202 @@ INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(uuid, hypervisor_type, hype ALTER TABLE `cloud`.`network_acl_item` modify `cidr` varchar(2048); -INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Advanced", 'DEFAULT', 'management-server', "api.servlet.endpoint", "http://localhost:8080/client/api?", "API end point. Can be used by CS components/services deployed remotely, for sending CS API requests", "http://localhost:8080/client/api?", NULL,NULL,0); +DROP VIEW IF EXISTS `cloud`.`user_vm_view`; +CREATE VIEW `cloud`.`user_vm_view` AS + select + vm_instance.id id, + vm_instance.name name, + user_vm.display_name display_name, + user_vm.user_data user_data, + account.id account_id, + account.uuid account_uuid, + account.account_name account_name, + account.type account_type, + domain.id domain_id, + domain.uuid domain_uuid, + domain.name domain_name, + domain.path domain_path, + projects.id project_id, + projects.uuid project_uuid, + projects.name project_name, + instance_group.id instance_group_id, + instance_group.uuid instance_group_uuid, + instance_group.name instance_group_name, + vm_instance.uuid uuid, + vm_instance.last_host_id last_host_id, + vm_instance.vm_type type, + vm_instance.limit_cpu_use limit_cpu_use, + vm_instance.created created, + vm_instance.state state, + vm_instance.removed removed, + vm_instance.ha_enabled ha_enabled, + vm_instance.hypervisor_type hypervisor_type, + vm_instance.instance_name instance_name, + vm_instance.guest_os_id guest_os_id, + vm_instance.display_vm display_vm, + guest_os.uuid guest_os_uuid, + vm_instance.pod_id pod_id, + host_pod_ref.uuid pod_uuid, + vm_instance.private_ip_address private_ip_address, + vm_instance.private_mac_address private_mac_address, + vm_instance.vm_type vm_type, + data_center.id data_center_id, + data_center.uuid data_center_uuid, + data_center.name data_center_name, + data_center.is_security_group_enabled security_group_enabled, + data_center.networktype data_center_type, + host.id host_id, + host.uuid host_uuid, + host.name host_name, + vm_template.id template_id, + vm_template.uuid template_uuid, + vm_template.name template_name, + vm_template.display_text template_display_text, + vm_template.enable_password password_enabled, + iso.id iso_id, + iso.uuid iso_uuid, + iso.name iso_name, + iso.display_text iso_display_text, + service_offering.id service_offering_id, + disk_offering.uuid service_offering_uuid, + Case + When (`cloud`.`service_offering`.`cpu` is null) then (`custom_cpu`.`value`) + Else ( `cloud`.`service_offering`.`cpu`) + End as `cpu`, + Case + When (`cloud`.`service_offering`.`speed` is null) then (`custom_speed`.`value`) + Else ( `cloud`.`service_offering`.`speed`) + End as `speed`, + Case + When (`cloud`.`service_offering`.`ram_size` is null) then (`custom_ram_size`.`value`) + Else ( `cloud`.`service_offering`.`ram_size`) + END as `ram_size`, + disk_offering.name service_offering_name, + storage_pool.id pool_id, + storage_pool.uuid pool_uuid, + storage_pool.pool_type pool_type, + volumes.id volume_id, + volumes.uuid volume_uuid, + volumes.device_id volume_device_id, + volumes.volume_type volume_type, + security_group.id security_group_id, + security_group.uuid security_group_uuid, + security_group.name security_group_name, + security_group.description security_group_description, + nics.id nic_id, + nics.uuid nic_uuid, + nics.network_id network_id, + nics.ip4_address ip_address, + nics.ip6_address ip6_address, + nics.ip6_gateway ip6_gateway, + nics.ip6_cidr ip6_cidr, + nics.default_nic is_default_nic, + nics.gateway gateway, + nics.netmask netmask, + nics.mac_address mac_address, + nics.broadcast_uri broadcast_uri, + nics.isolation_uri isolation_uri, + vpc.id vpc_id, + vpc.uuid vpc_uuid, + networks.uuid network_uuid, + networks.name network_name, + networks.traffic_type traffic_type, + networks.guest_type guest_type, + user_ip_address.id public_ip_id, + user_ip_address.uuid public_ip_uuid, + user_ip_address.public_ip_address public_ip_address, + ssh_keypairs.keypair_name keypair_name, + resource_tags.id tag_id, + resource_tags.uuid tag_uuid, + resource_tags.key tag_key, + resource_tags.value tag_value, + resource_tags.domain_id tag_domain_id, + resource_tags.account_id tag_account_id, + resource_tags.resource_id tag_resource_id, + resource_tags.resource_uuid tag_resource_uuid, + resource_tags.resource_type tag_resource_type, + resource_tags.customer tag_customer, + async_job.id job_id, + async_job.uuid job_uuid, + async_job.job_status job_status, + async_job.account_id job_account_id, + affinity_group.id affinity_group_id, + affinity_group.uuid affinity_group_uuid, + affinity_group.name affinity_group_name, + affinity_group.description affinity_group_description, + vm_instance.dynamically_scalable dynamically_scalable, + all_details.name detail_name, + all_details.value detail_value + from + `cloud`.`user_vm` + inner join + `cloud`.`vm_instance` ON vm_instance.id = user_vm.id + and vm_instance.removed is NULL + inner join + `cloud`.`account` ON vm_instance.account_id = account.id + inner join + `cloud`.`domain` ON vm_instance.domain_id = domain.id + left join + `cloud`.`guest_os` ON vm_instance.guest_os_id = guest_os.id + left join + `cloud`.`host_pod_ref` ON vm_instance.pod_id = host_pod_ref.id + left join + `cloud`.`projects` ON projects.project_account_id = account.id + left join + `cloud`.`instance_group_vm_map` ON vm_instance.id = instance_group_vm_map.instance_id + left join + `cloud`.`instance_group` ON instance_group_vm_map.group_id = instance_group.id + left join + `cloud`.`data_center` ON vm_instance.data_center_id = data_center.id + left join + `cloud`.`host` ON vm_instance.host_id = host.id + left join + `cloud`.`vm_template` ON vm_instance.vm_template_id = vm_template.id + left join + `cloud`.`vm_template` iso ON iso.id = user_vm.iso_id + left join + `cloud`.`service_offering` ON vm_instance.service_offering_id = service_offering.id + left join + `cloud`.`disk_offering` ON vm_instance.service_offering_id = disk_offering.id + left join + `cloud`.`volumes` ON vm_instance.id = volumes.instance_id + left join + `cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id + left join + `cloud`.`security_group_vm_map` ON vm_instance.id = security_group_vm_map.instance_id + left join + `cloud`.`security_group` ON security_group_vm_map.security_group_id = security_group.id + left join + `cloud`.`nics` ON vm_instance.id = nics.instance_id and nics.removed is null + left join + `cloud`.`networks` ON nics.network_id = networks.id + left join + `cloud`.`vpc` ON networks.vpc_id = vpc.id and vpc.removed is null + left join + `cloud`.`user_ip_address` ON user_ip_address.vm_id = vm_instance.id + left join + `cloud`.`user_vm_details` as ssh_details ON ssh_details.vm_id = vm_instance.id + and ssh_details.name = 'SSH.PublicKey' + left join + `cloud`.`ssh_keypairs` ON ssh_keypairs.public_key = ssh_details.value + left join + `cloud`.`resource_tags` ON resource_tags.resource_id = vm_instance.id + and resource_tags.resource_type = 'UserVm' + left join + `cloud`.`async_job` ON async_job.instance_id = vm_instance.id + and async_job.instance_type = 'VirtualMachine' + and async_job.job_status = 0 + left join + `cloud`.`affinity_group_vm_map` ON vm_instance.id = affinity_group_vm_map.instance_id + left join + `cloud`.`affinity_group` ON affinity_group_vm_map.affinity_group_id = affinity_group.id + left join + `cloud`.`user_vm_details` as all_details ON all_details.vm_id = vm_instance.id + left join + `cloud`.`user_vm_details` `custom_cpu` ON (((`custom_cpu`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_cpu`.`name` = 'CpuNumber'))) + left join + `cloud`.`user_vm_details` `custom_speed` ON (((`custom_speed`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_speed`.`name` = 'CpuSpeed'))) + left join + `cloud`.`user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_ram_size`.`name` = 'memory'))); + diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index e7924806b6b..4ce7ba9fe86 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -24,6 +24,9 @@ SET foreign_key_checks = 0; ALTER TABLE `cloud`.`disk_offering` ADD `cache_mode` VARCHAR( 16 ) DEFAULT 'none' COMMENT 'The disk cache mode to use for disks created with this offering'; +UPDATE `cloud`.`hypervisor_capabilities` set max_guests_limit='150' WHERE hypervisor_version='6.1.0'; +UPDATE `cloud`.`hypervisor_capabilities` set max_guests_limit='500' WHERE hypervisor_version='6.2.0'; + DROP VIEW IF EXISTS `cloud`.`disk_offering_view`; CREATE VIEW `cloud`.`disk_offering_view` AS select @@ -552,3 +555,24 @@ INSERT INTO `cloud`.`acl_group_policy_map` (group_id, policy_id, created) values INSERT INTO `cloud`.`acl_group_policy_map` (group_id, policy_id, created) values(4, 4, Now()); INSERT INTO `cloud`.`acl_group_policy_map` (group_id, policy_id, created) values(5, 5, Now()); +INSERT INTO `cloud`.`configuration`(category, instance, component, name, value, description, default_value) VALUES ('NetworkManager', 'DEFAULT', 'management-server', 'vm.network.nic.max.secondary.ipaddresses', NULL, 'Specify the number of secondary ip addresses per nic per vm', '256') ON DUPLICATE KEY UPDATE category='NetworkManager'; + +CREATE TABLE `cloud`.`autoscale_vmprofile_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `autoscale_vmprofile_id` bigint unsigned NOT NULL COMMENT 'VPC gateway id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the detail can be displayed to the end autoscale_vmprofile', + PRIMARY KEY (`id`), + CONSTRAINT `fk_autoscale_vmprofile_details__autoscale_vmprofile_id` FOREIGN KEY `fk_autoscale_vmprofile_details__autoscale_vmprofile_id`(`autoscale_vmprofile_id`) REFERENCES `autoscale_vmprofiles`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`autoscale_vmgroup_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `autoscale_vmgroup_id` bigint unsigned NOT NULL COMMENT 'VPC gateway id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the detail can be displayed to the end autoscale_vmgroup', + PRIMARY KEY (`id`), + CONSTRAINT `fk_autoscale_vmgroup_details__autoscale_vmgroup_id` FOREIGN KEY `fk_autoscale_vmgroup_details__autoscale_vmgroup_id`(`autoscale_vmgroup_id`) REFERENCES `autoscale_vmgroups`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/setup/db/templates.simulator.sql b/setup/db/templates.simulator.sql index 5f9b67d1f7e..25e91bd9c5f 100755 --- a/setup/db/templates.simulator.sql +++ b/setup/db/templates.simulator.sql @@ -16,7 +16,7 @@ -- under the License. -INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (100, UUID(), 'simulator-domR', 'SystemVM Template (simulator)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/routing/debian/latest/systemvm.vhd.bz2', '', 0, 'SystemVM Template (simulator)', 'VHD', 15, 0, 1, 'Simulator'); -INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (111, UUID(), 'simulator-Centos', 'CentOS 5.3(64-bit) no GUI (Simulator)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/centos53-x86_64/latest/f59f18fb-ae94-4f97-afd2-f84755767aca.vhd.bz2', '', 0, 'CentOS 5.3(64-bit) no GUI (Simulator)', 'VHD', 11, 1, 1, 'Simulator'); +INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type, state) + VALUES (100, UUID(), 'simulator-domR', 'SystemVM Template (simulator)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/routing/debian/latest/systemvm.vhd.bz2', '', 0, 'SystemVM Template (simulator)', 'VHD', 15, 0, 1, 'Simulator','Active'); +INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type,state) + VALUES (111, UUID(), 'simulator-Centos', 'CentOS 5.3(64-bit) no GUI (Simulator)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/centos53-x86_64/latest/f59f18fb-ae94-4f97-afd2-f84755767aca.vhd.bz2', '', 0, 'CentOS 5.3(64-bit) no GUI (Simulator)', 'VHD', 11, 1, 1, 'Simulator','Active'); diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config index d6dc8f02031..fa95fdadb16 100755 --- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config +++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config @@ -135,7 +135,7 @@ get_boot_params() { virtualpc|hyperv) # Hyper-V is recognized as virtualpc hypervisor type. Boot args are passed using KVP Daemon #waiting for the hv_kvp_daemon to start up - #sleep 30 need to fix the race condition of hv_kvp_daemon and cloud-early-config + #sleep need to fix the race condition of hv_kvp_daemon and cloud-early-config sleep 5 cp -f /var/opt/hyperv/.kvp_pool_0 /var/cache/cloud/cmdline cat /dev/null > /var/opt/hyperv/.kvp_pool_0 @@ -750,6 +750,16 @@ setup_dnsmasq() { sed -i -e "/^dhcp-client-update/d" /etc/dnsmasq.conf echo 'dhcp-client-update' >> /etc/dnsmasq.conf fi + + command -v dhcp_release > /dev/null 2>&1 + no_dhcp_release=$? + if [ $no_dhcp_release -eq 0 -a -z "$ETH0_IP6" ] + then + echo 1 > /var/cache/cloud/dnsmasq_managed_lease + sed -i -e "/^leasefile-ro/d" /etc/dnsmasq.conf + else + echo 0 > /var/cache/cloud/dnsmasq_managed_lease + fi } setup_sshd(){ @@ -1211,6 +1221,10 @@ start() { patch_log4j parse_cmd_line change_password + if [ "$hyp" == "hyperv" ]; then + # eject the systemvm.iso + eject + fi case $TYPE in router) [ "$NAME" == "" ] && NAME=router diff --git a/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh b/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh index b82fb8e79be..8e7ddac8fd8 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh @@ -80,8 +80,7 @@ fi grep "redundant_router=1" /var/cache/cloud/cmdline > /dev/null no_redundant=$? -command -v dhcp_release > /dev/null 2>&1 -no_dhcp_release=$? +dnsmasq_managed_lease=`cat /var/cache/cloud/dnsmasq_managed_lease` wait_for_dnsmasq () { local _pid=$(pidof dnsmasq) @@ -96,12 +95,7 @@ wait_for_dnsmasq () { return 1 } -if [ $ipv6 ] -then - no_dhcp_release=1 -fi - -if [ $no_dhcp_release -eq 0 ] +if [ $dnsmasq_managed_lease ] then #release previous dhcp lease if present logger -t cloud "edithosts: releasing $ipv4" @@ -145,27 +139,30 @@ then fi fi -#delete leases to supplied mac and ip addresses -if [ $ipv4 ] +if [ $dnsmasq_managed_lease -eq 0 ] then - sed -i /$mac/d $DHCP_LEASES - sed -i /"$ipv4 "/d $DHCP_LEASES -fi -if [ $ipv6 ] -then - sed -i /$duid/d $DHCP_LEASES - sed -i /"$ipv6 "/d $DHCP_LEASES -fi -sed -i /"$host "/d $DHCP_LEASES + #delete leases to supplied mac and ip addresses + if [ $ipv4 ] + then + sed -i /$mac/d $DHCP_LEASES + sed -i /"$ipv4 "/d $DHCP_LEASES + fi + if [ $ipv6 ] + then + sed -i /$duid/d $DHCP_LEASES + sed -i /"$ipv6 "/d $DHCP_LEASES + fi + sed -i /"$host "/d $DHCP_LEASES -#put in the new entry -if [ $ipv4 ] -then - echo "0 $mac $ipv4 $host *" >> $DHCP_LEASES -fi -if [ $ipv6 ] -then - echo "0 $duid $ipv6 $host *" >> $DHCP_LEASES + #put in the new entry + if [ $ipv4 ] + then + echo "0 $mac $ipv4 $host *" >> $DHCP_LEASES + fi + if [ $ipv6 ] + then + echo "0 $duid $ipv6 $host *" >> $DHCP_LEASES + fi fi #edit hosts file as well @@ -215,7 +212,7 @@ pid=$(pidof dnsmasq) if [ "$pid" != "" ] then # use SIGHUP to avoid service outage if dhcp_release is available. - if [ $no_dhcp_release -eq 0 ] + if [ $dnsmasq_managed_lease ] then kill -HUP $pid else diff --git a/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh b/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh index ae2d7e4296c..2a9d7807743 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh @@ -254,10 +254,11 @@ remove_first_ip() { if [ $? -gt 0 -a $? -ne 2 ] then remove_routing $1 + sudo ip link set $ethDev down return 1 fi remove_routing $1 - + sudo ip link set $ethDev down return $? } diff --git a/systemvm/scripts/_run.sh b/systemvm/scripts/_run.sh index bd063468cfb..1a37c7d372c 100755 --- a/systemvm/scripts/_run.sh +++ b/systemvm/scripts/_run.sh @@ -61,4 +61,11 @@ then maxmem=$eightypcnt fi +if [ "$(uname -m | grep '64')" == "" ]; then + let "maxmem32bit=2600" + if [ $maxmem -gt $maxmem32bit ]; then + maxmem=$maxmem32bit + fi +fi + java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@ diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index a94e7095577..ef30a79c72c 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -161,7 +161,8 @@ known_categories = { 'CacheStores' : 'Cache Stores', 'CacheStore' : 'Cache Store', 'Acl' : 'Acl', - 'OvsElement' : 'Ovs Element' + 'OvsElement' : 'Ovs Element', + 'StratosphereSsp' : ' Stratosphere SSP' } diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh index ddcaec9e43c..2e8bc88d903 100644 --- a/tools/appliance/build.sh +++ b/tools/appliance/build.sh @@ -101,9 +101,9 @@ echo "$appliance exported for VMWare: dist/$appliance-$build_date-$branch-vmware # Export for HyperV vboxmanage clonehd $hdd_uuid $appliance-$build_date-$branch-hyperv.vhd --format VHD -# HyperV doesn't support import a zipped image from S3 -#bzip2 $appliance-$build_date-$branch-hyperv.vhd +# HyperV doesn't support import a zipped image from S3, but we create a zipped version to save space on the jenkins box +zip $appliance-$build_date-$branch-hyperv.vhd.zip $appliance-$build_date-$branch-hyperv.vhd echo "$appliance exported for HyperV: dist/$appliance-$build_date-$branch-hyperv.vhd" -mv *-hyperv.vhd *.bz2 *.ova dist/ +mv *-hyperv.vhd *-hyperv.vhd.zip *.bz2 *.ova dist/ diff --git a/tools/appliance/definitions/systemvm64template/postinstall.sh b/tools/appliance/definitions/systemvm64template/postinstall.sh index a9a057d4e55..1eddbdb371c 100644 --- a/tools/appliance/definitions/systemvm64template/postinstall.sh +++ b/tools/appliance/definitions/systemvm64template/postinstall.sh @@ -68,8 +68,9 @@ install_packages() { apt-get --no-install-recommends -q -y --force-yes install keepalived conntrackd ipvsadm libnetfilter-conntrack3 libnl1 # ipcalc apt-get --no-install-recommends -q -y --force-yes install ipcalc + apt-get update # java - apt-get --no-install-recommends -q -y --force-yes install default-jre-headless + apt-get --no-install-recommends -q -y --force-yes install openjdk-7-jre-headless echo "iptables-persistent iptables-persistent/autosave_v4 boolean true" | debconf-set-selections echo "iptables-persistent iptables-persistent/autosave_v6 boolean true" | debconf-set-selections diff --git a/tools/appliance/definitions/systemvmtemplate/postinstall.sh b/tools/appliance/definitions/systemvmtemplate/postinstall.sh index 48ba04b5280..175fc1f745b 100644 --- a/tools/appliance/definitions/systemvmtemplate/postinstall.sh +++ b/tools/appliance/definitions/systemvmtemplate/postinstall.sh @@ -64,8 +64,9 @@ install_packages() { apt-get --no-install-recommends -q -y --force-yes install keepalived conntrackd ipvsadm libnetfilter-conntrack3 libnl1 # ipcalc apt-get --no-install-recommends -q -y --force-yes install ipcalc + apt-get update # java - apt-get --no-install-recommends -q -y --force-yes install default-jre-headless + apt-get --no-install-recommends -q -y --force-yes install openjdk-7-jre-headless echo "iptables-persistent iptables-persistent/autosave_v4 boolean true" | debconf-set-selections echo "iptables-persistent iptables-persistent/autosave_v6 boolean true" | debconf-set-selections diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 18a88babc3e..993673bbd71 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -7624,7 +7624,6 @@ div.container div.panel div#details-tab-addloadBalancer.detail-group div.loadBal .multi-edit .range input { width: 35px; - margin-left: 6px; margin-right: 2px; position: relative; } diff --git a/ui/images/infrastructure-icons.png b/ui/images/infrastructure-icons.png index 5d35a8ed493..a589fc42dc2 100644 Binary files a/ui/images/infrastructure-icons.png and b/ui/images/infrastructure-icons.png differ diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index 9430fe4b9bb..3b1931b862b 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -45,7 +45,16 @@ quiescevm: { label: 'label.quiesce.vm', isBoolean: true, - isChecked: false + isChecked: false, + isHidden: function(args) { + if (args.context.instances[0].hypervisor !== 'VMware') { + return true; + } + + args.form.fields.quiescevm.isChecked = true; + + return false; + } } } }, diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 4e1ce05ff91..0aa5473117c 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -2226,7 +2226,7 @@ } } - if (ipAddress.issourcenat) { + if (ipAddress.vpcid != null && ipAddress.issourcenat) { //don't show Configuration(ipRules) tab on VPC sourceNAT IP disableIpRules = true; } @@ -2382,6 +2382,7 @@ listView: $.extend(true, {}, cloudStack.sections.instances, { listView: { + advSearchFields: null, // Not supported in dialogs right now due to display issues filters: false, subselect: { label: 'label.use.vm.ip', @@ -2394,6 +2395,10 @@ listAll: true }; + if (args.filterBy.search.value) { + data.keyword = args.filterBy.search.value; + } + var $tierSelect = $(".ui-dialog-content").find('.tier-select select'); // if $tierSelect is not initialized, return; tierSelect() will refresh listView and come back here later diff --git a/ui/scripts/plugins.js b/ui/scripts/plugins.js index afeae7c7eaf..82d92429a7d 100644 --- a/ui/scripts/plugins.js +++ b/ui/scripts/plugins.js @@ -98,15 +98,37 @@ } // Execute module - cloudStack[type][id]( - $.extend(true, {}, cloudStack.pluginAPI, { - pluginAPI: { - extend: function(api) { - cloudStack.pluginAPI[id] = api; + var target = cloudStack[type][id]; + + if ($.isArray(target)) { // Load additional JS includes + pluginTotal += target[0].length; + require( + $(target[0]).map(function(index, val) { + return basePath + val; + }).toArray(), + function() { + loadedPlugins = loadedPlugins + target[0].length; + target[1]( + $.extend(true, {}, cloudStack.pluginAPI, { + pluginAPI: { + extend: function(api) { + cloudStack.pluginAPI[id] = api; + } + } + }) + ); + }); + } else { + target( + $.extend(true, {}, cloudStack.pluginAPI, { + pluginAPI: { + extend: function(api) { + cloudStack.pluginAPI[id] = api; + } } - } - }) - ); + }) + ); + } if (pluginDictionary) { // Callback for extending the dictionary with new entries @@ -133,13 +155,16 @@ loadedPlugins = loadedPlugins + 1; - if (loadedPlugins === pluginTotal) { - $(window).trigger('cloudStack.pluginReady'); - } - loadCSS(css); }); } ); }); + + var loadTimer = setInterval(function() { + if (loadedPlugins === pluginTotal) { + clearInterval(loadTimer); + $(window).trigger('cloudStack.pluginReady'); + } + }, 100); }(jQuery, cloudStack, require)); diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 64e4f5c959f..955d391060a 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -325,7 +325,6 @@ virtualRouterCount: function (data) { var data2 = { - projectid: -1, page: 1, pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property. }; @@ -334,24 +333,35 @@ data: data2, success: function (json) { var total1 = json.listroutersresponse.count ? json.listroutersresponse.count: 0; + var total2 = 0; //reset + /* + * In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1), + * because in project view, all API calls are appended with projectid=[projectID]. + * Therefore, we only call the second listRouters API(with projectid=-1) in non-project view. + */ + if (cloudStack.context && cloudStack.context.projects == null) { //non-project view var data3 = { listAll: true, + projectid: -1, page: 1, pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property. }; $.ajax({ url: createURL('listRouters'), data: data3, + async: false, success: function (json) { - var total2 = json.listroutersresponse.count ? json.listroutersresponse.count: 0; + total2 = json.listroutersresponse.count ? json.listroutersresponse.count : 0; + } + }); + } + dataFns.capacity($.extend(data, { virtualRouterCount: (total1 + total2) })); } }); - } - }); }, capacity: function (data) { @@ -404,7 +414,7 @@ var returnedHostCount = 0; var returnedHostCpusocketsSum = 0; - var callListHostsWithPage = function (setTotalHostCount) { + var callListHostsWithPage = function() { $.ajax({ url: createURL('listHosts'), async: false, @@ -419,9 +429,7 @@ return; } - if (setTotalHostCount) { totalHostCount = json.listhostsresponse.count; - } returnedHostCount += json.listhostsresponse.host.length; var items = json.listhostsresponse.host; @@ -433,13 +441,13 @@ if (returnedHostCount < totalHostCount) { currentPage++; - callListHostsWithPage(false); + callListHostsWithPage(); } } }); } - callListHostsWithPage(true); + callListHostsWithPage(); socketCount += returnedHostCpusocketsSum; }) @@ -2358,10 +2366,16 @@ routers.push(item); }); - // Get project routers + /* + * In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1), + * because in project view, all API calls are appended with projectid=[projectID]. + * Therefore, we only call the second listRouters API(with projectid=-1) in non-project view. + */ + if (cloudStack.context && cloudStack.context.projects == null) { //non-project view $.ajax({ url: createURL("listRouters&zoneid=" + selectedZoneObj.id + "&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("") + "&projectid=-1"), data: data2, + async: false, success: function (json) { var items = json.listroutersresponse.router ? json.listroutersresponse.router:[]; @@ -2369,14 +2383,16 @@ $(items).map(function (index, item) { routers.push(item); }); + } + }); + } + args.response.success({ actionFilter: routerActionfilter, data: $(routers).map(mapRouterType) }); } }); - } - }); }, detailView: { name: 'Virtual applicance details', @@ -2549,7 +2565,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { @@ -3075,7 +3091,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listInternalLoadBalancerVMs&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listInternalLoadBalancerVMs&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { @@ -3446,25 +3462,32 @@ routers.push(item); }); - // Get project routers + /* + * In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1), + * because in project view, all API calls are appended with projectid=[projectID]. + * Therefore, we only call the second listRouters API(with projectid=-1) in non-project view. + */ + if (cloudStack.context && cloudStack.context.projects == null) { //non-project view $.ajax({ url: createURL("listRouters&zoneid=" + selectedZoneObj.id + "&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("") + "&projectid=-1"), dataType: 'json', data: data2, - async: true, + async: false, success: function (json) { var items = json.listroutersresponse.router; $(items).map(function (index, item) { routers.push(item); }); + } + }); + } + args.response.success({ actionFilter: routerActionfilter, data: $(routers).map(mapRouterType) }); } }); - } - }); }, detailView: { name: 'Virtual applicance details', @@ -3673,7 +3696,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { @@ -6266,7 +6289,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { @@ -7722,7 +7745,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listSystemVms&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listSystemVms&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { @@ -8338,24 +8361,24 @@ routers.push(item); }); - //get project-owned routers - var toSearchByProjectid = true; + //if account is specified in advanced search, don't search project-owned routers + var accountIsNotSpecifiedInAdvSearch = true; if (args.filterBy != null) { - if (args.filterBy.advSearch != null && typeof (args.filterBy.advSearch) == "object") { - //advanced search - if ('account' in args.filterBy.advSearch && args.filterBy.advSearch.account.length > 0) { - //if account is specified in advanced search, don't search project-owned routers - toSearchByProjectid = false; //since account and projectid can't be specified together + if (args.filterBy.advSearch != null && typeof(args.filterBy.advSearch) == "object") { //advanced search + if ('account' in args.filterBy.advSearch && args.filterBy.advSearch.account.length > 0) { + accountIsNotSpecifiedInAdvSearch = false; //since account and projectid can't be specified together } } } - if (toSearchByProjectid) { + if (accountIsNotSpecifiedInAdvSearch) { + /* + * In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1), + * because in project view, all API calls are appended with projectid=[projectID]. + * Therefore, we only call the second listRouters API(with projectid=-1) in non-project view. + */ + if (cloudStack.context && cloudStack.context.projects == null) { //non-project view $.ajax({ - url: createURL('listRouters'), - data: $.extend(data, { - listAll: true, - projectid: -1 - }), + url: createURL("listRouters&listAll=true&page=" + args.page + "&pagesize=" + pageSize + "&projectid=-1"), async: false, success: function (json) { var items = json.listroutersresponse.router ? json.listroutersresponse.router:[]; @@ -8364,7 +8387,14 @@ }); } }); + } + } + + args.response.success({ + actionFilter: routerActionfilter, + data: $(routers).map(mapRouterType) + }); } }); @@ -8419,30 +8449,30 @@ } }, dataProvider: function (args) { - $.ajax({ - url: createURL('listHypervisors'), - success: function (json) { + var array1 = []; + + // ***** non XenServer (begin) ***** + var hypervisors = ["Hyperv", "KVM", "VMware", "BareMetal", "Ovm", "LXC"]; + var supportSocketHypervisors = { "Hyperv": 1, "KVM": 1, - "XenServer": 1, "VMware": 1 }; - args.response.success({ - data: $(json.listhypervisorsresponse.hypervisor).map(function (index, hypervisor) { + for (var h = 0; h < hypervisors.length; h++) { var totalHostCount = 0; var currentPage = 1; var returnedHostCount = 0; var returnedHostCpusocketsSum = 0; - var callListHostsWithPage = function (setTotalHostCount) { + var callListHostsWithPage = function() { $.ajax({ url: createURL('listHosts'), async: false, data: { type: 'routing', - hypervisor: hypervisor.name, + hypervisor: hypervisors[h], page: currentPage, pagesize: pageSize //global variable }, @@ -8451,9 +8481,7 @@ return; } - if (setTotalHostCount) { totalHostCount = json.listhostsresponse.count; - } returnedHostCount += json.listhostsresponse.host.length; var items = json.listhostsresponse.host; @@ -8465,27 +8493,100 @@ if (returnedHostCount < totalHostCount) { currentPage++; - callListHostsWithPage(false); + callListHostsWithPage(); } } }); } - callListHostsWithPage(true); + callListHostsWithPage(); - if ((hypervisor.name in supportSocketHypervisors) == false) { + if ((hypervisors[h] in supportSocketHypervisors) == false) { returnedHostCpusocketsSum = 'N/A'; } - return { - hypervisor: hypervisor.name, + var hypervisorName = hypervisors[h]; + if (hypervisorName == "Hyperv") { + hypervisorName = "Hyper-V"; + } + + array1.push({ + hypervisor: hypervisorName, hosts: totalHostCount, sockets: returnedHostCpusocketsSum - }; - }) }); } + // ***** non XenServer (end) ***** + + + // ***** XenServer (begin) ***** + var totalHostCount = 0; + var currentPage = 1; + var returnedHostCount = 0; + + var returnedHostCountForXenServer = 0; + var returnedHostCountForXenServer620 = 0; + var returnedHostCpusocketsSumForXenServer620 = 0; + + var callListHostsWithPage = function() { + $.ajax({ + url: createURL('listHosts'), + async: false, + data: { + type: 'routing', + hypervisor: 'XenServer', + page: currentPage, + pagesize: pageSize //global variable + }, + success: function(json) { + if (json.listhostsresponse.count == undefined) { + return; + } + + totalHostCount = json.listhostsresponse.count; + returnedHostCount += json.listhostsresponse.host.length; + + var items = json.listhostsresponse.host; + for (var i = 0; i < items.length; i++) { + //"hypervisorversion" == "6.2.0" + if (items[i].hypervisorversion == "6.2.0") { + returnedHostCountForXenServer620 ++; + if (items[i].cpusockets != undefined && isNaN(items[i].cpusockets) == false) { + returnedHostCpusocketsSumForXenServer620 += items[i].cpusockets; + } + } else { + returnedHostCountForXenServer++; + } + } + + if (returnedHostCount < totalHostCount) { + currentPage++; + callListHostsWithPage(); + } + } + }); + } + + callListHostsWithPage(); + + array1.push({ + hypervisor: 'XenServer', + hosts: returnedHostCountForXenServer, + sockets: 'N/A' }); + + array1.push({ + hypervisor: 'XenServer 6.2.0', + hosts: returnedHostCountForXenServer620, + sockets: returnedHostCpusocketsSumForXenServer620 + }); + // ***** XenServer (end) ***** + + + args.response.success({ + data: array1 + }); + } }; @@ -8563,10 +8664,17 @@ $(items).map(function (index, item) { routers.push(item); }); - // Get project routers + + /* + * In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1), + * because in project view, all API calls are appended with projectid=[projectID]. + * Therefore, we only call the second listRouters API(with projectid=-1) in non-project view. + */ + if (cloudStack.context && cloudStack.context.projects == null) { //non-project view $.ajax({ url: createURL("listRouters&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("") + "&projectid=-1"), data: data2, + async: false, success: function (json) { var items = json.listroutersresponse.router ? json.listroutersresponse.router:[]; @@ -8574,14 +8682,16 @@ $(items).map(function (index, item) { routers.push(item); }); + } + }); + } + args.response.success({ actionFilter: routerActionfilter, data: $(routers).map(mapRouterType) }); } }); - } - }); }, detailView: { name: 'Virtual applicance details', @@ -8823,7 +8933,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { @@ -10048,7 +10158,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listSystemVms&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listSystemVms&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { diff --git a/ui/scripts/ui/widgets/cloudBrowser.js b/ui/scripts/ui/widgets/cloudBrowser.js index ffb5f157abe..31ac533dd11 100644 --- a/ui/scripts/ui/widgets/cloudBrowser.js +++ b/ui/scripts/ui/widgets/cloudBrowser.js @@ -205,16 +205,7 @@ .addClass('reduced') ).removeClass('active maximized'); - $toRemove.css( - _panel.initialState($container), { - duration: 500, - complete: function() { - $(this).remove(); - - if (complete) complete($toShow); - } - } - ); + $toRemove.remove(); $toShow.show(); $panel.css({ left: _panel.position($container, { diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index d94744d5222..cb4544c7af0 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -877,7 +877,7 @@ $('
').attr({ id: 'advanced_search' }) - .addClass('button search') + .addClass('button search advanced-search') .append($('
').addClass('icon')) ); } @@ -1872,11 +1872,11 @@ }; var closeAdvancedSearch = function() { - $('#advanced_search .form-container:visible').remove(); + $listView.find('.advanced-search .form-container:visible').remove(); }; - $listView.find('.button.search#advanced_search .icon').bind('click', function(event) { - if ($('#advanced_search .form-container:visible').size()) { + $listView.find('.advanced-search .icon').bind('click', function(event) { + if ($listView.find('.advanced-search .form-container:visible').size()) { closeAdvancedSearch(); return false; @@ -1897,7 +1897,7 @@ var $formContainer = form.$formContainer; var $form = $formContainer.find('form'); - $formContainer.hide().appendTo('#advanced_search').show(); + $formContainer.hide().appendTo($listView.find('.advanced-search')).show(); $form.find('.form-item:first input').focus(); $form.find('input[type=submit]') .show() diff --git a/ui/tests/test.widget.listView.js b/ui/tests/test.widget.listView.js index 2209c42ddb9..43c42f9d16a 100644 --- a/ui/tests/test.widget.listView.js +++ b/ui/tests/test.widget.listView.js @@ -86,4 +86,160 @@ equal($field.html(), v.label, k + '-> Has correct label'); }); }); + + test('Data loading state', function() { + var $listView = listView(); + + equal($listView.find('table.body tr.loading').size(), 1, 'Row has loading state'); + equal($listView.find('table.body tr.loading td.loading.icon').size(), 1, 'Row cell has loading icon'); + }); + + asyncTest('Data provider: basic', function() { + expect(3); + var $listView = listView({ + listView: { + fields: { + fieldA: { label: 'TestFieldA' }, + fieldB: { label: 'TestFieldB' } + }, + dataProvider: function(args) { + args.response.success({ data: [] }); + + ok(true, 'Data provider called'); + start(); + } + } + }); + + equal($listView.find('.data-table table.body tbody tr.empty td').size(), 1, 'Body table has empty table row'); + equal($listView.find('.data-table table.body tbody tr.empty td').html(), 'label.no.data', 'Empty contents notice displayed'); + }); + + asyncTest('Data provider: load data', function() { + var $listView = listView({ + listView: { + fields: { + fieldA: { label: 'TestFieldA' }, + fieldB: { label: 'TestFieldB' } + }, + dataProvider: function(args) { + args.response.success({ + data: [ + { fieldA: 'FieldDataA', fieldB: 'FieldDataB' } + ] + }); + + start(); + } + } + }); + + equal($listView.find('table.body tbody tr').size(), 1, 'Body table has table row'); + equal($listView.find('table.body tbody tr td').size(), 2, 'Body table has table cells'); + equal($listView.find('table.body tbody tr td.fieldA > span').html(), 'FieldDataA', 'FieldDataA content present'); + equal($listView.find('table.body tbody tr td.fieldB > span').html(), 'FieldDataB', 'FieldDataB content present'); + }); + + asyncTest('Data provider: multiple rows of data', function() { + var testData = [ + { fieldA: 'FieldDataA1', fieldB: 'FieldDataB1' }, + { fieldA: 'FieldDataA2', fieldB: 'FieldDataB2' }, + { fieldA: 'FieldDataA3', fieldB: 'FieldDataB3' } + ]; + + var $listView = listView({ + listView: { + fields: { + fieldA: { label: 'TestFieldA' }, + fieldB: { label: 'TestFieldB' } + }, + dataProvider: function(args) { + args.response.success({ + data: testData + }); + + start(); + } + } + }); + + equal($listView.find('table.body tbody tr').size(), 3, 'Body table has correct # of table rows'); + + $(testData).map(function(index, data) { + var $tr = $listView.find('table.body tbody tr').filter(function() { + return $(this).index() === index; + }); + + equal($tr.find('td.fieldA > span').html(), 'FieldDataA' + (index + 1), 'FieldDataA' + (index + 1) + ' present'); + equal($tr.find('td.fieldB > span').html(), 'FieldDataB' + (index + 1), 'FieldDataB' + (index + 1) + ' present'); + }); + }); + + test('Field pre-filter', function() { + var $listView = listView({ + listView: { + fields: { + fieldA: { label: 'TestFieldA' }, + fieldB: { label: 'TestFieldB' }, + fieldHidden: { label: 'TestFieldHidden' } + }, + preFilter: function(args) { + return ['fieldHidden']; + }, + dataProvider: function(args) { + args.response.success({ + data: [ + { fieldA: 'FieldDataA', fieldB: 'FieldDataB', fieldHidden: 'FieldDataHidden' } + ] + }); + + start(); + } + } + }); + + equal($listView.find('table tr th').size(), 2, 'Correct number of header columns present'); + equal($listView.find('table.body tbody tr td').size(), 2, 'Correct number of data body columns present'); + ok(!$listView.find('table.body tbody td.fieldHidden').size(), 'Hidden field not present'); + }); + + test('Filter dropdown', function() { + var $listView = listView({ + listView: { + fields: { + state: { label: 'State' } + }, + filters: { + on: { label: 'FilterOnLabel' }, + off: { label: 'FilterOffLabel' } + }, + dataProvider: function(args) { + var filterBy = args.filterBy.kind; + var data = filterBy === 'on' ? [{ state: 'on' }] : [{ state: 'off' }]; + + args.response.success({ + data: data + }); + + start(); + } + } + }); + + var $filters = $listView.find('.filters select'); + + var testFilterDropdownContent = function() { + equal($filters.find('option').size(), 2, 'Correct # of filters present'); + equal($filters.find('option:first').html(), 'FilterOnLabel', 'Filter on label present'); + equal($filters.find('option:last').html(), 'FilterOffLabel', 'Filter off label present'); + }; + + testFilterDropdownContent(); + equal($filters.find('option').val(), 'on', 'Correct default filter active'); + equal($listView.find('tbody td.state span').html(), 'on', '"on" data item visible'); + ok($filters.val('off').trigger('change'), 'Change filter to "off"'); + equal($listView.find('tbody td.state span').html(), 'off', '"off" data item visible'); + equal($filters.val(), 'off', 'Correct filter active'); + testFilterDropdownContent(); + }); }()); diff --git a/utils/src/com/cloud/utils/ExecutionResult.java b/utils/src/com/cloud/utils/ExecutionResult.java new file mode 100644 index 00000000000..8edb55b93f3 --- /dev/null +++ b/utils/src/com/cloud/utils/ExecutionResult.java @@ -0,0 +1,44 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package com.cloud.utils; + +public class ExecutionResult { + private Boolean success; + private String details; + + public ExecutionResult(Boolean success, String details) { + this.success = success; + this.details = details; + } + + public Boolean isSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } +} diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index 8e994f1baec..f64b2302a5b 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -41,13 +41,14 @@ import org.apache.commons.lang.SystemUtils; import org.apache.commons.net.util.SubnetUtils; import org.apache.log4j.Logger; -import com.cloud.utils.IteratorUtil; -import com.cloud.utils.Pair; -import com.cloud.utils.script.Script; import com.googlecode.ipv6.IPv6Address; import com.googlecode.ipv6.IPv6AddressRange; import com.googlecode.ipv6.IPv6Network; +import com.cloud.utils.IteratorUtil; +import com.cloud.utils.Pair; +import com.cloud.utils.script.Script; + public class NetUtils { protected final static Logger s_logger = Logger.getLogger(NetUtils.class); public final static String HTTP_PORT = "80"; @@ -832,7 +833,7 @@ public class NetUtils { if (cidrALong[1] < cidrBLong[1]) { //this implies cidrA is super set of cidrB return supersetOrSubset.isSuperset; - } else if (cidrALong[1] == cidrBLong[1]) { + } else if (cidrALong[1].equals(cidrBLong[1])) { //this implies both the cidrs are equal return supersetOrSubset.sameSubnet; } @@ -1209,7 +1210,7 @@ public class NetUtils { public static boolean isValidIpv6(String ip) { try { - IPv6Address address = IPv6Address.fromString(ip); + IPv6Address.fromString(ip); } catch (IllegalArgumentException ex) { return false; } @@ -1218,7 +1219,7 @@ public class NetUtils { public static boolean isValidIp6Cidr(String ip6Cidr) { try { - IPv6Network network = IPv6Network.fromString(ip6Cidr); + IPv6Network.fromString(ip6Cidr); } catch (IllegalArgumentException ex) { return false; } diff --git a/utils/src/com/cloud/utils/script/OutputInterpreter.java b/utils/src/com/cloud/utils/script/OutputInterpreter.java index 5af607e4590..5845c9ca0ff 100755 --- a/utils/src/com/cloud/utils/script/OutputInterpreter.java +++ b/utils/src/com/cloud/utils/script/OutputInterpreter.java @@ -16,11 +16,11 @@ // under the License. package com.cloud.utils.script; +import org.apache.log4j.Logger; + import java.io.BufferedReader; import java.io.IOException; -import org.apache.log4j.Logger; - /** */ public abstract class OutputInterpreter { diff --git a/utils/src/com/cloud/utils/script/Script.java b/utils/src/com/cloud/utils/script/Script.java index 91f32dedeb7..8dad697feae 100755 --- a/utils/src/com/cloud/utils/script/Script.java +++ b/utils/src/com/cloud/utils/script/Script.java @@ -16,6 +16,11 @@ // under the License. package com.cloud.utils.script; +import com.cloud.utils.PropertiesUtil; +import com.cloud.utils.concurrency.NamedThreadFactory; +import com.cloud.utils.script.OutputInterpreter.TimedOutLogger; +import org.apache.log4j.Logger; + import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; @@ -35,12 +40,6 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import org.apache.log4j.Logger; - -import com.cloud.utils.PropertiesUtil; -import com.cloud.utils.concurrency.NamedThreadFactory; -import com.cloud.utils.script.OutputInterpreter.TimedOutLogger; - public class Script implements Callable { private static final Logger s_logger = Logger.getLogger(Script.class); @@ -61,6 +60,10 @@ public class Script implements Callable { Process _process; Thread _thread; + public int getExitValue() { + return _process.exitValue(); + } + public Script(String command, long timeout, Logger logger) { _command = new ArrayList(); _command.add(command); diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java index 21b3026154b..363b91f9c68 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java @@ -32,6 +32,7 @@ import com.vmware.vim25.PropertySpec; import com.vmware.vim25.SelectionSpec; import com.vmware.vim25.TraversalSpec; +import com.cloud.exception.CloudException; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.utils.Pair; @@ -181,7 +182,7 @@ public class DatastoreMO extends BaseMO { } public boolean copyDatastoreFile(String srcFilePath, ManagedObjectReference morSrcDc, ManagedObjectReference morDestDs, String destFilePath, - ManagedObjectReference morDestDc, boolean forceOverwrite) throws Exception { + ManagedObjectReference morDestDc, boolean forceOverwrite) throws Exception { String srcDsName = getName(); DatastoreMO destDsMo = new DatastoreMO(_context, morDestDs); @@ -209,7 +210,7 @@ public class DatastoreMO extends BaseMO { } public boolean moveDatastoreFile(String srcFilePath, ManagedObjectReference morSrcDc, ManagedObjectReference morDestDs, String destFilePath, - ManagedObjectReference morDestDc, boolean forceOverwrite) throws Exception { + ManagedObjectReference morDestDc, boolean forceOverwrite) throws Exception { String srcDsName = getName(); DatastoreMO destDsMo = new DatastoreMO(_context, morDestDs); @@ -342,6 +343,10 @@ public class DatastoreMO extends BaseMO { ArrayList results = browserMo.searchDatastoreSubFolders("[" + getName() + "]", fileName, caseInsensitive); if (results != null && results.size() > 1) { s_logger.warn("Multiple files with name " + fileName + " exists in datastore " + datastorePath + ". Trying to choose first file found in search attempt."); + } else if (results == null) { + String msg = "No file found with name " + fileName + " found in datastore " + datastorePath; + s_logger.error(msg); + throw new CloudException(msg); } for (HostDatastoreBrowserSearchResults result : results) { List info = result.getFile(); diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java index e81665f71b7..9284569da32 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java @@ -263,12 +263,12 @@ public class VmwareClient { props.add(propertyName); List objContent = retrieveMoRefProperties(mor, props); - T propertyValue = null; + Object propertyValue = null; if (objContent != null && objContent.size() > 0) { List dynamicProperty = objContent.get(0).getPropSet(); if (dynamicProperty != null && dynamicProperty.size() > 0) { DynamicProperty dp = dynamicProperty.get(0); - propertyValue = (T)dp.getVal(); + propertyValue = dp.getVal(); /* * If object is ArrayOfXXX object, then get the XXX[] by * invoking getXXX() on the object. @@ -276,17 +276,17 @@ public class VmwareClient { * ArrayOfManagedObjectReference.getManagedObjectReference() * returns ManagedObjectReference[] array. */ - Class dpCls = propertyValue.getClass(); + Class dpCls = propertyValue.getClass(); String dynamicPropertyName = dpCls.getName(); if (dynamicPropertyName.indexOf("ArrayOf") != -1) { String methodName = "get" + dynamicPropertyName.substring(dynamicPropertyName.indexOf("ArrayOf") + "ArrayOf".length(), dynamicPropertyName.length()); - Method getMorMethod = dpCls.getDeclaredMethod(methodName, (Class)null); - propertyValue = (T)getMorMethod.invoke(propertyValue, (Object[])null); + Method getMorMethod = dpCls.getDeclaredMethod(methodName, null); + propertyValue = getMorMethod.invoke(propertyValue, (Object[])null); } } } - return propertyValue; + return (T)propertyValue; } private List retrieveMoRefProperties(ManagedObjectReference mObj, List props) throws Exception {