mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
merge to master
This commit is contained in:
commit
f7c1b711ad
121
api/src/com/cloud/agent/api/PvlanSetupCommand.java
Normal file
121
api/src/com/cloud/agent/api/PvlanSetupCommand.java
Normal file
@ -0,0 +1,121 @@
|
||||
// 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.net.URI;
|
||||
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
|
||||
public class PvlanSetupCommand extends Command {
|
||||
public enum Type {
|
||||
DHCP,
|
||||
VM
|
||||
}
|
||||
private String op;
|
||||
private String primary;
|
||||
private String isolated;
|
||||
private String vmMac;
|
||||
private String dhcpName;
|
||||
private String dhcpMac;
|
||||
private String dhcpIp;
|
||||
private Type type;
|
||||
private String networkTag;
|
||||
|
||||
protected PvlanSetupCommand() {}
|
||||
|
||||
protected PvlanSetupCommand(Type type, String op, URI uri, String networkTag)
|
||||
{
|
||||
this.type = type;
|
||||
this.op = op;
|
||||
this.primary = NetUtils.getPrimaryPvlanFromUri(uri);
|
||||
this.isolated = NetUtils.getIsolatedPvlanFromUri(uri);
|
||||
this.networkTag = networkTag;
|
||||
}
|
||||
|
||||
static public PvlanSetupCommand createDhcpSetup(String op, URI uri, String networkTag, String dhcpName, String dhcpMac, String dhcpIp)
|
||||
{
|
||||
PvlanSetupCommand cmd = new PvlanSetupCommand(Type.DHCP, op, uri, networkTag);
|
||||
cmd.setDhcpName(dhcpName);
|
||||
cmd.setDhcpMac(dhcpMac);
|
||||
cmd.setDhcpIp(dhcpIp);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static public PvlanSetupCommand createVmSetup(String op, URI uri, String networkTag, String vmMac)
|
||||
{
|
||||
PvlanSetupCommand cmd = new PvlanSetupCommand(Type.VM, op, uri, networkTag);
|
||||
cmd.setVmMac(vmMac);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getOp() {
|
||||
return op;
|
||||
}
|
||||
|
||||
public String getPrimary() {
|
||||
return primary;
|
||||
}
|
||||
|
||||
public String getIsolated() {
|
||||
return isolated;
|
||||
}
|
||||
|
||||
public String getVmMac() {
|
||||
return vmMac;
|
||||
}
|
||||
|
||||
protected void setVmMac(String vmMac) {
|
||||
this.vmMac = vmMac;
|
||||
}
|
||||
|
||||
public String getDhcpMac() {
|
||||
return dhcpMac;
|
||||
}
|
||||
|
||||
protected void setDhcpMac(String dhcpMac) {
|
||||
this.dhcpMac = dhcpMac;
|
||||
}
|
||||
|
||||
public String getDhcpIp() {
|
||||
return dhcpIp;
|
||||
}
|
||||
|
||||
protected void setDhcpIp(String dhcpIp) {
|
||||
this.dhcpIp = dhcpIp;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getDhcpName() {
|
||||
return dhcpName;
|
||||
}
|
||||
|
||||
public void setDhcpName(String dhcpName) {
|
||||
this.dhcpName = dhcpName;
|
||||
}
|
||||
|
||||
public String getNetworkTag() {
|
||||
return networkTag;
|
||||
}
|
||||
}
|
||||
45
api/src/com/cloud/deploy/DeploymentClusterPlanner.java
Normal file
45
api/src/com/cloud/deploy/DeploymentClusterPlanner.java
Normal file
@ -0,0 +1,45 @@
|
||||
// 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.deploy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.exception.InsufficientServerCapacityException;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
/**
|
||||
*/
|
||||
public interface DeploymentClusterPlanner extends DeploymentPlanner {
|
||||
/**
|
||||
* This is called to determine list of possible clusters where a virtual
|
||||
* machine can be deployed.
|
||||
*
|
||||
* @param vm
|
||||
* virtual machine.
|
||||
* @param plan
|
||||
* deployment plan that tells you where it's being deployed to.
|
||||
* @param avoid
|
||||
* avoid these data centers, pods, clusters, or hosts.
|
||||
* @return DeployDestination for that virtual machine.
|
||||
*/
|
||||
List<Long> orderClusters(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid)
|
||||
throws InsufficientServerCapacityException;
|
||||
|
||||
PlannerResourceUsage getResourceUsage();
|
||||
|
||||
}
|
||||
@ -35,6 +35,7 @@ import com.cloud.vm.VirtualMachineProfile;
|
||||
/**
|
||||
*/
|
||||
public interface DeploymentPlanner extends Adapter {
|
||||
|
||||
/**
|
||||
* plan is called to determine where a virtual machine should be running.
|
||||
*
|
||||
@ -46,6 +47,7 @@ public interface DeploymentPlanner extends Adapter {
|
||||
* avoid these data centers, pods, clusters, or hosts.
|
||||
* @return DeployDestination for that virtual machine.
|
||||
*/
|
||||
@Deprecated
|
||||
DeployDestination plan(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid) throws InsufficientServerCapacityException;
|
||||
|
||||
/**
|
||||
@ -88,6 +90,10 @@ public interface DeploymentPlanner extends Adapter {
|
||||
userconcentratedpod_firstfit;
|
||||
}
|
||||
|
||||
public enum PlannerResourceUsage {
|
||||
Shared, Dedicated;
|
||||
}
|
||||
|
||||
public static class ExcludeList {
|
||||
private Set<Long> _dcIds;
|
||||
private Set<Long> _podIds;
|
||||
@ -99,10 +105,22 @@ public interface DeploymentPlanner extends Adapter {
|
||||
}
|
||||
|
||||
public ExcludeList(Set<Long> _dcIds, Set<Long> _podIds, Set<Long> _clusterIds, Set<Long> _hostIds, Set<Long> _poolIds) {
|
||||
this._dcIds = _dcIds;
|
||||
this._podIds = _podIds;
|
||||
this._clusterIds = _clusterIds;
|
||||
this._poolIds = _poolIds;
|
||||
if (_dcIds != null) {
|
||||
this._dcIds = new HashSet<Long>(_dcIds);
|
||||
}
|
||||
if (_podIds != null) {
|
||||
this._podIds = new HashSet<Long>(_podIds);
|
||||
}
|
||||
if (_clusterIds != null) {
|
||||
this._clusterIds = new HashSet<Long>(_clusterIds);
|
||||
}
|
||||
|
||||
if (_hostIds != null) {
|
||||
this._hostIds = new HashSet<Long>(_hostIds);
|
||||
}
|
||||
if (_poolIds != null) {
|
||||
this._poolIds = new HashSet<Long>(_poolIds);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean add(InsufficientCapacityException e) {
|
||||
|
||||
@ -134,6 +134,7 @@ public class EventTypes {
|
||||
public static final String EVENT_REMOVE_FROM_GLOBAL_LOAD_BALANCER_RULE = "GLOBAL.LB.REMOVE";
|
||||
public static final String EVENT_GLOBAL_LOAD_BALANCER_CREATE = "GLOBAL.LB.CREATE";
|
||||
public static final String EVENT_GLOBAL_LOAD_BALANCER_DELETE = "GLOBAL.LB.DELETE";
|
||||
public static final String EVENT_GLOBAL_LOAD_BALANCER_UPDATE = "GLOBAL.LB.UPDATE";
|
||||
|
||||
// Account events
|
||||
public static final String EVENT_ACCOUNT_ENABLE = "ACCOUNT.ENABLE";
|
||||
@ -422,6 +423,7 @@ public class EventTypes {
|
||||
public static final String EVENT_INTERNAL_LB_VM_START = "INTERNALLBVM.START";
|
||||
public static final String EVENT_INTERNAL_LB_VM_STOP = "INTERNALLBVM.STOP";
|
||||
|
||||
public static final String EVENT_HOST_RESERVATION_RELEASE = "HOST.RESERVATION.RELEASE";
|
||||
// Dedicated guest vlan range
|
||||
public static final String EVENT_GUEST_VLAN_RANGE_DEDICATE = "GUESTVLANRANGE.DEDICATE";
|
||||
public static final String EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE = "GUESTVLANRANGE.RELEASE";
|
||||
@ -727,7 +729,6 @@ public class EventTypes {
|
||||
entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_UPDATE, AutoScaleVmGroup.class.getName());
|
||||
entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_ENABLE, AutoScaleVmGroup.class.getName());
|
||||
entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DISABLE, AutoScaleVmGroup.class.getName());
|
||||
|
||||
entityEventDetails.put(EVENT_GUEST_VLAN_RANGE_DEDICATE, GuestVlan.class.getName());
|
||||
entityEventDetails.put(EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE, GuestVlan.class.getName());
|
||||
}
|
||||
|
||||
@ -147,6 +147,7 @@ public enum Status {
|
||||
s_fsm.addTransition(Status.Down, Event.Remove, Status.Removed);
|
||||
s_fsm.addTransition(Status.Down, Event.ManagementServerDown, Status.Down);
|
||||
s_fsm.addTransition(Status.Down, Event.AgentDisconnected, Status.Down);
|
||||
s_fsm.addTransition(Status.Down, Event.PingTimeout, Status.Down);
|
||||
s_fsm.addTransition(Status.Alert, Event.AgentConnected, Status.Connecting);
|
||||
s_fsm.addTransition(Status.Alert, Event.Ping, Status.Up);
|
||||
s_fsm.addTransition(Status.Alert, Event.Remove, Status.Removed);
|
||||
|
||||
@ -63,6 +63,7 @@ public class Networks {
|
||||
Storage("storage", Integer.class),
|
||||
Lswitch("lswitch", String.class),
|
||||
Mido("mido", String.class),
|
||||
Pvlan("pvlan", String.class),
|
||||
UnDecided(null, null);
|
||||
|
||||
private String scheme;
|
||||
|
||||
@ -108,4 +108,6 @@ public interface ServiceOffering extends InfrastructureEntity, InternalIdentity,
|
||||
boolean getDefaultUse();
|
||||
|
||||
String getSystemVmType();
|
||||
|
||||
String getDeploymentPlanner();
|
||||
}
|
||||
|
||||
@ -101,12 +101,12 @@ public interface ResourceService {
|
||||
|
||||
S3 discoverS3(AddS3Cmd cmd) throws DiscoveryException;
|
||||
|
||||
|
||||
|
||||
List<HypervisorType> getSupportedHypervisorTypes(long zoneId, boolean forVirtualRouter, Long podId);
|
||||
|
||||
Pair<List<? extends Swift>, Integer> listSwifts(ListSwiftsCmd cmd);
|
||||
|
||||
List<? extends S3> listS3s(ListS3sCmd cmd);
|
||||
|
||||
boolean releaseHostReservation(Long hostId);
|
||||
|
||||
}
|
||||
|
||||
@ -389,4 +389,6 @@ public interface ManagementService {
|
||||
*/
|
||||
List<? extends Capacity> listTopConsumedResources(ListCapacityCmd cmd);
|
||||
|
||||
List<String> listDeploymentPlanners();
|
||||
|
||||
}
|
||||
|
||||
@ -230,6 +230,7 @@ public class ApiConstants {
|
||||
public static final String VLAN_RANGE = "vlanrange";
|
||||
public static final String REMOVE_VLAN="removevlan";
|
||||
public static final String VLAN_ID = "vlanid";
|
||||
public static final String ISOLATED_PVLAN = "isolatedpvlan";
|
||||
public static final String VM_AVAILABLE = "vmavailable";
|
||||
public static final String VM_LIMIT = "vmlimit";
|
||||
public static final String VM_TOTAL = "vmtotal";
|
||||
@ -495,6 +496,7 @@ public class ApiConstants {
|
||||
public static final String AFFINITY_GROUP_NAMES = "affinitygroupnames";
|
||||
public static final String ASA_INSIDE_PORT_PROFILE = "insideportprofile";
|
||||
public static final String AFFINITY_GROUP_ID = "affinitygroupid";
|
||||
public static final String DEPLOYMENT_PLANNER = "deploymentplanner";
|
||||
public static final String ACL_ID = "aclid";
|
||||
public static final String NUMBER = "number";
|
||||
|
||||
|
||||
@ -0,0 +1,71 @@
|
||||
// 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.api.command.admin.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.BaseListCmd;
|
||||
import org.apache.cloudstack.api.response.DeploymentPlannersResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
@APICommand(name = "listDeploymentPlanners", description = "Lists all DeploymentPlanners available.", responseObject = DeploymentPlannersResponse.class)
|
||||
public class ListDeploymentPlannersCmd extends BaseListCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(ListDeploymentPlannersCmd.class.getName());
|
||||
|
||||
private static final String s_name = "listdeploymentplannersresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(){
|
||||
List<String> planners = _mgr.listDeploymentPlanners();
|
||||
ListResponse<DeploymentPlannersResponse> response = new ListResponse<DeploymentPlannersResponse>();
|
||||
List<DeploymentPlannersResponse> plannerResponses = new ArrayList<DeploymentPlannersResponse>();
|
||||
|
||||
for (String planner : planners) {
|
||||
DeploymentPlannersResponse plannerResponse = new DeploymentPlannersResponse();
|
||||
plannerResponse.setName(planner);
|
||||
plannerResponse.setObjectName("deploymentPlanner");
|
||||
plannerResponses.add(plannerResponse);
|
||||
}
|
||||
|
||||
response.setResponses(plannerResponses);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
// 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.api.command.admin.host;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.HostResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.async.AsyncJob;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
|
||||
@APICommand(name = "releaseHostReservation", description = "Releases host reservation.", responseObject = SuccessResponse.class)
|
||||
public class ReleaseHostReservationCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(ReleaseHostReservationCmd.class.getName());
|
||||
|
||||
private static final String s_name = "releasehostreservationresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=HostResponse.class,
|
||||
required=true, description="the host ID")
|
||||
private Long id;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Account account = UserContext.current().getCaller();
|
||||
if (account != null) {
|
||||
return account.getId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_HOST_RESERVATION_RELEASE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "releasing reservation for host: " + getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncJob.Type getInstanceType() {
|
||||
return AsyncJob.Type.Host;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getInstanceId() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(){
|
||||
boolean result = _resourceService.releaseHostReservation(getId());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release host reservation");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -44,7 +44,7 @@ public class ListNetworkIsolationMethodsCmd extends BaseListCmd{
|
||||
isolationResponses.add(isolationMethod);
|
||||
}
|
||||
}
|
||||
response.setResponses(isolationResponses, methods.length);
|
||||
response.setResponses(isolationResponses, isolationResponses.size());
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
|
||||
|
||||
@ -84,6 +84,9 @@ public class CreateServiceOfferingCmd extends BaseCmd {
|
||||
@Parameter(name=ApiConstants.NETWORKRATE, type=CommandType.INTEGER, description="data transfer rate in megabits per second allowed. Supported only for non-System offering and system offerings having \"domainrouter\" systemvmtype")
|
||||
private Integer networkRate;
|
||||
|
||||
@Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "The deployment planner heuristics used to deploy a VM of this offering. If null, value of global config vm.deployment.planner is used")
|
||||
private String deploymentPlanner;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -148,6 +151,9 @@ public class CreateServiceOfferingCmd extends BaseCmd {
|
||||
return networkRate;
|
||||
}
|
||||
|
||||
public String getDeploymentPlanner() {
|
||||
return deploymentPlanner;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
|
||||
@ -80,6 +80,9 @@ public class CreateNetworkCmd extends BaseCmd {
|
||||
@Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network")
|
||||
private String vlan;
|
||||
|
||||
@Parameter(name=ApiConstants.ISOLATED_PVLAN, type=CommandType.STRING, description="the isolated private vlan for this network")
|
||||
private String isolatedPvlan;
|
||||
|
||||
@Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="network domain")
|
||||
private String networkDomain;
|
||||
|
||||
@ -141,6 +144,10 @@ public class CreateNetworkCmd extends BaseCmd {
|
||||
return vlan;
|
||||
}
|
||||
|
||||
public String getIsolatedPvlan() {
|
||||
return isolatedPvlan;
|
||||
}
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ public class AssignToGlobalLoadBalancerRuleCmd extends BaseAsyncCmd {
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "applying load balancer rules " + StringUtils.join(getLoadBalancerRulesIds(), ",") +
|
||||
return "assign load balancer rules " + StringUtils.join(getLoadBalancerRulesIds(), ",") +
|
||||
" to global load balancer rule " + getGlobalLoadBalancerRuleId();
|
||||
}
|
||||
|
||||
|
||||
@ -85,7 +85,11 @@ public class CreateGlobalLoadBalancerRuleCmd extends BaseAsyncCreateCmd {
|
||||
}
|
||||
|
||||
public String getAlgorithm() {
|
||||
if (algorithm != null) {
|
||||
return algorithm;
|
||||
} else {
|
||||
return GlobalLoadBalancerRule.Algorithm.RoundRobin.name();
|
||||
}
|
||||
}
|
||||
|
||||
public String getGslbMethod() {
|
||||
@ -158,7 +162,7 @@ public class CreateGlobalLoadBalancerRuleCmd extends BaseAsyncCreateCmd {
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "creating a global load balancer: " + getName() + " for account: " + getAccountName();
|
||||
return "creating a global load balancer rule Id: " + getEntityId();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -77,12 +77,12 @@ public class DeleteGlobalLoadBalancerRuleCmd extends BaseAsyncCmd {
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_LOAD_BALANCER_DELETE;
|
||||
return EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "deleting global load balancer: " + getGlobalLoadBalancerId();
|
||||
return "deleting global load balancer rule: " + getGlobalLoadBalancerId();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -17,11 +17,11 @@
|
||||
|
||||
package org.apache.cloudstack.api.command.user.region.ha.gslb;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.region.ha.GlobalLoadBalancerRule;
|
||||
import com.cloud.region.ha.GlobalLoadBalancingRulesService;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import com.cloud.user.Account;
|
||||
import org.apache.cloudstack.api.*;
|
||||
import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
|
||||
import org.apache.cloudstack.api.response.LoadBalancerResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
@ -29,7 +29,7 @@ import org.apache.log4j.Logger;
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "updateGlobalLoadBalancerRule", description = "update global load balancer rules.", responseObject = LoadBalancerResponse.class)
|
||||
public class UpdateGlobalLoadBalancerRuleCmd extends BaseListTaggedResourcesCmd {
|
||||
public class UpdateGlobalLoadBalancerRuleCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(GlobalLoadBalancerResponse.class.getName());
|
||||
|
||||
private static final String s_name = "updategloballoadbalancerruleresponse";
|
||||
@ -88,9 +88,27 @@ public class UpdateGlobalLoadBalancerRuleCmd extends BaseListTaggedResourcesCmd
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
GlobalLoadBalancerRule lb = _entityMgr.findById(GlobalLoadBalancerRule.class, getId());
|
||||
if (lb != null) {
|
||||
return lb.getAccountId();
|
||||
}
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
_gslbService.updateGlobalLoadBalancerRule(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_GLOBAL_LOAD_BALANCER_UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,8 @@ package org.apache.cloudstack.api.response;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Column;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
@ -82,6 +84,8 @@ public class ServiceOfferingResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.NETWORKRATE) @Param(description="data transfer rate in megabits per second allowed.")
|
||||
private Integer networkRate;
|
||||
|
||||
@SerializedName(ApiConstants.DEPLOYMENT_PLANNER) @Param(description="deployment strategy used to deploy VM.")
|
||||
private String deploymentPlanner;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
@ -225,4 +229,12 @@ public class ServiceOfferingResponse extends BaseResponse {
|
||||
public void setNetworkRate(Integer networkRate) {
|
||||
this.networkRate = networkRate;
|
||||
}
|
||||
|
||||
public String getDeploymentPlanner() {
|
||||
return deploymentPlanner;
|
||||
}
|
||||
|
||||
public void setDeploymentPlanner(String deploymentPlanner) {
|
||||
this.deploymentPlanner = deploymentPlanner;
|
||||
}
|
||||
}
|
||||
|
||||
@ -545,15 +545,11 @@
|
||||
Deployment planners
|
||||
-->
|
||||
<bean id="UserDispersingPlanner" class="com.cloud.deploy.UserDispersingPlanner">
|
||||
<property name="name" value="UserDispersing"/>
|
||||
<property name="StoragePoolAllocators" value="#{storagePoolAllocators.Adapters}" />
|
||||
<property name="HostAllocators" value="#{hostAllocators.Adapters}" />
|
||||
<property name="name" value="UserDispersingPlanner"/>
|
||||
</bean>
|
||||
|
||||
<bean id="UserConcentratedPodPlanner" class="com.cloud.deploy.UserConcentratedPodPlanner">
|
||||
<property name="name" value="UserConcentratedPod"/>
|
||||
<property name="StoragePoolAllocators" value="#{storagePoolAllocators.Adapters}" />
|
||||
<property name="HostAllocators" value="#{hostAllocators.Adapters}" />
|
||||
<property name="name" value="UserConcentratedPodPlanner"/>
|
||||
</bean>
|
||||
|
||||
<bean id="clusterBasedAgentLoadBalancerPlanner" class="com.cloud.cluster.agentlb.ClusterBasedAgentLoadBalancerPlanner">
|
||||
@ -610,10 +606,6 @@
|
||||
<property name="name" value="OvmGuru"/>
|
||||
</bean>
|
||||
|
||||
<bean id="HypervisorPlannerSelector" class="com.cloud.deploy.HypervisorVmPlannerSelector">
|
||||
<property name="name" value="HypervisorPlannerSelector"/>
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
Managers
|
||||
-->
|
||||
@ -628,6 +620,7 @@
|
||||
<property name="UserPasswordEncoders" value="#{userPasswordEncoders.Adapters}" />
|
||||
<property name="HostAllocators" value="#{hostAllocators.Adapters}" />
|
||||
<property name="AffinityGroupProcessors" value="#{affinityProcessors.Adapters}" />
|
||||
<property name="Planners" value="#{deploymentPlanners.Adapters}" />
|
||||
</bean>
|
||||
|
||||
<bean id="storageManagerImpl" class="com.cloud.storage.StorageManagerImpl">
|
||||
@ -635,9 +628,7 @@
|
||||
</bean>
|
||||
|
||||
<bean id="FirstFitPlanner" class="com.cloud.deploy.FirstFitPlanner">
|
||||
<property name="name" value="First Fit"/>
|
||||
<property name="StoragePoolAllocators" value="#{storagePoolAllocators.Adapters}" />
|
||||
<property name="HostAllocators" value="#{hostAllocators.Adapters}" />
|
||||
<property name="name" value="FirstFitPlanner"/>
|
||||
</bean>
|
||||
|
||||
<bean id="resourceManagerImpl" class="com.cloud.resource.ResourceManagerImpl" >
|
||||
@ -842,17 +833,13 @@
|
||||
</bean>
|
||||
|
||||
<bean id="BareMetalPlanner" class="com.cloud.baremetal.manager.BareMetalPlanner">
|
||||
<property name="name" value="BareMetal Fit"/>
|
||||
<property name="name" value="BareMetalPlanner"/>
|
||||
</bean>
|
||||
|
||||
<bean id="BaremetalGuru" class="com.cloud.baremetal.manager.BareMetalGuru">
|
||||
<property name="name" value="BaremetalGuru"/>
|
||||
</bean>
|
||||
|
||||
<bean id="BaremetalPlannerSelector" class="com.cloud.baremetal.manager.BaremetalPlannerSelector">
|
||||
<property name="name" value="BaremetalPlannerSelector"/>
|
||||
</bean>
|
||||
|
||||
<bean id="BaremetalManager" class="com.cloud.baremetal.manager.BaremetalManagerImpl"/>
|
||||
<bean id="BaremetalDhcpManager" class="com.cloud.baremetal.networkservice.BaremetalDhcpManagerImpl"/>
|
||||
<bean id="BaremetalKickStartPxeService" class="com.cloud.baremetal.networkservice.BaremetalKickStartServiceImpl"/>
|
||||
@ -868,6 +855,8 @@
|
||||
<bean id="DeploymentPlanningManager" class="com.cloud.deploy.DeploymentPlanningManagerImpl">
|
||||
<property name="Planners" value="#{deploymentPlanners.Adapters}" />
|
||||
<property name="AffinityGroupProcessors" value="#{affinityProcessors.Adapters}" />
|
||||
<property name="StoragePoolAllocators" value="#{storagePoolAllocators.Adapters}" />
|
||||
<property name="HostAllocators" value="#{hostAllocators.Adapters}" />
|
||||
</bean>
|
||||
|
||||
<bean id="AffinityGroupJoinDaoImpl" class="com.cloud.api.query.dao.AffinityGroupJoinDaoImpl">
|
||||
@ -877,4 +866,7 @@
|
||||
<bean id="AffinityGroupVMMapDaoImpl" class="org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDaoImpl">
|
||||
</bean>
|
||||
|
||||
<bean id="PlannerHostReservationDaoImpl" class="com.cloud.deploy.dao.PlannerHostReservationDaoImpl">
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@ -212,6 +212,7 @@ listConfigurations=1
|
||||
ldapConfig=1
|
||||
ldapRemove=1
|
||||
listCapabilities=15
|
||||
listDeploymentPlanners=1
|
||||
|
||||
#### pod commands
|
||||
createPod=1
|
||||
@ -267,6 +268,7 @@ listHosts=3
|
||||
findHostsForMigration=1
|
||||
addSecondaryStorage=1
|
||||
updateHostPassword=1
|
||||
releaseHostReservation=1
|
||||
|
||||
#### volume commands
|
||||
attachVolume=15
|
||||
|
||||
@ -17,11 +17,13 @@
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import com.cloud.agent.api.to.NicTO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
public class PlugNicCommand extends Command {
|
||||
|
||||
NicTO nic;
|
||||
String instanceName;
|
||||
VirtualMachine.Type vmType;
|
||||
|
||||
public NicTO getNic() {
|
||||
return nic;
|
||||
@ -35,12 +37,17 @@ public class PlugNicCommand extends Command {
|
||||
protected PlugNicCommand() {
|
||||
}
|
||||
|
||||
public PlugNicCommand(NicTO nic, String instanceName) {
|
||||
public PlugNicCommand(NicTO nic, String instanceName, VirtualMachine.Type vmtype) {
|
||||
this.nic = nic;
|
||||
this.instanceName = instanceName;
|
||||
this.vmType = vmtype;
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
return instanceName;
|
||||
}
|
||||
|
||||
public VirtualMachine.Type getVMType() {
|
||||
return vmType;
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,9 +41,9 @@ under the License.
|
||||
<para>You probably want to ensure that your environment variables will survive a logout/reboot.
|
||||
Be sure to update <filename>~/.bashrc</filename> with the PATH and JAVA_HOME variables.</para>
|
||||
|
||||
<para>Building RPMs for $PRODUCT; is fairly simple. Assuming you already have the source downloaded and have uncompressed the tarball into a local directory, you're going to be able to generate packages in just a few minutes.</para>
|
||||
<para>Building RPMs for &PRODUCT; is fairly simple. Assuming you already have the source downloaded and have uncompressed the tarball into a local directory, you're going to be able to generate packages in just a few minutes.</para>
|
||||
<note><title>Packaging has Changed</title>
|
||||
<para>If you've created packages for $PRODUCT; previously, you should be aware that the process has changed considerably since the project has moved to using Apache Maven. Please be sure to follow the steps in this section closely.</para>
|
||||
<para>If you've created packages for &PRODUCT; previously, you should be aware that the process has changed considerably since the project has moved to using Apache Maven. Please be sure to follow the steps in this section closely.</para>
|
||||
</note>
|
||||
<section id="generating-rpms">
|
||||
<title>Generating RPMS</title>
|
||||
@ -69,7 +69,7 @@ under the License.
|
||||
<title>Configuring your systems to use your new yum repository</title>
|
||||
<para>
|
||||
Now that your yum repository is populated with RPMs and metadata
|
||||
we need to configure the machines that need to install $PRODUCT;.
|
||||
we need to configure the machines that need to install &PRODUCT;.
|
||||
Create a file named <filename>/etc/yum.repos.d/cloudstack.repo</filename> with this information:
|
||||
<programlisting>
|
||||
[apache-cloudstack]
|
||||
@ -79,7 +79,7 @@ under the License.
|
||||
gpgcheck=0
|
||||
</programlisting>
|
||||
</para>
|
||||
<para> Completing this step will allow you to easily install $PRODUCT; on a number of machines across the network.
|
||||
<para> Completing this step will allow you to easily install &PRODUCT; on a number of machines across the network.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@ -49,7 +49,7 @@
|
||||
multi-node Management Server installation and up to tens of thousands of
|
||||
hosts using any of several advanced networking setups. For
|
||||
information about deployment options, see the "Choosing a Deployment Architecture"
|
||||
section of the $PRODUCT; Installation Guide.
|
||||
section of the &PRODUCT; Installation Guide.
|
||||
</para>
|
||||
<xi:include href="management-server-overview.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="cloud-infrastructure-overview.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.engine.datacenter.entity.api.db.dao;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -30,6 +32,7 @@ import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Component(value="EngineHostDetailsDao")
|
||||
@Local(value=HostDetailsDao.class)
|
||||
@ -91,19 +94,27 @@ public class HostDetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implement
|
||||
|
||||
@Override
|
||||
public void persist(long hostId, Map<String, String> details) {
|
||||
final String InsertOrUpdateSql = "INSERT INTO `cloud`.`host_details` (host_id, name, value) VALUES (?,?,?) ON DUPLICATE KEY UPDATE value=?";
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
SearchCriteria<DetailVO> sc = HostSearch.create();
|
||||
sc.setParameters("hostId", hostId);
|
||||
expunge(sc);
|
||||
|
||||
for (Map.Entry<String, String> detail : details.entrySet()) {
|
||||
String value = detail.getValue();
|
||||
if ("password".equals(detail.getKey())) {
|
||||
value = DBEncryptionUtil.encrypt(value);
|
||||
}
|
||||
DetailVO vo = new DetailVO(hostId, detail.getKey(), value);
|
||||
persist(vo);
|
||||
try {
|
||||
PreparedStatement pstmt = txn.prepareAutoCloseStatement(InsertOrUpdateSql);
|
||||
pstmt.setLong(1, hostId);
|
||||
pstmt.setString(2, detail.getKey());
|
||||
pstmt.setString(3, value);
|
||||
pstmt.setString(4, value);
|
||||
pstmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Unable to persist the host_details key: " + detail.getKey()
|
||||
+ " for host id: " + hostId, e);
|
||||
}
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
// under the License.
|
||||
package com.cloud.host.dao;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -30,6 +32,7 @@ import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Component
|
||||
@Local(value=HostDetailsDao.class)
|
||||
@ -91,19 +94,27 @@ public class HostDetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implement
|
||||
|
||||
@Override
|
||||
public void persist(long hostId, Map<String, String> details) {
|
||||
final String InsertOrUpdateSql = "INSERT INTO `cloud`.`host_details` (host_id, name, value) VALUES (?,?,?) ON DUPLICATE KEY UPDATE value=?";
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
SearchCriteria<DetailVO> sc = HostSearch.create();
|
||||
sc.setParameters("hostId", hostId);
|
||||
expunge(sc);
|
||||
|
||||
for (Map.Entry<String, String> detail : details.entrySet()) {
|
||||
String value = detail.getValue();
|
||||
if ("password".equals(detail.getKey())) {
|
||||
value = DBEncryptionUtil.encrypt(value);
|
||||
}
|
||||
DetailVO vo = new DetailVO(hostId, detail.getKey(), value);
|
||||
persist(vo);
|
||||
try {
|
||||
PreparedStatement pstmt = txn.prepareAutoCloseStatement(InsertOrUpdateSql);
|
||||
pstmt.setLong(1, hostId);
|
||||
pstmt.setString(2, detail.getKey());
|
||||
pstmt.setString(3, value);
|
||||
pstmt.setString(4, value);
|
||||
pstmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Unable to persist the host_details key: " + detail.getKey()
|
||||
+ " for host id: " + hostId, e);
|
||||
}
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
@ -174,5 +174,10 @@ public class ServiceOffering21VO extends DiskOffering21VO implements ServiceOffe
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeploymentPlanner() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -113,4 +113,6 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long> , StateDao<State
|
||||
List<NetworkVO> listRedundantNetworks();
|
||||
|
||||
List<NetworkVO> listByAclId(long aclId);
|
||||
|
||||
int getNonSystemNetworkCountByVpcId(long vpcId);
|
||||
}
|
||||
|
||||
@ -162,6 +162,9 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
|
||||
CountBy.and("offeringId", CountBy.entity().getNetworkOfferingId(), Op.EQ);
|
||||
CountBy.and("vpcId", CountBy.entity().getVpcId(), Op.EQ);
|
||||
CountBy.and("removed", CountBy.entity().getRemoved(), Op.NULL);
|
||||
SearchBuilder<NetworkOfferingVO> ntwkOffJoin = _ntwkOffDao.createSearchBuilder();
|
||||
ntwkOffJoin.and("isSystem", ntwkOffJoin.entity().isSystemOnly(), Op.EQ);
|
||||
CountBy.join("offerings", ntwkOffJoin, CountBy.entity().getNetworkOfferingId(), ntwkOffJoin.entity().getId(), JoinBuilder.JoinType.INNER);
|
||||
CountBy.done();
|
||||
|
||||
PhysicalNetworkSearch = createSearchBuilder();
|
||||
@ -627,4 +630,14 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
|
||||
|
||||
return listBy(sc, null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getNonSystemNetworkCountByVpcId(long vpcId) {
|
||||
SearchCriteria<Integer> sc = CountBy.create();
|
||||
sc.setParameters("vpcId", vpcId);
|
||||
sc.setJoinParameters("offerings", "isSystem", false);
|
||||
List<Integer> results = customSearch(sc, null);
|
||||
return results.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,6 +68,9 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
||||
@Column(name="sort_key")
|
||||
int sortKey;
|
||||
|
||||
@Column(name = "deployment_planner")
|
||||
private String deploymentPlanner = null;
|
||||
|
||||
protected ServiceOfferingVO() {
|
||||
super();
|
||||
}
|
||||
@ -104,6 +107,15 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
||||
this.hostTag = hostTag;
|
||||
}
|
||||
|
||||
public ServiceOfferingVO(String name, int cpu, int ramSize, int speed, Integer rateMbps, Integer multicastRateMbps,
|
||||
boolean offerHA, boolean limitResourceUse, boolean volatileVm, String displayText, boolean useLocalStorage,
|
||||
boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vm_type, Long domainId,
|
||||
String hostTag, String deploymentPlanner) {
|
||||
this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm,
|
||||
displayText, useLocalStorage, recreatable, tags, systemUse, vm_type, domainId, hostTag);
|
||||
this.deploymentPlanner = deploymentPlanner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getOfferHA() {
|
||||
return offerHA;
|
||||
@ -208,4 +220,9 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
||||
return volatileVm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeploymentPlanner() {
|
||||
return deploymentPlanner;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -17,6 +17,10 @@
|
||||
|
||||
package com.cloud.upgrade.dao;
|
||||
|
||||
import com.cloud.deploy.DeploymentPlanner;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
import org.apache.log4j.Logger;
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Date;
|
||||
@ -25,12 +29,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.cloud.network.vpc.NetworkACL;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
|
||||
public class Upgrade410to420 implements DbUpgrade {
|
||||
final static Logger s_logger = Logger.getLogger(Upgrade410to420.class);
|
||||
@ -70,9 +69,12 @@ public class Upgrade410to420 implements DbUpgrade {
|
||||
updatePrimaryStore(conn);
|
||||
addEgressFwRulesForSRXGuestNw(conn);
|
||||
upgradeEIPNetworkOfferings(conn);
|
||||
updateGlobalDeploymentPlanner(conn);
|
||||
upgradeDefaultVpcOffering(conn);
|
||||
upgradePhysicalNtwksWithInternalLbProvider(conn);
|
||||
updateNetworkACLs(conn);
|
||||
addHostDetailsIndex(conn);
|
||||
updateNetworksForPrivateGateways(conn);
|
||||
}
|
||||
|
||||
private void updateSystemVmTemplates(Connection conn) {
|
||||
@ -563,9 +565,55 @@ public class Upgrade410to420 implements DbUpgrade {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateGlobalDeploymentPlanner(Connection conn) {
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
|
||||
try {
|
||||
pstmt = conn
|
||||
.prepareStatement("select value from `cloud`.`configuration` where name = 'vm.allocation.algorithm'");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
String globalValue = rs.getString(1);
|
||||
String plannerName = "FirstFitPlanner";
|
||||
|
||||
if (globalValue != null) {
|
||||
if (globalValue.equals(DeploymentPlanner.AllocationAlgorithm.random.toString())) {
|
||||
plannerName = "FirstFitPlanner";
|
||||
} else if (globalValue.equals(DeploymentPlanner.AllocationAlgorithm.firstfit.toString())) {
|
||||
plannerName = "FirstFitPlanner";
|
||||
} else if (globalValue.equals(DeploymentPlanner.AllocationAlgorithm.userconcentratedpod_firstfit
|
||||
.toString())) {
|
||||
plannerName = "UserConcentratedPodPlanner";
|
||||
} else if (globalValue.equals(DeploymentPlanner.AllocationAlgorithm.userconcentratedpod_random
|
||||
.toString())) {
|
||||
plannerName = "UserConcentratedPodPlanner";
|
||||
} else if (globalValue.equals(DeploymentPlanner.AllocationAlgorithm.userdispersing.toString())) {
|
||||
plannerName = "UserDispersingPlanner";
|
||||
}
|
||||
}
|
||||
// update vm.deployment.planner global config
|
||||
pstmt = conn.prepareStatement("UPDATE `cloud`.`configuration` set value=? where name = 'vm.deployment.planner'");
|
||||
pstmt.setString(1, plannerName);
|
||||
pstmt.executeUpdate();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Unable to set vm.deployment.planner global config", e);
|
||||
} finally {
|
||||
try {
|
||||
if (rs != null) {
|
||||
rs.close();
|
||||
}
|
||||
if (pstmt != null) {
|
||||
pstmt.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void upgradeDefaultVpcOffering(Connection conn) {
|
||||
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
|
||||
@ -597,8 +645,6 @@ public class Upgrade410to420 implements DbUpgrade {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void upgradePhysicalNtwksWithInternalLbProvider(Connection conn) {
|
||||
|
||||
PreparedStatement pstmt = null;
|
||||
@ -645,6 +691,62 @@ public class Upgrade410to420 implements DbUpgrade {
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addHostDetailsIndex(Connection conn) {
|
||||
s_logger.debug("Checking if host_details index exists, if not we will add it");
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
pstmt = conn.prepareStatement("SHOW INDEX FROM `cloud`.`host_details` where KEY_NAME = 'fk_host_details__host_id'");
|
||||
rs = pstmt.executeQuery();
|
||||
if (rs.next()) {
|
||||
s_logger.debug("Index already exists on host_details - not adding new one");
|
||||
} else {
|
||||
// add the index
|
||||
PreparedStatement pstmtUpdate = conn.prepareStatement("ALTER IGNORE TABLE `cloud`.`host_details` ADD INDEX `fk_host_details__host_id` (`host_id`)");
|
||||
pstmtUpdate.executeUpdate();
|
||||
s_logger.debug("Index did not exist on host_details - added new one");
|
||||
pstmtUpdate.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Failed to check/update the host_details index ", e);
|
||||
} finally {
|
||||
try {
|
||||
if (rs != null) {
|
||||
rs.close();
|
||||
}
|
||||
|
||||
if (pstmt != null) {
|
||||
pstmt.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateNetworksForPrivateGateways(Connection conn) {
|
||||
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
|
||||
try {
|
||||
//1) get all non removed gateways
|
||||
pstmt = conn.prepareStatement("SELECT network_id, vpc_id FROM `cloud`.`vpc_gateways` WHERE type='Private' AND removed IS null");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
Long networkId = rs.getLong(1);
|
||||
Long vpcId = rs.getLong(2);
|
||||
//2) Update networks with vpc_id if its set to NULL
|
||||
pstmt = conn.prepareStatement("UPDATE `cloud`.`networks` set vpc_id=? where id=? and vpc_id is NULL and removed is NULL");
|
||||
pstmt.setLong(1, vpcId);
|
||||
pstmt.setLong(2, networkId);
|
||||
pstmt.executeUpdate();
|
||||
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Failed to update private networks with VPC id.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,18 +118,18 @@ public class UsageNetworkOfferingDaoImpl extends GenericDaoBase<UsageNetworkOffe
|
||||
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
//zoneId, account_id, domain_id, vm_instance_id, network_offering_id, is_default, created, deleted
|
||||
//zoneId, account_id, domain_id, vm_instance_id, network_offering_id, nic_id, is_default, created, deleted
|
||||
Long zoneId = Long.valueOf(rs.getLong(1));
|
||||
Long acctId = Long.valueOf(rs.getLong(2));
|
||||
Long dId = Long.valueOf(rs.getLong(3));
|
||||
long vmId = Long.valueOf(rs.getLong(4));
|
||||
long noId = Long.valueOf(rs.getLong(5));
|
||||
long nicId = Long.valueOf(rs.getLong(6));
|
||||
boolean isDefault = Boolean.valueOf(rs.getBoolean(6));
|
||||
boolean isDefault = Boolean.valueOf(rs.getBoolean(7));
|
||||
Date createdDate = null;
|
||||
Date deletedDate = null;
|
||||
String createdTS = rs.getString(7);
|
||||
String deletedTS = rs.getString(8);
|
||||
String createdTS = rs.getString(8);
|
||||
String deletedTS = rs.getString(9);
|
||||
|
||||
|
||||
if (createdTS != null) {
|
||||
|
||||
@ -116,4 +116,8 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
|
||||
*/
|
||||
List<String> listDistinctHostNames(long networkId, VirtualMachine.Type... types);
|
||||
|
||||
List<VMInstanceVO> findByHostInStates(Long hostId, State... states);
|
||||
|
||||
List<VMInstanceVO> listStartingWithNoHostId();
|
||||
|
||||
}
|
||||
|
||||
@ -83,6 +83,8 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
||||
protected GenericSearchBuilder<VMInstanceVO, Long> CountRunningByAccount;
|
||||
protected SearchBuilder<VMInstanceVO> NetworkTypeSearch;
|
||||
protected GenericSearchBuilder<VMInstanceVO, String> DistinctHostNameSearch;
|
||||
protected SearchBuilder<VMInstanceVO> HostAndStateSearch;
|
||||
protected SearchBuilder<VMInstanceVO> StartingWithNoHostSearch;
|
||||
|
||||
@Inject ResourceTagDao _tagsDao;
|
||||
@Inject NicDao _nicDao;
|
||||
@ -209,6 +211,16 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
||||
CountRunningByAccount.and("state", CountRunningByAccount.entity().getState(), SearchCriteria.Op.EQ);
|
||||
CountRunningByAccount.done();
|
||||
|
||||
HostAndStateSearch = createSearchBuilder();
|
||||
HostAndStateSearch.and("host", HostAndStateSearch.entity().getHostId(), Op.EQ);
|
||||
HostAndStateSearch.and("states", HostAndStateSearch.entity().getState(), Op.IN);
|
||||
HostAndStateSearch.done();
|
||||
|
||||
StartingWithNoHostSearch = createSearchBuilder();
|
||||
StartingWithNoHostSearch.and("state", StartingWithNoHostSearch.entity().getState(), Op.EQ);
|
||||
StartingWithNoHostSearch.and("host", StartingWithNoHostSearch.entity().getHostId(), Op.NULL);
|
||||
StartingWithNoHostSearch.done();
|
||||
|
||||
_updateTimeAttr = _allAttributes.get("updateTime");
|
||||
assert _updateTimeAttr != null : "Couldn't get this updateTime attribute";
|
||||
}
|
||||
@ -625,4 +637,19 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMInstanceVO> findByHostInStates(Long hostId, State... states) {
|
||||
SearchCriteria<VMInstanceVO> sc = HostAndStateSearch.create();
|
||||
sc.setParameters("host", hostId);
|
||||
sc.setParameters("states", (Object[]) states);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMInstanceVO> listStartingWithNoHostId() {
|
||||
SearchCriteria<VMInstanceVO> sc = StartingWithNoHostSearch.create();
|
||||
sc.setParameters("state", State.Starting);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -65,6 +65,14 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat
|
||||
}
|
||||
|
||||
List<StoragePoolVO> pools = _storagePoolDao.findPoolsByTags(dcId, podId, clusterId, dskCh.getTags());
|
||||
|
||||
// add remaining pools in cluster, that did not match tags, to avoid set
|
||||
List<StoragePoolVO> allPools = _storagePoolDao.findPoolsByTags(dcId, podId, clusterId, null);
|
||||
allPools.removeAll(pools);
|
||||
for (StoragePoolVO pool : allPools) {
|
||||
avoid.addPool(pool.getId());
|
||||
}
|
||||
|
||||
if (pools.size() == 0) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
String storageType = dskCh.useLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString();
|
||||
@ -80,6 +88,8 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat
|
||||
StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
|
||||
if (filter(avoid, pol, dskCh, plan)) {
|
||||
suitablePools.add(pol);
|
||||
} else {
|
||||
avoid.addPool(pool.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -85,6 +85,8 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
||||
if (filter(avoid, pol, dskCh, plan)) {
|
||||
s_logger.debug("Found suitable local storage pool " + pool.getId() + ", adding to list");
|
||||
suitablePools.add(pol);
|
||||
} else {
|
||||
avoid.addPool(pool.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,8 +103,19 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
||||
StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
|
||||
if (filter(avoid, pol, dskCh, plan)) {
|
||||
suitablePools.add(pol);
|
||||
} else {
|
||||
avoid.addPool(pool.getId());
|
||||
}
|
||||
}
|
||||
|
||||
// add remaining pools in cluster, that did not match tags, to avoid
|
||||
// set
|
||||
List<StoragePoolVO> allPools = _storagePoolDao.findLocalStoragePoolsByTags(plan.getDataCenterId(),
|
||||
plan.getPodId(), plan.getClusterId(), null);
|
||||
allPools.removeAll(availablePools);
|
||||
for (StoragePoolVO pool : allPools) {
|
||||
avoid.addPool(pool.getId());
|
||||
}
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
|
||||
@ -67,6 +67,13 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
||||
|
||||
List<StoragePoolVO> storagePools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), dskCh.getTags());
|
||||
|
||||
// add remaining pools in zone, that did not match tags, to avoid set
|
||||
List<StoragePoolVO> allPools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), null);
|
||||
allPools.removeAll(storagePools);
|
||||
for (StoragePoolVO pool : allPools) {
|
||||
avoid.addPool(pool.getId());
|
||||
}
|
||||
|
||||
for (StoragePoolVO storage : storagePools) {
|
||||
if (suitablePools.size() == returnUpTo) {
|
||||
break;
|
||||
@ -74,6 +81,8 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
||||
StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(storage.getId());
|
||||
if (filter(avoid, pol, dskCh, plan)) {
|
||||
suitablePools.add(pol);
|
||||
} else {
|
||||
avoid.addPool(pol.getId());
|
||||
}
|
||||
}
|
||||
return suitablePools;
|
||||
|
||||
@ -434,6 +434,12 @@ setup_common() {
|
||||
ping -n -c 3 $MGMT_GW &
|
||||
sleep 3
|
||||
pkill ping
|
||||
|
||||
fi
|
||||
|
||||
local hyp=$(hypervisor)
|
||||
if [ "$hyp" == "vmware" ]; then
|
||||
ntpq -p &> /dev/null || vmware-toolbox-cmd timesync enable
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@ -24,13 +24,12 @@ import javax.ejb.Local;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
@Local(value=DeploymentPlanner.class)
|
||||
public class UserConcentratedPodPlanner extends FirstFitPlanner implements DeploymentPlanner {
|
||||
public class UserConcentratedPodPlanner extends FirstFitPlanner implements DeploymentClusterPlanner {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(UserConcentratedPodPlanner.class);
|
||||
|
||||
@ -141,15 +140,4 @@ public class UserConcentratedPodPlanner extends FirstFitPlanner implements Deplo
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canHandle(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid) {
|
||||
if(vm.getHypervisorType() != HypervisorType.BareMetal){
|
||||
//check the allocation strategy
|
||||
if (_allocationAlgorithm != null && (_allocationAlgorithm.equals(AllocationAlgorithm.userconcentratedpod_random.toString()) || _allocationAlgorithm.equals(AllocationAlgorithm.userconcentratedpod_firstfit.toString()))){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -29,14 +29,13 @@ import javax.naming.ConfigurationException;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
@Local(value=DeploymentPlanner.class)
|
||||
public class UserDispersingPlanner extends FirstFitPlanner implements DeploymentPlanner {
|
||||
public class UserDispersingPlanner extends FirstFitPlanner implements DeploymentClusterPlanner {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(UserDispersingPlanner.class);
|
||||
|
||||
@ -191,17 +190,6 @@ public class UserDispersingPlanner extends FirstFitPlanner implements Deployment
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canHandle(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid) {
|
||||
if(vm.getHypervisorType() != HypervisorType.BareMetal){
|
||||
//check the allocation strategy
|
||||
if (_allocationAlgorithm != null && _allocationAlgorithm.equals(AllocationAlgorithm.userdispersing.toString())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float _userDispersionWeight;
|
||||
|
||||
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
// 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.baremetal.manager;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.deploy.AbstractDeployPlannerSelector;
|
||||
import com.cloud.deploy.DeployPlannerSelector;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
@Local(value = {DeployPlannerSelector.class})
|
||||
public class BaremetalPlannerSelector extends AbstractDeployPlannerSelector{
|
||||
|
||||
@Override
|
||||
public String selectPlanner(UserVmVO vm) {
|
||||
if (vm.getHypervisorType() == HypervisorType.BareMetal) {
|
||||
return "BareMetalPlanner";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -127,6 +127,7 @@ import com.cloud.agent.api.PlugNicAnswer;
|
||||
import com.cloud.agent.api.PlugNicCommand;
|
||||
import com.cloud.agent.api.PrepareForMigrationAnswer;
|
||||
import com.cloud.agent.api.PrepareForMigrationCommand;
|
||||
import com.cloud.agent.api.PvlanSetupCommand;
|
||||
import com.cloud.agent.api.ReadyAnswer;
|
||||
import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.RebootAnswer;
|
||||
@ -276,6 +277,8 @@ ServerResource {
|
||||
private String _createTmplPath;
|
||||
private String _heartBeatPath;
|
||||
private String _securityGroupPath;
|
||||
private String _ovsPvlanDhcpHostPath;
|
||||
private String _ovsPvlanVmPath;
|
||||
private String _routerProxyPath;
|
||||
private String _host;
|
||||
private String _dcId;
|
||||
@ -597,6 +600,18 @@ ServerResource {
|
||||
"Unable to find the router_proxy.sh");
|
||||
}
|
||||
|
||||
_ovsPvlanDhcpHostPath = Script.findScript(networkScriptsDir, "ovs-pvlan-dhcp-host.sh");
|
||||
if ( _ovsPvlanDhcpHostPath == null) {
|
||||
throw new ConfigurationException(
|
||||
"Unable to find the ovs-pvlan-dhcp-host.sh");
|
||||
}
|
||||
|
||||
_ovsPvlanVmPath = Script.findScript(networkScriptsDir, "ovs-pvlan-vm.sh");
|
||||
if ( _ovsPvlanVmPath == null) {
|
||||
throw new ConfigurationException(
|
||||
"Unable to find the ovs-pvlan-vm.sh");
|
||||
}
|
||||
|
||||
String value = (String) params.get("developer");
|
||||
boolean isDeveloper = Boolean.parseBoolean(value);
|
||||
|
||||
@ -1213,6 +1228,8 @@ ServerResource {
|
||||
return execute((NetworkRulesVmSecondaryIpCommand) cmd);
|
||||
} else if (cmd instanceof StorageSubSystemCommand) {
|
||||
return this.storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd);
|
||||
} else if (cmd instanceof PvlanSetupCommand) {
|
||||
return execute((PvlanSetupCommand) cmd);
|
||||
} else {
|
||||
s_logger.warn("Unsupported command ");
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
@ -1526,6 +1543,65 @@ ServerResource {
|
||||
}
|
||||
}
|
||||
|
||||
private Answer execute(PvlanSetupCommand cmd) {
|
||||
String primaryPvlan = cmd.getPrimary();
|
||||
String isolatedPvlan = cmd.getIsolated();
|
||||
String op = cmd.getOp();
|
||||
String dhcpName = cmd.getDhcpName();
|
||||
String dhcpMac = cmd.getDhcpMac();
|
||||
String dhcpIp = cmd.getDhcpIp();
|
||||
String vmMac = cmd.getVmMac();
|
||||
boolean add = true;
|
||||
|
||||
String opr = "-A";
|
||||
if (op.equals("delete")) {
|
||||
opr = "-D";
|
||||
add = false;
|
||||
}
|
||||
|
||||
String result = null;
|
||||
Connect conn;
|
||||
try {
|
||||
if (cmd.getType() == PvlanSetupCommand.Type.DHCP) {
|
||||
Script script = new Script(_ovsPvlanDhcpHostPath, _timeout, s_logger);
|
||||
if (add) {
|
||||
conn = LibvirtConnection.getConnectionByVmName(dhcpName);
|
||||
List<InterfaceDef> ifaces = getInterfaces(conn, dhcpName);
|
||||
InterfaceDef guestNic = ifaces.get(0);
|
||||
script.add(opr, "-b", _guestBridgeName,
|
||||
"-p", primaryPvlan, "-i", isolatedPvlan, "-n", dhcpName,
|
||||
"-d", dhcpIp, "-m", dhcpMac, "-I", guestNic.getDevName());
|
||||
} else {
|
||||
script.add(opr, "-b", _guestBridgeName,
|
||||
"-p", primaryPvlan, "-i", isolatedPvlan, "-n", dhcpName,
|
||||
"-d", dhcpIp, "-m", dhcpMac);
|
||||
}
|
||||
result = script.execute();
|
||||
if (result != null) {
|
||||
s_logger.warn("Failed to program pvlan for dhcp server with mac " + dhcpMac);
|
||||
return new Answer(cmd, false, result);
|
||||
} else {
|
||||
s_logger.info("Programmed pvlan for dhcp server with mac " + dhcpMac);
|
||||
}
|
||||
} else if (cmd.getType() == PvlanSetupCommand.Type.VM) {
|
||||
Script script = new Script(_ovsPvlanVmPath, _timeout, s_logger);
|
||||
script.add(opr, "-b", _guestBridgeName,
|
||||
"-p", primaryPvlan, "-i", isolatedPvlan, "-v", vmMac);
|
||||
result = script.execute();
|
||||
if (result != null) {
|
||||
s_logger.warn("Failed to program pvlan for vm with mac " + vmMac);
|
||||
return new Answer(cmd, false, result);
|
||||
} else {
|
||||
s_logger.info("Programmed pvlan for vm with mac " + vmMac);
|
||||
}
|
||||
}
|
||||
} catch (LibvirtException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new Answer(cmd, true, result);
|
||||
}
|
||||
|
||||
private void VifHotPlug(Connect conn, String vmName, String vlanId,
|
||||
String macAddr) throws InternalErrorException, LibvirtException {
|
||||
NicTO nicTO = new NicTO();
|
||||
@ -2760,7 +2836,7 @@ ServerResource {
|
||||
Pair<Double, Double> nicStats = getNicStats(_publicBridgeName);
|
||||
|
||||
HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), cpuUtil,
|
||||
nicStats.first() / 1000, nicStats.second() / 1000, "host",
|
||||
nicStats.first() / 1024, nicStats.second() / 1024, "host",
|
||||
totMem, freeMem, 0, 0);
|
||||
return new GetHostStatsAnswer(cmd, hostStats);
|
||||
}
|
||||
@ -4417,10 +4493,10 @@ ServerResource {
|
||||
if (oldStats != null) {
|
||||
long deltarx = rx - oldStats._rx;
|
||||
if (deltarx > 0)
|
||||
stats.setNetworkReadKBs(deltarx / 1000);
|
||||
stats.setNetworkReadKBs(deltarx / 1024);
|
||||
long deltatx = tx - oldStats._tx;
|
||||
if (deltatx > 0)
|
||||
stats.setNetworkWriteKBs(deltatx / 1000);
|
||||
stats.setNetworkWriteKBs(deltatx / 1024);
|
||||
}
|
||||
|
||||
vmStats newStat = new vmStats();
|
||||
|
||||
@ -76,10 +76,12 @@ public class OvsVifDriver extends VifDriverBase {
|
||||
}
|
||||
else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
|
||||
logicalSwitchUuid = nic.getBroadcastUri().getSchemeSpecificPart();
|
||||
} else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan) {
|
||||
vlanId = NetUtils.getPrimaryPvlanFromUri(nic.getBroadcastUri());
|
||||
}
|
||||
String trafficLabel = nic.getName();
|
||||
if (nic.getType() == Networks.TrafficType.Guest) {
|
||||
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan
|
||||
if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan)
|
||||
&& !vlanId.equalsIgnoreCase("untagged")) {
|
||||
if(trafficLabel != null && !trafficLabel.isEmpty()) {
|
||||
s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel);
|
||||
|
||||
@ -78,7 +78,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.UnregisterVMCommand;
|
||||
import com.cloud.agent.api.GetDomRVersionAnswer;
|
||||
import com.cloud.agent.api.GetDomRVersionCmd;
|
||||
import com.cloud.agent.api.GetHostStatsAnswer;
|
||||
@ -109,6 +108,7 @@ import com.cloud.agent.api.PlugNicCommand;
|
||||
import com.cloud.agent.api.PoolEjectCommand;
|
||||
import com.cloud.agent.api.PrepareForMigrationAnswer;
|
||||
import com.cloud.agent.api.PrepareForMigrationCommand;
|
||||
import com.cloud.agent.api.PvlanSetupCommand;
|
||||
import com.cloud.agent.api.ReadyAnswer;
|
||||
import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.RebootAnswer;
|
||||
@ -116,8 +116,8 @@ import com.cloud.agent.api.RebootCommand;
|
||||
import com.cloud.agent.api.RebootRouterCommand;
|
||||
import com.cloud.agent.api.RevertToVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.RevertToVMSnapshotCommand;
|
||||
import com.cloud.agent.api.ScaleVmCommand;
|
||||
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;
|
||||
@ -132,6 +132,7 @@ import com.cloud.agent.api.StopCommand;
|
||||
import com.cloud.agent.api.StoragePoolInfo;
|
||||
import com.cloud.agent.api.UnPlugNicAnswer;
|
||||
import com.cloud.agent.api.UnPlugNicCommand;
|
||||
import com.cloud.agent.api.UnregisterVMCommand;
|
||||
import com.cloud.agent.api.UpgradeSnapshotCommand;
|
||||
import com.cloud.agent.api.ValidateSnapshotAnswer;
|
||||
import com.cloud.agent.api.ValidateSnapshotCommand;
|
||||
@ -166,14 +167,14 @@ 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.CreateVolumeOVACommand;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVAAnswer;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingAnswer;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
|
||||
import com.cloud.agent.api.storage.CreateAnswer;
|
||||
import com.cloud.agent.api.storage.CreateCommand;
|
||||
import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVAAnswer;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVACommand;
|
||||
import com.cloud.agent.api.storage.DestroyCommand;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingAnswer;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
import com.cloud.agent.api.storage.ResizeVolumeAnswer;
|
||||
@ -289,30 +290,6 @@ import com.vmware.vim25.VirtualMachineGuestOsIdentifier;
|
||||
import com.vmware.vim25.VirtualMachinePowerState;
|
||||
import com.vmware.vim25.VirtualMachineRuntimeInfo;
|
||||
import com.vmware.vim25.VirtualSCSISharing;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.NDC;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService {
|
||||
@ -542,6 +519,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd);
|
||||
} else if (clz == ScaleVmCommand.class) {
|
||||
return execute((ScaleVmCommand) cmd);
|
||||
} else if (clz == PvlanSetupCommand.class) {
|
||||
return execute((PvlanSetupCommand) cmd);
|
||||
} else {
|
||||
answer = Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
@ -1084,7 +1063,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
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 cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask()));
|
||||
String domainName = cmd.getNetworkDomain();
|
||||
String dns = cmd.getDefaultDns1();
|
||||
if (dns == null || dns.isEmpty()) {
|
||||
@ -1423,7 +1402,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
|
||||
NicTO nicTo = cmd.getNic();
|
||||
VirtualDevice nic;
|
||||
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, false);
|
||||
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, false, cmd.getVMType());;
|
||||
if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
|
||||
String dvSwitchUuid;
|
||||
ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
|
||||
@ -1689,8 +1668,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
networkInfo = HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), "cloud.public",
|
||||
vmMo.getRunningHost(), vlanId, null, null, _ops_timeout, true);
|
||||
} else {
|
||||
networkInfo = HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), "cloud.public",
|
||||
vmMo.getRunningHost(), vlanId, null, null, _ops_timeout, vSwitchType, _portsPerDvPortGroup, null, false);
|
||||
networkInfo = HypervisorHostHelper.prepareNetwork(this._publicTrafficInfo.getVirtualSwitchName(), "cloud.public",
|
||||
vmMo.getRunningHost(), vlanId, null, null, null, this._ops_timeout, vSwitchType, _portsPerDvPortGroup, null, false);
|
||||
}
|
||||
|
||||
int nicIndex = allocPublicNicIndex(vmMo);
|
||||
@ -2606,7 +2585,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
s_logger.info("Prepare NIC device based on NicTO: " + _gson.toJson(nicTo));
|
||||
|
||||
boolean configureVServiceInNexus = (nicTo.getType() == TrafficType.Guest) && (vmSpec.getDetails().containsKey("ConfigureVServiceInNexus"));
|
||||
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, configureVServiceInNexus);
|
||||
VirtualMachine.Type vmType = cmd.getVirtualMachine().getType();
|
||||
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, configureVServiceInNexus, vmType);
|
||||
if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
|
||||
String dvSwitchUuid;
|
||||
ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
|
||||
@ -2790,16 +2770,28 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
return poolMors;
|
||||
}
|
||||
|
||||
|
||||
private String getPvlanInfo(NicTO nicTo) {
|
||||
if (nicTo.getBroadcastType() == BroadcastDomainType.Pvlan) {
|
||||
return NetUtils.getIsolatedPvlanFromUri(nicTo.getBroadcastUri());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getVlanInfo(NicTO nicTo, String defaultVlan) {
|
||||
if (nicTo.getBroadcastType() == BroadcastDomainType.Native) {
|
||||
return defaultVlan;
|
||||
}
|
||||
|
||||
if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan) {
|
||||
if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan || nicTo.getBroadcastType() == BroadcastDomainType.Pvlan) {
|
||||
if (nicTo.getBroadcastUri() != null) {
|
||||
if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan)
|
||||
// For vlan, the broadcast uri is of the form vlan://<vlanid>
|
||||
return nicTo.getBroadcastUri().getHost();
|
||||
else
|
||||
// for pvlan, the broacast uri will be of the form pvlan://<vlanid>-i<pvlanid>
|
||||
return NetUtils.getPrimaryPvlanFromUri(nicTo.getBroadcastUri());
|
||||
} else {
|
||||
s_logger.warn("BroadcastType is not claimed as VLAN, but without vlan info in broadcast URI. Use vlan info from labeling: " + defaultVlan);
|
||||
s_logger.warn("BroadcastType is not claimed as VLAN or PVLAN, but without vlan info in broadcast URI. Use vlan info from labeling: " + defaultVlan);
|
||||
return defaultVlan;
|
||||
}
|
||||
}
|
||||
@ -2808,7 +2800,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
return defaultVlan;
|
||||
}
|
||||
|
||||
private Pair<ManagedObjectReference, String> prepareNetworkFromNicInfo(HostMO hostMo, NicTO nicTo, boolean configureVServiceInNexus) throws Exception {
|
||||
private Pair<ManagedObjectReference, String> prepareNetworkFromNicInfo(HostMO hostMo, NicTO nicTo, boolean configureVServiceInNexus, VirtualMachine.Type vmType) throws Exception {
|
||||
Pair<String, String> switchName;
|
||||
TrafficType trafficType;
|
||||
VirtualSwitchType switchType;
|
||||
@ -2832,12 +2824,22 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
s_logger.info("Prepare network on " + switchType + " " + switchName + " with name prefix: " + namePrefix);
|
||||
|
||||
if (VirtualSwitchType.StandardVirtualSwitch == switchType) {
|
||||
networkInfo = HypervisorHostHelper.prepareNetwork(switchName.first(), namePrefix, hostMo, getVlanInfo(nicTo, switchName.second()),
|
||||
nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _ops_timeout,
|
||||
networkInfo = HypervisorHostHelper.prepareNetwork(switchName.first(), namePrefix,
|
||||
hostMo, getVlanInfo(nicTo, switchName.second()), nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _ops_timeout,
|
||||
!namePrefix.startsWith("cloud.private"));
|
||||
}
|
||||
else {
|
||||
networkInfo = HypervisorHostHelper.prepareNetwork(switchName.first(), namePrefix, hostMo, getVlanInfo(nicTo, switchName.second()),
|
||||
String vlanId = getVlanInfo(nicTo, switchName.second());
|
||||
String svlanId = null;
|
||||
boolean pvlannetwork = (getPvlanInfo(nicTo) == null)?false:true;
|
||||
if (vmType != null && vmType.equals(VirtualMachine.Type.DomainRouter) && pvlannetwork) {
|
||||
// plumb this network to the promiscuous vlan.
|
||||
svlanId = vlanId;
|
||||
} else {
|
||||
// plumb this network to the isolated vlan.
|
||||
svlanId = getPvlanInfo(nicTo);
|
||||
}
|
||||
networkInfo = HypervisorHostHelper.prepareNetwork(switchName.first(), namePrefix, hostMo, vlanId, svlanId,
|
||||
nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _ops_timeout, switchType, _portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus);
|
||||
}
|
||||
|
||||
@ -3324,7 +3326,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
NicTO[] nics = vm.getNics();
|
||||
for (NicTO nic : nics) {
|
||||
// prepare network on the host
|
||||
prepareNetworkFromNicInfo(new HostMO(getServiceContext(), _morHyperHost), nic, false);
|
||||
prepareNetworkFromNicInfo(new HostMO(getServiceContext(), _morHyperHost), nic, false, cmd.getVirtualMachine().getType());
|
||||
}
|
||||
|
||||
String secStoreUrl = mgr.getSecondaryStorageStoreUrl(Long.parseLong(_dcId));
|
||||
@ -3988,6 +3990,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
}
|
||||
}
|
||||
|
||||
protected Answer execute(PvlanSetupCommand cmd) {
|
||||
// Pvlan related operations are performed in the start/stop command paths
|
||||
// for vmware. This function is implemented to support mgmt layer code
|
||||
// that issue this command. Note that pvlan operations are supported only
|
||||
// in Distributed Virtual Switch environments for vmware deployments.
|
||||
return new Answer(cmd, true, "success");
|
||||
}
|
||||
|
||||
protected Answer execute(UnregisterVMCommand cmd){
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource UnregisterVMCommand: " + _gson.toJson(cmd));
|
||||
|
||||
@ -133,6 +133,7 @@ import com.cloud.agent.api.PlugNicCommand;
|
||||
import com.cloud.agent.api.PoolEjectCommand;
|
||||
import com.cloud.agent.api.PrepareForMigrationAnswer;
|
||||
import com.cloud.agent.api.PrepareForMigrationCommand;
|
||||
import com.cloud.agent.api.PvlanSetupCommand;
|
||||
import com.cloud.agent.api.ReadyAnswer;
|
||||
import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.RebootAnswer;
|
||||
@ -666,6 +667,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
return execute((NetworkRulesVmSecondaryIpCommand)cmd);
|
||||
} else if (clazz == ScaleVmCommand.class) {
|
||||
return execute((ScaleVmCommand) cmd);
|
||||
} else if (clazz == PvlanSetupCommand.class) {
|
||||
return execute((PvlanSetupCommand) cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
@ -1082,6 +1085,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
} else if (nic.getBroadcastType() == BroadcastDomainType.Lswitch) {
|
||||
// Nicira Logical Switch
|
||||
return network.getNetwork();
|
||||
} else if (nic.getBroadcastType() == BroadcastDomainType.Pvlan) {
|
||||
URI broadcastUri = nic.getBroadcastUri();
|
||||
assert broadcastUri.getScheme().equals(BroadcastDomainType.Pvlan.scheme());
|
||||
long vlan = Long.parseLong(NetUtils.getPrimaryPvlanFromUri(broadcastUri));
|
||||
return enableVlanNetwork(conn, vlan, network);
|
||||
}
|
||||
|
||||
throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri());
|
||||
@ -1546,6 +1554,55 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
}
|
||||
}
|
||||
|
||||
private Answer execute(PvlanSetupCommand cmd) {
|
||||
Connection conn = getConnection();
|
||||
|
||||
String primaryPvlan = cmd.getPrimary();
|
||||
String isolatedPvlan = cmd.getIsolated();
|
||||
String op = cmd.getOp();
|
||||
String dhcpName = cmd.getDhcpName();
|
||||
String dhcpMac = cmd.getDhcpMac();
|
||||
String dhcpIp = cmd.getDhcpIp();
|
||||
String vmMac = cmd.getVmMac();
|
||||
String networkTag = cmd.getNetworkTag();
|
||||
|
||||
XsLocalNetwork nw = null;
|
||||
String nwNameLabel = null;
|
||||
try {
|
||||
nw = getNativeNetworkForTraffic(conn, TrafficType.Guest, networkTag);
|
||||
nwNameLabel = nw.getNetwork().getNameLabel(conn);
|
||||
} catch (XenAPIException e) {
|
||||
s_logger.warn("Fail to get network", e);
|
||||
return new Answer(cmd, false, e.toString());
|
||||
} catch (XmlRpcException e) {
|
||||
s_logger.warn("Fail to get network", e);
|
||||
return new Answer(cmd, false, e.toString());
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
} else {
|
||||
s_logger.info("Programmed pvlan for dhcp server with mac " + dhcpMac);
|
||||
}
|
||||
} 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);
|
||||
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);
|
||||
} else {
|
||||
s_logger.info("Programmed pvlan for vm with mac " + vmMac);
|
||||
}
|
||||
}
|
||||
return new Answer(cmd, true, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StartAnswer execute(StartCommand cmd) {
|
||||
Connection conn = getConnection();
|
||||
|
||||
@ -80,7 +80,7 @@ under the License.
|
||||
</pair>
|
||||
<pair key="%aclruledn%/rule-cond-3/nw-expr2/nw-attr-qual">
|
||||
<policyNwAttrQualifier
|
||||
attrEp="destination"
|
||||
attrEp="source"
|
||||
dn="%aclruledn%/rule-cond-3/nw-expr2/nw-attr-qual"
|
||||
status="created"/>
|
||||
</pair>
|
||||
@ -93,7 +93,7 @@ under the License.
|
||||
name=""
|
||||
placement="begin"
|
||||
status="created"
|
||||
value="%deststartip%"/>
|
||||
value="%sourcestartip%"/>
|
||||
</pair>
|
||||
<pair key="%aclruledn%/rule-cond-3/nw-expr2/nw-ip-3">
|
||||
<policyIPAddress
|
||||
@ -104,7 +104,7 @@ under the License.
|
||||
name=""
|
||||
placement="end"
|
||||
status="created"
|
||||
value="%destendip%"/>
|
||||
value="%sourceendip%"/>
|
||||
</pair>
|
||||
|
||||
<pair key="%aclruledn%/rule-cond-4">
|
||||
@ -161,8 +161,8 @@ under the License.
|
||||
descr=value
|
||||
actiontype="drop" or "permit"
|
||||
protocolvalue = "TCP" or "UDP"
|
||||
deststartip="destination start ip"
|
||||
destendip="destination end ip"
|
||||
sourcestartip="source start ip"
|
||||
sourceendip="source end ip"
|
||||
deststartport="start port at destination"
|
||||
destendport="end port at destination"
|
||||
--!>
|
||||
|
||||
@ -54,7 +54,7 @@ under the License.
|
||||
</pair>
|
||||
<pair key="%aclruledn%/rule-cond-2/nw-expr2/nw-attr-qual">
|
||||
<policyNwAttrQualifier
|
||||
attrEp="destination"
|
||||
attrEp="source"
|
||||
dn="%aclruledn%/rule-cond-2/nw-expr2/nw-attr-qual"
|
||||
status="created"/>
|
||||
</pair>
|
||||
@ -67,7 +67,7 @@ under the License.
|
||||
name=""
|
||||
placement="begin"
|
||||
status="created"
|
||||
value="%deststartip%"/>
|
||||
value="%sourcestartip%"/>
|
||||
</pair>
|
||||
<pair key="%aclruledn%/rule-cond-2/nw-expr2/nw-ip-3">
|
||||
<policyIPAddress
|
||||
@ -78,7 +78,7 @@ under the License.
|
||||
name=""
|
||||
placement="end"
|
||||
status="created"
|
||||
value="%destendip%"/>
|
||||
value="%sourceendip%"/>
|
||||
</pair>
|
||||
|
||||
</inConfigs>
|
||||
@ -89,6 +89,6 @@ under the License.
|
||||
aclrulename="dummy"
|
||||
descr=value
|
||||
actiontype="drop" or "permit"
|
||||
deststartip="destination start ip"
|
||||
destendip="destination end ip"
|
||||
sourcestartip="source start ip"
|
||||
sourceendip="source end ip"
|
||||
--!>
|
||||
|
||||
@ -80,7 +80,7 @@ under the License.
|
||||
</pair>
|
||||
<pair key="%aclruledn%/rule-cond-3/nw-expr2/nw-attr-qual">
|
||||
<policyNwAttrQualifier
|
||||
attrEp="destination"
|
||||
attrEp="source"
|
||||
dn="%aclruledn%/rule-cond-3/nw-expr2/nw-attr-qual"
|
||||
status="created"/>
|
||||
</pair>
|
||||
@ -93,7 +93,7 @@ under the License.
|
||||
name=""
|
||||
placement="begin"
|
||||
status="created"
|
||||
value="%deststartip%"/>
|
||||
value="%sourcestartip%"/>
|
||||
</pair>
|
||||
<pair key="%aclruledn%/rule-cond-3/nw-expr2/nw-ip-3">
|
||||
<policyIPAddress
|
||||
@ -104,7 +104,7 @@ under the License.
|
||||
name=""
|
||||
placement="end"
|
||||
status="created"
|
||||
value="%destendip%"/>
|
||||
value="%sourceendip%"/>
|
||||
</pair>
|
||||
|
||||
</inConfigs>
|
||||
@ -116,6 +116,6 @@ under the License.
|
||||
descr=value
|
||||
actiontype="drop" or "permit"
|
||||
protocolvalue = "TCP" or "UDP" or "ICMP"
|
||||
deststartip="destination start ip"
|
||||
destendip="destination end ip"
|
||||
sourcestartip="source start ip"
|
||||
sourceendip="source end ip"
|
||||
--!>
|
||||
|
||||
@ -150,13 +150,13 @@ public interface CiscoVnmcConnection {
|
||||
|
||||
public boolean createTenantVDCEgressAclRule(String tenantName,
|
||||
String identifier, String policyIdentifier,
|
||||
String protocol, String destStartIp, String destEndIp,
|
||||
String protocol, String sourceStartIp, String sourceEndIp,
|
||||
String destStartPort, String destEndPort)
|
||||
throws ExecutionException;
|
||||
|
||||
public boolean createTenantVDCEgressAclRule(String tenantName,
|
||||
String identifier, String policyIdentifier,
|
||||
String protocol, String destStartIp, String destEndIp)
|
||||
String protocol, String sourceStartIp, String sourceEndIp)
|
||||
throws ExecutionException;
|
||||
|
||||
public boolean deleteTenantVDCAclRule(String tenantName,
|
||||
|
||||
@ -729,7 +729,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
@Override
|
||||
public boolean createTenantVDCEgressAclRule(String tenantName,
|
||||
String identifier, String policyIdentifier,
|
||||
String protocol, String destStartIp, String destEndIp,
|
||||
String protocol, String sourceStartIp, String sourceEndIp,
|
||||
String destStartPort, String destEndPort) throws ExecutionException {
|
||||
String xml = VnmcXml.CREATE_EGRESS_ACL_RULE.getXml();
|
||||
String service = VnmcXml.CREATE_EGRESS_ACL_RULE.getService();
|
||||
@ -740,8 +740,8 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
xml = replaceXmlValue(xml, "descr", "Egress ACL rule for Tenant VDC " + tenantName);
|
||||
xml = replaceXmlValue(xml, "actiontype", "permit");
|
||||
xml = replaceXmlValue(xml, "protocolvalue", protocol);
|
||||
xml = replaceXmlValue(xml, "deststartip", destStartIp);
|
||||
xml = replaceXmlValue(xml, "destendip", destEndIp);
|
||||
xml = replaceXmlValue(xml, "sourcestartip", sourceStartIp);
|
||||
xml = replaceXmlValue(xml, "sourceendip", sourceEndIp);
|
||||
xml = replaceXmlValue(xml, "deststartport", destStartPort);
|
||||
xml = replaceXmlValue(xml, "destendport", destEndPort);
|
||||
|
||||
@ -759,7 +759,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
@Override
|
||||
public boolean createTenantVDCEgressAclRule(String tenantName,
|
||||
String identifier, String policyIdentifier,
|
||||
String protocol, String destStartIp, String destEndIp) throws ExecutionException {
|
||||
String protocol, String sourceStartIp, String sourceEndIp) throws ExecutionException {
|
||||
String xml = VnmcXml.CREATE_GENERIC_EGRESS_ACL_RULE.getXml();
|
||||
String service = VnmcXml.CREATE_GENERIC_EGRESS_ACL_RULE.getService();
|
||||
if (protocol.equalsIgnoreCase("all")) { // any protocol
|
||||
@ -773,8 +773,8 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
xml = replaceXmlValue(xml, "aclrulename", getNameForAclRule(tenantName, identifier));
|
||||
xml = replaceXmlValue(xml, "descr", "Egress ACL rule for Tenant VDC " + tenantName);
|
||||
xml = replaceXmlValue(xml, "actiontype", "permit");
|
||||
xml = replaceXmlValue(xml, "deststartip", destStartIp);
|
||||
xml = replaceXmlValue(xml, "destendip", destEndIp);
|
||||
xml = replaceXmlValue(xml, "sourcestartip", sourceStartIp);
|
||||
xml = replaceXmlValue(xml, "sourceendip", sourceEndIp);
|
||||
|
||||
List<String> rules = listChildren(getDnForAclPolicy(tenantName, policyIdentifier));
|
||||
int order = 100;
|
||||
|
||||
@ -60,6 +60,7 @@ import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper;
|
||||
import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.OperationType;
|
||||
import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.SwitchPortMode;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.exception.ExecutionException;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
|
||||
@ -280,30 +281,30 @@ public class CiscoVnmcResource implements ServerResource {
|
||||
String policyIdentifier = cmd.getIpAddress().getPublicIp().replace('.', '-');
|
||||
try {
|
||||
if (!_connection.createTenantVDCNatPolicySet(tenant)) {
|
||||
throw new Exception("Failed to create NAT policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create NAT policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCSourceNatPolicy(tenant, policyIdentifier)) {
|
||||
throw new Exception("Failed to create source NAT policy in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create source NAT policy in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCSourceNatPolicyRef(tenant, policyIdentifier)) {
|
||||
throw new Exception("Failed to associate source NAT policy with NAT policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate source NAT policy with NAT policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCSourceNatIpPool(tenant, policyIdentifier, cmd.getIpAddress().getPublicIp())) {
|
||||
throw new Exception("Failed to create source NAT ip pool in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create source NAT ip pool in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
String[] ipRange = getIpRangeFromCidr(cmd.getContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR));
|
||||
if (!_connection.createTenantVDCSourceNatRule(tenant, policyIdentifier, ipRange[0], ipRange[1])) {
|
||||
throw new Exception("Failed to create source NAT rule in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create source NAT rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.associateNatPolicySet(tenant)) {
|
||||
throw new Exception("Failed to associate source NAT policy set with edge security profile in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate source NAT policy set with edge security profile in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
} catch (ExecutionException e) {
|
||||
String msg = "SetSourceNatCommand failed due to " + e.getMessage();
|
||||
s_logger.error(msg, e);
|
||||
return new Answer(cmd, false, msg);
|
||||
@ -337,29 +338,29 @@ public class CiscoVnmcResource implements ServerResource {
|
||||
|
||||
try {
|
||||
if (!_connection.createTenantVDCAclPolicySet(tenant, true)) {
|
||||
throw new Exception("Failed to create ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
if (!_connection.createTenantVDCAclPolicySet(tenant, false)) {
|
||||
throw new Exception("Failed to create ACL egress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL egress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
for (String publicIp : publicIpRulesMap.keySet()) {
|
||||
String policyIdentifier = publicIp.replace('.', '-');
|
||||
|
||||
if (!_connection.createTenantVDCAclPolicy(tenant, policyIdentifier)) {
|
||||
throw new Exception("Failed to create ACL policy in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL policy in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
if (!_connection.createTenantVDCAclPolicyRef(tenant, policyIdentifier, true)) {
|
||||
throw new Exception("Failed to associate ACL policy with ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate ACL policy with ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
if (!_connection.createTenantVDCAclPolicyRef(tenant, policyIdentifier, false)) {
|
||||
throw new Exception("Failed to associate ACL policy with ACL egress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate ACL policy with ACL egress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
for (FirewallRuleTO rule : publicIpRulesMap.get(publicIp)) {
|
||||
if (rule.revoked()) {
|
||||
if (!_connection.deleteTenantVDCAclRule(tenant, Long.toString(rule.getId()), policyIdentifier)) {
|
||||
throw new Exception("Failed to delete ACL rule in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to delete ACL rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
} else {
|
||||
String[] externalIpRange = getIpRangeFromCidr(rule.getSourceCidrList().get(0));
|
||||
@ -370,13 +371,13 @@ public class CiscoVnmcResource implements ServerResource {
|
||||
Long.toString(rule.getId()), policyIdentifier,
|
||||
rule.getProtocol().toUpperCase(), externalIpRange[0], externalIpRange[1],
|
||||
Integer.toString(rule.getSrcPortRange()[0]), Integer.toString(rule.getSrcPortRange()[1]))) {
|
||||
throw new Exception("Failed to create ACL ingress rule in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL ingress rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
} else {
|
||||
if (!_connection.createTenantVDCIngressAclRule(tenant,
|
||||
Long.toString(rule.getId()), policyIdentifier,
|
||||
rule.getProtocol().toUpperCase(), externalIpRange[0], externalIpRange[1])) {
|
||||
throw new Exception("Failed to create ACL ingress rule in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL ingress rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -387,13 +388,13 @@ public class CiscoVnmcResource implements ServerResource {
|
||||
rule.getProtocol().toUpperCase(),
|
||||
externalIpRange[0], externalIpRange[1],
|
||||
Integer.toString(rule.getSrcPortRange()[0]), Integer.toString(rule.getSrcPortRange()[1]))) {
|
||||
throw new Exception("Failed to create ACL egress rule in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL egress rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
} else {
|
||||
if (!_connection.createTenantVDCEgressAclRule(tenant,
|
||||
Long.toString(rule.getId()), policyIdentifier,
|
||||
rule.getProtocol().toUpperCase(), externalIpRange[0], externalIpRange[1])) {
|
||||
throw new Exception("Failed to create ACL egress rule in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL egress rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -402,9 +403,9 @@ public class CiscoVnmcResource implements ServerResource {
|
||||
}
|
||||
|
||||
if (!_connection.associateAclPolicySet(tenant)) {
|
||||
throw new Exception("Failed to associate ACL policy set with edge security profile in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate ACL policy set with edge security profile in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
} catch (ExecutionException e) {
|
||||
String msg = "SetFirewallRulesCommand failed due to " + e.getMessage();
|
||||
s_logger.error(msg, e);
|
||||
return new Answer(cmd, false, msg);
|
||||
@ -438,69 +439,60 @@ public class CiscoVnmcResource implements ServerResource {
|
||||
|
||||
try {
|
||||
if (!_connection.createTenantVDCNatPolicySet(tenant)) {
|
||||
throw new Exception("Failed to create NAT policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create NAT policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCAclPolicySet(tenant, true)) {
|
||||
throw new Exception("Failed to create ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCAclPolicySet(tenant, false)) {
|
||||
throw new Exception("Failed to create ACL egress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL egress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
for (String publicIp : publicIpRulesMap.keySet()) {
|
||||
String policyIdentifier = publicIp.replace('.', '-');
|
||||
|
||||
if (!_connection.createTenantVDCDNatPolicy(tenant, policyIdentifier)) {
|
||||
throw new Exception("Failed to create DNAT policy in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create DNAT policy in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
if (!_connection.createTenantVDCDNatPolicyRef(tenant, policyIdentifier)) {
|
||||
throw new Exception("Failed to associate DNAT policy with NAT policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate DNAT policy with NAT policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCAclPolicy(tenant, policyIdentifier)) {
|
||||
throw new Exception("Failed to create ACL policy in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL policy in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
if (!_connection.createTenantVDCAclPolicyRef(tenant, policyIdentifier, true)) {
|
||||
throw new Exception("Failed to associate ACL policy with ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate ACL policy with ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
if (!_connection.createTenantVDCAclPolicyRef(tenant, policyIdentifier, false)) {
|
||||
throw new Exception("Failed to associate ACL policy with ACL egress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate ACL policy with ACL egress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
for (StaticNatRuleTO rule : publicIpRulesMap.get(publicIp)) {
|
||||
if (rule.revoked()) {
|
||||
if (!_connection.deleteTenantVDCDNatRule(tenant, Long.toString(rule.getId()), policyIdentifier)) {
|
||||
throw new Exception("Failed to delete DNAT rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.deleteTenantVDCAclRule(tenant, Long.toString(rule.getId()), policyIdentifier)) {
|
||||
throw new Exception("Failed to delete ACL ingress rule for DNAT in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to delete DNAT rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
} else {
|
||||
if (!_connection.createTenantVDCDNatIpPool(tenant, Long.toString(rule.getId()), rule.getDstIp())) {
|
||||
throw new Exception("Failed to create DNAT ip pool in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create DNAT ip pool in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCDNatRule(tenant,
|
||||
Long.toString(rule.getId()), policyIdentifier, rule.getSrcIp())) {
|
||||
throw new Exception("Failed to create DNAT rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCAclRuleForDNat(tenant,
|
||||
Long.toString(rule.getId()), policyIdentifier, rule.getDstIp())) {
|
||||
throw new Exception("Failed to create ACL rule for DNAT in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create DNAT rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_connection.associateAclPolicySet(tenant)) {
|
||||
throw new Exception("Failed to associate source NAT policy set with edge security profile in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate source NAT policy set with edge security profile in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
String msg = "SetSourceNatCommand failed due to " + e.getMessage();
|
||||
} catch (ExecutionException e) {
|
||||
String msg = "SetStaticNatRulesCommand failed due to " + e.getMessage();
|
||||
s_logger.error(msg, e);
|
||||
return new Answer(cmd, false, msg);
|
||||
}
|
||||
@ -533,77 +525,66 @@ public class CiscoVnmcResource implements ServerResource {
|
||||
|
||||
try {
|
||||
if (!_connection.createTenantVDCNatPolicySet(tenant)) {
|
||||
throw new Exception("Failed to create NAT policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create NAT policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCAclPolicySet(tenant, true)) {
|
||||
throw new Exception("Failed to create ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCAclPolicySet(tenant, false)) {
|
||||
throw new Exception("Failed to create ACL egress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL egress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
for (String publicIp : publicIpRulesMap.keySet()) {
|
||||
String policyIdentifier = publicIp.replace('.', '-');
|
||||
|
||||
if (!_connection.createTenantVDCPFPolicy(tenant, policyIdentifier)) {
|
||||
throw new Exception("Failed to create PF policy in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create PF policy in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
if (!_connection.createTenantVDCPFPolicyRef(tenant, policyIdentifier)) {
|
||||
throw new Exception("Failed to associate PF policy with NAT policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate PF policy with NAT policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCAclPolicy(tenant, policyIdentifier)) {
|
||||
throw new Exception("Failed to create ACL policy in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create ACL policy in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
if (!_connection.createTenantVDCAclPolicyRef(tenant, policyIdentifier, true)) {
|
||||
throw new Exception("Failed to associate ACL policy with ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate ACL policy with ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
if (!_connection.createTenantVDCAclPolicyRef(tenant, policyIdentifier, false)) {
|
||||
throw new Exception("Failed to associate ACL policy with ACL egress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate ACL policy with ACL egress policy set in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
for (PortForwardingRuleTO rule : publicIpRulesMap.get(publicIp)) {
|
||||
if (rule.revoked()) {
|
||||
if (!_connection.deleteTenantVDCPFRule(tenant, Long.toString(rule.getId()), policyIdentifier)) {
|
||||
throw new Exception("Failed to delete PF rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.deleteTenantVDCAclRule(tenant, Long.toString(rule.getId()), policyIdentifier)) {
|
||||
throw new Exception("Failed to delete ACL ingress rule for PF in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to delete PF rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
} else {
|
||||
if (!_connection.createTenantVDCPFIpPool(tenant, Long.toString(rule.getId()), rule.getDstIp())) {
|
||||
throw new Exception("Failed to create PF ip pool in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create PF ip pool in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
if (!_connection.createTenantVDCPFPortPool(tenant, Long.toString(rule.getId()),
|
||||
Integer.toString(rule.getDstPortRange()[0]), Integer.toString(rule.getDstPortRange()[1]))) {
|
||||
throw new Exception("Failed to create PF port pool in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create PF port pool in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCPFRule(tenant,
|
||||
Long.toString(rule.getId()), policyIdentifier,
|
||||
rule.getProtocol().toUpperCase(), rule.getSrcIp(),
|
||||
Integer.toString(rule.getSrcPortRange()[0]), Integer.toString(rule.getSrcPortRange()[1]))) {
|
||||
throw new Exception("Failed to create PF rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
if (!_connection.createTenantVDCAclRuleForPF(tenant,
|
||||
Long.toString(rule.getId()), policyIdentifier,
|
||||
rule.getProtocol().toUpperCase(), rule.getDstIp(),
|
||||
Integer.toString(rule.getDstPortRange()[0]), Integer.toString(rule.getDstPortRange()[1]))) {
|
||||
throw new Exception("Failed to create ACL rule for PF in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create PF rule in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_connection.associateAclPolicySet(tenant)) {
|
||||
throw new Exception("Failed to associate source NAT policy set with edge security profile in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate source NAT policy set with edge security profile in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
String msg = "SetSourceNatCommand failed due to " + e.getMessage();
|
||||
} catch (ExecutionException e) {
|
||||
String msg = "SetPortForwardingRulesCommand failed due to " + e.getMessage();
|
||||
s_logger.error(msg, e);
|
||||
return new Answer(cmd, false, msg);
|
||||
}
|
||||
@ -619,24 +600,24 @@ public class CiscoVnmcResource implements ServerResource {
|
||||
return execute(cmd, _numRetries);
|
||||
}
|
||||
|
||||
private void createEdgeDeviceProfile(String tenant, List<String> gateways, Long vlanId) throws Exception {
|
||||
private void createEdgeDeviceProfile(String tenant, List<String> gateways, Long vlanId) throws ExecutionException {
|
||||
// create edge device profile
|
||||
if (!_connection.createTenantVDCEdgeDeviceProfile(tenant))
|
||||
throw new Exception("Failed to create tenant edge device profile in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create tenant edge device profile in VNMC for guest network with vlan " + vlanId);
|
||||
|
||||
// create edge static route policy
|
||||
if (!_connection.createTenantVDCEdgeStaticRoutePolicy(tenant))
|
||||
throw new Exception("Failed to create tenant edge static route policy in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create tenant edge static route policy in VNMC for guest network with vlan " + vlanId);
|
||||
|
||||
// create edge static route for all gateways
|
||||
for (String gateway : gateways) {
|
||||
if (!_connection.createTenantVDCEdgeStaticRoute(tenant, gateway, "0.0.0.0", "0.0.0.0"))
|
||||
throw new Exception("Failed to create tenant edge static route in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to create tenant edge static route in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
// associate edge
|
||||
if (!_connection.associateTenantVDCEdgeStaticRoutePolicy(tenant))
|
||||
throw new Exception("Failed to associate edge static route policy with edge device profile in VNMC for guest network with vlan " + vlanId);
|
||||
throw new ExecutionException("Failed to associate edge static route policy with edge device profile in VNMC for guest network with vlan " + vlanId);
|
||||
}
|
||||
|
||||
private Answer execute(CreateLogicalEdgeFirewallCommand cmd, int numRetries) {
|
||||
@ -644,23 +625,23 @@ public class CiscoVnmcResource implements ServerResource {
|
||||
try {
|
||||
// create tenant
|
||||
if (!_connection.createTenant(tenant))
|
||||
throw new Exception("Failed to create tenant in VNMC for guest network with vlan " + cmd.getVlanId());
|
||||
throw new ExecutionException("Failed to create tenant in VNMC for guest network with vlan " + cmd.getVlanId());
|
||||
|
||||
// create tenant VDC
|
||||
if (!_connection.createTenantVDC(tenant))
|
||||
throw new Exception("Failed to create tenant VDC in VNMC for guest network with vlan " + cmd.getVlanId());
|
||||
throw new ExecutionException("Failed to create tenant VDC in VNMC for guest network with vlan " + cmd.getVlanId());
|
||||
|
||||
// create edge security profile
|
||||
if (!_connection.createTenantVDCEdgeSecurityProfile(tenant))
|
||||
throw new Exception("Failed to create tenant edge security profile in VNMC for guest network with vlan " + cmd.getVlanId());
|
||||
throw new ExecutionException("Failed to create tenant edge security profile in VNMC for guest network with vlan " + cmd.getVlanId());
|
||||
|
||||
// create edge device profile and associated route
|
||||
createEdgeDeviceProfile(tenant, cmd.getPublicGateways(), cmd.getVlanId());
|
||||
|
||||
// create logical edge firewall
|
||||
if (!_connection.createEdgeFirewall(tenant, cmd.getPublicIp(), cmd.getInternalIp(), cmd.getPublicSubnet(), cmd.getInternalSubnet()))
|
||||
throw new Exception("Failed to create edge firewall in VNMC for guest network with vlan " + cmd.getVlanId());
|
||||
} catch (Throwable e) {
|
||||
throw new ExecutionException("Failed to create edge firewall in VNMC for guest network with vlan " + cmd.getVlanId());
|
||||
} catch (ExecutionException e) {
|
||||
String msg = "CreateLogicalEdgeFirewallCommand failed due to " + e.getMessage();
|
||||
s_logger.error(msg, e);
|
||||
return new Answer(cmd, false, msg);
|
||||
@ -688,7 +669,7 @@ public class CiscoVnmcResource implements ServerResource {
|
||||
s_logger.debug("Created vservice node for ASA appliance in Cisco VSM for vlan " + vlanId);
|
||||
helper.updatePortProfile(cmd.getAsaInPortProfile(), SwitchPortMode.access, params);
|
||||
s_logger.debug("Updated inside port profile for ASA appliance in Cisco VSM with new vlan " + vlanId);
|
||||
} catch (Throwable e) {
|
||||
} catch (CloudRuntimeException e) {
|
||||
String msg = "ConfigureVSMForASACommand failed due to " + e.getMessage();
|
||||
s_logger.error(msg, e);
|
||||
return new Answer(cmd, false, msg);
|
||||
@ -711,18 +692,18 @@ public class CiscoVnmcResource implements ServerResource {
|
||||
try {
|
||||
Map<String, String> availableAsaAppliances = _connection.listUnAssocAsa1000v();
|
||||
if (availableAsaAppliances.isEmpty()) {
|
||||
throw new Exception("No ASA 1000v available to associate with logical edge firewall for guest vlan " + cmd.getVlanId());
|
||||
throw new ExecutionException("No ASA 1000v available to associate with logical edge firewall for guest vlan " + cmd.getVlanId());
|
||||
}
|
||||
|
||||
String asaInstanceDn = availableAsaAppliances.get(cmd.getAsaMgmtIp());
|
||||
if (asaInstanceDn == null) {
|
||||
throw new Exception("Requested ASA 1000v (" + cmd.getAsaMgmtIp() + ") is not available");
|
||||
throw new ExecutionException("Requested ASA 1000v (" + cmd.getAsaMgmtIp() + ") is not available");
|
||||
}
|
||||
|
||||
if (!_connection.assignAsa1000v(tenant, asaInstanceDn)) {
|
||||
throw new Exception("Failed to associate ASA 1000v (" + cmd.getAsaMgmtIp() + ") with logical edge firewall for guest vlan " + cmd.getVlanId());
|
||||
throw new ExecutionException("Failed to associate ASA 1000v (" + cmd.getAsaMgmtIp() + ") with logical edge firewall for guest vlan " + cmd.getVlanId());
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
} catch (ExecutionException e) {
|
||||
String msg = "AssociateAsaWithLogicalEdgeFirewallCommand failed due to " + e.getMessage();
|
||||
s_logger.error(msg, e);
|
||||
return new Answer(cmd, false, msg);
|
||||
@ -743,7 +724,7 @@ public class CiscoVnmcResource implements ServerResource {
|
||||
String tenant = "vlan-" + cmd.getVlanId();
|
||||
try {
|
||||
_connection.deleteTenant(tenant);
|
||||
} catch (Throwable e) {
|
||||
} catch (ExecutionException e) {
|
||||
String msg = "CleanupLogicalEdgeFirewallCommand failed due to " + e.getMessage();
|
||||
s_logger.error(msg, e);
|
||||
return new Answer(cmd, false, msg);
|
||||
|
||||
@ -923,13 +923,13 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyGlobalLoadBalancerRule(long zoneId, GlobalLoadBalancerConfigCommand gslbConfigCmd)
|
||||
public boolean applyGlobalLoadBalancerRule(long zoneId, long physicalNetworkId, GlobalLoadBalancerConfigCommand gslbConfigCmd)
|
||||
throws ResourceUnavailableException {
|
||||
|
||||
long zoneGslbProviderHosId = 0;
|
||||
|
||||
// find the NetScaler device configured as gslb service provider in the zone
|
||||
ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId);
|
||||
ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
|
||||
if (nsGslbProvider == null) {
|
||||
String msg = "Unable to find a NetScaler configured as gslb service provider in zone " + zoneId;
|
||||
s_logger.debug(msg);
|
||||
@ -950,28 +950,37 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
||||
return true;
|
||||
}
|
||||
|
||||
private ExternalLoadBalancerDeviceVO findGslbProvider(long zoneId) {
|
||||
private ExternalLoadBalancerDeviceVO findGslbProvider(long zoneId, long physicalNetworkId) {
|
||||
List<PhysicalNetworkVO> pNtwks = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, TrafficType.Guest);
|
||||
if (pNtwks.isEmpty() || pNtwks.size() > 1) {
|
||||
throw new InvalidParameterValueException("Unable to get physical network in zone id = " + zoneId);
|
||||
}
|
||||
|
||||
if (pNtwks == null || pNtwks.isEmpty()) {
|
||||
throw new InvalidParameterValueException("Unable to get physical network: " + physicalNetworkId +
|
||||
" in zone id = " + zoneId);
|
||||
} else {
|
||||
for (PhysicalNetwork physicalNetwork : pNtwks) {
|
||||
if (physicalNetwork.getId() == physicalNetworkId) {
|
||||
PhysicalNetworkVO physNetwork = pNtwks.get(0);
|
||||
ExternalLoadBalancerDeviceVO nsGslbProvider = _externalLoadBalancerDeviceDao.findGslbServiceProvider(
|
||||
physNetwork.getId(), Provider.Netscaler.getName());
|
||||
return nsGslbProvider;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isServiceEnabledInZone(long zoneId) {
|
||||
public boolean isServiceEnabledInZone(long zoneId, long physicalNetworkId) {
|
||||
|
||||
ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId);
|
||||
ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
|
||||
//return true if a NetScaler device is configured in the zone
|
||||
return (nsGslbProvider != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getZoneGslbProviderPublicIp(long zoneId) {
|
||||
ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId);
|
||||
public String getZoneGslbProviderPublicIp(long zoneId, long physicalNetworkId) {
|
||||
ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
|
||||
if (nsGslbProvider != null) {
|
||||
return nsGslbProvider.getGslbSitePublicIP();
|
||||
}
|
||||
@ -979,8 +988,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getZoneGslbProviderPrivateIp(long zoneId) {
|
||||
ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId);
|
||||
public String getZoneGslbProviderPrivateIp(long zoneId, long physicalNetworkId) {
|
||||
ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
|
||||
if (nsGslbProvider != null) {
|
||||
return nsGslbProvider.getGslbSitePrivateIP();
|
||||
}
|
||||
|
||||
@ -1095,7 +1095,15 @@ public class NetscalerResource implements ServerResource {
|
||||
}
|
||||
|
||||
vserver.set_name(vserverName);
|
||||
vserver.set_lbmethod(lbMethod);
|
||||
if ("RoundRobin".equalsIgnoreCase(lbMethod)) {
|
||||
vserver.set_lbmethod("ROUNDROBIN");
|
||||
} else if ("LeastConn".equalsIgnoreCase(lbMethod)) {
|
||||
vserver.set_lbmethod("LEASTCONNECTION");
|
||||
} else if ("Proximity".equalsIgnoreCase(lbMethod)) {
|
||||
vserver.set_lbmethod("RTT");
|
||||
} else {
|
||||
throw new ExecutionException("Unsupported LB method");
|
||||
}
|
||||
vserver.set_persistencetype(persistenceType);
|
||||
if ("SOURCEIP".equalsIgnoreCase(persistenceType)) {
|
||||
vserver.set_persistenceid(persistenceId);
|
||||
|
||||
27
scripts/vm/hypervisor/xenserver/ovs-get-bridge.sh
Executable file
27
scripts/vm/hypervisor/xenserver/ovs-get-bridge.sh
Executable file
@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
# 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.
|
||||
|
||||
nw_label=$1
|
||||
br=`xe network-list name-label="$nw_label" params=bridge |cut -d ':' -f 2 |tr -d ' ' `
|
||||
pbr=`ovs-vsctl br-to-parent $br`
|
||||
while [ "$br" != "$pbr" ]
|
||||
do
|
||||
br=$pbr
|
||||
pbr=`ovs-vsctl br-to-parent $br`
|
||||
done
|
||||
echo $pbr
|
||||
25
scripts/vm/hypervisor/xenserver/ovs-get-dhcp-iface.sh
Executable file
25
scripts/vm/hypervisor/xenserver/ovs-get-dhcp-iface.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
# 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.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
bridge=$1
|
||||
dhcp_name=$2
|
||||
dom_id=`xe vm-list is-control-domain=false power-state=running params=dom-id name-label=$dhcp_name|cut -d ':' -f 2 |tr -d ' ' `
|
||||
iface="vif${dom_id}.0"
|
||||
echo $iface
|
||||
145
scripts/vm/hypervisor/xenserver/ovs-pvlan
Executable file
145
scripts/vm/hypervisor/xenserver/ovs-pvlan
Executable file
@ -0,0 +1,145 @@
|
||||
#!/usr/bin/python
|
||||
# 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.
|
||||
|
||||
|
||||
import cloudstack_pluginlib as lib
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import time
|
||||
import XenAPIPlugin
|
||||
|
||||
sys.path.append("/opt/xensource/sm/")
|
||||
import util
|
||||
|
||||
from time import localtime as _localtime, asctime as _asctime
|
||||
|
||||
xePath = "/opt/xensource/bin/xe"
|
||||
lib.setup_logging("/var/log/ovs-pvlan.log")
|
||||
dhcpSetupPath = "/opt/xensource/bin/ovs-pvlan-dhcp-host.sh"
|
||||
vmSetupPath = "/opt/xensource/bin/ovs-pvlan-vm.sh"
|
||||
getDhcpIfacePath = "/opt/xensource/bin/ovs-get-dhcp-iface.sh"
|
||||
pvlanCleanupPath = "/opt/xensource/bin/ovs-pvlan-cleanup.sh"
|
||||
getBridgePath = "/opt/xensource/bin/ovs-get-bridge.sh"
|
||||
|
||||
def echo(fn):
|
||||
def wrapped(*v, **k):
|
||||
name = fn.__name__
|
||||
util.SMlog("#### VMOPS enter %s ####" % name)
|
||||
res = fn(*v, **k)
|
||||
util.SMlog("#### VMOPS exit %s ####" % name)
|
||||
return res
|
||||
return wrapped
|
||||
|
||||
@echo
|
||||
def setup_pvlan_dhcp(session, args):
|
||||
op = args.pop("op")
|
||||
nw_label = args.pop("nw-label")
|
||||
primary = args.pop("primary-pvlan")
|
||||
isolated = args.pop("isolated-pvlan")
|
||||
dhcp_name = args.pop("dhcp-name")
|
||||
dhcp_ip = args.pop("dhcp-ip")
|
||||
dhcp_mac = args.pop("dhcp-mac")
|
||||
|
||||
res = lib.check_switch()
|
||||
if res != "SUCCESS":
|
||||
return "FAILURE:%s" % res
|
||||
|
||||
logging.debug("Network is:%s" % (nw_label))
|
||||
bridge = lib.do_cmd([getBridgePath, nw_label])
|
||||
logging.debug("Determine bridge/switch is :%s" % (bridge))
|
||||
|
||||
if op == "add":
|
||||
logging.debug("Try to get dhcp vm %s port on the switch:%s" % (dhcp_name, bridge))
|
||||
dhcp_iface = lib.do_cmd([getDhcpIfacePath, bridge, dhcp_name])
|
||||
logging.debug("About to setup dhcp vm on the switch:%s" % bridge)
|
||||
res = lib.do_cmd([dhcpSetupPath, "-A", "-b", bridge, "-p", primary,
|
||||
"-i", isolated, "-n", dhcp_name, "-d", dhcp_ip, "-m", dhcp_mac,
|
||||
"-I", dhcp_iface])
|
||||
if res:
|
||||
result = "FAILURE:%s" % res
|
||||
return result;
|
||||
logging.debug("Setup dhcp vm on switch program done")
|
||||
elif op == "delete":
|
||||
logging.debug("About to remove dhcp the switch:%s" % bridge)
|
||||
res = lib.do_cmd([dhcpSetupPath, "-D", "-b", bridge, "-p", primary,
|
||||
"-i", isolated, "-n", dhcp_name, "-d", dhcp_ip, "-m", dhcp_mac])
|
||||
if res:
|
||||
result = "FAILURE:%s" % res
|
||||
return result;
|
||||
logging.debug("Remove DHCP on switch program done")
|
||||
|
||||
result = "true"
|
||||
logging.debug("Setup_pvlan_dhcp completed with result:%s" % result)
|
||||
return result
|
||||
|
||||
@echo
|
||||
def setup_pvlan_vm(session, args):
|
||||
op = args.pop("op")
|
||||
nw_label = args.pop("nw-label")
|
||||
primary = args.pop("primary-pvlan")
|
||||
isolated = args.pop("isolated-pvlan")
|
||||
vm_mac = args.pop("vm-mac")
|
||||
trunk_port = 1
|
||||
|
||||
res = lib.check_switch()
|
||||
if res != "SUCCESS":
|
||||
return "FAILURE:%s" % res
|
||||
|
||||
bridge = lib.do_cmd([getBridgePath, nw_label])
|
||||
logging.debug("Determine bridge/switch is :%s" % (bridge))
|
||||
|
||||
if op == "add":
|
||||
logging.debug("About to setup vm on the switch:%s" % bridge)
|
||||
res = lib.do_cmd([vmSetupPath, "-A", "-b", bridge, "-p", primary, "-i", isolated, "-v", vm_mac])
|
||||
if res:
|
||||
result = "FAILURE:%s" % res
|
||||
return result;
|
||||
logging.debug("Setup vm on switch program done")
|
||||
elif op == "delete":
|
||||
logging.debug("About to remove vm on the switch:%s" % bridge)
|
||||
res = lib.do_cmd([vmSetupPath, "-D", "-b", bridge, "-p", primary, "-i", isolated, "-v", vm_mac])
|
||||
if res:
|
||||
result = "FAILURE:%s" % res
|
||||
return result;
|
||||
logging.debug("Remove vm on switch program done")
|
||||
|
||||
result = "true"
|
||||
logging.debug("Setup_pvlan_vm_alone completed with result:%s" % result)
|
||||
return result
|
||||
|
||||
@echo
|
||||
def cleanup(session, args):
|
||||
res = lib.check_switch()
|
||||
if res != "SUCCESS":
|
||||
return "FAILURE:%s" % res
|
||||
|
||||
res = lib.do_cmd([pvlanCleanUpPath])
|
||||
if res:
|
||||
result = "FAILURE:%s" % res
|
||||
return result;
|
||||
|
||||
result = "true"
|
||||
logging.debug("Setup_pvlan_vm_dhcp completed with result:%s" % result)
|
||||
return result
|
||||
|
||||
if __name__ == "__main__":
|
||||
XenAPIPlugin.dispatch({"setup-pvlan-dhcp": setup_pvlan_dhcp,
|
||||
"setup-pvlan-vm": setup_pvlan_vm,
|
||||
"cleanup":cleanup})
|
||||
@ -70,4 +70,9 @@ swift=..,0755,/opt/xensource/bin
|
||||
swiftxen=..,0755,/etc/xapi.d/plugins
|
||||
s3xen=..,0755,/etc/xapi.d/plugins
|
||||
add_to_vcpus_params_live.sh=..,0755,/opt/xensource/bin
|
||||
|
||||
ovs-pvlan=..,0755,/etc/xapi.d/plugins
|
||||
ovs-pvlan-dhcp-host.sh=../../../network,0755,/opt/xensource/bin
|
||||
ovs-pvlan-vm.sh=../../../network,0755,/opt/xensource/bin
|
||||
ovs-pvlan-cleanup.sh=../../../network,0755,/opt/xensource/bin
|
||||
ovs-get-dhcp-iface.sh=..,0755,/opt/xensource/bin
|
||||
ovs-get-bridge.sh=..,0755,/opt/xensource/bin
|
||||
|
||||
23
scripts/vm/network/ovs-pvlan-cleanup.sh
Executable file
23
scripts/vm/network/ovs-pvlan-cleanup.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
# 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.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
ovs-ofctl del-flows xenbr0
|
||||
ovs-ofctl add-flow xenbr0 priority=0,actions=NORMAL
|
||||
|
||||
123
scripts/vm/network/ovs-pvlan-dhcp-host.sh
Executable file
123
scripts/vm/network/ovs-pvlan-dhcp-host.sh
Executable file
@ -0,0 +1,123 @@
|
||||
#!/bin/bash
|
||||
# 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.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
usage() {
|
||||
printf "Usage: %s: (-A|-D) -b <bridge/switch> -p <primary vlan> -i <secondary isolated vlan> -n <DHCP server name> -d <DHCP server IP> -m <DHCP server MAC> -I <interface> -v <VM MAC> -h \n" $(basename $0) >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
br=
|
||||
pri_vlan=
|
||||
sec_iso_vlan=
|
||||
dhcp_name=
|
||||
dhcp_ip=
|
||||
dhcp_mac=
|
||||
vm_mac=
|
||||
iface=
|
||||
op=
|
||||
|
||||
while getopts 'ADb:p:i:d:m:v:n:I:h' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
A) op="add"
|
||||
;;
|
||||
D) op="del"
|
||||
;;
|
||||
b) br="$OPTARG"
|
||||
;;
|
||||
p) pri_vlan="$OPTARG"
|
||||
;;
|
||||
i) sec_iso_vlan="$OPTARG"
|
||||
;;
|
||||
n) dhcp_name="$OPTARG"
|
||||
;;
|
||||
d) dhcp_ip="$OPTARG"
|
||||
;;
|
||||
m) dhcp_mac="$OPTARG"
|
||||
;;
|
||||
I) iface="$OPTARG"
|
||||
;;
|
||||
v) vm_mac="$OPTARG"
|
||||
;;
|
||||
h) usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$op" ]
|
||||
then
|
||||
echo Missing operation pararmeter!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$br" ]
|
||||
then
|
||||
echo Missing parameter bridge!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$pri_vlan" ]
|
||||
then
|
||||
echo Missing parameter primary vlan!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$sec_iso_vlan" ]
|
||||
then
|
||||
echo Missing parameter secondary isolate vlan!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$dhcp_name" ]
|
||||
then
|
||||
echo Missing parameter DHCP NAME!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$dhcp_ip" ]
|
||||
then
|
||||
echo Missing parameter DHCP IP!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$dhcp_mac" ]
|
||||
then
|
||||
echo Missing parameter DHCP MAC!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$op" == "add" -a -z "$iface" ]
|
||||
then
|
||||
echo Missing parameter DHCP VM interface!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$op" == "add" ]
|
||||
then
|
||||
dhcp_port=`ovs-ofctl show $br | grep $iface | cut -d '(' -f 1|tr -d ' '`
|
||||
ovs-ofctl add-flow $br priority=200,arp,dl_vlan=$sec_iso_vlan,nw_dst=$dhcp_ip,actions=strip_vlan,output:$dhcp_port
|
||||
ovs-ofctl add-flow $br priority=150,dl_vlan=$sec_iso_vlan,dl_dst=$dhcp_mac,actions=strip_vlan,output:$dhcp_port
|
||||
ovs-ofctl add-flow $br priority=100,udp,dl_vlan=$sec_iso_vlan,nw_dst=255.255.255.255,tp_dst=67,actions=strip_vlan,output:$dhcp_port
|
||||
else
|
||||
ovs-ofctl del-flows --strict $br priority=200,arp,dl_vlan=$sec_iso_vlan,nw_dst=$dhcp_ip
|
||||
ovs-ofctl del-flows --strict $br priority=150,dl_vlan=$sec_iso_vlan,dl_dst=$dhcp_mac
|
||||
ovs-ofctl del-flows --strict $br priority=100,udp,dl_vlan=$sec_iso_vlan,nw_dst=255.255.255.255,tp_dst=67
|
||||
fi
|
||||
99
scripts/vm/network/ovs-pvlan-vm.sh
Executable file
99
scripts/vm/network/ovs-pvlan-vm.sh
Executable file
@ -0,0 +1,99 @@
|
||||
#!/bin/bash
|
||||
# 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.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
usage() {
|
||||
printf "Usage: %s: (-A|-D) -b <bridge/switch> -p <primary vlan> -i <secondary isolated vlan> -d <DHCP server IP> -m <DHCP server MAC> -v <VM MAC> -h \n" $(basename $0) >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
br=
|
||||
pri_vlan=
|
||||
sec_iso_vlan=
|
||||
dhcp_ip=
|
||||
dhcp_mac=
|
||||
vm_mac=
|
||||
op=
|
||||
|
||||
while getopts 'ADb:p:i:d:m:v:h' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
A) op="add"
|
||||
;;
|
||||
D) op="del"
|
||||
;;
|
||||
b) br="$OPTARG"
|
||||
;;
|
||||
p) pri_vlan="$OPTARG"
|
||||
;;
|
||||
i) sec_iso_vlan="$OPTARG"
|
||||
;;
|
||||
d) dhcp_ip="$OPTARG"
|
||||
;;
|
||||
m) dhcp_mac="$OPTARG"
|
||||
;;
|
||||
v) vm_mac="$OPTARG"
|
||||
;;
|
||||
h) usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$op" ]
|
||||
then
|
||||
echo Missing operation pararmeter!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$br" ]
|
||||
then
|
||||
echo Missing parameter bridge!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$vm_mac" ]
|
||||
then
|
||||
echo Missing parameter VM MAC!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$pri_vlan" ]
|
||||
then
|
||||
echo Missing parameter secondary isolate vlan!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$sec_iso_vlan" ]
|
||||
then
|
||||
echo Missing parameter secondary isolate vlan!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trunk_port=1
|
||||
|
||||
if [ "$op" == "add" ]
|
||||
then
|
||||
ovs-ofctl add-flow $br priority=50,dl_vlan=0xffff,dl_src=$vm_mac,actions=mod_vlan_vid:$sec_iso_vlan,resubmit:$trunk_port
|
||||
ovs-ofctl add-flow $br priority=60,dl_vlan=$sec_iso_vlan,dl_src=$vm_mac,actions=output:$trunk_port
|
||||
else
|
||||
ovs-ofctl del-flows --strict $br priority=50,dl_vlan=0xffff,dl_src=$vm_mac
|
||||
ovs-ofctl del-flows --strict $br priority=60,dl_vlan=$sec_iso_vlan,dl_src=$vm_mac
|
||||
fi
|
||||
|
||||
@ -90,6 +90,11 @@
|
||||
<artifactId>cloud-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-framework-ipc</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-framework-events</artifactId>
|
||||
|
||||
@ -169,6 +169,13 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator {
|
||||
}
|
||||
}
|
||||
|
||||
// add all hosts that we are not considering to the avoid list
|
||||
List<HostVO> allhostsInCluster = _hostDao.listAllUpAndEnabledNonHAHosts(type, clusterId, podId, dcId, null);
|
||||
allhostsInCluster.removeAll(clusterHosts);
|
||||
for (HostVO host : allhostsInCluster) {
|
||||
avoid.addHost(host.getId());
|
||||
}
|
||||
|
||||
return allocateTo(plan, offering, template, avoid, clusterHosts, returnUpTo, considerReservedCapacity, account);
|
||||
}
|
||||
|
||||
@ -285,6 +292,7 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Not using host " + host.getId() + "; numCpusGood: " + numCpusGood + "; cpuFreqGood: " + cpuFreqGood + ", host has capacity?" + hostHasCapacity);
|
||||
}
|
||||
avoid.addHost(host.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1684,4 +1684,9 @@ public class ApiDBUtils {
|
||||
public static List<? extends LoadBalancer> listSiteLoadBalancers(long gslbRuleId) {
|
||||
return _gslbService.listSiteLoadBalancers(gslbRuleId);
|
||||
}
|
||||
|
||||
public static String getDnsNameConfiguredForGslb() {
|
||||
String providerDnsName = _configDao.getValue(Config.CloudDnsName.key());
|
||||
return providerDnsName;
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ public class ApiDispatcher {
|
||||
pageSize = Long.valueOf((String) pageSizeObj);
|
||||
}
|
||||
|
||||
if ((unpackedParams.get(ApiConstants.PAGE) == null) && (pageSize != null && pageSize != BaseListCmd.PAGESIZE_UNLIMITED)) {
|
||||
if ((unpackedParams.get(ApiConstants.PAGE) == null) && (pageSize != null && !pageSize.equals(BaseListCmd.PAGESIZE_UNLIMITED))) {
|
||||
ServerApiException ex = new ServerApiException(ApiErrorCode.PARAM_ERROR, "\"page\" parameter is required when \"pagesize\" is specified");
|
||||
ex.setCSErrorCode(CSExceptionErrorCode.getCSErrCode(ex.getClass().getName()));
|
||||
throw ex;
|
||||
|
||||
@ -792,7 +792,8 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
response.setAlgorithm(globalLoadBalancerRule.getAlgorithm());
|
||||
response.setStickyMethod(globalLoadBalancerRule.getPersistence());
|
||||
response.setServiceType(globalLoadBalancerRule.getServiceType());
|
||||
response.setServiceDomainName(globalLoadBalancerRule.getGslbDomain());
|
||||
response.setServiceDomainName(globalLoadBalancerRule.getGslbDomain() + "."
|
||||
+ ApiDBUtils.getDnsNameConfiguredForGslb());
|
||||
response.setName(globalLoadBalancerRule.getName());
|
||||
response.setDescription(globalLoadBalancerRule.getDescription());
|
||||
response.setRegionIdId(globalLoadBalancerRule.getRegion());
|
||||
|
||||
@ -2468,7 +2468,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
|
||||
// offerings
|
||||
private boolean isPermissible(Long accountDomainId, Long offeringDomainId) {
|
||||
|
||||
if (accountDomainId == offeringDomainId) {
|
||||
if (accountDomainId.equals(offeringDomainId)) {
|
||||
return true; // account and service offering in same domain
|
||||
}
|
||||
|
||||
|
||||
@ -73,6 +73,7 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJo
|
||||
offeringResponse.setDomainId(offering.getDomainUuid());
|
||||
offeringResponse.setNetworkRate(offering.getRateMbps());
|
||||
offeringResponse.setHostTag(offering.getHostTag());
|
||||
offeringResponse.setDeploymentPlanner(offering.getDeploymentPlanner());
|
||||
offeringResponse.setObjectName("serviceoffering");
|
||||
|
||||
return offeringResponse;
|
||||
|
||||
@ -106,6 +106,9 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit
|
||||
@Column(name="domain_path")
|
||||
private String domainPath = null;
|
||||
|
||||
@Column(name = "deployment_planner")
|
||||
private String deploymentPlanner;
|
||||
|
||||
|
||||
public ServiceOfferingJoinVO() {
|
||||
}
|
||||
@ -307,5 +310,13 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit
|
||||
this.vm_type = vm_type;
|
||||
}
|
||||
|
||||
public String getDeploymentPlanner() {
|
||||
return deploymentPlanner;
|
||||
}
|
||||
|
||||
public void setDeploymentPlanner(String deploymentPlanner) {
|
||||
this.deploymentPlanner = deploymentPlanner;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -27,6 +27,8 @@ import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||
import org.apache.cloudstack.framework.messagebus.PublishScope;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -77,11 +79,14 @@ import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.fsm.StateListener;
|
||||
import com.cloud.vm.UserVmDetailVO;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.Event;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
@ -121,6 +126,8 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
|
||||
protected VMSnapshotDao _vmSnapshotDao;
|
||||
@Inject
|
||||
protected UserVmDao _userVMDao;
|
||||
@Inject
|
||||
protected UserVmDetailsDao _userVmDetailsDao;
|
||||
|
||||
@Inject
|
||||
ClusterDetailsDao _clusterDetailsDao;
|
||||
@ -132,6 +139,11 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
|
||||
long _extraBytesPerVolume = 0;
|
||||
private float _storageOverProvisioningFactor = 1.0f;
|
||||
|
||||
@Inject
|
||||
MessageBus _messageBus;
|
||||
|
||||
private static final String MESSAGE_RESERVED_CAPACITY_FREED_FLAG = "Message.ReservedCapacityFreed.Flag";
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
_vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
|
||||
@ -552,6 +564,20 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
|
||||
ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId());
|
||||
reservedMemory += so.getRamSize() * 1024L * 1024L;
|
||||
reservedCpu += so.getCpu() * so.getSpeed();
|
||||
} else {
|
||||
// signal if not done already, that the VM has been stopped for skip.counting.hours,
|
||||
// hence capacity will not be reserved anymore.
|
||||
UserVmDetailVO messageSentFlag = _userVmDetailsDao.findDetail(vm.getId(), MESSAGE_RESERVED_CAPACITY_FREED_FLAG);
|
||||
if (messageSentFlag == null || !Boolean.valueOf(messageSentFlag.getValue())) {
|
||||
_messageBus.publish(_name, "VM_ReservedCapacity_Free", PublishScope.LOCAL, vm);
|
||||
|
||||
if (vm.getType() == VirtualMachine.Type.User) {
|
||||
UserVmVO userVM = _userVMDao.findById(vm.getId());
|
||||
_userVMDao.loadDetails(userVM);
|
||||
userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "true");
|
||||
_userVMDao.saveDetails(userVM);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -681,13 +707,25 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
|
||||
|
||||
if ((newState == State.Starting || newState == State.Migrating || event == Event.AgentReportMigrated) && vm.getHostId() != null) {
|
||||
boolean fromLastHost = false;
|
||||
if (vm.getLastHostId() == vm.getHostId()) {
|
||||
if (vm.getHostId().equals(vm.getLastHostId())) {
|
||||
s_logger.debug("VM starting again on the last host it was stopped on");
|
||||
fromLastHost = true;
|
||||
}
|
||||
allocateVmCapacity(vm, fromLastHost);
|
||||
}
|
||||
|
||||
if (newState == State.Stopped) {
|
||||
if (vm.getType() == VirtualMachine.Type.User) {
|
||||
|
||||
UserVmVO userVM = _userVMDao.findById(vm.getId());
|
||||
_userVMDao.loadDetails(userVM);
|
||||
// free the message sent flag if it exists
|
||||
userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "false");
|
||||
_userVMDao.saveDetails(userVM);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -214,6 +214,8 @@ public enum Config {
|
||||
SecStorageProxy("Advanced", AgentManager.class, String.class, "secstorage.proxy", null, "http proxy used by ssvm, in http://username:password@proxyserver:port format", null),
|
||||
AlertPurgeInterval("Advanced", ManagementServer.class, Integer.class, "alert.purge.interval", "86400", "The interval (in seconds) to wait before running the alert purge thread", null),
|
||||
AlertPurgeDelay("Advanced", ManagementServer.class, Integer.class, "alert.purge.delay", "0", "Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts", null),
|
||||
HostReservationReleasePeriod("Advanced", ManagementServer.class, Integer.class, "host.reservation.release.period", "300000", "The interval in milliseconds between host reservation release checks", null),
|
||||
|
||||
|
||||
// LB HealthCheck Interval.
|
||||
LBHealthCheck("Advanced", ManagementServer.class, String.class, "healthcheck.update.interval", "600",
|
||||
@ -235,6 +237,7 @@ public enum Config {
|
||||
ApplyAllocationAlgorithmToPods("Advanced", ManagementServer.class, Boolean.class, "apply.allocation.algorithm.to.pods", "false", "If true, deployment planner applies the allocation heuristics at pods first in the given datacenter during VM resource allocation", "true,false"),
|
||||
VmUserDispersionWeight("Advanced", ManagementServer.class, Float.class, "vm.user.dispersion.weight", "1", "Weight for user dispersion heuristic (as a value between 0 and 1) applied to resource allocation during vm deployment. Weight for capacity heuristic will be (1 - weight of user dispersion)", null),
|
||||
VmAllocationAlgorithm("Advanced", ManagementServer.class, String.class, "vm.allocation.algorithm", "random", "'random', 'firstfit', 'userdispersing', 'userconcentratedpod_random', 'userconcentratedpod_firstfit' : Order in which hosts within a cluster will be considered for VM/volume allocation.", null),
|
||||
VmDeploymentPlanner("Advanced", ManagementServer.class, String.class, "vm.deployment.planner", "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, String.class, "network.loadbalancer.basiczone.elb.enabled", "false", "Whether the load balancing service is enabled for basic zones", "true,false"),
|
||||
ElasticLoadBalancerNetwork("Advanced", ManagementServer.class, String.class, "network.loadbalancer.basiczone.elb.network", "guest", "Whether the elastic load balancing service public ips are taken from the public or guest network", "guest,public"),
|
||||
|
||||
@ -79,10 +79,11 @@ public interface ConfigurationManager extends ConfigurationService, Manager {
|
||||
* TODO
|
||||
* @param id
|
||||
* @param useVirtualNetwork
|
||||
* @param deploymentPlanner
|
||||
* @return ID
|
||||
*/
|
||||
ServiceOfferingVO createServiceOffering(long userId, boolean isSystem, VirtualMachine.Type vm_typeType, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired,
|
||||
boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate);
|
||||
boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner);
|
||||
|
||||
/**
|
||||
* Creates a new disk offering
|
||||
|
||||
@ -162,6 +162,7 @@ import com.cloud.org.Grouping.AllocationState;
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.projects.ProjectManager;
|
||||
import com.cloud.server.ConfigurationServer;
|
||||
import com.cloud.server.ManagementService;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
@ -345,6 +346,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
@Inject
|
||||
NicIpAliasDao _nicIpAliasDao;
|
||||
|
||||
@Inject
|
||||
public ManagementService _mgr;
|
||||
|
||||
// FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
|
||||
@Inject protected DataCenterLinkLocalIpAddressDao _LinkLocalIpAllocDao;
|
||||
|
||||
@ -2033,17 +2037,29 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
throw new InvalidParameterValueException("Network rate can be specified only for non-System offering and system offerings having \"domainrouter\" systemvmtype");
|
||||
}
|
||||
|
||||
if (cmd.getDeploymentPlanner() != null) {
|
||||
List<String> planners = _mgr.listDeploymentPlanners();
|
||||
if (planners != null && !planners.isEmpty()) {
|
||||
if (!planners.contains(cmd.getDeploymentPlanner())) {
|
||||
throw new InvalidParameterValueException(
|
||||
"Invalid name for Deployment Planner specified, please use listDeploymentPlanners to get the valid set");
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterValueException("No deployment planners found");
|
||||
}
|
||||
}
|
||||
|
||||
return createServiceOffering(userId, cmd.getIsSystem(), vmType, cmd.getServiceOfferingName(), cpuNumber.intValue(), memory.intValue(), cpuSpeed.intValue(), cmd.getDisplayText(),
|
||||
localStorageRequired, offerHA, limitCpuUse, volatileVm, cmd.getTags(), cmd.getDomainId(), cmd.getHostTag(), cmd.getNetworkRate());
|
||||
localStorageRequired, offerHA, limitCpuUse, volatileVm, cmd.getTags(), cmd.getDomainId(), cmd.getHostTag(), cmd.getNetworkRate(), cmd.getDeploymentPlanner());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_SERVICE_OFFERING_CREATE, eventDescription = "creating service offering")
|
||||
public ServiceOfferingVO createServiceOffering(long userId, boolean isSystem, VirtualMachine.Type vm_type, String name, int cpu, int ramSize, int speed, String displayText,
|
||||
boolean localStorageRequired, boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate) {
|
||||
boolean localStorageRequired, boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner) {
|
||||
tags = cleanupTags(tags);
|
||||
ServiceOfferingVO offering = new ServiceOfferingVO(name, cpu, ramSize, speed, networkRate, null, offerHA, limitResourceUse, volatileVm, displayText, localStorageRequired, false, tags, isSystem, vm_type,
|
||||
domainId, hostTag);
|
||||
domainId, hostTag, deploymentPlanner);
|
||||
|
||||
if ((offering = _serviceOfferingDao.persist(offering)) != null) {
|
||||
UserContext.current().setEventDetails("Service offering id=" + offering.getId());
|
||||
@ -2490,7 +2506,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
if ( vlans != null && vlans.size() > 0 ) {
|
||||
if ( vlanId == null ) {
|
||||
vlanId = vlan.getVlanTag();
|
||||
} else if ( vlan.getVlanTag() != vlanId ) {
|
||||
} else if (!vlan.getVlanTag().equals(vlanId)) {
|
||||
throw new InvalidParameterValueException("there is already one vlan " + vlan.getVlanTag() + " on network :" +
|
||||
+ network.getId() + ", only one vlan is allowed on guest network");
|
||||
}
|
||||
@ -2656,6 +2672,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
if (uri != null) {
|
||||
String[] vlan = uri.toString().split("vlan:\\/\\/");
|
||||
networkVlanId = vlan[1];
|
||||
//For pvlan
|
||||
networkVlanId = networkVlanId.split("-")[0];
|
||||
}
|
||||
|
||||
if (vlanId != null) {
|
||||
|
||||
@ -57,7 +57,7 @@ AgentBasedConsoleProxyManager {
|
||||
if (allocatedHost == null) {
|
||||
/*Is there a consoleproxy agent running in the same pod?*/
|
||||
for (HostVO hv : hosts) {
|
||||
if (hv.getType() == Host.Type.ConsoleProxy && hv.getPodId() == host.getPodId()) {
|
||||
if (hv.getType() == Host.Type.ConsoleProxy && hv.getPodId().equals(host.getPodId())) {
|
||||
allocatedHost = hv;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1,84 +0,0 @@
|
||||
// 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.deploy;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
|
||||
public abstract class AbstractDeployPlannerSelector extends AdapterBase implements DeployPlannerSelector {
|
||||
protected Map<String, Object> params;
|
||||
protected String name;
|
||||
protected int runLevel;
|
||||
|
||||
@Inject
|
||||
protected ConfigurationDao _configDao;
|
||||
protected String _allocationAlgorithm = "random";
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfigParams(Map<String, Object> params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getConfigParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRunLevel() {
|
||||
return runLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRunLevel(int level) {
|
||||
this.runLevel = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
_allocationAlgorithm = _configDao.getValue(Config.VmAllocationAlgorithm.key());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -49,6 +49,7 @@ import com.cloud.dc.Pod;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.exception.InsufficientServerCapacityException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
@ -81,7 +82,7 @@ import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@Local(value=DeploymentPlanner.class)
|
||||
public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
public class FirstFitPlanner extends PlannerBase implements DeploymentClusterPlanner {
|
||||
private static final Logger s_logger = Logger.getLogger(FirstFitPlanner.class);
|
||||
@Inject protected HostDao _hostDao;
|
||||
@Inject protected DataCenterDao _dcDao;
|
||||
@ -103,28 +104,13 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
@Inject DataStoreManager dataStoreMgr;
|
||||
@Inject protected ClusterDetailsDao _clusterDetailsDao;
|
||||
|
||||
protected List<StoragePoolAllocator> _storagePoolAllocators;
|
||||
public List<StoragePoolAllocator> getStoragePoolAllocators() {
|
||||
return _storagePoolAllocators;
|
||||
}
|
||||
public void setStoragePoolAllocators(
|
||||
List<StoragePoolAllocator> _storagePoolAllocators) {
|
||||
this._storagePoolAllocators = _storagePoolAllocators;
|
||||
}
|
||||
|
||||
protected List<HostAllocator> _hostAllocators;
|
||||
public List<HostAllocator> getHostAllocators() {
|
||||
return _hostAllocators;
|
||||
}
|
||||
public void setHostAllocators(List<HostAllocator> _hostAllocators) {
|
||||
this._hostAllocators = _hostAllocators;
|
||||
}
|
||||
|
||||
protected String _allocationAlgorithm = "random";
|
||||
protected String _globalDeploymentPlanner = "FirstFitPlanner";
|
||||
|
||||
|
||||
@Override
|
||||
public DeployDestination plan(VirtualMachineProfile<? extends VirtualMachine> vmProfile,
|
||||
public List<Long> orderClusters(VirtualMachineProfile<? extends VirtualMachine> vmProfile,
|
||||
DeploymentPlan plan, ExcludeList avoid)
|
||||
throws InsufficientServerCapacityException {
|
||||
VirtualMachine vm = vmProfile.getVirtualMachine();
|
||||
@ -138,136 +124,19 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
return null;
|
||||
}
|
||||
|
||||
ServiceOffering offering = vmProfile.getServiceOffering();
|
||||
int cpu_requested = offering.getCpu() * offering.getSpeed();
|
||||
long ram_requested = offering.getRamSize() * 1024L * 1024L;
|
||||
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("DeploymentPlanner allocation algorithm: "+_allocationAlgorithm);
|
||||
|
||||
s_logger.debug("Trying to allocate a host and storage pools from dc:" + plan.getDataCenterId() + ", pod:" + plan.getPodId() + ",cluster:" + plan.getClusterId() +
|
||||
", requested cpu: " + cpu_requested + ", requested ram: " + ram_requested);
|
||||
|
||||
s_logger.debug("Is ROOT volume READY (pool already allocated)?: " + (plan.getPoolId()!=null ? "Yes": "No"));
|
||||
}
|
||||
|
||||
String haVmTag = (String)vmProfile.getParameter(VirtualMachineProfile.Param.HaTag);
|
||||
|
||||
if(plan.getHostId() != null && haVmTag == null){
|
||||
Long hostIdSpecified = plan.getHostId();
|
||||
if (s_logger.isDebugEnabled()){
|
||||
s_logger.debug("DeploymentPlan has host_id specified, choosing this host and making no checks on this host: "
|
||||
+ hostIdSpecified);
|
||||
}
|
||||
HostVO host = _hostDao.findById(hostIdSpecified);
|
||||
if (host == null) {
|
||||
s_logger.debug("The specified host cannot be found");
|
||||
} else if (avoid.shouldAvoid(host)) {
|
||||
s_logger.debug("The specified host is in avoid set");
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Looking for suitable pools for this host under zone: "+host.getDataCenterId() +", pod: "+ host.getPodId()+", cluster: "+ host.getClusterId());
|
||||
}
|
||||
|
||||
// search for storage under the zone, pod, cluster of the host.
|
||||
DataCenterDeployment lastPlan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(),
|
||||
host.getClusterId(), hostIdSpecified, plan.getPoolId(), null, plan.getReservationContext());
|
||||
|
||||
Pair<Map<Volume, List<StoragePool>>, List<Volume>> result = findSuitablePoolsForVolumes(vmProfile,
|
||||
lastPlan, avoid, HostAllocator.RETURN_UPTO_ALL);
|
||||
Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
|
||||
List<Volume> readyAndReusedVolumes = result.second();
|
||||
|
||||
// choose the potential pool for this VM for this host
|
||||
if (!suitableVolumeStoragePools.isEmpty()) {
|
||||
List<Host> suitableHosts = new ArrayList<Host>();
|
||||
suitableHosts.add(host);
|
||||
|
||||
Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(
|
||||
suitableHosts, suitableVolumeStoragePools);
|
||||
if (potentialResources != null) {
|
||||
Pod pod = _podDao.findById(host.getPodId());
|
||||
Cluster cluster = _clusterDao.findById(host.getClusterId());
|
||||
Map<Volume, StoragePool> storageVolMap = potentialResources.second();
|
||||
// remove the reused vol<->pool from 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);
|
||||
s_logger.debug("Returning Deployment Destination: " + dest);
|
||||
return dest;
|
||||
}
|
||||
}
|
||||
}
|
||||
s_logger.debug("Cannnot deploy to specified host, returning.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (vm.getLastHostId() != null && haVmTag == null) {
|
||||
s_logger.debug("This VM has last host_id specified, trying to choose the same host: " +vm.getLastHostId());
|
||||
|
||||
HostVO host = _hostDao.findById(vm.getLastHostId());
|
||||
if(host == null){
|
||||
s_logger.debug("The last host of this VM cannot be found");
|
||||
}else if(avoid.shouldAvoid(host)){
|
||||
s_logger.debug("The last host of this VM is in avoid set");
|
||||
}else if(_capacityMgr.checkIfHostReachMaxGuestLimit(host)){
|
||||
s_logger.debug("The last Host, hostId: "+ host.getId() +" 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) {
|
||||
long cluster_id = host.getClusterId();
|
||||
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)){
|
||||
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 the last host.
|
||||
DataCenterDeployment lastPlan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId(), null);
|
||||
Pair<Map<Volume, List<StoragePool>>, List<Volume>> result = findSuitablePoolsForVolumes(vmProfile, lastPlan, avoid, HostAllocator.RETURN_UPTO_ALL);
|
||||
Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
|
||||
List<Volume> readyAndReusedVolumes = result.second();
|
||||
//choose the potential pool for this VM for this host
|
||||
if(!suitableVolumeStoragePools.isEmpty()){
|
||||
List<Host> suitableHosts = new ArrayList<Host>();
|
||||
suitableHosts.add(host);
|
||||
|
||||
Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(suitableHosts, suitableVolumeStoragePools);
|
||||
if(potentialResources != null){
|
||||
Pod pod = _podDao.findById(host.getPodId());
|
||||
Cluster cluster = _clusterDao.findById(host.getClusterId());
|
||||
Map<Volume, StoragePool> storageVolMap = potentialResources.second();
|
||||
// remove the reused vol<->pool from 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);
|
||||
s_logger.debug("Returning Deployment Destination: "+ dest);
|
||||
return dest;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
s_logger.debug("The last host of this VM does not have enough capacity");
|
||||
}
|
||||
}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());
|
||||
}
|
||||
}
|
||||
s_logger.debug("Cannot choose the last host to deploy this VM ");
|
||||
}
|
||||
|
||||
|
||||
List<Long> clusterList = new ArrayList<Long>();
|
||||
if (plan.getClusterId() != null) {
|
||||
Long clusterIdSpecified = plan.getClusterId();
|
||||
s_logger.debug("Searching resources only under specified Cluster: "+ clusterIdSpecified);
|
||||
ClusterVO cluster = _clusterDao.findById(plan.getClusterId());
|
||||
if (cluster != null ){
|
||||
if (avoid.shouldAvoid(cluster)) {
|
||||
s_logger.debug("The specified cluster is in avoid set, returning.");
|
||||
} else {
|
||||
clusterList.add(clusterIdSpecified);
|
||||
return checkClustersforDestination(clusterList, vmProfile, plan, avoid, dc);
|
||||
removeClustersCrossingThreshold(clusterList, avoid, vmProfile, plan);
|
||||
}
|
||||
return clusterList;
|
||||
}else{
|
||||
s_logger.debug("The specified cluster cannot be found, returning.");
|
||||
avoid.addCluster(plan.getClusterId());
|
||||
@ -280,11 +149,15 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
|
||||
HostPodVO pod = _podDao.findById(podIdSpecified);
|
||||
if (pod != null) {
|
||||
DeployDestination dest = scanClustersForDestinationInZoneOrPod(podIdSpecified, false, vmProfile, plan, avoid);
|
||||
if(dest == null){
|
||||
if (avoid.shouldAvoid(pod)) {
|
||||
s_logger.debug("The specified pod is in avoid set, returning.");
|
||||
} else {
|
||||
clusterList = scanClustersForDestinationInZoneOrPod(podIdSpecified, false, vmProfile, plan, avoid);
|
||||
if (clusterList == null) {
|
||||
avoid.addPod(plan.getPodId());
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
return clusterList;
|
||||
} else {
|
||||
s_logger.debug("The specified Pod cannot be found, returning.");
|
||||
avoid.addPod(plan.getPodId());
|
||||
@ -305,7 +178,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
|
||||
}
|
||||
|
||||
private DeployDestination scanPodsForDestination(VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid){
|
||||
private List<Long> scanPodsForDestination(VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid){
|
||||
|
||||
ServiceOffering offering = vmProfile.getServiceOffering();
|
||||
int requiredCpu = offering.getCpu() * offering.getSpeed();
|
||||
@ -341,20 +214,24 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
if(!podsWithCapacity.isEmpty()){
|
||||
|
||||
prioritizedPodIds = reorderPods(podCapacityInfo, vmProfile, plan);
|
||||
|
||||
//loop over pods
|
||||
for(Long podId : prioritizedPodIds){
|
||||
s_logger.debug("Checking resources under Pod: "+podId);
|
||||
DeployDestination dest = scanClustersForDestinationInZoneOrPod(podId, false, vmProfile, plan, avoid);
|
||||
if(dest != null){
|
||||
return dest;
|
||||
}
|
||||
avoid.addPod(podId);
|
||||
}
|
||||
if (prioritizedPodIds == null || prioritizedPodIds.isEmpty()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("No Pods found for destination, returning.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Long> clusterList = new ArrayList<Long>();
|
||||
//loop over pods
|
||||
for(Long podId : prioritizedPodIds){
|
||||
s_logger.debug("Checking resources under Pod: "+podId);
|
||||
List<Long> clustersUnderPod = scanClustersForDestinationInZoneOrPod(podId, false, vmProfile, plan,
|
||||
avoid);
|
||||
if (clustersUnderPod != null) {
|
||||
clusterList.addAll(clustersUnderPod);
|
||||
}
|
||||
}
|
||||
return clusterList;
|
||||
}else{
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("No Pods found after removing disabled pods and pods in avoid list, returning.");
|
||||
@ -363,7 +240,69 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
}
|
||||
}
|
||||
|
||||
private DeployDestination scanClustersForDestinationInZoneOrPod(long id, boolean isZone, VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid){
|
||||
private Map<Short, Float> getCapacityThresholdMap() {
|
||||
// Lets build this real time so that the admin wont have to restart MS
|
||||
// if he changes these values
|
||||
Map<Short, Float> disableThresholdMap = new HashMap<Short, Float>();
|
||||
|
||||
String cpuDisableThresholdString = _configDao.getValue(Config.CPUCapacityDisableThreshold.key());
|
||||
float cpuDisableThreshold = NumbersUtil.parseFloat(cpuDisableThresholdString, 0.85F);
|
||||
disableThresholdMap.put(Capacity.CAPACITY_TYPE_CPU, cpuDisableThreshold);
|
||||
|
||||
String memoryDisableThresholdString = _configDao.getValue(Config.MemoryCapacityDisableThreshold.key());
|
||||
float memoryDisableThreshold = NumbersUtil.parseFloat(memoryDisableThresholdString, 0.85F);
|
||||
disableThresholdMap.put(Capacity.CAPACITY_TYPE_MEMORY, memoryDisableThreshold);
|
||||
|
||||
return disableThresholdMap;
|
||||
}
|
||||
|
||||
private List<Short> getCapacitiesForCheckingThreshold() {
|
||||
List<Short> capacityList = new ArrayList<Short>();
|
||||
capacityList.add(Capacity.CAPACITY_TYPE_CPU);
|
||||
capacityList.add(Capacity.CAPACITY_TYPE_MEMORY);
|
||||
return capacityList;
|
||||
}
|
||||
|
||||
private void removeClustersCrossingThreshold(List<Long> clusterListForVmAllocation, ExcludeList avoid,
|
||||
VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan) {
|
||||
|
||||
List<Short> capacityList = getCapacitiesForCheckingThreshold();
|
||||
List<Long> clustersCrossingThreshold = new ArrayList<Long>();
|
||||
|
||||
ServiceOffering offering = vmProfile.getServiceOffering();
|
||||
int cpu_requested = offering.getCpu() * offering.getSpeed();
|
||||
long ram_requested = offering.getRamSize() * 1024L * 1024L;
|
||||
|
||||
// For each capacity get the cluster list crossing the threshold and
|
||||
// remove it from the clusterList that will be used for vm allocation.
|
||||
for (short capacity : capacityList) {
|
||||
|
||||
if (clusterListForVmAllocation == null || clusterListForVmAllocation.size() == 0) {
|
||||
return;
|
||||
}
|
||||
if (capacity == Capacity.CAPACITY_TYPE_CPU) {
|
||||
clustersCrossingThreshold = _capacityDao.listClustersCrossingThreshold(capacity,
|
||||
plan.getDataCenterId(), Config.CPUCapacityDisableThreshold.key(), cpu_requested);
|
||||
} else if (capacity == Capacity.CAPACITY_TYPE_MEMORY) {
|
||||
clustersCrossingThreshold = _capacityDao.listClustersCrossingThreshold(capacity,
|
||||
plan.getDataCenterId(), Config.MemoryCapacityDisableThreshold.key(), ram_requested);
|
||||
}
|
||||
|
||||
if (clustersCrossingThreshold != null && clustersCrossingThreshold.size() != 0) {
|
||||
// addToAvoid Set
|
||||
avoid.addClusterList(clustersCrossingThreshold);
|
||||
// Remove clusters crossing disabled threshold
|
||||
clusterListForVmAllocation.removeAll(clustersCrossingThreshold);
|
||||
|
||||
s_logger.debug("Cannot allocate cluster list " + clustersCrossingThreshold.toString() + " for vm creation since their allocated percentage" +
|
||||
" crosses the disable capacity threshold defined at each cluster/ at global value for capacity Type : " + capacity + ", skipping these clusters");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private List<Long> scanClustersForDestinationInZoneOrPod(long id, boolean isZone,
|
||||
VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid) {
|
||||
|
||||
VirtualMachine vm = vmProfile.getVirtualMachine();
|
||||
ServiceOffering offering = vmProfile.getServiceOffering();
|
||||
@ -396,6 +335,9 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
prioritizedClusterIds.removeAll(disabledClusters);
|
||||
}
|
||||
}
|
||||
|
||||
removeClustersCrossingThreshold(prioritizedClusterIds, avoid, vmProfile, plan);
|
||||
|
||||
}else{
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("No clusters found having a host with enough capacity, returning.");
|
||||
@ -404,7 +346,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
}
|
||||
if(!prioritizedClusterIds.isEmpty()){
|
||||
List<Long> clusterList = reorderClusters(id, isZone, clusterCapacityInfo, vmProfile, plan);
|
||||
return checkClustersforDestination(clusterList, vmProfile, plan, avoid, dc);
|
||||
return clusterList; //return checkClustersforDestination(clusterList, vmProfile, plan, avoid, dc);
|
||||
}else{
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("No clusters found after removing disabled clusters and clusters in avoid list, returning.");
|
||||
@ -452,114 +394,6 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
return disabledPods;
|
||||
}
|
||||
|
||||
private List<Short> getCapacitiesForCheckingThreshold(){
|
||||
List<Short> capacityList = new ArrayList<Short>();
|
||||
capacityList.add(Capacity.CAPACITY_TYPE_CPU);
|
||||
capacityList.add(Capacity.CAPACITY_TYPE_MEMORY);
|
||||
return capacityList;
|
||||
}
|
||||
|
||||
private void removeClustersCrossingThreshold(List<Long> clusterListForVmAllocation, ExcludeList avoid, VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan){
|
||||
|
||||
List<Short> capacityList = getCapacitiesForCheckingThreshold();
|
||||
List<Long> clustersCrossingThreshold = new ArrayList<Long>();
|
||||
|
||||
ServiceOffering offering = vmProfile.getServiceOffering();
|
||||
int cpu_requested = offering.getCpu() * offering.getSpeed();
|
||||
long ram_requested = offering.getRamSize() * 1024L * 1024L;
|
||||
|
||||
// For each capacity get the cluster list crossing the threshold and remove it from the clusterList that will be used for vm allocation.
|
||||
for(short capacity : capacityList){
|
||||
|
||||
if (clusterListForVmAllocation == null || clusterListForVmAllocation.size() == 0){
|
||||
return;
|
||||
}
|
||||
if (capacity == Capacity.CAPACITY_TYPE_CPU) {
|
||||
clustersCrossingThreshold = _capacityDao.listClustersCrossingThreshold(capacity, plan.getDataCenterId(), Config.CPUCapacityDisableThreshold.key(), cpu_requested);
|
||||
}
|
||||
else if (capacity == Capacity.CAPACITY_TYPE_MEMORY ) {
|
||||
clustersCrossingThreshold = _capacityDao.listClustersCrossingThreshold(capacity, plan.getDataCenterId(),
|
||||
Config.MemoryCapacityDisableThreshold.key(), ram_requested );
|
||||
}
|
||||
|
||||
|
||||
if (clustersCrossingThreshold != null && clustersCrossingThreshold.size() != 0){
|
||||
// addToAvoid Set
|
||||
avoid.addClusterList(clustersCrossingThreshold);
|
||||
// Remove clusters crossing disabled threshold
|
||||
clusterListForVmAllocation.removeAll(clustersCrossingThreshold);
|
||||
|
||||
s_logger.debug("Cannot allocate cluster list " + clustersCrossingThreshold.toString() + " for vm creation since their allocated percentage" +
|
||||
" crosses the disable capacity threshold defined at each cluster/ at global value for capacity Type : " + capacity + ", skipping these clusters");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private DeployDestination checkClustersforDestination(List<Long> clusterList, VirtualMachineProfile<? extends VirtualMachine> vmProfile,
|
||||
DeploymentPlan plan, ExcludeList avoid, DataCenter dc){
|
||||
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("ClusterId List to consider: " + clusterList);
|
||||
}
|
||||
|
||||
removeClustersCrossingThreshold(clusterList, avoid, vmProfile, plan);
|
||||
|
||||
for(Long clusterId : clusterList){
|
||||
Cluster clusterVO = _clusterDao.findById(clusterId);
|
||||
|
||||
if (clusterVO.getHypervisorType() != vmProfile.getHypervisorType()) {
|
||||
s_logger.debug("Cluster: "+clusterId + " has HyperVisorType that does not match the VM, skipping this cluster");
|
||||
avoid.addCluster(clusterVO.getId());
|
||||
continue;
|
||||
}
|
||||
|
||||
s_logger.debug("Checking resources in Cluster: "+clusterId + " under Pod: "+clusterVO.getPodId());
|
||||
//search for resources(hosts and storage) under this zone, pod, cluster.
|
||||
DataCenterDeployment potentialPlan = new DataCenterDeployment(plan.getDataCenterId(), clusterVO.getPodId(), clusterVO.getId(), null, plan.getPoolId(), null, plan.getReservationContext());
|
||||
|
||||
//find suitable hosts under this cluster, need as many hosts as we get.
|
||||
List<Host> suitableHosts = findSuitableHosts(vmProfile, potentialPlan, avoid, HostAllocator.RETURN_UPTO_ALL);
|
||||
//if found suitable hosts in this cluster, find suitable storage pools for each volume of the VM
|
||||
if(suitableHosts != null && !suitableHosts.isEmpty()){
|
||||
if (vmProfile.getHypervisorType() == HypervisorType.BareMetal) {
|
||||
Pod pod = _podDao.findById(clusterVO.getPodId());
|
||||
DeployDestination dest = new DeployDestination(dc, pod, clusterVO, suitableHosts.get(0));
|
||||
return dest;
|
||||
}
|
||||
|
||||
Pair<Map<Volume, List<StoragePool>>, List<Volume>> result = findSuitablePoolsForVolumes(vmProfile, potentialPlan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL);
|
||||
Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
|
||||
List<Volume> readyAndReusedVolumes = result.second();
|
||||
|
||||
//choose the potential host and pool for the VM
|
||||
if(!suitableVolumeStoragePools.isEmpty()){
|
||||
Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(suitableHosts, suitableVolumeStoragePools);
|
||||
|
||||
if(potentialResources != null){
|
||||
Pod pod = _podDao.findById(clusterVO.getPodId());
|
||||
Host host = _hostDao.findById(potentialResources.first().getId());
|
||||
Map<Volume, StoragePool> storageVolMap = potentialResources.second();
|
||||
// remove the reused vol<->pool from destination, since we don't have to prepare this volume.
|
||||
for(Volume vol : readyAndReusedVolumes){
|
||||
storageVolMap.remove(vol);
|
||||
}
|
||||
DeployDestination dest = new DeployDestination(dc, pod, clusterVO, host, storageVolMap );
|
||||
s_logger.debug("Returning Deployment Destination: "+ dest);
|
||||
return dest;
|
||||
}
|
||||
}else{
|
||||
s_logger.debug("No suitable storagePools found under this Cluster: "+clusterId);
|
||||
}
|
||||
}else{
|
||||
s_logger.debug("No suitable hosts found under this Cluster: "+clusterId);
|
||||
}
|
||||
avoid.addCluster(clusterVO.getId());
|
||||
}
|
||||
s_logger.debug("Could not find suitable Deployment Destination for this VM under any clusters, returning. ");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected Pair<List<Long>, Map<Long, Double>> listClustersByCapacity(long id, int requiredCpu, long requiredRam, ExcludeList avoid, boolean isZone){
|
||||
//look at the aggregate available cpu and ram per cluster
|
||||
@ -630,215 +464,6 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected Pair<Host, Map<Volume, StoragePool>> findPotentialDeploymentResources(List<Host> suitableHosts, Map<Volume, List<StoragePool>> suitableVolumeStoragePools){
|
||||
s_logger.debug("Trying to find a potenial host and associated storage pools from the suitable host/pool lists for this VM");
|
||||
|
||||
boolean hostCanAccessPool = false;
|
||||
boolean haveEnoughSpace = false;
|
||||
Map<Volume, StoragePool> storage = new HashMap<Volume, StoragePool>();
|
||||
TreeSet<Volume> volumesOrderBySizeDesc = new TreeSet<Volume>(new Comparator<Volume>() {
|
||||
@Override
|
||||
public int compare(Volume v1, Volume v2) {
|
||||
if(v1.getSize() < v2.getSize())
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
volumesOrderBySizeDesc.addAll(suitableVolumeStoragePools.keySet());
|
||||
boolean multipleVolume = volumesOrderBySizeDesc.size() > 1;
|
||||
for(Host potentialHost : suitableHosts){
|
||||
Map<StoragePool,List<Volume>> volumeAllocationMap = new HashMap<StoragePool,List<Volume>>();
|
||||
for(Volume vol : volumesOrderBySizeDesc){
|
||||
haveEnoughSpace = false;
|
||||
s_logger.debug("Checking if host: "+potentialHost.getId() +" can access any suitable storage pool for volume: "+ vol.getVolumeType());
|
||||
List<StoragePool> volumePoolList = suitableVolumeStoragePools.get(vol);
|
||||
hostCanAccessPool = false;
|
||||
for(StoragePool potentialSPool : volumePoolList){
|
||||
if(hostCanAccessSPool(potentialHost, potentialSPool)){
|
||||
hostCanAccessPool = true;
|
||||
if(multipleVolume){
|
||||
List<Volume> requestVolumes = null;
|
||||
if(volumeAllocationMap.containsKey(potentialSPool))
|
||||
requestVolumes = volumeAllocationMap.get(potentialSPool);
|
||||
else
|
||||
requestVolumes = new ArrayList<Volume>();
|
||||
requestVolumes.add(vol);
|
||||
|
||||
if(!_storageMgr.storagePoolHasEnoughSpace(requestVolumes, potentialSPool))
|
||||
continue;
|
||||
volumeAllocationMap.put(potentialSPool,requestVolumes);
|
||||
}
|
||||
storage.put(vol, potentialSPool);
|
||||
haveEnoughSpace = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!hostCanAccessPool){
|
||||
break;
|
||||
}
|
||||
if(!haveEnoughSpace) {
|
||||
s_logger.warn("insufficient capacity to allocate all volumes");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(hostCanAccessPool && haveEnoughSpace){
|
||||
s_logger.debug("Found a potential host " + "id: "+potentialHost.getId() + " name: " +potentialHost.getName() + " and associated storage pools for this VM");
|
||||
return new Pair<Host, Map<Volume, StoragePool>>(potentialHost, storage);
|
||||
}
|
||||
}
|
||||
s_logger.debug("Could not find a potential host that has associated storage pools from the suitable host/pool lists for this VM");
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean hostCanAccessSPool(Host host, StoragePool pool){
|
||||
boolean hostCanAccessSPool = false;
|
||||
|
||||
StoragePoolHostVO hostPoolLinkage = _poolHostDao.findByPoolHost(pool.getId(), host.getId());
|
||||
if(hostPoolLinkage != null){
|
||||
hostCanAccessSPool = true;
|
||||
}
|
||||
|
||||
s_logger.debug("Host: "+ host.getId() + (hostCanAccessSPool ?" can" : " cannot") + " access pool: "+ pool.getId());
|
||||
return hostCanAccessSPool;
|
||||
}
|
||||
|
||||
protected List<Host> findSuitableHosts(VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo){
|
||||
List<Host> suitableHosts = new ArrayList<Host>();
|
||||
for(HostAllocator allocator : _hostAllocators) {
|
||||
suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, avoid, returnUpTo);
|
||||
if (suitableHosts != null && !suitableHosts.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(suitableHosts.isEmpty()){
|
||||
s_logger.debug("No suitable hosts found");
|
||||
}
|
||||
return suitableHosts;
|
||||
}
|
||||
|
||||
protected Pair<Map<Volume, List<StoragePool>>, List<Volume>> findSuitablePoolsForVolumes(VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo){
|
||||
List<VolumeVO> volumesTobeCreated = _volsDao.findUsableVolumesForInstance(vmProfile.getId());
|
||||
Map<Volume, List<StoragePool>> suitableVolumeStoragePools = new HashMap<Volume, List<StoragePool>>();
|
||||
List<Volume> readyAndReusedVolumes = new ArrayList<Volume>();
|
||||
|
||||
//for each volume find list of suitable storage pools by calling the allocators
|
||||
for (VolumeVO toBeCreated : volumesTobeCreated) {
|
||||
s_logger.debug("Checking suitable pools for volume (Id, Type): ("+toBeCreated.getId() +"," +toBeCreated.getVolumeType().name() + ")");
|
||||
|
||||
//If the plan specifies a poolId, it means that this VM's ROOT volume is ready and the pool should be reused.
|
||||
//In this case, also check if rest of the volumes are ready and can be reused.
|
||||
if(plan.getPoolId() != null){
|
||||
s_logger.debug("Volume has pool(" + plan.getPoolId() + ") already allocated, checking if pool can be reused, poolId: "+toBeCreated.getPoolId());
|
||||
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
|
||||
StoragePool pool = null;
|
||||
if(toBeCreated.getPoolId() != null){
|
||||
s_logger.debug("finding pool by id '" + toBeCreated.getPoolId() + "'");
|
||||
pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(toBeCreated.getPoolId());
|
||||
}else{
|
||||
s_logger.debug("finding pool by id '" + plan.getPoolId() + "'");
|
||||
pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(plan.getPoolId());
|
||||
}
|
||||
|
||||
if(pool != null){
|
||||
if(!pool.isInMaintenance()){
|
||||
if(!avoid.shouldAvoid(pool)){
|
||||
long exstPoolDcId = pool.getDataCenterId();
|
||||
|
||||
long exstPoolPodId = pool.getPodId() != null ? pool.getPodId() : -1;
|
||||
long exstPoolClusterId = pool.getClusterId() != null ? pool.getClusterId() : -1;
|
||||
if(plan.getDataCenterId() == exstPoolDcId && plan.getPodId() == exstPoolPodId && plan.getClusterId() == exstPoolClusterId){
|
||||
s_logger.debug("Planner need not allocate a pool for this volume since its READY");
|
||||
suitablePools.add(pool);
|
||||
suitableVolumeStoragePools.put(toBeCreated, suitablePools);
|
||||
if (!(toBeCreated.getState() == Volume.State.Allocated || toBeCreated.getState() == Volume.State.Creating)) {
|
||||
readyAndReusedVolumes.add(toBeCreated);
|
||||
}
|
||||
continue;
|
||||
}else{
|
||||
s_logger.debug("Pool of the volume does not fit the specified plan, need to reallocate a pool for this volume");
|
||||
}
|
||||
}else{
|
||||
s_logger.debug("Pool of the volume is in avoid set, need to reallocate a pool for this volume");
|
||||
}
|
||||
}else{
|
||||
s_logger.debug("Pool of the volume is in maintenance, need to reallocate a pool for this volume");
|
||||
}
|
||||
}else{
|
||||
s_logger.debug("Unable to find pool by provided id");
|
||||
}
|
||||
}
|
||||
|
||||
if(s_logger.isDebugEnabled()){
|
||||
s_logger.debug("We need to allocate new storagepool for this volume");
|
||||
}
|
||||
if(!isRootAdmin(plan.getReservationContext())){
|
||||
if(!isEnabledForAllocation(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId())){
|
||||
if(s_logger.isDebugEnabled()){
|
||||
s_logger.debug("Cannot allocate new storagepool for this volume in this cluster, allocation state is disabled");
|
||||
s_logger.debug("Cannot deploy to this specified plan, allocation state is disabled, returning.");
|
||||
}
|
||||
//Cannot find suitable storage pools under this cluster for this volume since allocation_state is disabled.
|
||||
//- remove any suitable pools found for other volumes.
|
||||
//All volumes should get suitable pools under this cluster; else we cant use this cluster.
|
||||
suitableVolumeStoragePools.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
s_logger.debug("Calling StoragePoolAllocators to find suitable pools");
|
||||
|
||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId());
|
||||
DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType());
|
||||
|
||||
boolean useLocalStorage = false;
|
||||
if (vmProfile.getType() != VirtualMachine.Type.User) {
|
||||
String ssvmUseLocalStorage = _configDao.getValue(Config.SystemVMUseLocalStorage.key());
|
||||
if (ssvmUseLocalStorage.equalsIgnoreCase("true")) {
|
||||
useLocalStorage = true;
|
||||
}
|
||||
} else {
|
||||
useLocalStorage = diskOffering.getUseLocalStorage();
|
||||
|
||||
// TODO: this is a hacking fix for the problem of deploy ISO-based VM on local storage
|
||||
// when deploying VM based on ISO, we have a service offering and an additional disk offering, use-local storage flag is actually
|
||||
// saved in service offering, overrde the flag from service offering when it is a ROOT disk
|
||||
if(!useLocalStorage && vmProfile.getServiceOffering().getUseLocalStorage()) {
|
||||
if(toBeCreated.getVolumeType() == Volume.Type.ROOT)
|
||||
useLocalStorage = true;
|
||||
}
|
||||
}
|
||||
diskProfile.setUseLocalStorage(useLocalStorage);
|
||||
|
||||
boolean foundPotentialPools = false;
|
||||
for(StoragePoolAllocator allocator : _storagePoolAllocators) {
|
||||
final List<StoragePool> suitablePools = allocator.allocateToPool(diskProfile, vmProfile, plan, avoid, returnUpTo);
|
||||
if (suitablePools != null && !suitablePools.isEmpty()) {
|
||||
suitableVolumeStoragePools.put(toBeCreated, suitablePools);
|
||||
foundPotentialPools = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!foundPotentialPools){
|
||||
s_logger.debug("No suitable pools found for volume: "+toBeCreated +" under cluster: "+plan.getClusterId());
|
||||
//No suitable storage pools found under this cluster for this volume. - remove any suitable pools found for other volumes.
|
||||
//All volumes should get suitable pools under this cluster; else we cant use this cluster.
|
||||
suitableVolumeStoragePools.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(suitableVolumeStoragePools.isEmpty()){
|
||||
s_logger.debug("No suitable pools found");
|
||||
}
|
||||
|
||||
return new Pair<Map<Volume, List<StoragePool>>, List<Volume>>(suitableVolumeStoragePools, readyAndReusedVolumes);
|
||||
}
|
||||
|
||||
|
||||
private boolean isRootAdmin(ReservationContext reservationContext) {
|
||||
if(reservationContext != null){
|
||||
if(reservationContext.getAccount() != null){
|
||||
@ -859,11 +484,18 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
|
||||
@Override
|
||||
public boolean canHandle(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid) {
|
||||
// check what the ServiceOffering says. If null, check the global config
|
||||
ServiceOffering offering = vm.getServiceOffering();
|
||||
if (vm.getHypervisorType() != HypervisorType.BareMetal) {
|
||||
//check the allocation strategy
|
||||
if (_allocationAlgorithm != null && (_allocationAlgorithm.equals(AllocationAlgorithm.random.toString()) || _allocationAlgorithm.equals(AllocationAlgorithm.firstfit.toString()))) {
|
||||
if (offering != null && offering.getDeploymentPlanner() != null) {
|
||||
if (offering.getDeploymentPlanner().equals(this.getName())) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (_globalDeploymentPlanner != null && _globalDeploymentPlanner.equals(this._name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -872,29 +504,20 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
_allocationAlgorithm = _configDao.getValue(Config.VmAllocationAlgorithm.key());
|
||||
_globalDeploymentPlanner = _configDao.getValue(Config.VmDeploymentPlanner.key());
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isEnabledForAllocation(long zoneId, Long podId, Long clusterId){
|
||||
// Check if the zone exists in the system
|
||||
DataCenterVO zone = _dcDao.findById(zoneId);
|
||||
if(zone != null && Grouping.AllocationState.Disabled == zone.getAllocationState()){
|
||||
s_logger.info("Zone is currently disabled, cannot allocate to this zone: "+ zoneId);
|
||||
return false;
|
||||
|
||||
@Override
|
||||
public DeployDestination plan(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan,
|
||||
ExcludeList avoid) throws InsufficientServerCapacityException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
Pod pod = _podDao.findById(podId);
|
||||
if(pod != null && Grouping.AllocationState.Disabled == pod.getAllocationState()){
|
||||
s_logger.info("Pod is currently disabled, cannot allocate to this pod: "+ podId);
|
||||
return false;
|
||||
}
|
||||
|
||||
Cluster cluster = _clusterDao.findById(clusterId);
|
||||
if(cluster != null && Grouping.AllocationState.Disabled == cluster.getAllocationState()){
|
||||
s_logger.info("Cluster is currently disabled, cannot allocate to this cluster: "+ clusterId);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@Override
|
||||
public PlannerResourceUsage getResourceUsage() {
|
||||
return PlannerResourceUsage.Shared;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
// 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.deploy;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.deploy.DeploymentPlanner.AllocationAlgorithm;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
|
||||
@Local(value = {DeployPlannerSelector.class})
|
||||
public class HypervisorVmPlannerSelector extends AbstractDeployPlannerSelector {
|
||||
private static final Logger s_logger = Logger.getLogger(HypervisorVmPlannerSelector.class);
|
||||
|
||||
@Override
|
||||
public String selectPlanner(UserVmVO vm) {
|
||||
if (vm.getHypervisorType() != HypervisorType.BareMetal) {
|
||||
//check the allocation strategy
|
||||
if (_allocationAlgorithm != null) {
|
||||
if (_allocationAlgorithm.equals(AllocationAlgorithm.random.toString())
|
||||
|| _allocationAlgorithm.equals(AllocationAlgorithm.firstfit.toString())) {
|
||||
return "FirstFitPlanner";
|
||||
} else if (_allocationAlgorithm.equals(AllocationAlgorithm.userdispersing.toString())) {
|
||||
return "UserDispersingPlanner";
|
||||
} else if (_allocationAlgorithm.equals(AllocationAlgorithm.userconcentratedpod_random.toString())
|
||||
|| _allocationAlgorithm.equals(AllocationAlgorithm.userconcentratedpod_firstfit.toString())) {
|
||||
return "UserConcentratedPodPlanner";
|
||||
}
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("The allocation algorithm is null, cannot select the planner");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
117
server/src/com/cloud/deploy/PlannerHostReservationVO.java
Normal file
117
server/src/com/cloud/deploy/PlannerHostReservationVO.java
Normal file
@ -0,0 +1,117 @@
|
||||
// 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.deploy;
|
||||
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import com.cloud.deploy.DeploymentPlanner.PlannerResourceUsage;
|
||||
|
||||
@Entity
|
||||
@Table(name = "op_host_planner_reservation")
|
||||
public class PlannerHostReservationVO implements InternalIdentity {
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||
@Column(name="id")
|
||||
private long id;
|
||||
|
||||
@Column(name="host_id")
|
||||
private Long hostId;
|
||||
|
||||
@Column(name="data_center_id")
|
||||
private Long dataCenterId;
|
||||
|
||||
@Column(name="pod_id")
|
||||
private Long podId;
|
||||
|
||||
@Column(name="cluster_id")
|
||||
private Long clusterId;
|
||||
|
||||
@Column(name = "resource_usage")
|
||||
@Enumerated(EnumType.STRING)
|
||||
private PlannerResourceUsage resourceUsage;
|
||||
|
||||
public PlannerHostReservationVO() {
|
||||
}
|
||||
|
||||
public PlannerHostReservationVO(Long hostId, Long dataCenterId, Long podId, Long clusterId) {
|
||||
this.hostId = hostId;
|
||||
this.dataCenterId = dataCenterId;
|
||||
this.podId = podId;
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public PlannerHostReservationVO(Long hostId, Long dataCenterId, Long podId, Long clusterId,
|
||||
PlannerResourceUsage resourceUsage) {
|
||||
this.hostId = hostId;
|
||||
this.dataCenterId = dataCenterId;
|
||||
this.podId = podId;
|
||||
this.clusterId = clusterId;
|
||||
this.resourceUsage = resourceUsage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long getHostId() {
|
||||
return hostId;
|
||||
}
|
||||
|
||||
public void setHostId(Long hostId) {
|
||||
this.hostId = hostId;
|
||||
}
|
||||
|
||||
public Long getDataCenterId() {
|
||||
return dataCenterId;
|
||||
}
|
||||
public void setDataCenterId(Long dataCenterId) {
|
||||
this.dataCenterId = dataCenterId;
|
||||
}
|
||||
|
||||
public Long getPodId() {
|
||||
return podId;
|
||||
}
|
||||
public void setPodId(long podId) {
|
||||
this.podId = new Long(podId);
|
||||
}
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
public void setClusterId(long clusterId) {
|
||||
this.clusterId = new Long(clusterId);
|
||||
}
|
||||
|
||||
public PlannerResourceUsage getResourceUsage() {
|
||||
return resourceUsage;
|
||||
}
|
||||
|
||||
public void setResourceUsage(PlannerResourceUsage resourceType) {
|
||||
this.resourceUsage = resourceType;
|
||||
}
|
||||
|
||||
}
|
||||
16
server/src/com/cloud/deploy/DeployPlannerSelector.java → server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java
Executable file → Normal file
16
server/src/com/cloud/deploy/DeployPlannerSelector.java → server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java
Executable file → Normal file
@ -14,11 +14,17 @@
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.deploy;
|
||||
package com.cloud.deploy.dao;
|
||||
|
||||
import com.cloud.utils.component.Adapter;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.deploy.PlannerHostReservationVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface PlannerHostReservationDao extends GenericDao<PlannerHostReservationVO, Long> {
|
||||
|
||||
PlannerHostReservationVO findByHostId(long hostId);
|
||||
|
||||
List<PlannerHostReservationVO> listAllReservedHosts();
|
||||
|
||||
public interface DeployPlannerSelector extends Adapter {
|
||||
String selectPlanner(UserVmVO vm);
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
// 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.deploy.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.ejb.Local;
|
||||
import com.cloud.deploy.PlannerHostReservationVO;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
||||
@Local(value = { PlannerHostReservationDao.class })
|
||||
public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostReservationVO, Long> implements
|
||||
PlannerHostReservationDao {
|
||||
|
||||
private SearchBuilder<PlannerHostReservationVO> _hostIdSearch;
|
||||
private SearchBuilder<PlannerHostReservationVO> _reservedHostSearch;
|
||||
|
||||
public PlannerHostReservationDaoImpl() {
|
||||
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
_hostIdSearch = createSearchBuilder();
|
||||
_hostIdSearch.and("hostId", _hostIdSearch.entity().getHostId(), SearchCriteria.Op.EQ);
|
||||
_hostIdSearch.done();
|
||||
|
||||
_reservedHostSearch = createSearchBuilder();
|
||||
_reservedHostSearch.and("usage", _reservedHostSearch.entity().getResourceUsage(), SearchCriteria.Op.NNULL);
|
||||
_reservedHostSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlannerHostReservationVO findByHostId(long hostId) {
|
||||
SearchCriteria<PlannerHostReservationVO> sc = _hostIdSearch.create();
|
||||
sc.setParameters("hostId", hostId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlannerHostReservationVO> listAllReservedHosts() {
|
||||
SearchCriteria<PlannerHostReservationVO> sc = _reservedHostSearch.create();
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
}
|
||||
@ -130,7 +130,8 @@ public interface NetworkManager {
|
||||
|
||||
Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr,
|
||||
String vlanId, String networkDomain, Account owner, Long domainId, PhysicalNetwork physicalNetwork,
|
||||
long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr, Boolean displayNetworkEnabled)
|
||||
long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr,
|
||||
Boolean displayNetworkEnabled, String isolatedPvlan)
|
||||
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
|
||||
|
||||
/**
|
||||
|
||||
@ -283,6 +283,10 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
Long guestNetworkId, boolean sourceNat, boolean assign, String requestedIp, boolean isSystem, Long vpcId)
|
||||
throws InsufficientAddressCapacityException {
|
||||
StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in ");
|
||||
boolean fetchFromDedicatedRange = false;
|
||||
List<Long> dedicatedVlanDbIds = new ArrayList<Long>();
|
||||
List<Long> nonDedicatedVlanDbIds = new ArrayList<Long>();
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
SearchCriteria<IPAddressVO> sc = null;
|
||||
@ -295,9 +299,37 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
errorMessage.append(" zone id=" + dcId);
|
||||
}
|
||||
|
||||
if ( vlanDbIds != null && !vlanDbIds.isEmpty() ) {
|
||||
sc.setParameters("vlanId", vlanDbIds.toArray());
|
||||
errorMessage.append(", vlanId id=" + vlanDbIds.toArray());
|
||||
// If owner has dedicated Public IP ranges, fetch IP from the dedicated range
|
||||
// Otherwise fetch IP from the system pool
|
||||
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId());
|
||||
for (AccountVlanMapVO map : maps) {
|
||||
if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
|
||||
dedicatedVlanDbIds.add(map.getVlanDbId());
|
||||
}
|
||||
List<VlanVO> nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId);
|
||||
for (VlanVO nonDedicatedVlan : nonDedicatedVlans) {
|
||||
if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId()))
|
||||
nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId());
|
||||
}
|
||||
if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
|
||||
fetchFromDedicatedRange = true;
|
||||
sc.setParameters("vlanId", dedicatedVlanDbIds.toArray());
|
||||
errorMessage.append(", vlanId id=" + dedicatedVlanDbIds.toArray());
|
||||
} else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
|
||||
sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
|
||||
errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
|
||||
} else {
|
||||
if (podId != null) {
|
||||
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException
|
||||
("Insufficient address capacity", Pod.class, podId);
|
||||
ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
|
||||
throw ex;
|
||||
}
|
||||
s_logger.warn(errorMessage.toString());
|
||||
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException
|
||||
("Insufficient address capacity", DataCenter.class, dcId);
|
||||
ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
|
||||
throw ex;
|
||||
}
|
||||
|
||||
sc.setParameters("dc", dcId);
|
||||
@ -320,6 +352,16 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
|
||||
List<IPAddressVO> addrs = _ipAddressDao.lockRows(sc, filter, true);
|
||||
|
||||
// If all the dedicated IPs of the owner are in use fetch an IP from the system pool
|
||||
if (addrs.size() == 0 && fetchFromDedicatedRange) {
|
||||
if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
|
||||
fetchFromDedicatedRange = false;
|
||||
sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
|
||||
errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
|
||||
addrs = _ipAddressDao.lockRows(sc, filter, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (addrs.size() == 0) {
|
||||
if (podId != null) {
|
||||
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException
|
||||
@ -337,6 +379,16 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
|
||||
assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size();
|
||||
|
||||
if (!fetchFromDedicatedRange) {
|
||||
// Check that the maximum number of public IPs for the given accountId will not be exceeded
|
||||
try {
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
|
||||
} catch (ResourceAllocationException ex) {
|
||||
s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner);
|
||||
throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded.");
|
||||
}
|
||||
}
|
||||
|
||||
IPAddressVO addr = addrs.get(0);
|
||||
addr.setSourceNat(sourceNat);
|
||||
addr.setAllocatedTime(new Date());
|
||||
@ -441,14 +493,6 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
|
||||
long ownerId = owner.getId();
|
||||
|
||||
// Check that the maximum number of public IPs for the given accountId will not be exceeded
|
||||
try {
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
|
||||
} catch (ResourceAllocationException ex) {
|
||||
s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner);
|
||||
throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded.");
|
||||
}
|
||||
|
||||
PublicIp ip = null;
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
@ -465,15 +509,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
s_logger.debug("lock account " + ownerId + " is acquired");
|
||||
}
|
||||
|
||||
// If account has Account specific ip ranges, try to allocate ip from there
|
||||
List<Long> vlanIds = new ArrayList<Long>();
|
||||
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(ownerId);
|
||||
if (maps != null && !maps.isEmpty()) {
|
||||
vlanIds.add(maps.get(0).getVlanDbId());
|
||||
}
|
||||
|
||||
|
||||
ip = fetchNewPublicIp(dcId, null, vlanIds, owner, VlanType.VirtualNetwork, guestNtwkId,
|
||||
ip = fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId,
|
||||
isSourceNat, false, null, false, vpcId);
|
||||
IPAddressVO publicIp = ip.ip();
|
||||
|
||||
@ -609,9 +645,6 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
|
||||
VlanType vlanType = VlanType.VirtualNetwork;
|
||||
boolean assign = false;
|
||||
boolean allocateFromDedicatedRange = false;
|
||||
List<Long> dedicatedVlanDbIds = new ArrayList<Long>();
|
||||
List<Long> nonDedicatedVlanDbIds = new ArrayList<Long>();
|
||||
|
||||
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) {
|
||||
// zone is of type DataCenter. See DataCenterVO.java.
|
||||
@ -641,39 +674,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
|
||||
txn.start();
|
||||
|
||||
// If account has dedicated Public IP ranges, allocate IP from the dedicated range
|
||||
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(ipOwner.getId());
|
||||
for (AccountVlanMapVO map : maps) {
|
||||
dedicatedVlanDbIds.add(map.getVlanDbId());
|
||||
}
|
||||
if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
|
||||
allocateFromDedicatedRange = true;
|
||||
}
|
||||
|
||||
try {
|
||||
if (allocateFromDedicatedRange) {
|
||||
ip = fetchNewPublicIp(zone.getId(), null, dedicatedVlanDbIds, ipOwner, vlanType, null,
|
||||
false, assign, null, isSystem, null);
|
||||
}
|
||||
} catch(InsufficientAddressCapacityException e) {
|
||||
s_logger.warn("All IPs dedicated to account " + ipOwner.getId() + " has been acquired." +
|
||||
" Now acquiring from the system pool");
|
||||
txn.close();
|
||||
allocateFromDedicatedRange = false;
|
||||
}
|
||||
|
||||
if (!allocateFromDedicatedRange) {
|
||||
// Check that the maximum number of public IPs for the given
|
||||
// accountId will not be exceeded
|
||||
_resourceLimitMgr.checkResourceLimit(accountToLock, ResourceType.public_ip);
|
||||
|
||||
List<VlanVO> nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(zone.getId());
|
||||
for (VlanVO nonDedicatedVlan : nonDedicatedVlans) {
|
||||
nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId());
|
||||
}
|
||||
ip = fetchNewPublicIp(zone.getId(), null, nonDedicatedVlanDbIds, ipOwner, vlanType, null, false, assign, null,
|
||||
ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null,
|
||||
isSystem, null);
|
||||
}
|
||||
|
||||
if (ip == null) {
|
||||
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException
|
||||
@ -1899,7 +1901,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
@DB
|
||||
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway,
|
||||
String cidr, String vlanId, String networkDomain, Account owner, Long domainId,
|
||||
PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr, Boolean isDisplayNetworkEnabled)
|
||||
PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr,
|
||||
Boolean isDisplayNetworkEnabled, String isolatedPvlan)
|
||||
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
|
||||
|
||||
NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
|
||||
@ -1989,6 +1992,9 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
if (ipv6) {
|
||||
throw new InvalidParameterValueException("IPv6 is not supported with security group!");
|
||||
}
|
||||
if (isolatedPvlan != null) {
|
||||
throw new InvalidParameterValueException("Isolated Private VLAN is not supported with security group!");
|
||||
}
|
||||
// Only Account specific Isolated network with sourceNat service disabled are allowed in security group
|
||||
// enabled zone
|
||||
if ( ntwkOff.getGuestType() != GuestType.Shared ){
|
||||
@ -2148,13 +2154,20 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
}
|
||||
|
||||
if (vlanId != null) {
|
||||
if (isolatedPvlan == null) {
|
||||
userNetwork.setBroadcastUri(URI.create("vlan://" + vlanId));
|
||||
userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
|
||||
if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
|
||||
userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
|
||||
} else {
|
||||
userNetwork.setBroadcastDomainType(BroadcastDomainType.Native);
|
||||
}
|
||||
} else {
|
||||
if (vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
|
||||
throw new InvalidParameterValueException("Cannot support pvlan with untagged primary vlan!");
|
||||
}
|
||||
userNetwork.setBroadcastUri(NetUtils.generateUriForPvlan(vlanId, isolatedPvlan));
|
||||
userNetwork.setBroadcastDomainType(BroadcastDomainType.Pvlan);
|
||||
}
|
||||
}
|
||||
|
||||
List<NetworkVO> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId,
|
||||
@ -2757,7 +2770,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
guestNetwork = createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network"
|
||||
, owner.getAccountName() + "-network", null, null, null, null, owner, null, physicalNetwork,
|
||||
zoneId, ACLType.Account,
|
||||
null, null, null, null, true);
|
||||
null, null, null, null, true, null);
|
||||
if (guestNetwork == null) {
|
||||
s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
|
||||
throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT " +
|
||||
@ -2992,6 +3005,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
|
||||
Random _rand = new Random(System.currentTimeMillis());
|
||||
|
||||
@Override
|
||||
public List<? extends Nic> listVmNics(Long vmId, Long nicId) {
|
||||
List<NicVO> result = null;
|
||||
if (nicId == null) {
|
||||
@ -3002,6 +3016,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String allocateGuestIP(Account ipOwner, boolean isSystem, long zoneId, Long networkId, String requestedIp)
|
||||
throws InsufficientAddressCapacityException {
|
||||
String ipaddr = null;
|
||||
@ -3633,8 +3648,10 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
nic.setGateway(ip.getGateway());
|
||||
nic.setNetmask(ip.getNetmask());
|
||||
nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
|
||||
nic.setBroadcastType(BroadcastDomainType.Vlan);
|
||||
nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
|
||||
//nic.setBroadcastType(BroadcastDomainType.Vlan);
|
||||
//nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
|
||||
nic.setBroadcastType(network.getBroadcastDomainType());
|
||||
nic.setBroadcastUri(network.getBroadcastUri());
|
||||
nic.setFormat(AddressFormat.Ip4);
|
||||
nic.setReservationId(String.valueOf(ip.getVlanTag()));
|
||||
nic.setMacAddress(ip.getMacAddress());
|
||||
|
||||
@ -952,6 +952,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
String ip6Cidr = cmd.getIp6Cidr();
|
||||
Boolean displayNetwork = cmd.getDisplayNetwork();
|
||||
Long aclId = cmd.getAclId();
|
||||
String isolatedPvlan = cmd.getIsolatedPvlan();
|
||||
|
||||
// Validate network offering
|
||||
NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
|
||||
@ -1143,6 +1144,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
}
|
||||
}
|
||||
|
||||
if (isolatedPvlan != null && (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() != Network.GuestType.Shared)) {
|
||||
throw new InvalidParameterValueException("Can only support create Private VLAN network with advance shared network!");
|
||||
}
|
||||
|
||||
if (isolatedPvlan != null && ipv6) {
|
||||
throw new InvalidParameterValueException("Can only support create Private VLAN network with IPv4!");
|
||||
}
|
||||
|
||||
// Regular user can create Guest Isolated Source Nat enabled network only
|
||||
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL
|
||||
&& (ntwkOff.getTrafficType() != TrafficType.Guest || ntwkOff.getGuestType() != Network.GuestType.Isolated
|
||||
@ -1175,6 +1184,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
throw new InvalidParameterValueException("Cannot support IPv6 on network offering with external devices!");
|
||||
}
|
||||
|
||||
if (isolatedPvlan != null && providersConfiguredForExternalNetworking(ntwkProviders)) {
|
||||
throw new InvalidParameterValueException("Cannot support private vlan on network offering with external devices!");
|
||||
}
|
||||
|
||||
if (cidr != null && providersConfiguredForExternalNetworking(ntwkProviders)) {
|
||||
if (ntwkOff.getGuestType() == GuestType.Shared && (zone.getNetworkType() == NetworkType.Advanced) &&
|
||||
isSharedNetworkOfferingWithServices(networkOfferingId)) {
|
||||
@ -1251,7 +1264,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
throw new InvalidParameterValueException("Unable to find specified NetworkACL");
|
||||
}
|
||||
|
||||
if(vpcId != acl.getVpcId()){
|
||||
if(!vpcId.equals(acl.getVpcId())){
|
||||
throw new InvalidParameterValueException("ACL: "+aclId+" do not belong to the VPC");
|
||||
}
|
||||
}
|
||||
@ -1266,7 +1279,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
}
|
||||
|
||||
network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId,
|
||||
networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork);
|
||||
networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId,
|
||||
ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan);
|
||||
}
|
||||
|
||||
if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN && createVlan) {
|
||||
@ -3813,8 +3827,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
if (privateNetwork == null) {
|
||||
//create Guest network
|
||||
privateNetwork = _networkMgr.createGuestNetwork(ntwkOff.getId(), networkName, displayText, gateway, cidr, vlan,
|
||||
null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, null, null, null, true);
|
||||
|
||||
null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true, null);
|
||||
s_logger.debug("Created private network " + privateNetwork);
|
||||
} else {
|
||||
s_logger.debug("Private network already exists: " + privateNetwork);
|
||||
|
||||
@ -315,9 +315,10 @@ public class StorageNetworkManagerImpl extends ManagerBase implements StorageNet
|
||||
List<StorageNetworkIpRangeVO> ranges = _sNwIpRangeDao.listByPodId(podId);
|
||||
for (StorageNetworkIpRangeVO r : ranges) {
|
||||
try {
|
||||
r = _sNwIpRangeDao.acquireInLockTable(r.getId());
|
||||
Long rangeId = r.getId();
|
||||
r = _sNwIpRangeDao.acquireInLockTable(rangeId);
|
||||
if (r == null) {
|
||||
String msg = "Unable to acquire lock on storage network ip range id=" + r.getId() + ", delete failed";
|
||||
String msg = "Unable to acquire lock on storage network ip range id=" + rangeId + ", delete failed";
|
||||
s_logger.warn(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElement
|
||||
import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.api.PvlanSetupCommand;
|
||||
import com.cloud.agent.api.to.LoadBalancerTO;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
@ -47,6 +48,7 @@ import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
import com.cloud.network.PhysicalNetworkServiceProvider;
|
||||
import com.cloud.network.PublicIpAddress;
|
||||
@ -228,7 +230,6 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
|
||||
throw new ResourceUnavailableException("Can't find at least one running router!",
|
||||
DataCenter.class, network.getDataCenterId());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru {
|
||||
if (networkType == NetworkType.Advanced
|
||||
&& isMyTrafficType(offering.getTrafficType())
|
||||
&& offering.getGuestType() == Network.GuestType.Isolated
|
||||
&& isMyIsolationMethod(physicalNetwork)) {
|
||||
&& isMyIsolationMethod(physicalNetwork) && !offering.isSystemOnly()) {
|
||||
return true;
|
||||
} else {
|
||||
s_logger.trace("We only take care of Guest networks of type "
|
||||
|
||||
@ -33,6 +33,7 @@ import com.cloud.user.User;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ import com.cloud.agent.api.GetDomRVersionCmd;
|
||||
import com.cloud.agent.api.ModifySshKeysCommand;
|
||||
import com.cloud.agent.api.NetworkUsageAnswer;
|
||||
import com.cloud.agent.api.NetworkUsageCommand;
|
||||
import com.cloud.agent.api.PvlanSetupCommand;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StopAnswer;
|
||||
import com.cloud.agent.api.check.CheckSshAnswer;
|
||||
@ -2223,6 +2224,28 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
|
||||
return dhcpRange;
|
||||
}
|
||||
|
||||
private boolean setupDhcpForPvlan(boolean add, DomainRouterVO router, Nic nic) {
|
||||
if (!nic.getBroadcastUri().getScheme().equals("pvlan")) {
|
||||
return false;
|
||||
}
|
||||
String op = "add";
|
||||
if (!add) {
|
||||
op = "delete";
|
||||
}
|
||||
Network network = _networkDao.findById(nic.getNetworkId());
|
||||
String networkTag = _networkModel.getNetworkTag(router.getHypervisorType(), network);
|
||||
PvlanSetupCommand cmd = PvlanSetupCommand.createDhcpSetup(op, nic.getBroadcastUri(), networkTag, router.getInstanceName(), nic.getMacAddress(), nic.getIp4Address());
|
||||
Commands cmds = new Commands(cmd);
|
||||
// In fact we send command to the host of router, we're not programming router but the host
|
||||
try {
|
||||
sendCommandsToRouter(router, cmds);
|
||||
} catch (AgentUnavailableException e) {
|
||||
s_logger.warn("Agent Unavailable ", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile<DomainRouterVO> profile,
|
||||
DeployDestination dest, ReservationContext context) throws ResourceUnavailableException {
|
||||
@ -2536,12 +2559,19 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
|
||||
List<Network> guestNetworks = new ArrayList<Network>();
|
||||
|
||||
List<? extends Nic> routerNics = _nicDao.listByVmId(profile.getId());
|
||||
for (Nic routerNic : routerNics) {
|
||||
Network network = _networkModel.getNetwork(routerNic.getNetworkId());
|
||||
for (Nic nic : routerNics) {
|
||||
Network network = _networkModel.getNetwork(nic.getNetworkId());
|
||||
if (network.getTrafficType() == TrafficType.Guest) {
|
||||
guestNetworks.add(network);
|
||||
if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
|
||||
result = setupDhcpForPvlan(true, router, nic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
answer = cmds.getAnswer("getDomRVersion");
|
||||
if (answer != null && answer instanceof GetDomRVersionAnswer) {
|
||||
@ -2568,6 +2598,14 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
|
||||
VMInstanceVO vm = profile.getVirtualMachine();
|
||||
DomainRouterVO domR = _routerDao.findById(vm.getId());
|
||||
processStopOrRebootAnswer(domR, answer);
|
||||
List<? extends Nic> routerNics = _nicDao.listByVmId(profile.getId());
|
||||
for (Nic nic : routerNics) {
|
||||
Network network = _networkModel.getNetwork(nic.getNetworkId());
|
||||
if (network.getTrafficType() == TrafficType.Guest && nic.getBroadcastUri().getScheme().equals("pvlan")) {
|
||||
setupDhcpForPvlan(false, domR, nic);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -27,24 +27,6 @@ import java.util.TreeSet;
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.network.vpc.NetworkACLItem;
|
||||
import com.cloud.network.vpc.NetworkACLItemDao;
|
||||
import com.cloud.network.vpc.NetworkACLItemVO;
|
||||
import com.cloud.network.vpc.NetworkACLManager;
|
||||
import com.cloud.network.vpc.PrivateGateway;
|
||||
import com.cloud.network.vpc.PrivateIpAddress;
|
||||
import com.cloud.network.vpc.PrivateIpVO;
|
||||
import com.cloud.network.vpc.StaticRoute;
|
||||
import com.cloud.network.vpc.StaticRouteProfile;
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
import com.cloud.network.vpc.VpcGateway;
|
||||
import com.cloud.network.vpc.VpcManager;
|
||||
import com.cloud.network.vpc.VpcVO;
|
||||
import com.cloud.network.vpc.dao.PrivateIpDao;
|
||||
import com.cloud.network.vpc.dao.StaticRouteDao;
|
||||
import com.cloud.network.vpc.dao.VpcDao;
|
||||
import com.cloud.network.vpc.dao.VpcGatewayDao;
|
||||
import com.cloud.network.vpc.dao.VpcOfferingDao;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -108,6 +90,24 @@ import com.cloud.network.dao.Site2SiteCustomerGatewayVO;
|
||||
import com.cloud.network.dao.Site2SiteVpnConnectionDao;
|
||||
import com.cloud.network.dao.Site2SiteVpnGatewayDao;
|
||||
import com.cloud.network.dao.Site2SiteVpnGatewayVO;
|
||||
import com.cloud.network.vpc.NetworkACLItem;
|
||||
import com.cloud.network.vpc.NetworkACLItemDao;
|
||||
import com.cloud.network.vpc.NetworkACLItemVO;
|
||||
import com.cloud.network.vpc.NetworkACLManager;
|
||||
import com.cloud.network.vpc.PrivateGateway;
|
||||
import com.cloud.network.vpc.PrivateIpAddress;
|
||||
import com.cloud.network.vpc.PrivateIpVO;
|
||||
import com.cloud.network.vpc.StaticRoute;
|
||||
import com.cloud.network.vpc.StaticRouteProfile;
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
import com.cloud.network.vpc.VpcGateway;
|
||||
import com.cloud.network.vpc.VpcManager;
|
||||
import com.cloud.network.vpc.VpcVO;
|
||||
import com.cloud.network.vpc.dao.PrivateIpDao;
|
||||
import com.cloud.network.vpc.dao.StaticRouteDao;
|
||||
import com.cloud.network.vpc.dao.VpcDao;
|
||||
import com.cloud.network.vpc.dao.VpcGatewayDao;
|
||||
import com.cloud.network.vpc.dao.VpcOfferingDao;
|
||||
import com.cloud.network.vpn.Site2SiteVpnManager;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.user.Account;
|
||||
@ -127,7 +127,6 @@ import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.VirtualMachineProfile.Param;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
|
||||
@Component
|
||||
@Local(value = {VpcVirtualNetworkApplianceManager.class, VpcVirtualNetworkApplianceService.class})
|
||||
public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplianceManagerImpl implements VpcVirtualNetworkApplianceManager{
|
||||
@ -339,7 +338,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
|
||||
DomainRouterVO router = _routerDao.findById(vm.getId());
|
||||
if (router.getState() == State.Running) {
|
||||
try {
|
||||
PlugNicCommand plugNicCmd = new PlugNicCommand(nic, vm.getName());
|
||||
PlugNicCommand plugNicCmd = new PlugNicCommand(nic, vm.getName(), vm.getType());
|
||||
|
||||
Commands cmds = new Commands(OnError.Stop);
|
||||
cmds.addCommand("plugnic", plugNicCmd);
|
||||
@ -748,7 +747,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
|
||||
// if (rule.getSourceCidrList() == null && (rule.getPurpose() == Purpose.Firewall || rule.getPurpose() == Purpose.NetworkACL)) {
|
||||
// _firewallDao.loadSourceCidrs((FirewallRuleVO)rule);
|
||||
// }
|
||||
NetworkACLTO ruleTO = new NetworkACLTO((NetworkACLItemVO)rule, guestVlan, rule.getTrafficType());
|
||||
NetworkACLTO ruleTO = new NetworkACLTO(rule, guestVlan, rule.getTrafficType());
|
||||
rulesTO.add(ruleTO);
|
||||
}
|
||||
}
|
||||
@ -828,7 +827,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
|
||||
_routerDao.update(routerVO.getId(), routerVO);
|
||||
}
|
||||
}
|
||||
PlugNicCommand plugNicCmd = new PlugNicCommand(getNicTO(router, publicNic.getNetworkId(), publicNic.getBroadcastUri().toString()), router.getInstanceName());
|
||||
PlugNicCommand plugNicCmd = new PlugNicCommand(getNicTO(router, publicNic.getNetworkId(), publicNic.getBroadcastUri().toString()), router.getInstanceName(), router.getType());
|
||||
cmds.addCommand(plugNicCmd);
|
||||
VpcVO vpc = _vpcDao.findById(router.getVpcId());
|
||||
NetworkUsageCommand netUsageCmd = new NetworkUsageCommand(router.getPrivateIpAddress(), router.getInstanceName(), true, publicNic.getIp4Address(), vpc.getCidr());
|
||||
@ -851,7 +850,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
|
||||
for (Pair<Nic, Network> nicNtwk : guestNics) {
|
||||
Nic guestNic = nicNtwk.first();
|
||||
//plug guest nic
|
||||
PlugNicCommand plugNicCmd = new PlugNicCommand(getNicTO(router, guestNic.getNetworkId(), null), router.getInstanceName());
|
||||
PlugNicCommand plugNicCmd = new PlugNicCommand(getNicTO(router, guestNic.getNetworkId(), null), router.getInstanceName(), router.getType());
|
||||
cmds.addCommand(plugNicCmd);
|
||||
|
||||
if (!_networkModel.isPrivateGateway(guestNic)) {
|
||||
@ -1236,13 +1235,15 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
|
||||
//1) allocate nic for control and source nat public ip
|
||||
networks = super.createRouterNetworks(owner, isRedundant, plan, null, sourceNatIp);
|
||||
|
||||
//2) allocate nic for private gateway if needed
|
||||
PrivateGateway privateGateway = _vpcMgr.getVpcPrivateGateway(vpcId);
|
||||
if (privateGateway != null) {
|
||||
//2) allocate nic for private gateways if needed
|
||||
List<PrivateGateway> privateGateways = _vpcMgr.getVpcPrivateGateways(vpcId);
|
||||
if (privateGateways != null && !privateGateways.isEmpty()) {
|
||||
for (PrivateGateway privateGateway : privateGateways) {
|
||||
NicProfile privateNic = createPrivateNicProfileForGateway(privateGateway);
|
||||
Network privateNetwork = _networkModel.getNetwork(privateGateway.getNetworkId());
|
||||
networks.add(new Pair<NetworkVO, NicProfile>((NetworkVO) privateNetwork, privateNic));
|
||||
}
|
||||
}
|
||||
|
||||
//3) allocate nic for guest gateway if needed
|
||||
List<? extends Network> guestNetworks = _vpcMgr.getVpcNetworks(vpcId);
|
||||
|
||||
@ -182,7 +182,7 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
throw new InvalidParameterValueException("Unable to find Vpc associated with the NetworkACL");
|
||||
}
|
||||
_accountMgr.checkAccess(caller, null, true, vpc);
|
||||
if(gateway.getVpcId() != acl.getVpcId()){
|
||||
if(!gateway.getVpcId().equals(acl.getVpcId())){
|
||||
throw new InvalidParameterValueException("private gateway: "+privateGatewayId+" and ACL: "+aclId+" do not belong to the same VPC");
|
||||
}
|
||||
}
|
||||
@ -225,7 +225,7 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(caller, null, true, vpc);
|
||||
if(network.getVpcId() != acl.getVpcId()){
|
||||
if(!network.getVpcId().equals(acl.getVpcId())){
|
||||
throw new InvalidParameterValueException("Network: "+networkId+" and ACL: "+aclId+" do not belong to the same VPC");
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,5 +166,5 @@ public interface VpcManager extends VpcService{
|
||||
*/
|
||||
void validateNtwkOffForNtwkInVpc(Long networkId, long newNtwkOffId, String newCidr, String newNetworkDomain, Vpc vpc, String gateway, Account networkOwner);
|
||||
|
||||
List<PrivateGateway> getVpcPrivateGateways(long id);
|
||||
List<PrivateGateway> getVpcPrivateGateways(long vpcId);
|
||||
}
|
||||
|
||||
@ -711,8 +711,9 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
public boolean destroyVpc(Vpc vpc, Account caller, Long callerUserId) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
s_logger.debug("Destroying vpc " + vpc);
|
||||
|
||||
//don't allow to delete vpc if it's in use by existing networks
|
||||
int networksCount = _ntwkDao.getNetworkCountByVpcId(vpc.getId());
|
||||
//don't allow to delete vpc if it's in use by existing non system networks (system networks are networks of a private gateway of the VPC,
|
||||
//and they will get removed as a part of VPC cleanup
|
||||
int networksCount = _ntwkDao.getNonSystemNetworkCountByVpcId(vpc.getId());
|
||||
if (networksCount > 0) {
|
||||
throw new InvalidParameterValueException("Can't delete VPC " + vpc + " as its used by " + networksCount + " networks");
|
||||
}
|
||||
@ -1235,7 +1236,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
return false;
|
||||
}
|
||||
|
||||
//4) Delete private gateway
|
||||
//4) Delete private gateways
|
||||
List<PrivateGateway> gateways = getVpcPrivateGateways(vpcId);
|
||||
if (gateways != null) {
|
||||
for (PrivateGateway gateway: gateways) {
|
||||
@ -1299,8 +1300,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
|
||||
|
||||
@Override
|
||||
public List<PrivateGateway> getVpcPrivateGateways(long id) {
|
||||
List<VpcGatewayVO> gateways = _vpcGatewayDao.listByVpcIdAndType(id, VpcGateway.Type.Private);
|
||||
public List<PrivateGateway> getVpcPrivateGateways(long vpcId) {
|
||||
List<VpcGatewayVO> gateways = _vpcGatewayDao.listByVpcIdAndType(vpcId, VpcGateway.Type.Private);
|
||||
|
||||
if (gateways != null) {
|
||||
List<PrivateGateway> pvtGateway = new ArrayList();
|
||||
@ -2024,8 +2025,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
|
||||
//2) Create network
|
||||
Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId,
|
||||
networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, null, null, isDisplayNetworkEnabled);
|
||||
|
||||
networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, null, null, isDisplayNetworkEnabled, null);
|
||||
|
||||
if(guestNetwork != null){
|
||||
guestNetwork.setNetworkACLId(aclId);
|
||||
|
||||
@ -92,6 +92,10 @@ import com.cloud.dc.dao.ClusterVSMMapDao;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.DataCenterIpAddressDao;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.deploy.PlannerHostReservationVO;
|
||||
import com.cloud.deploy.dao.PlannerHostReservationDao;
|
||||
import com.cloud.event.ActionEvent;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.DiscoveryException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
@ -221,7 +225,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
protected HighAvailabilityManager _haMgr;
|
||||
@Inject
|
||||
protected StorageService _storageSvr;
|
||||
|
||||
@Inject
|
||||
PlannerHostReservationDao _plannerHostReserveDao;
|
||||
|
||||
protected List<? extends Discoverer> _discoverers;
|
||||
|
||||
@ -2532,4 +2537,41 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
sc.addAnd(sc.getEntity().getResourceState(), Op.EQ, ResourceState.Enabled);
|
||||
return sc.list();
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_HOST_RESERVATION_RELEASE, eventDescription = "releasing host reservation", async = true)
|
||||
public boolean releaseHostReservation(Long hostId) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
txn.start();
|
||||
PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
|
||||
if (reservationEntry != null) {
|
||||
long id = reservationEntry.getId();
|
||||
PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true);
|
||||
if (hostReservation == null) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Host reservation for host: " + hostId + " does not even exist. Release reservartion call is ignored.");
|
||||
}
|
||||
txn.rollback();
|
||||
return false;
|
||||
}
|
||||
hostReservation.setResourceUsage(null);
|
||||
_plannerHostReserveDao.persist(hostReservation);
|
||||
txn.commit();
|
||||
return true;
|
||||
}
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Host reservation for host: " + hostId
|
||||
+ " does not even exist. Release reservartion call is ignored.");
|
||||
}
|
||||
return false;
|
||||
} catch (CloudRuntimeException e) {
|
||||
throw e;
|
||||
} catch (Throwable t) {
|
||||
s_logger.error("Unable to release host reservation for host: " + hostId, t);
|
||||
txn.rollback();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +78,7 @@ import org.apache.cloudstack.api.command.admin.host.FindHostsForMigrationCmd;
|
||||
import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd;
|
||||
import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd;
|
||||
import org.apache.cloudstack.api.command.admin.host.ReleaseHostReservationCmd;
|
||||
import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd;
|
||||
import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd;
|
||||
import org.apache.cloudstack.api.command.admin.internallb.ConfigureInternalLoadBalancerElementCmd;
|
||||
@ -457,6 +458,7 @@ import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.dc.dao.PodVlanMapDao;
|
||||
import com.cloud.dc.dao.VlanDao;
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeploymentPlanner;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
@ -660,6 +662,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.cloudstack.api.command.admin.config.ListDeploymentPlannersCmd;
|
||||
|
||||
public class ManagementServerImpl extends ManagerBase implements ManagementServer {
|
||||
public static final Logger s_logger = Logger.getLogger(ManagementServerImpl.class.getName());
|
||||
@ -796,6 +799,16 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
private List<UserAuthenticator> _userAuthenticators;
|
||||
private List<UserAuthenticator> _userPasswordEncoders;
|
||||
|
||||
protected List<DeploymentPlanner> _planners;
|
||||
|
||||
public List<DeploymentPlanner> getPlanners() {
|
||||
return _planners;
|
||||
}
|
||||
|
||||
public void setPlanners(List<DeploymentPlanner> _planners) {
|
||||
this._planners = _planners;
|
||||
}
|
||||
|
||||
@Inject ClusterManager _clusterMgr;
|
||||
private String _hashKey = null;
|
||||
private String _encryptionKey = null;
|
||||
@ -1222,7 +1235,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
if (volumePools.isEmpty()) {
|
||||
allHosts.remove(host);
|
||||
} else {
|
||||
if (host.getClusterId() != srcHost.getClusterId() || usesLocal) {
|
||||
if (!host.getClusterId().equals(srcHost.getClusterId()) || usesLocal) {
|
||||
requiresStorageMotion.put(host, true);
|
||||
}
|
||||
}
|
||||
@ -1868,6 +1881,89 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
}
|
||||
*/
|
||||
|
||||
private VMTemplateVO updateTemplateOrIso(BaseUpdateTemplateOrIsoCmd cmd) {
|
||||
Long id = cmd.getId();
|
||||
String name = cmd.getTemplateName();
|
||||
String displayText = cmd.getDisplayText();
|
||||
String format = cmd.getFormat();
|
||||
Long guestOSId = cmd.getOsTypeId();
|
||||
Boolean passwordEnabled = cmd.isPasswordEnabled();
|
||||
Boolean bootable = cmd.isBootable();
|
||||
Integer sortKey = cmd.getSortKey();
|
||||
Account account = UserContext.current().getCaller();
|
||||
|
||||
// verify that template exists
|
||||
VMTemplateVO template = _templateDao.findById(id);
|
||||
if (template == null || template.getRemoved() != null) {
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException("unable to find template/iso with specified id");
|
||||
ex.addProxyObject(template, id, "templateId");
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// Don't allow to modify system template
|
||||
if (id.equals(Long.valueOf(1))) {
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update template/iso of specified id");
|
||||
ex.addProxyObject(template, id, "templateId");
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// do a permission check
|
||||
_accountMgr.checkAccess(account, AccessType.ModifyEntry, true, template);
|
||||
|
||||
boolean updateNeeded = !(name == null && displayText == null && format == null && guestOSId == null && passwordEnabled == null
|
||||
&& bootable == null && sortKey == null);
|
||||
if (!updateNeeded) {
|
||||
return template;
|
||||
}
|
||||
|
||||
template = _templateDao.createForUpdate(id);
|
||||
|
||||
if (name != null) {
|
||||
template.setName(name);
|
||||
}
|
||||
|
||||
if (displayText != null) {
|
||||
template.setDisplayText(displayText);
|
||||
}
|
||||
|
||||
if (sortKey != null) {
|
||||
template.setSortKey(sortKey);
|
||||
}
|
||||
|
||||
ImageFormat imageFormat = null;
|
||||
if (format != null) {
|
||||
try {
|
||||
imageFormat = ImageFormat.valueOf(format.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new InvalidParameterValueException("Image format: " + format + " is incorrect. Supported formats are "
|
||||
+ EnumUtils.listValues(ImageFormat.values()));
|
||||
}
|
||||
|
||||
template.setFormat(imageFormat);
|
||||
}
|
||||
|
||||
if (guestOSId != null) {
|
||||
GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
|
||||
|
||||
if (guestOS == null) {
|
||||
throw new InvalidParameterValueException("Please specify a valid guest OS ID.");
|
||||
} else {
|
||||
template.setGuestOSId(guestOSId);
|
||||
}
|
||||
}
|
||||
|
||||
if (passwordEnabled != null) {
|
||||
template.setEnablePassword(passwordEnabled);
|
||||
}
|
||||
|
||||
if (bootable != null) {
|
||||
template.setBootable(bootable);
|
||||
}
|
||||
|
||||
_templateDao.update(id, template);
|
||||
|
||||
return _templateDao.findById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<? extends IpAddress>, Integer> searchForIPAddresses(ListPublicIpAddressesCmd cmd) {
|
||||
@ -2332,7 +2428,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
public int compare(SummedCapacity arg0, SummedCapacity arg1) {
|
||||
if (arg0.getPercentUsed() < arg1.getPercentUsed()) {
|
||||
return 1;
|
||||
} else if (arg0.getPercentUsed() == arg1.getPercentUsed()) {
|
||||
} else if (arg0.getPercentUsed().equals(arg1.getPercentUsed())) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
@ -2826,7 +2922,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
cmdList.add(UpdateVMAffinityGroupCmd.class);
|
||||
cmdList.add(ListAffinityGroupTypesCmd.class);
|
||||
cmdList.add(ListNetworkIsolationMethodsCmd.class);
|
||||
|
||||
cmdList.add(ListDeploymentPlannersCmd.class);
|
||||
cmdList.add(ReleaseHostReservationCmd.class);
|
||||
cmdList.add(AddResourceDetailCmd.class);
|
||||
cmdList.add(RemoveResourceDetailCmd.class);
|
||||
cmdList.add(ListResourceDetailsCmd.class);
|
||||
@ -3979,4 +4076,15 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listDeploymentPlanners() {
|
||||
List<String> plannersAvailable = new ArrayList<String>();
|
||||
for (DeploymentPlanner planner : _planners) {
|
||||
plannersAvailable.add(planner.getName());
|
||||
}
|
||||
|
||||
return plannersAvailable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -438,6 +438,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
||||
SearchCriteria.Op.EQ);
|
||||
volumeSB.and("removed", volumeSB.entity().getRemoved(),
|
||||
SearchCriteria.Op.NULL);
|
||||
volumeSB.and("state", volumeSB.entity().getState(), SearchCriteria.Op.NIN);
|
||||
|
||||
SearchBuilder<VMInstanceVO> activeVmSB = _vmInstanceDao
|
||||
.createSearchBuilder();
|
||||
@ -449,6 +450,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
||||
|
||||
SearchCriteria<VolumeVO> volumeSC = volumeSB.create();
|
||||
volumeSC.setParameters("poolId", PrimaryDataStoreVO.getId());
|
||||
volumeSC.setParameters("state", Volume.State.Expunging, Volume.State.Destroy);
|
||||
volumeSC.setJoinParameters("activeVmSB", "state",
|
||||
State.Starting, State.Running, State.Stopping,
|
||||
State.Migrating);
|
||||
@ -644,6 +646,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
||||
SearchCriteria.Op.EQ);
|
||||
volumeSearch.and("poolId", volumeSearch.entity().getPoolId(),
|
||||
SearchCriteria.Op.EQ);
|
||||
volumeSearch.and("state", volumeSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
StoragePoolSearch.join("vmVolume", volumeSearch, volumeSearch.entity()
|
||||
.getInstanceId(), StoragePoolSearch.entity().getId(),
|
||||
JoinBuilder.JoinType.INNER);
|
||||
@ -1591,6 +1594,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
||||
SearchCriteria<VMInstanceVO> sc = StoragePoolSearch.create();
|
||||
sc.setJoinParameters("vmVolume", "volumeType", Volume.Type.ROOT);
|
||||
sc.setJoinParameters("vmVolume", "poolId", storagePoolId);
|
||||
sc.setJoinParameters("vmVolume", "state", Volume.State.Ready);
|
||||
return _vmInstanceDao.search(sc, null);
|
||||
}
|
||||
|
||||
|
||||
@ -739,7 +739,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
//Verify parameters
|
||||
if (sourceZoneId == destZoneId) {
|
||||
if (sourceZoneId.equals(destZoneId)) {
|
||||
throw new InvalidParameterValueException("Please specify different source and destination zones.");
|
||||
}
|
||||
|
||||
@ -1160,7 +1160,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
Account caller = UserContext.current().getCaller();
|
||||
Long id = cmd.getId();
|
||||
|
||||
if (id == Long.valueOf(1)) {
|
||||
if (id.equals(Long.valueOf(1))) {
|
||||
throw new PermissionDeniedException("unable to list permissions for " + cmd.getMediaType() + " with id " + id);
|
||||
}
|
||||
|
||||
@ -1252,7 +1252,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
throw new InvalidParameterValueException("unable to update permissions for " + mediaType + " with id " + id + " as it is removed ");
|
||||
}
|
||||
|
||||
if (id == Long.valueOf(1)) {
|
||||
if (id.equals(Long.valueOf(1))) {
|
||||
throw new InvalidParameterValueException("unable to update permissions for " + mediaType + " with id " + id);
|
||||
}
|
||||
|
||||
|
||||
@ -792,14 +792,14 @@ public class DatabaseConfig {
|
||||
}
|
||||
|
||||
// If a netmask was provided, check that the startIP, endIP, and gateway all belong to the same subnet
|
||||
if (netmask != null && netmask != "") {
|
||||
if (netmask != null && !netmask.equals("")) {
|
||||
if (endIP != null) {
|
||||
if (!IPRangeConfig.sameSubnet(startIP, endIP, netmask)) {
|
||||
printError("Start and end IPs for the public IP range must be in the same subnet, as per the provided netmask.");
|
||||
}
|
||||
}
|
||||
|
||||
if (gateway != null && gateway != "") {
|
||||
if (gateway != null && !gateway.equals("")) {
|
||||
if (!IPRangeConfig.sameSubnet(startIP, gateway, netmask)) {
|
||||
printError("The start IP for the public IP range must be in the same subnet as the gateway, as per the provided netmask.");
|
||||
}
|
||||
|
||||
@ -73,6 +73,7 @@ import com.cloud.agent.api.GetVmStatsAnswer;
|
||||
import com.cloud.agent.api.GetVmStatsCommand;
|
||||
import com.cloud.agent.api.PlugNicAnswer;
|
||||
import com.cloud.agent.api.PlugNicCommand;
|
||||
import com.cloud.agent.api.PvlanSetupCommand;
|
||||
import com.cloud.agent.api.StartAnswer;
|
||||
import com.cloud.agent.api.StopAnswer;
|
||||
import com.cloud.agent.api.UnPlugNicAnswer;
|
||||
@ -101,7 +102,6 @@ import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.deploy.DeployPlannerSelector;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
@ -398,9 +398,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
AffinityGroupVMMapDao _affinityGroupVMMapDao;
|
||||
@Inject
|
||||
AffinityGroupDao _affinityGroupDao;
|
||||
|
||||
@Inject
|
||||
List<DeployPlannerSelector> plannerSelectors;
|
||||
@Inject
|
||||
TemplateDataFactory templateFactory;
|
||||
|
||||
@ -1023,6 +1020,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
throw new CloudRuntimeException("Failed to find a nic profile for the existing default network. This is bad and probably means some sort of configuration corruption");
|
||||
}
|
||||
|
||||
Network oldDefaultNetwork = null;
|
||||
oldDefaultNetwork = _networkModel.getDefaultNetworkForVm(vmId);
|
||||
long oldNetworkOfferingId = -1L;
|
||||
|
||||
if(oldDefaultNetwork!=null) {
|
||||
oldNetworkOfferingId = oldDefaultNetwork.getNetworkOfferingId();
|
||||
}
|
||||
NicVO existingVO = _nicDao.findById(existing.id);
|
||||
Integer chosenID = nic.getDeviceId();
|
||||
Integer existingID = existing.getDeviceId();
|
||||
@ -1054,6 +1058,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
throw new CloudRuntimeException("Failed to change default nic to " + nic + " and now we have no default");
|
||||
} else if (newdefault.getId() == nic.getNetworkId()) {
|
||||
s_logger.debug("successfully set default network to " + network + " for " + vmInstance);
|
||||
String nicIdString = Long.toString(nic.getId());
|
||||
long newNetworkOfferingId = network.getNetworkOfferingId();
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vmInstance.getAccountId(), vmInstance.getDataCenterId(),
|
||||
vmInstance.getId(), nicIdString, oldNetworkOfferingId, null, 1L, VirtualMachine.class.getName(), vmInstance.getUuid());
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vmInstance.getAccountId(), vmInstance.getDataCenterId(),
|
||||
vmInstance.getId(), nicIdString, newNetworkOfferingId, null, 1L, VirtualMachine.class.getName(), vmInstance.getUuid());
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vmInstance.getAccountId(), vmInstance.getDataCenterId(),
|
||||
vmInstance.getId(), nicIdString, newNetworkOfferingId, null, 0L, VirtualMachine.class.getName(), vmInstance.getUuid());
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vmInstance.getAccountId(), vmInstance.getDataCenterId(),
|
||||
vmInstance.getId(), nicIdString, oldNetworkOfferingId, null, 0L, VirtualMachine.class.getName(), vmInstance.getUuid());
|
||||
return _vmDao.findById(vmInstance.getId());
|
||||
}
|
||||
|
||||
@ -1655,7 +1669,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
|
||||
String description = "";
|
||||
|
||||
if (displayName != vmInstance.getDisplayName()) {
|
||||
if (!displayName.equals(vmInstance.getDisplayName())) {
|
||||
description += "New display name: " + displayName + ". ";
|
||||
}
|
||||
|
||||
@ -2191,7 +2205,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
s_logger.debug("Creating network for account " + owner + " from the network offering id=" +requiredOfferings.get(0).getId() + " as a part of deployVM process");
|
||||
Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(),
|
||||
owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null,
|
||||
null, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true);
|
||||
null, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null);
|
||||
defaultNetwork = _networkDao.findById(newNetwork.getId());
|
||||
} else if (virtualNetworks.size() > 1) {
|
||||
throw new InvalidParameterValueException(
|
||||
@ -2769,6 +2783,37 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setupVmForPvlan(boolean add, Long hostId, NicVO nic) {
|
||||
if (!nic.getBroadcastUri().getScheme().equals("pvlan")) {
|
||||
return false;
|
||||
}
|
||||
String op = "add";
|
||||
if (!add) {
|
||||
// "delete" would remove all the rules(if using ovs) related to this vm
|
||||
op = "delete";
|
||||
}
|
||||
Network network = _networkDao.findById(nic.getNetworkId());
|
||||
Host host = _hostDao.findById(hostId);
|
||||
String networkTag = _networkModel.getNetworkTag(host.getHypervisorType(), network);
|
||||
PvlanSetupCommand cmd = PvlanSetupCommand.createVmSetup(op, nic.getBroadcastUri(), networkTag, nic.getMacAddress());
|
||||
Answer answer = null;
|
||||
try {
|
||||
answer = _agentMgr.send(hostId, cmd);
|
||||
} catch (OperationTimedoutException e) {
|
||||
s_logger.warn("Timed Out", e);
|
||||
return false;
|
||||
} catch (AgentUnavailableException e) {
|
||||
s_logger.warn("Agent Unavailable ", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean result = true;
|
||||
if (answer == null || !answer.getResult()) {
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finalizeDeployment(Commands cmds,
|
||||
VirtualMachineProfile<UserVmVO> profile, DeployDestination dest,
|
||||
@ -2830,6 +2875,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
originalIp = nic.getIp4Address();
|
||||
guestNic = nic;
|
||||
guestNetwork = network;
|
||||
// In vmware, we will be effecting pvlan settings in portgroups in StartCommand.
|
||||
if (profile.getHypervisorType() != HypervisorType.VMware) {
|
||||
if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
|
||||
if (!setupVmForPvlan(true, hostId, nic)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean ipChanged = false;
|
||||
@ -2960,6 +3013,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
+ " stop due to exception ", ex);
|
||||
}
|
||||
}
|
||||
|
||||
VMInstanceVO vm = profile.getVirtualMachine();
|
||||
List<NicVO> nics = _nicDao.listByVmId(vm.getId());
|
||||
for (NicVO nic : nics) {
|
||||
NetworkVO network = _networkDao.findById(nic.getNetworkId());
|
||||
if (network.getTrafficType() == TrafficType.Guest) {
|
||||
if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
|
||||
setupVmForPvlan(false, vm.getHostId(), nic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String generateRandomPassword() {
|
||||
@ -3087,15 +3151,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
|
||||
VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid());
|
||||
|
||||
String plannerName = null;
|
||||
for (DeployPlannerSelector dps : plannerSelectors) {
|
||||
plannerName = dps.selectPlanner(vm);
|
||||
if (plannerName != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Get serviceOffering for Virtual Machine
|
||||
ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId());
|
||||
String plannerName = offering.getDeploymentPlanner();
|
||||
if (plannerName == null) {
|
||||
throw new CloudRuntimeException(String.format("cannot find DeployPlannerSelector for vm[uuid:%s, hypervisorType:%s]", vm.getUuid(), vm.getHypervisorType()));
|
||||
if (vm.getHypervisorType() == HypervisorType.BareMetal) {
|
||||
plannerName = "BareMetalPlanner";
|
||||
} else {
|
||||
plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key());
|
||||
}
|
||||
}
|
||||
|
||||
String reservationId = vmEntity.reserve(plannerName, plan, new ExcludeList(), new Long(callerUser.getId()).toString());
|
||||
@ -3624,7 +3688,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
|
||||
List<VolumeVO> vmVolumes = _volsDao.findUsableVolumesForInstance(vm.getId());
|
||||
Map<VolumeVO, StoragePoolVO> volToPoolObjectMap = new HashMap<VolumeVO, StoragePoolVO>();
|
||||
if (!isVMUsingLocalStorage(vm) && destinationHost.getClusterId() == srcHost.getClusterId()) {
|
||||
if (!isVMUsingLocalStorage(vm) && destinationHost.getClusterId().equals(srcHost.getClusterId())) {
|
||||
if (volumeToPool.isEmpty()) {
|
||||
// If the destination host is in the same cluster and volumes do not have to be migrated across pools
|
||||
// then fail the call. migrateVirtualMachine api should have been used.
|
||||
@ -4019,7 +4083,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
requiredOfferings.get(0).getId() + " as a part of deployVM process");
|
||||
Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(),
|
||||
newAccount.getAccountName() + "-network", newAccount.getAccountName() + "-network", null, null,
|
||||
null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true);
|
||||
null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null);
|
||||
// if the network offering has persistent set to true, implement the network
|
||||
if (requiredOfferings.get(0).getIsPersistent()) {
|
||||
DeployDestination dest = new DeployDestination(zone, null, null, null);
|
||||
@ -4252,7 +4316,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
UserVmVO vmVO = _vmDao.findById(vm.getId());
|
||||
if (vmVO.getState() == State.Running) {
|
||||
try {
|
||||
PlugNicCommand plugNicCmd = new PlugNicCommand(nic,vm.getName());
|
||||
PlugNicCommand plugNicCmd = new PlugNicCommand(nic,vm.getName(), vm.getType());
|
||||
Commands cmds = new Commands(OnError.Stop);
|
||||
cmds.addCommand("plugnic",plugNicCmd);
|
||||
_agentMgr.send(dest.getHost().getId(),cmds);
|
||||
|
||||
@ -1322,7 +1322,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
if (migrationResult) {
|
||||
//if the vm is migrated to different pod in basic mode, need to reallocate ip
|
||||
|
||||
if (vm.getPodIdToDeployIn() != destPool.getPodId()) {
|
||||
if (!vm.getPodIdToDeployIn().equals(destPool.getPodId())) {
|
||||
DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), destPool.getPodId(), null, null, null, null);
|
||||
VirtualMachineProfileImpl<T> vmProfile = new VirtualMachineProfileImpl<T>(vm, null, null, null, null);
|
||||
_networkMgr.reallocate(vmProfile, plan);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user