mirror of https://github.com/apache/cloudstack.git
Merge branch 'master' into internallb1
Conflicts: server/src/com/cloud/network/NetworkModelImpl.java server/src/com/cloud/network/NetworkServiceImpl.java server/src/com/cloud/server/ManagementServerImpl.java server/test/com/cloud/network/MockNetworkManagerImpl.java server/test/com/cloud/vpc/MockNetworkManagerImpl.java
This commit is contained in:
commit
1cff609347
|
|
@ -0,0 +1,26 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.agent.api.storage;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
|
||||
public class CreateVolumeOVAAnswer extends Answer {
|
||||
public CreateVolumeOVAAnswer(CreateVolumeOVACommand cmd, boolean result, String details) {
|
||||
super(cmd, result, details);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
// 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.storage;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.to.StorageFilerTO;
|
||||
import com.cloud.storage.StoragePool;
|
||||
|
||||
public class CreateVolumeOVACommand extends Command {
|
||||
String secUrl;
|
||||
String volPath;
|
||||
String volName;
|
||||
StorageFilerTO pool;
|
||||
|
||||
public CreateVolumeOVACommand() {
|
||||
}
|
||||
|
||||
public CreateVolumeOVACommand(String secUrl, String volPath, String volName, StoragePool pool, int wait) {
|
||||
this.secUrl = secUrl;
|
||||
this.volPath = volPath;
|
||||
this.volName = volName;
|
||||
this.pool = new StorageFilerTO(pool);
|
||||
setWait(wait);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getVolPath() {
|
||||
return this.volPath;
|
||||
}
|
||||
|
||||
public String getVolName() {
|
||||
return this.volName;
|
||||
}
|
||||
public String getSecondaryStorageUrl() {
|
||||
return this.secUrl;
|
||||
}
|
||||
public StorageFilerTO getPool() {
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.agent.api.storage;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
|
||||
public class PrepareOVAPackingAnswer extends Answer {
|
||||
public PrepareOVAPackingAnswer(PrepareOVAPackingCommand cmd, boolean result, String details) {
|
||||
super(cmd, result, details);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// 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.storage;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
|
||||
public class PrepareOVAPackingCommand extends Command {
|
||||
private String templatePath;
|
||||
private String secUrl;
|
||||
|
||||
public PrepareOVAPackingCommand() {
|
||||
}
|
||||
|
||||
public PrepareOVAPackingCommand(String secUrl, String templatePath) {
|
||||
this.secUrl = secUrl;
|
||||
this.templatePath = templatePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getTemplatePath() {
|
||||
return this.templatePath;
|
||||
}
|
||||
|
||||
public String getSecondaryStorageUrl() {
|
||||
return this.secUrl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -138,6 +138,7 @@ public interface NetworkService {
|
|||
ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param networkName
|
||||
* @param displayText
|
||||
* @param physicalNetworkId
|
||||
|
|
@ -148,13 +149,14 @@ public interface NetworkService {
|
|||
* @param netmask
|
||||
* @param networkOwnerId
|
||||
* @param vpcId TODO
|
||||
* @param sourceNat
|
||||
* @return
|
||||
* @throws InsufficientCapacityException
|
||||
* @throws ConcurrentOperationException
|
||||
* @throws ResourceAllocationException
|
||||
*/
|
||||
Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan,
|
||||
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId)
|
||||
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat)
|
||||
throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException;
|
||||
|
||||
/* Requests an IP address for the guest nic */
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public interface RulesService {
|
|||
|
||||
boolean applyPortForwardingRules(long ipAdddressId, Account caller) throws ResourceUnavailableException;
|
||||
|
||||
boolean enableStaticNat(long ipAddressId, long vmId, long networkId, boolean isSystemVm, String vmGuestIp) throws NetworkRuleConflictException, ResourceUnavailableException;
|
||||
boolean enableStaticNat(long ipAddressId, long vmId, long networkId, String vmGuestIp) throws NetworkRuleConflictException, ResourceUnavailableException;
|
||||
|
||||
PortForwardingRule getPortForwardigRule(long ruleId);
|
||||
|
||||
|
|
|
|||
|
|
@ -44,5 +44,6 @@ public interface PrivateIp {
|
|||
String getMacAddress();
|
||||
|
||||
long getNetworkId();
|
||||
boolean getSourceNat();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,4 +77,8 @@ public interface VpcGateway extends Identity, ControlledEntity, InternalIdentity
|
|||
* @return
|
||||
*/
|
||||
State getState();
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
boolean getSourceNat();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ public interface VpcService {
|
|||
/**
|
||||
* Persists VPC private gateway in the Database.
|
||||
*
|
||||
*
|
||||
* @param vpcId TODO
|
||||
* @param physicalNetworkId
|
||||
* @param vlan
|
||||
|
|
@ -170,13 +171,14 @@ public interface VpcService {
|
|||
* @param gateway
|
||||
* @param netmask
|
||||
* @param gatewayOwnerId
|
||||
* @param isSourceNat
|
||||
* @return
|
||||
* @throws InsufficientCapacityException
|
||||
* @throws ConcurrentOperationException
|
||||
* @throws ResourceAllocationException
|
||||
*/
|
||||
public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress,
|
||||
String gateway, String netmask, long gatewayOwnerId) throws ResourceAllocationException,
|
||||
String gateway, String netmask, long gatewayOwnerId, Boolean isSourceNat) throws ResourceAllocationException,
|
||||
ConcurrentOperationException, InsufficientCapacityException;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -451,6 +451,6 @@ public interface UserVmService {
|
|||
|
||||
UserVm restoreVM(RestoreVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException;
|
||||
|
||||
UserVm upgradeVirtualMachine(ScaleVMCmd scaleVMCmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException;
|
||||
boolean upgradeVirtualMachine(ScaleVMCmd scaleVMCmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,11 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
|
|||
required=true, description="the VPC network belongs to")
|
||||
private Long vpcId;
|
||||
|
||||
@Parameter(name=ApiConstants.SOURCE_NAT_SUPPORTED, type=CommandType.BOOLEAN, required=false,
|
||||
description="source NAT supported value. Default value false. If 'true' source NAT is enabled on the private gateway" +
|
||||
" 'false': sourcenat is not supported")
|
||||
private Boolean isSourceNat;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -97,6 +102,13 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
|
|||
return vpcId;
|
||||
}
|
||||
|
||||
public Boolean getIsSourceNat () {
|
||||
if (isSourceNat == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -111,7 +123,7 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
|
|||
PrivateGateway result = null;
|
||||
try {
|
||||
result = _vpcService.createVpcPrivateGateway(getVpcId(), getPhysicalNetworkId(),
|
||||
getVlan(), getStartIp(), getGateway(), getNetmask(), getEntityOwnerId());
|
||||
getVlan(), getStartIp(), getGateway(), getNetmask(), getEntityOwnerId(), getIsSourceNat());
|
||||
} catch (InsufficientCapacityException ex){
|
||||
s_logger.info(ex);
|
||||
s_logger.trace(ex);
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ public class EnableStaticNatCmd extends BaseCmd{
|
|||
@Override
|
||||
public void execute() throws ResourceUnavailableException{
|
||||
try {
|
||||
boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, getNetworkId(), false, getVmSecondaryIp());
|
||||
boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, getNetworkId(), getVmSecondaryIp());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd {
|
|||
|
||||
@Override
|
||||
public void execute() {
|
||||
s_logger.info("VOLSS: createSnapshotCmd starts:" + System.currentTimeMillis());
|
||||
UserContext.current().setEventDetails("Volume Id: "+getVolumeId());
|
||||
Snapshot snapshot = _snapshotService.createSnapshot(getVolumeId(), getPolicyId(), getEntityId(), _accountService.getAccount(getEntityOwnerId()));
|
||||
if (snapshot != null) {
|
||||
|
|
@ -172,6 +173,7 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd {
|
|||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot due to an internal error creating snapshot for volume " + volumeId);
|
||||
}
|
||||
s_logger.info("VOLSS: backupSnapshotCmd finishes:" + System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,11 +22,12 @@ import com.cloud.user.UserContext;
|
|||
import com.cloud.uservm.UserVm;
|
||||
import org.apache.cloudstack.api.*;
|
||||
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
||||
@APICommand(name = "scaleVirtualMachine", description="Scales the virtual machine to a new service offering.", responseObject=UserVmResponse.class)
|
||||
@APICommand(name = "scaleVirtualMachine", description="Scales the virtual machine to a new service offering.", responseObject=SuccessResponse.class)
|
||||
public class ScaleVMCmd extends BaseCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(ScaleVMCmd.class.getName());
|
||||
private static final String s_name = "scalevirtualmachineresponse";
|
||||
|
|
@ -83,7 +84,7 @@ public class ScaleVMCmd extends BaseCmd {
|
|||
@Override
|
||||
public void execute(){
|
||||
//UserContext.current().setEventDetails("Vm Id: "+getId());
|
||||
UserVm result = null;
|
||||
boolean result;
|
||||
try {
|
||||
result = _userVmService.upgradeVirtualMachine(this);
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
|
|
@ -99,9 +100,8 @@ public class ScaleVMCmd extends BaseCmd {
|
|||
s_logger.warn("Exception: ", ex);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
|
||||
}
|
||||
if (result != null){
|
||||
UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
|
||||
response.setResponseName(getCommandName());
|
||||
if (result){
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to scale vm");
|
||||
|
|
|
|||
|
|
@ -37,11 +37,11 @@ import com.cloud.user.UserContext;
|
|||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
|
||||
@APICommand(name = "revertToSnapshot",description = "Revert VM from a vmsnapshot.", responseObject = UserVmResponse.class, since="4.2.0")
|
||||
public class RevertToSnapshotCmd extends BaseAsyncCmd {
|
||||
@APICommand(name = "revertToVMSnapshot",description = "Revert VM from a vmsnapshot.", responseObject = UserVmResponse.class, since="4.2.0")
|
||||
public class RevertToVMSnapshotCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger
|
||||
.getLogger(RevertToSnapshotCmd.class.getName());
|
||||
private static final String s_name = "reverttosnapshotresponse";
|
||||
.getLogger(RevertToVMSnapshotCmd.class.getName());
|
||||
private static final String s_name = "reverttovmsnapshotresponse";
|
||||
|
||||
@Parameter(name = ApiConstants.VM_SNAPSHOT_ID, type = CommandType.UUID, required = true,entityType=VMSnapshotResponse.class,description = "The ID of the vm snapshot")
|
||||
private Long vmSnapShotId;
|
||||
|
|
@ -76,6 +76,10 @@ public class PrivateGatewayResponse extends BaseResponse implements ControlledEn
|
|||
private String state;
|
||||
|
||||
|
||||
@SerializedName(ApiConstants.SOURCE_NAT_SUPPORTED) @Param(description = "Souce Nat enable status")
|
||||
private Boolean sourceNat;
|
||||
|
||||
|
||||
@Override
|
||||
public String getObjectId() {
|
||||
return this.id;
|
||||
|
|
@ -145,5 +149,11 @@ public class PrivateGatewayResponse extends BaseResponse implements ControlledEn
|
|||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public void setSourceNat(Boolean sourceNat) {
|
||||
this.sourceNat = sourceNat;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,31 +16,20 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.api.command.test;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.vm.UserVmService;
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.cloudstack.api.ResponseGenerator;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.command.admin.region.AddRegionCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
|
||||
import org.apache.cloudstack.api.response.RegionResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.region.Region;
|
||||
import org.apache.cloudstack.region.RegionService;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
public class ScaleVMCmdTest extends TestCase{
|
||||
|
||||
private ScaleVMCmd scaleVMCmd;
|
||||
|
|
@ -57,12 +46,11 @@ public class ScaleVMCmdTest extends TestCase{
|
|||
public Long getId() {
|
||||
return 2L;
|
||||
}
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "scalevirtualmachineresponse";
|
||||
}
|
||||
};
|
||||
|
||||
//Account account = new AccountVO("testaccount", 1L, "networkdomain", (short) 0, "uuid");
|
||||
//UserContext.registerContext(1, account, null, true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -71,11 +59,10 @@ public class ScaleVMCmdTest extends TestCase{
|
|||
|
||||
UserVmService userVmService = Mockito.mock(UserVmService.class);
|
||||
|
||||
UserVm uservm = Mockito.mock(UserVm.class);
|
||||
try {
|
||||
Mockito.when(
|
||||
userVmService.upgradeVirtualMachine(scaleVMCmd))
|
||||
.thenReturn(uservm);
|
||||
.thenReturn(true);
|
||||
}catch (Exception e){
|
||||
Assert.fail("Received exception when success expected " +e.getMessage());
|
||||
}
|
||||
|
|
@ -83,13 +70,6 @@ public class ScaleVMCmdTest extends TestCase{
|
|||
scaleVMCmd._userVmService = userVmService;
|
||||
responseGenerator = Mockito.mock(ResponseGenerator.class);
|
||||
|
||||
UserVmResponse userVmResponse = Mockito.mock(UserVmResponse.class);
|
||||
List<UserVmResponse> responseList = new ArrayList<UserVmResponse>();
|
||||
responseList.add(userVmResponse);
|
||||
|
||||
Mockito.when(responseGenerator.createUserVmResponse("virtualmachine",uservm))
|
||||
.thenReturn(responseList);
|
||||
|
||||
scaleVMCmd._responseGenerator = responseGenerator;
|
||||
scaleVMCmd.execute();
|
||||
|
||||
|
|
@ -101,10 +81,9 @@ public class ScaleVMCmdTest extends TestCase{
|
|||
UserVmService userVmService = Mockito.mock(UserVmService.class);
|
||||
|
||||
try {
|
||||
UserVm uservm = Mockito.mock(UserVm.class);
|
||||
Mockito.when(
|
||||
userVmService.upgradeVirtualMachine(scaleVMCmd))
|
||||
.thenReturn(null);
|
||||
.thenReturn(false);
|
||||
}catch (Exception e){
|
||||
Assert.fail("Received exception when success expected " +e.getMessage());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -569,7 +569,7 @@ removeFromGlobalLoadBalancerRule=15
|
|||
listVMSnapshot=15
|
||||
createVMSnapshot=15
|
||||
deleteVMSnapshot=15
|
||||
revertToSnapshot=15
|
||||
revertToVMSnapshot=15
|
||||
|
||||
#### Baremetal commands
|
||||
addBaremetalHost=1
|
||||
|
|
|
|||
|
|
@ -863,13 +863,16 @@ public class VirtualRoutingResource implements Manager {
|
|||
}
|
||||
|
||||
public void assignVpcIpToRouter(final String routerIP, final boolean add, final String pubIP,
|
||||
final String nicname, final String gateway, final String netmask, final String subnet) throws InternalErrorException {
|
||||
final String nicname, final String gateway, final String netmask, final String subnet, boolean sourceNat) throws InternalErrorException {
|
||||
String args = "";
|
||||
String snatArgs = "";
|
||||
|
||||
if (add) {
|
||||
args += " -A ";
|
||||
snatArgs += " -A ";
|
||||
} else {
|
||||
args += " -D ";
|
||||
snatArgs += " -D ";
|
||||
}
|
||||
|
||||
args += " -l ";
|
||||
|
|
@ -887,6 +890,16 @@ public class VirtualRoutingResource implements Manager {
|
|||
if (result != null) {
|
||||
throw new InternalErrorException("KVM plugin \"vpc_ipassoc\" failed:"+result);
|
||||
}
|
||||
if (sourceNat) {
|
||||
snatArgs += " -l " + pubIP;
|
||||
snatArgs += " -c " + nicname;
|
||||
|
||||
result = routerProxy("vpc_privateGateway.sh", routerIP, snatArgs);
|
||||
if (result != null) {
|
||||
throw new InternalErrorException("KVM plugin \"vpc_privateGateway\" failed:"+result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import com.cloud.agent.api.storage.CopyVolumeAnswer;
|
|||
import com.cloud.agent.api.storage.CopyVolumeCommand;
|
||||
import com.cloud.agent.api.storage.CreateAnswer;
|
||||
import com.cloud.agent.api.storage.CreateCommand;
|
||||
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.PrimaryStorageDownloadAnswer;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
|
|
@ -34,5 +36,7 @@ public interface StoragePoolResource {
|
|||
|
||||
CopyVolumeAnswer execute(CopyVolumeCommand cmd);
|
||||
|
||||
CreateVolumeOVAAnswer execute(CreateVolumeOVACommand cmd);
|
||||
|
||||
CreateAnswer execute(CreateCommand cmd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,16 +21,31 @@
|
|||
<section id="elastic-ip">
|
||||
<title>About Elastic IP</title>
|
||||
<para>Elastic IP (EIP) addresses are the IP addresses that are associated with an account, and act
|
||||
as static IP addresses. The account owner has complete control over the Elastic IP addresses
|
||||
that belong to the account. You can allocate an Elastic IP to a VM of your choice from the EIP
|
||||
pool of your account. Later if required you can reassign the IP address to a different VM. This
|
||||
feature is extremely helpful during VM failure. Instead of replacing the VM which is down, the
|
||||
IP address can be reassigned to a new VM in your account. Elastic IP service provides Static NAT
|
||||
(1:1) service in an EIP-enabled basic zone. The default network offering,
|
||||
as static IP addresses. The account owner has the complete control over the Elastic IP addresses
|
||||
that belong to the account. As an account owner, you can allocate an Elastic IP to a VM of your
|
||||
choice from the EIP pool of your account. Later if required you can reassign the IP address to a
|
||||
different VM. This feature is extremely helpful during VM failure. Instead of replacing the VM
|
||||
which is down, the IP address can be reassigned to a new VM in your account. </para>
|
||||
<para>Similar to the public IP address, Elastic IP addresses are mapped to their associated
|
||||
private IP addresses by using StaticNAT. The EIP service is equipped with StaticNAT (1:1)
|
||||
service in an EIP-enabled basic zone. The default network offering,
|
||||
DefaultSharedNetscalerEIPandELBNetworkOffering, provides your network with EIP and ELB network
|
||||
services if a NetScaler device is deployed in your zone. Similar to the public IP address,
|
||||
Elastic IP addresses are also mapped to their associated private IP addresses by using Stactic
|
||||
NAT.</para>
|
||||
services if a NetScaler device is deployed in your zone. Consider the following illustration for
|
||||
more details.</para>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="./images/eip-ns-basiczone.png"/>
|
||||
</imageobject>
|
||||
<textobject>
|
||||
<phrase>eip-ns-basiczone.png: Elastic IP in a NetScaler-enabled Basic Zone.</phrase>
|
||||
</textobject>
|
||||
</mediaobject>
|
||||
<para>In the illustration, a NetScaler appliance is the default entry or exit point for the
|
||||
&PRODUCT; instances, and firewall is the default entry or exit point for the rest of the data
|
||||
center. Netscaler provides LB services and staticNAT service to the guest networks. The guest
|
||||
traffic in the pods and the Management Server are on different subnets / VLANs. The policy-based
|
||||
routing in the data center core switch sends the public traffic through the NetScaler, whereas
|
||||
the rest of the data center goes through the firewall. </para>
|
||||
<para>The EIP work flow is as follows:</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
|
|
@ -48,7 +63,6 @@
|
|||
supported by NetScaler, in which the source IP address is replaced in the packets
|
||||
generated by a VM in the private network with the public IP address.</para>
|
||||
</note>
|
||||
<para/>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>This default public IP will be released in two cases:</para>
|
||||
|
|
@ -68,12 +82,12 @@
|
|||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>However, for the deployments where public IPs are limited resources, you have the
|
||||
flexibility to choose not to allocate a public IP by default. You can use the Associate Public
|
||||
IP option to turn on or off the automatic public IP assignment in the EIP-enabled Basic zones.
|
||||
If you turn off the automatic public IP assignment while creating a network offering, only a
|
||||
private IP is assigned to a VM when the VM is deployed with that network offering. Later, the
|
||||
user can acquire an IP for the VM and enable static NAT.</para>
|
||||
<para>For the deployments where public IPs are limited resources, you have the flexibility to
|
||||
choose not to allocate a public IP by default. You can use the Associate Public IP option to
|
||||
turn on or off the automatic public IP assignment in the EIP-enabled Basic zones. If you turn
|
||||
off the automatic public IP assignment while creating a network offering, only a private IP is
|
||||
assigned to a VM when the VM is deployed with that network offering. Later, the user can acquire
|
||||
an IP for the VM and enable static NAT.</para>
|
||||
<para condition="admin">For more information on the Associate Public IP option, see <xref
|
||||
linkend="creating-network-offerings"/>.</para>
|
||||
<para condition="install">For more information on the Associate Public IP option, see the
|
||||
|
|
@ -83,7 +97,6 @@
|
|||
continue to get both public IP and private by default, irrespective of the network offering
|
||||
configuration.</para>
|
||||
</note>
|
||||
<para/>
|
||||
<para>New deployments which use the default shared network offering with EIP and ELB services to
|
||||
create a shared network in the Basic zone will continue allocating public IPs to each user
|
||||
VM.</para>
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 62 KiB |
|
|
@ -442,6 +442,9 @@ setup_dnsmasq() {
|
|||
[ -z $DHCP_RANGE ] && [ $ETH0_IP ] && DHCP_RANGE=$ETH0_IP
|
||||
[ $ETH0_IP6 ] && DHCP_RANGE_IP6=$ETH0_IP6
|
||||
[ -z $DOMAIN ] && DOMAIN="cloudnine.internal"
|
||||
|
||||
#get the template
|
||||
cp /etc/dnsmasq.conf.tmpl /etc/dnsmasq.conf
|
||||
|
||||
if [ -n "$DOMAIN" ]
|
||||
then
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ fi
|
|||
|
||||
if [ "$Dflag" == "1" ]
|
||||
then
|
||||
remove_sat $publicIp
|
||||
remove_snat $publicIp
|
||||
unlock_exit $? $lock $locked
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -113,7 +113,8 @@ if [ $ipv6 ]
|
|||
then
|
||||
sed -i /$ipv6,/d $DHCP_HOSTS
|
||||
fi
|
||||
sed -i /$host,/d $DHCP_HOSTS
|
||||
# don't want to do this in the future, we can have same VM with multiple nics/entries
|
||||
#sed -i /$host,/d $DHCP_HOSTS
|
||||
|
||||
|
||||
#put in the new entry
|
||||
|
|
|
|||
|
|
@ -1756,7 +1756,7 @@ ServerResource {
|
|||
String netmask = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask()));
|
||||
String subnet = NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask());
|
||||
_virtRouterResource.assignVpcIpToRouter(routerIP, ip.isAdd(), ip.getPublicIp(),
|
||||
nicName, ip.getVlanGateway(), netmask, subnet);
|
||||
nicName, ip.getVlanGateway(), netmask, subnet, ip.isSourceNat());
|
||||
results[i++] = ip.getPublicIp() + " - success";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
|
|||
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
|
||||
import com.cloud.agent.api.UnregisterVMCommand;
|
||||
import com.cloud.agent.api.storage.CopyVolumeCommand;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVACommand;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
import com.cloud.agent.api.to.NicTO;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
|
|
@ -282,10 +284,18 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
|
|||
cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
|
||||
cmd instanceof CreatePrivateTemplateFromSnapshotCommand ||
|
||||
cmd instanceof CopyVolumeCommand ||
|
||||
cmd instanceof CreateVolumeOVACommand ||
|
||||
cmd instanceof PrepareOVAPackingCommand ||
|
||||
cmd instanceof CreateVolumeFromSnapshotCommand) {
|
||||
needDelegation = true;
|
||||
}
|
||||
/* Fang: remove this before checking in */
|
||||
// needDelegation = false;
|
||||
|
||||
if (cmd instanceof PrepareOVAPackingCommand ||
|
||||
cmd instanceof CreateVolumeOVACommand ) {
|
||||
cmd.setContextParam("hypervisor", HypervisorType.VMware.toString());
|
||||
}
|
||||
if(needDelegation) {
|
||||
HostVO host = _hostDao.findById(hostId);
|
||||
assert(host != null);
|
||||
|
|
@ -311,6 +321,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
|
|||
cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
|
||||
cmd instanceof CreatePrivateTemplateFromSnapshotCommand ||
|
||||
cmd instanceof CopyVolumeCommand ||
|
||||
cmd instanceof CreateVolumeOVACommand ||
|
||||
cmd instanceof PrepareOVAPackingCommand ||
|
||||
cmd instanceof CreateVolumeFromSnapshotCommand) {
|
||||
|
||||
String workerName = _vmwareMgr.composeWorkerName();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
|
|||
import com.cloud.agent.api.DeleteVMSnapshotCommand;
|
||||
import com.cloud.agent.api.RevertToVMSnapshotCommand;
|
||||
import com.cloud.agent.api.storage.CopyVolumeCommand;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVACommand;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
|
||||
public interface VmwareStorageManager {
|
||||
|
|
@ -33,6 +35,8 @@ public interface VmwareStorageManager {
|
|||
Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVolumeCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromSnapshotCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CopyVolumeCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CreateVolumeOVACommand cmd);
|
||||
Answer execute(VmwareHostService hostService, PrepareOVAPackingCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CreateVolumeFromSnapshotCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CreateVMSnapshotCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, DeleteVMSnapshotCommand cmd);
|
||||
|
|
|
|||
|
|
@ -18,12 +18,14 @@ package com.cloud.hypervisor.vmware.manager;
|
|||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -44,6 +46,10 @@ import com.cloud.agent.api.RevertToVMSnapshotAnswer;
|
|||
import com.cloud.agent.api.RevertToVMSnapshotCommand;
|
||||
import com.cloud.agent.api.storage.CopyVolumeAnswer;
|
||||
import com.cloud.agent.api.storage.CopyVolumeCommand;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingAnswer;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVAAnswer;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVACommand;
|
||||
import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
|
|
@ -102,6 +108,109 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
|||
_timeout = NumbersUtil.parseInt(value, 1440) * 1000;
|
||||
}
|
||||
|
||||
//Fang note: use Answer here instead of the PrepareOVAPackingAnswer
|
||||
@Override
|
||||
public Answer execute(VmwareHostService hostService, PrepareOVAPackingCommand cmd) {
|
||||
String secStorageUrl = ((PrepareOVAPackingCommand) cmd).getSecondaryStorageUrl();
|
||||
assert (secStorageUrl != null);
|
||||
String installPath = cmd.getTemplatePath();
|
||||
String details = null;
|
||||
boolean success = false;
|
||||
String ovafileName = "";
|
||||
s_logger.info("Fang: execute OVAPacking cmd at vmwareMngImpl. ");
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
|
||||
// String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId);
|
||||
String installFullPath = secondaryMountPoint + "/" + installPath;
|
||||
|
||||
String templateName = installFullPath; // should be a file ending .ova;
|
||||
s_logger.info("Fang: execute vmwareMgrImpl: templateNAme " + templateName);
|
||||
// Fang: Dir list, if there is ova file, done; Fang: add answer cmd;
|
||||
// if not, from ova.meta, create a new OVA file;
|
||||
// change the install path to *.ova , not ova.meta;
|
||||
// VmwareContext context = hostService.getServiceContext(cmd); //Fang: we may not have the CTX here
|
||||
try {
|
||||
if (templateName.endsWith(".ova")) {
|
||||
if(new File(templateName).exists()) {
|
||||
details = "OVA files exists. succeed. ";
|
||||
return new Answer(cmd, true, details);
|
||||
} else {
|
||||
if (new File(templateName + ".meta").exists()) { //Fang parse the meta file
|
||||
//execute the tar command;
|
||||
s_logger.info("Fang: execute vmwareMgrImpl: getfromMeta " + templateName);
|
||||
ovafileName = getOVAFromMetafile(templateName + ".meta");
|
||||
details = "OVA file in meta file is " + ovafileName;
|
||||
return new Answer(cmd, true, details);
|
||||
} else {
|
||||
String msg = "Unable to find ova meta or ova file to prepare template (vmware)";
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof RemoteException) {
|
||||
//hostService.invalidateServiceContext(context); do not need context
|
||||
s_logger.error("Unable to connect to remote service ");
|
||||
details = "Unable to connect to remote service ";
|
||||
return new Answer(cmd, false, details);
|
||||
}
|
||||
String msg = "Unable to execute PrepareOVAPackingCommand due to exception";
|
||||
s_logger.error(msg, e);
|
||||
return new Answer(cmd, false, details);
|
||||
}
|
||||
return new Answer(cmd, true, details);
|
||||
}
|
||||
|
||||
//Fang: new command added;
|
||||
// Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature)
|
||||
@Override
|
||||
public Answer execute(VmwareHostService hostService, CreateVolumeOVACommand cmd) {
|
||||
String secStorageUrl = ((CreateVolumeOVACommand) cmd).getSecondaryStorageUrl();
|
||||
assert (secStorageUrl != null);
|
||||
String installPath = cmd.getVolPath();
|
||||
String details = null;
|
||||
boolean success = false;
|
||||
|
||||
s_logger.info("volss: execute CreateVolumeOVA cmd at vmwareMngImpl. ");
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
|
||||
// String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId);
|
||||
s_logger.info("volss: mountPoint: " + secondaryMountPoint + "installPath:" + installPath);
|
||||
String installFullPath = secondaryMountPoint + "/" + installPath;
|
||||
|
||||
String volName = cmd.getVolName(); // should be a UUID, without ova ovf, etc;
|
||||
s_logger.info("volss: execute vmwareMgrImpl: VolName " + volName);
|
||||
// Fang: Dir list, if there is ova file, done; Note: add answer cmd;
|
||||
|
||||
try {
|
||||
if(new File(volName + ".ova").exists()) {
|
||||
details = "OVA files exists. succeed. ";
|
||||
return new CreateVolumeOVAAnswer(cmd, true, details);
|
||||
} else {
|
||||
File ovaFile = new File(installFullPath);
|
||||
String exportDir = ovaFile.getParent();
|
||||
|
||||
s_logger.info("Fang: exportDir is (for VolumeOVA): " + exportDir);
|
||||
s_logger.info("Sync file system before we package OVA...");
|
||||
|
||||
Script commandSync = new Script(true, "sync", 0, s_logger);
|
||||
commandSync.execute();
|
||||
|
||||
Script command = new Script(false, "tar", 0, s_logger);
|
||||
command.setWorkDir(exportDir);
|
||||
command.add("-cf", volName + ".ova");
|
||||
command.add(volName + ".ovf"); // OVF file should be the first file in OVA archive
|
||||
command.add(volName + "-disk0.vmdk");
|
||||
|
||||
s_logger.info("Package Volume OVA with commmand: " + command.toString());
|
||||
command.execute();
|
||||
return new CreateVolumeOVAAnswer(cmd, true, details);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
s_logger.info("Exception for createVolumeOVA");
|
||||
}
|
||||
return new CreateVolumeOVAAnswer(cmd, true, "fail to pack OVA for volume");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Answer execute(VmwareHostService hostService, PrimaryStorageDownloadCommand cmd) {
|
||||
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
|
||||
|
|
@ -570,11 +679,14 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
|||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
|
||||
String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId);
|
||||
String installFullPath = secondaryMountPoint + "/" + installPath;
|
||||
String installFullName = installFullPath + "/" + templateUniqueName + ".ova";
|
||||
String snapshotFullName = secondaryMountPoint + "/" + getSnapshotRelativeDirInSecStorage(accountId, volumeId)
|
||||
+ "/" + backedUpSnapshotUuid + ".ova";
|
||||
String installFullOVAName = installFullPath + "/" + templateUniqueName + ".ova"; //Note: volss for tmpl
|
||||
String snapshotRoot = secondaryMountPoint + "/" + getSnapshotRelativeDirInSecStorage(accountId, volumeId);
|
||||
String snapshotFullOVAName = snapshotRoot + "/" + backedUpSnapshotUuid + ".ova";
|
||||
String snapshotFullOvfName = snapshotRoot + "/" + backedUpSnapshotUuid + ".ovf";
|
||||
String result;
|
||||
Script command;
|
||||
String templateVMDKName = "";
|
||||
String snapshotFullVMDKName = snapshotRoot + "/";
|
||||
|
||||
synchronized(installPath.intern()) {
|
||||
command = new Script(false, "mkdir", _timeout, s_logger);
|
||||
|
|
@ -591,40 +703,85 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
|||
}
|
||||
|
||||
try {
|
||||
command = new Script(false, "cp", _timeout, s_logger);
|
||||
command.add(snapshotFullName);
|
||||
command.add(installFullName);
|
||||
result = command.execute();
|
||||
if(result != null) {
|
||||
String msg = "unable to copy snapshot " + snapshotFullName + " to " + installFullPath;
|
||||
if(new File(snapshotFullOVAName).exists()) {
|
||||
command = new Script(false, "cp", _timeout, s_logger);
|
||||
command.add(snapshotFullOVAName);
|
||||
command.add(installFullOVAName);
|
||||
result = command.execute();
|
||||
if(result != null) {
|
||||
String msg = "unable to copy snapshot " + snapshotFullOVAName + " to " + installFullPath;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
// untar OVA file at template directory
|
||||
command = new Script("tar", 0, s_logger);
|
||||
command.add("--no-same-owner");
|
||||
command.add("-xf", installFullOVAName);
|
||||
command.setWorkDir(installFullPath);
|
||||
s_logger.info("Executing command: " + command.toString());
|
||||
result = command.execute();
|
||||
if(result != null) {
|
||||
String msg = "unable to untar snapshot " + snapshotFullOVAName + " to "
|
||||
+ installFullPath;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
} else { // there is no ova file, only ovf originally;
|
||||
if(new File(snapshotFullOvfName).exists()) {
|
||||
command = new Script(false, "cp", _timeout, s_logger);
|
||||
command.add(snapshotFullOvfName);
|
||||
//command.add(installFullOvfName);
|
||||
command.add(installFullPath);
|
||||
result = command.execute();
|
||||
if(result != null) {
|
||||
String msg = "unable to copy snapshot " + snapshotFullOvfName + " to " + installFullPath;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
File snapshotdir = new File(snapshotRoot);
|
||||
File[] ssfiles = snapshotdir.listFiles();
|
||||
// List<String> filenames = new ArrayList<String>();
|
||||
for (int i = 0; i < ssfiles.length; i++) {
|
||||
String vmdkfile = ssfiles[i].getName();
|
||||
if(vmdkfile.toLowerCase().startsWith(backedUpSnapshotUuid) && vmdkfile.toLowerCase().endsWith(".vmdk")) {
|
||||
snapshotFullVMDKName += vmdkfile;
|
||||
templateVMDKName += vmdkfile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (snapshotFullVMDKName != null) {
|
||||
command = new Script(false, "cp", _timeout, s_logger);
|
||||
command.add(snapshotFullVMDKName);
|
||||
command.add(installFullPath);
|
||||
result = command.execute();
|
||||
s_logger.info("Copy VMDK file: " + snapshotFullVMDKName);
|
||||
if(result != null) {
|
||||
String msg = "unable to copy snapshot vmdk file " + snapshotFullVMDKName + " to " + installFullPath;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String msg = "unable to find any snapshot ova/ovf files" + snapshotFullOVAName + " to " + installFullPath;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// untar OVA file at template directory
|
||||
command = new Script("tar", 0, s_logger);
|
||||
command.add("--no-same-owner");
|
||||
command.add("-xf", installFullName);
|
||||
command.setWorkDir(installFullPath);
|
||||
s_logger.info("Executing command: " + command.toString());
|
||||
result = command.execute();
|
||||
if(result != null) {
|
||||
String msg = "unable to untar snapshot " + snapshotFullName + " to "
|
||||
+ installFullPath;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
long physicalSize = new File(installFullPath + "/" + templateUniqueName + ".ova").length();
|
||||
long physicalSize = new File(installFullPath + "/" + templateVMDKName).length();
|
||||
VmdkProcessor processor = new VmdkProcessor();
|
||||
// long physicalSize = new File(installFullPath + "/" + templateUniqueName + ".ova").length();
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put(StorageLayer.InstanceConfigKey, _storage);
|
||||
processor.configure("VMDK Processor", params);
|
||||
long virtualSize = processor.getTemplateVirtualSize(installFullPath, templateUniqueName);
|
||||
|
||||
postCreatePrivateTemplate(installFullPath, templateId, templateUniqueName, physicalSize, virtualSize);
|
||||
writeMetaOvaForTemplate(installFullPath, backedUpSnapshotUuid + ".ovf", templateVMDKName, templateUniqueName, physicalSize);
|
||||
return new Ternary<String, Long, Long>(installPath + "/" + templateUniqueName + ".ova", physicalSize, virtualSize);
|
||||
|
||||
} catch(Exception e) {
|
||||
// TODO, clean up left over files
|
||||
throw e;
|
||||
|
|
@ -648,7 +805,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
|||
out.newLine();
|
||||
out.write("size=" + size);
|
||||
out.newLine();
|
||||
out.write("ova=true");
|
||||
//out.write("ova=true");
|
||||
out.write("ova=false"); //volss: the real ova file is not created
|
||||
out.newLine();
|
||||
out.write("id=" + templateId);
|
||||
out.newLine();
|
||||
|
|
@ -670,6 +828,31 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
|||
}
|
||||
}
|
||||
|
||||
private void writeMetaOvaForTemplate(String installFullPath, String ovfFilename, String vmdkFilename,
|
||||
String templateName, long diskSize) throws Exception {
|
||||
|
||||
// TODO a bit ugly here
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/" + templateName +".ova.meta")));
|
||||
out.write("ova.filename=" + templateName + ".ova");
|
||||
out.newLine();
|
||||
out.write("version=1.0");
|
||||
out.newLine();
|
||||
out.write("ovf=" + ovfFilename);
|
||||
out.newLine();
|
||||
out.write("numDisks=1");
|
||||
out.newLine();
|
||||
out.write("disk1.name=" + vmdkFilename);
|
||||
out.newLine();
|
||||
out.write("disk1.size=" + diskSize);
|
||||
out.newLine();
|
||||
} finally {
|
||||
if(out != null)
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
private String createVolumeFromSnapshot(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName,
|
||||
long accountId, long volumeId, String secStorageUrl, String snapshotBackupUuid) throws Exception {
|
||||
|
||||
|
|
@ -688,23 +871,35 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
|||
if (backupName.contains("/")){
|
||||
snapshotDir = backupName.split("/")[0];
|
||||
}
|
||||
String srcFileName = getOVFFilePath(srcOVAFileName);
|
||||
if(srcFileName == null) {
|
||||
Script command = new Script("tar", 0, s_logger);
|
||||
command.add("--no-same-owner");
|
||||
command.add("-xf", srcOVAFileName);
|
||||
command.setWorkDir(secondaryMountPoint + "/" + secStorageDir + "/" + snapshotDir);
|
||||
s_logger.info("Executing command: " + command.toString());
|
||||
String result = command.execute();
|
||||
if(result != null) {
|
||||
String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
|
||||
srcFileName = getOVFFilePath(srcOVAFileName);
|
||||
if(srcFileName == null) {
|
||||
File ovafile = new File(srcOVAFileName);
|
||||
String srcOVFFileName = secondaryMountPoint + "/" + secStorageDir + "/"
|
||||
+ backupName + ".ovf";
|
||||
File ovfFile = new File(srcOVFFileName);
|
||||
// String srcFileName = getOVFFilePath(srcOVAFileName);
|
||||
if (!ovfFile.exists()) {
|
||||
srcOVFFileName = getOVFFilePath(srcOVAFileName);
|
||||
if(srcOVFFileName == null && ovafile.exists() ) { // volss: ova file exists; o/w can't do tar
|
||||
Script command = new Script("tar", 0, s_logger);
|
||||
command.add("--no-same-owner");
|
||||
command.add("-xf", srcOVAFileName);
|
||||
command.setWorkDir(secondaryMountPoint + "/" + secStorageDir + "/" + snapshotDir);
|
||||
s_logger.info("Executing command: " + command.toString());
|
||||
String result = command.execute();
|
||||
if(result != null) {
|
||||
String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
} else {
|
||||
String msg = "Unable to find snapshot OVA file at: " + srcOVAFileName;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
srcOVFFileName = getOVFFilePath(srcOVAFileName);
|
||||
}
|
||||
if(srcOVFFileName == null) {
|
||||
String msg = "Unable to locate OVF file in template package directory: " + srcOVAFileName;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
|
|
@ -712,7 +907,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
|||
|
||||
VirtualMachineMO clonedVm = null;
|
||||
try {
|
||||
hyperHost.importVmFromOVF(srcFileName, newVolumeName, primaryDsMo, "thin");
|
||||
hyperHost.importVmFromOVF(srcOVFFileName, newVolumeName, primaryDsMo, "thin");
|
||||
clonedVm = hyperHost.findVmOnHyperHost(newVolumeName);
|
||||
if(clonedVm == null)
|
||||
throw new Exception("Unable to create container VM for volume creation");
|
||||
|
|
@ -774,7 +969,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
|||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
clonedVm.exportVm(exportPath, exportName, true, true);
|
||||
clonedVm.exportVm(exportPath, exportName, false, false); //Note: volss: not to create ova.
|
||||
} finally {
|
||||
if(clonedVm != null) {
|
||||
clonedVm.detachAllDisks();
|
||||
|
|
@ -787,17 +982,31 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
|||
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
|
||||
String snapshotMountRoot = secondaryMountPoint + "/" + getSnapshotRelativeDirInSecStorage(accountId, volumeId);
|
||||
File file = new File(snapshotMountRoot + "/" + backupUuid + ".ova");
|
||||
File file = new File(snapshotMountRoot + "/" + backupUuid + ".ovf");
|
||||
if(file.exists()) {
|
||||
if(file.delete())
|
||||
return null;
|
||||
|
||||
} else {
|
||||
return "Backup file does not exist. backupUuid: " + backupUuid;
|
||||
}
|
||||
|
||||
return "Failed to delete snapshot backup file, backupUuid: " + backupUuid;
|
||||
}
|
||||
File snapshotdir = new File(snapshotMountRoot);
|
||||
File[] ssfiles = snapshotdir.listFiles();
|
||||
// List<String> filenames = new ArrayList<String>();
|
||||
for (int i = 0; i < ssfiles.length; i++) {
|
||||
String vmdkfile = ssfiles[i].getName();
|
||||
if(vmdkfile.toLowerCase().startsWith(backupUuid) && vmdkfile.toLowerCase().endsWith(".vmdk")) {
|
||||
// filenames.add(vmdkfile);
|
||||
new File(vmdkfile).delete();
|
||||
}
|
||||
}
|
||||
if(file.delete())
|
||||
return null;
|
||||
} else {
|
||||
File file1 = new File(snapshotMountRoot + "/" + backupUuid + ".ova");
|
||||
if(file1.exists()) {
|
||||
if(file1.delete())
|
||||
return null;
|
||||
} else {
|
||||
return "Backup file does not exist. backupUuid: " + backupUuid;
|
||||
}
|
||||
}
|
||||
return "Failed to delete snapshot backup file, backupUuid: " + backupUuid;
|
||||
}
|
||||
|
||||
private Pair<String, String> copyVolumeToSecStorage(VmwareHostService hostService, VmwareHypervisorHost hyperHost, CopyVolumeCommand cmd,
|
||||
String vmName, long volumeId, String poolId, String volumePath,
|
||||
|
|
@ -881,6 +1090,92 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
|||
return new Pair<String, String>(volumeFolder, newVolume);
|
||||
}
|
||||
|
||||
//Fang: here I use a method to return the ovf and vmdk file names; Another way to do it:
|
||||
// create a new class, and like TemplateLocation.java and create templateOvfInfo.java to handle it;
|
||||
private String getOVAFromMetafile(String metafileName) throws Exception {
|
||||
File ova_metafile = new File(metafileName);
|
||||
Properties props = null;
|
||||
FileInputStream strm = null;
|
||||
String ovaFileName = "";
|
||||
s_logger.info("Fang: getOVAfromMetaFile: metafileName " + metafileName);
|
||||
try {
|
||||
strm = new FileInputStream(ova_metafile);
|
||||
if (null == strm) {
|
||||
String msg = "Cannot read ova meat file. Error";
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
s_logger.info("Fang: getOVAfromMetaFile: load strm " );
|
||||
if (null != ova_metafile) {
|
||||
props = new Properties();
|
||||
props.load(strm);
|
||||
if (props == null) {
|
||||
s_logger.info("Fang: getOVAfromMetaFile: props is null. " );
|
||||
}
|
||||
}
|
||||
if (null != props) {
|
||||
ovaFileName = props.getProperty("ova.filename");
|
||||
s_logger.info("Fang: ovafilename" + ovaFileName);
|
||||
String ovfFileName = props.getProperty("ovf");
|
||||
s_logger.info("Fang: ovffilename" + ovfFileName);
|
||||
int diskNum = Integer.parseInt(props.getProperty("numDisks"));
|
||||
if (diskNum <= 0) {
|
||||
String msg = "VMDK disk file number is 0. Error";
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
String[] disks = new String[diskNum];
|
||||
for (int i = 0; i < diskNum; i++) {
|
||||
//String diskNameKey = "disk" + Integer.toString(i+1) + ".name"; // Fang use this
|
||||
String diskNameKey = "disk1.name";
|
||||
disks[i] = props.getProperty(diskNameKey);
|
||||
s_logger.info("Fang: diskname " + disks[i]);
|
||||
}
|
||||
String exportDir = ova_metafile.getParent();
|
||||
s_logger.info("Fang: exportDir: " + exportDir);
|
||||
// Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature)
|
||||
s_logger.info("Fang: Sync file system before we package OVA..., before tar ");
|
||||
s_logger.info("Fang: ova: " + ovaFileName+ ", ovf:" + ovfFileName + ", vmdk:" + disks[0] + ".");
|
||||
Script commandSync = new Script(true, "sync", 0, s_logger);
|
||||
commandSync.execute();
|
||||
Script command = new Script(false, "tar", 0, s_logger);
|
||||
command.setWorkDir(exportDir); //Fang: pass this in to the method?
|
||||
command.add("-cf", ovaFileName);
|
||||
command.add(ovfFileName); // OVF file should be the first file in OVA archive
|
||||
for(String diskName: disks) {
|
||||
command.add(diskName);
|
||||
}
|
||||
command.execute();
|
||||
s_logger.info("Fang: Package OVA for template in dir: " + exportDir + "cmd: " + command.toString());
|
||||
// to be safe, physically test existence of the target OVA file
|
||||
if((new File(exportDir + ovaFileName)).exists()) {
|
||||
s_logger.info("Fang: ova file is created and ready to extract ");
|
||||
return (ovaFileName);
|
||||
} else {
|
||||
String msg = exportDir + File.separator + ovaFileName + ".ova is not created as expected";
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
} else {
|
||||
String msg = "Error reading the ova meta file: " + metafileName;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
//Do something, re-throw the exception
|
||||
} finally {
|
||||
if (strm != null) {
|
||||
try {
|
||||
strm.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getOVFFilePath(String srcOVAFileName) {
|
||||
File file = new File(srcOVAFileName);
|
||||
assert(_storage != null);
|
||||
|
|
|
|||
|
|
@ -155,6 +155,10 @@ 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;
|
||||
|
|
@ -392,6 +396,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
answer = execute((DeleteStoragePoolCommand) cmd);
|
||||
} else if (clz == CopyVolumeCommand.class) {
|
||||
answer = execute((CopyVolumeCommand) cmd);
|
||||
} else if (clz == CreateVolumeOVACommand.class) {
|
||||
answer = execute((CreateVolumeOVACommand) cmd);
|
||||
} else if (clz == PrepareOVAPackingCommand.class) {
|
||||
answer = execute((PrepareOVAPackingCommand) cmd);
|
||||
} else if (clz == AttachVolumeCommand.class) {
|
||||
answer = execute((AttachVolumeCommand) cmd);
|
||||
} else if (clz == AttachIsoCommand.class) {
|
||||
|
|
@ -1433,10 +1441,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
}
|
||||
|
||||
String args = "";
|
||||
String snatArgs = "";
|
||||
|
||||
if (ip.isAdd()) {
|
||||
args += " -A ";
|
||||
snatArgs += " -A ";
|
||||
} else {
|
||||
args += " -D ";
|
||||
snatArgs += " -D ";
|
||||
}
|
||||
|
||||
args += " -l ";
|
||||
|
|
@ -1460,6 +1472,21 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
if (!result.first()) {
|
||||
throw new InternalErrorException("Unable to assign public IP address");
|
||||
}
|
||||
|
||||
if (ip.isSourceNat()) {
|
||||
snatArgs += " -l ";
|
||||
snatArgs += ip.getPublicIp();
|
||||
snatArgs += " -c ";
|
||||
snatArgs += "eth" + ethDeviceNum;
|
||||
|
||||
Pair<Boolean, String> result_gateway = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null,
|
||||
"/opt/cloud/bin/vpc_privateGateway.sh " + args);
|
||||
|
||||
if (!result_gateway.first()) {
|
||||
throw new InternalErrorException("Unable to configure source NAT for public IP address.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void assignPublicIpAddress(VirtualMachineMO vmMo, final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP,
|
||||
|
|
@ -3905,8 +3932,48 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
}
|
||||
}
|
||||
|
||||
public CreateVolumeOVAAnswer execute(CreateVolumeOVACommand cmd) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource CreateVolumeOVACommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
try {
|
||||
VmwareContext context = getServiceContext();
|
||||
VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
|
||||
return (CreateVolumeOVAAnswer) mgr.getStorageManager().execute(this, cmd);
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof RemoteException) {
|
||||
s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
|
||||
invalidateServiceContext();
|
||||
}
|
||||
|
||||
String msg = "CreateVolumeOVACommand failed due to " + VmwareHelper.getExceptionMessage(e);
|
||||
s_logger.error(msg, e);
|
||||
return new CreateVolumeOVAAnswer(cmd, false, msg);
|
||||
}
|
||||
}
|
||||
|
||||
protected Answer execute(PrepareOVAPackingCommand cmd) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource PrepareOVAPackingCommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
try {
|
||||
VmwareContext context = getServiceContext();
|
||||
VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
|
||||
|
||||
return mgr.getStorageManager().execute(this, cmd);
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof RemoteException) {
|
||||
s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
|
||||
invalidateServiceContext();
|
||||
}
|
||||
|
||||
String details = "PrepareOVAPacking for template failed due to " + VmwareHelper.getExceptionMessage(e);
|
||||
s_logger.error(details, e);
|
||||
return new PrepareOVAPackingAnswer(cmd, false, details);
|
||||
}
|
||||
}
|
||||
private boolean createVMFullClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, DatastoreMO dsMo,
|
||||
String vmdkName, ManagedObjectReference morDatastore, ManagedObjectReference morPool) throws Exception {
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
|
|||
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
|
||||
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
|
||||
import com.cloud.agent.api.storage.CopyVolumeCommand;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVAAnswer;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVACommand;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
import com.cloud.hypervisor.vmware.manager.VmwareHostService;
|
||||
import com.cloud.hypervisor.vmware.manager.VmwareStorageManager;
|
||||
|
|
@ -76,6 +79,10 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
|
|||
answer = execute((CreatePrivateTemplateFromSnapshotCommand)cmd);
|
||||
} else if(cmd instanceof CopyVolumeCommand) {
|
||||
answer = execute((CopyVolumeCommand)cmd);
|
||||
} else if(cmd instanceof CreateVolumeOVACommand) {
|
||||
answer = execute((CreateVolumeOVACommand)cmd);
|
||||
} else if (cmd instanceof PrepareOVAPackingCommand) {
|
||||
answer = execute((PrepareOVAPackingCommand)cmd);
|
||||
} else if(cmd instanceof CreateVolumeFromSnapshotCommand) {
|
||||
answer = execute((CreateVolumeFromSnapshotCommand)cmd);
|
||||
} else {
|
||||
|
|
@ -138,6 +145,23 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
|
|||
return _storageMgr.execute(this, cmd);
|
||||
}
|
||||
|
||||
private Answer execute(PrepareOVAPackingCommand cmd) {
|
||||
s_logger.info("Fang: VmwareSecStorageResourceHandler: exec cmd. cmd is " + cmd.toString());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Executing resource PrepareOVAPackingCommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
return _storageMgr.execute(this, cmd);
|
||||
}
|
||||
|
||||
private CreateVolumeOVAAnswer execute(CreateVolumeOVACommand cmd) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Executing resource CreateVolumeOVACommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
return (CreateVolumeOVAAnswer) _storageMgr.execute(this, cmd);
|
||||
}
|
||||
|
||||
private Answer execute(CreateVolumeFromSnapshotCommand cmd) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Executing resource CreateVolumeFromSnapshotCommand: " + _gson.toJson(cmd));
|
||||
|
|
|
|||
|
|
@ -2217,11 +2217,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
}
|
||||
|
||||
String args = "vpc_ipassoc.sh " + routerIp;
|
||||
String snatArgs = "vpc_privateGateway.sh " + routerIp;
|
||||
|
||||
if (ip.isAdd()) {
|
||||
args += " -A ";
|
||||
snatArgs += " -A ";
|
||||
} else {
|
||||
args += " -D ";
|
||||
snatArgs+= " -D ";
|
||||
}
|
||||
|
||||
args += " -l ";
|
||||
|
|
@ -2244,6 +2247,17 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
if (result == null || result.isEmpty()) {
|
||||
throw new InternalErrorException("Xen plugin \"vpc_ipassoc\" failed.");
|
||||
}
|
||||
|
||||
if (ip.isSourceNat()) {
|
||||
snatArgs += " -l " + ip.getPublicIp();
|
||||
snatArgs += " -c " + "eth" + correctVif.getDevice(conn);
|
||||
|
||||
result = callHostPlugin(conn, "vmops", "routerProxy", "args", snatArgs);
|
||||
if (result == null || result.isEmpty()) {
|
||||
throw new InternalErrorException("Xen plugin \"vcp_privateGateway\" failed.");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
String msg = "Unable to assign public IP address due to " + e.toString();
|
||||
s_logger.warn(msg, e);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ import org.apache.log4j.Logger;
|
|||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.routing.GlobalLoadBalancerConfigCommand;
|
||||
import com.cloud.agent.api.routing.HealthCheckLBConfigAnswer;
|
||||
import com.cloud.agent.api.routing.HealthCheckLBConfigCommand;
|
||||
import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
|
||||
import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
|
||||
import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
|
||||
|
|
@ -714,7 +716,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
|||
List<LbDestination> destinations = rule.getDestinations();
|
||||
|
||||
if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) {
|
||||
LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked, false, false, destinations, rule.getStickinessPolicies());
|
||||
LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked, false, false, destinations, rule.getStickinessPolicies(), rule.getHealthCheckPolicies());
|
||||
if (rule.isAutoScaleConfig()) {
|
||||
loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup());
|
||||
}
|
||||
|
|
@ -840,11 +842,75 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
|||
return null;
|
||||
}
|
||||
|
||||
public List<LoadBalancerTO> getElasticLBRulesHealthCheck(Network network, List<? extends FirewallRule> rules)
|
||||
throws ResourceUnavailableException {
|
||||
|
||||
HealthCheckLBConfigAnswer answer = null;
|
||||
List<LoadBalancingRule> loadBalancingRules = new ArrayList<LoadBalancingRule>();
|
||||
for (FirewallRule rule : rules) {
|
||||
if (rule.getPurpose().equals(Purpose.LoadBalancing)) {
|
||||
loadBalancingRules.add((LoadBalancingRule) rule);
|
||||
}
|
||||
}
|
||||
|
||||
if (loadBalancingRules == null || loadBalancingRules.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String errMsg = null;
|
||||
ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
|
||||
|
||||
if (lbDeviceVO == null) {
|
||||
s_logger.warn("There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isNetscalerDevice(lbDeviceVO.getDeviceName())) {
|
||||
errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element can not be handle elastic load balancer rules.";
|
||||
s_logger.error(errMsg);
|
||||
throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
|
||||
}
|
||||
|
||||
List<LoadBalancerTO> loadBalancersToApply = new ArrayList<LoadBalancerTO>();
|
||||
for (int i = 0; i < loadBalancingRules.size(); i++) {
|
||||
LoadBalancingRule rule = loadBalancingRules.get(i);
|
||||
boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke));
|
||||
String protocol = rule.getProtocol();
|
||||
String algorithm = rule.getAlgorithm();
|
||||
String lbUuid = rule.getUuid();
|
||||
String srcIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress().addr();
|
||||
int srcPort = rule.getSourcePortStart();
|
||||
List<LbDestination> destinations = rule.getDestinations();
|
||||
|
||||
if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) {
|
||||
LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked,
|
||||
false, false, destinations, null, rule.getHealthCheckPolicies());
|
||||
loadBalancersToApply.add(loadBalancer);
|
||||
}
|
||||
}
|
||||
|
||||
if (loadBalancersToApply.size() > 0) {
|
||||
int numLoadBalancersForCommand = loadBalancersToApply.size();
|
||||
LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply
|
||||
.toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
|
||||
HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand);
|
||||
HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
|
||||
answer = (HealthCheckLBConfigAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
|
||||
return answer.getLoadBalancers();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<LoadBalancerTO> updateHealthChecks(Network network, List<LoadBalancingRule> lbrules) {
|
||||
|
||||
if (canHandle(network, Service.Lb) && canHandleLbRules(lbrules)) {
|
||||
try {
|
||||
return getLBHealthChecks(network, lbrules);
|
||||
|
||||
if (isBasicZoneNetwok(network)) {
|
||||
return getElasticLBRulesHealthCheck(network, lbrules);
|
||||
} else {
|
||||
return getLBHealthChecks(network, lbrules);
|
||||
}
|
||||
} catch (ResourceUnavailableException e) {
|
||||
s_logger.error("Error in getting the LB Rules from NetScaler " + e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1618,7 +1618,9 @@ public class NetscalerResource implements ServerResource {
|
|||
String srcIp = rule.getSrcIp();
|
||||
String dstIP = rule.getDstIp();
|
||||
String iNatRuleName = generateInatRuleName(srcIp, dstIP);
|
||||
String rNatRuleName = generateRnatRuleName(srcIp, dstIP);
|
||||
inat iNatRule = null;
|
||||
rnat rnatRule = null;
|
||||
|
||||
if (!rule.revoked()) {
|
||||
try {
|
||||
|
|
@ -1645,9 +1647,47 @@ public class NetscalerResource implements ServerResource {
|
|||
}
|
||||
s_logger.debug("Created Inat rule on the Netscaler device " + _ip + " to enable static NAT from " + srcIp + " to " + dstIP);
|
||||
}
|
||||
try {
|
||||
rnat[] rnatRules = rnat.get(_netscalerService);
|
||||
if (rnatRules != null) {
|
||||
for (rnat rantrule : rnatRules) {
|
||||
if (rantrule.get_network().equalsIgnoreCase(rNatRuleName)) {
|
||||
rnatRule = rantrule;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (nitro_exception e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (rnatRule == null) {
|
||||
rnatRule = new rnat();
|
||||
rnatRule.set_natip(srcIp);
|
||||
rnatRule.set_network(dstIP);
|
||||
rnatRule.set_netmask("255.255.255.255");
|
||||
try {
|
||||
apiCallResult = rnat.update(_netscalerService, rnatRule);
|
||||
} catch (nitro_exception e) {
|
||||
if (e.getErrorCode() != NitroError.NS_RESOURCE_EXISTS) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
s_logger.debug("Created Rnat rule on the Netscaler device " + _ip + " to enable revese static NAT from " + dstIP + " to " + srcIp);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
inat.delete(_netscalerService, iNatRuleName);
|
||||
rnat[] rnatRules = rnat.get(_netscalerService);
|
||||
if (rnatRules != null) {
|
||||
for (rnat rantrule : rnatRules) {
|
||||
if (rantrule.get_network().equalsIgnoreCase(dstIP)) {
|
||||
rnatRule = rantrule;
|
||||
rnat.clear(_netscalerService, rnatRule);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (nitro_exception e) {
|
||||
if (e.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) {
|
||||
throw e;
|
||||
|
|
@ -2257,6 +2297,7 @@ public class NetscalerResource implements ServerResource {
|
|||
}
|
||||
|
||||
csMon.set_interval(hcp.getHealthcheckInterval());
|
||||
csMon.set_retries(Math.max(hcp.getHealthcheckThresshold(), hcp.getUnhealthThresshold()) + 1);
|
||||
csMon.set_resptimeout(hcp.getResponseTime());
|
||||
csMon.set_failureretries(hcp.getUnhealthThresshold());
|
||||
csMon.set_successretries(hcp.getHealthcheckThresshold());
|
||||
|
|
@ -3090,6 +3131,10 @@ public class NetscalerResource implements ServerResource {
|
|||
return genObjectName("Cloud-Inat", srcIp);
|
||||
}
|
||||
|
||||
private String generateRnatRuleName(String srcIp, String dstIP) {
|
||||
return genObjectName("Cloud-Rnat", srcIp);
|
||||
}
|
||||
|
||||
private String generateNSVirtualServerName(String srcIp, long srcPort) {
|
||||
return genObjectName("Cloud-VirtualServer", srcIp, srcPort);
|
||||
}
|
||||
|
|
|
|||
2
pom.xml
2
pom.xml
|
|
@ -399,7 +399,7 @@
|
|||
<exclude>patches/systemvm/debian/config/etc/apache2/sites-available/default</exclude>
|
||||
<exclude>patches/systemvm/debian/config/etc/apache2/sites-available/default-ssl</exclude>
|
||||
<exclude>patches/systemvm/debian/config/etc/apache2/vhostexample.conf</exclude>
|
||||
<exclude>patches/systemvm/debian/config/etc/dnsmasq.conf</exclude>
|
||||
<exclude>patches/systemvm/debian/config/etc/dnsmasq.conf.tmpl</exclude>
|
||||
<exclude>patches/systemvm/debian/config/etc/vpcdnsmasq.conf</exclude>
|
||||
<exclude>patches/systemvm/debian/config/etc/ssh/sshd_config</exclude>
|
||||
<exclude>patches/systemvm/debian/config/etc/rsyslog.conf</exclude>
|
||||
|
|
|
|||
|
|
@ -3145,6 +3145,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
populateAccount(response, result.getAccountId());
|
||||
populateDomain(response, result.getDomainId());
|
||||
response.setState(result.getState().toString());
|
||||
response.setSourceNat(result.getSourceNat());
|
||||
|
||||
response.setObjectName("privategateway");
|
||||
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
|
|||
lbDeviceVO = new ExternalLoadBalancerDeviceVO(host.getId(), pNetwork.getId(), ntwkDevice.getNetworkServiceProvder(),
|
||||
deviceName, capacity, dedicatedUse, gslbProvider);
|
||||
if (gslbProvider) {
|
||||
lbDeviceVO.setGslbSitePrivateIP(gslbSitePublicIp);
|
||||
lbDeviceVO.setGslbSitePublicIP(gslbSitePublicIp);
|
||||
lbDeviceVO.setGslbSitePrivateIP(gslbSitePrivateIp);
|
||||
}
|
||||
_externalLoadBalancerDeviceDao.persist(lbDeviceVO);
|
||||
|
|
|
|||
|
|
@ -930,9 +930,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
|
|||
}
|
||||
}
|
||||
if (isUserVmsDefaultNetwork || isDomRGuestOrPublicNetwork) {
|
||||
return _configMgr.getServiceOfferingNetworkRate(vm.getServiceOfferingId(), vm.getDataCenterId());
|
||||
return _configMgr.getServiceOfferingNetworkRate(vm.getServiceOfferingId(), network.getDataCenterId());
|
||||
} else {
|
||||
return _configMgr.getNetworkOfferingNetworkRate(ntwkOff.getId(), vm.getDataCenterId());
|
||||
return _configMgr.getNetworkOfferingNetworkRate(ntwkOff.getId(), network.getDataCenterId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1669,20 +1669,17 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
|
|||
String[] cidr = network.getCidr().split("/");
|
||||
List<String> ips = getUsedIpsInNetwork(network);
|
||||
Set<Long> usedIps = new TreeSet<Long>();
|
||||
|
||||
|
||||
for (String ip : ips) {
|
||||
if (requestedIp != null && requestedIp.equals(ip)) {
|
||||
s_logger.warn("Requested ip address " + requestedIp + " is already in use in network" + network);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
usedIps.add(NetUtils.ip2Long(ip));
|
||||
}
|
||||
|
||||
Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]));
|
||||
if (usedIps.size() != 0) {
|
||||
allPossibleIps.removeAll(usedIps);
|
||||
}
|
||||
|
||||
Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]), usedIps);
|
||||
|
||||
String gateway = network.getGateway();
|
||||
if ((gateway != null) && (allPossibleIps.contains(NetUtils.ip2Long(gateway))))
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
|
@ -490,17 +491,19 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
|||
}
|
||||
|
||||
// if shared network in the advanced zone, then check the caller against the network for 'AccessType.UseNetwork'
|
||||
if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()) && zone.getNetworkType() == NetworkType.Advanced) {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
long callerUserId = UserContext.current().getCallerUserId();
|
||||
_accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
|
||||
if (zone.getNetworkType() == NetworkType.Advanced) {
|
||||
if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
long callerUserId = UserContext.current().getCallerUserId();
|
||||
_accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
|
||||
}
|
||||
return _networkMgr.allocateIp(ipOwner, false, caller, callerUserId, zone);
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Associate IP address can only be called on the shared networks in the advanced zone" +
|
||||
" with Firewall/Source Nat/Static Nat/Port Forwarding/Load balancing services enabled");
|
||||
}
|
||||
return _networkMgr.allocateIp(ipOwner, false, caller, callerUserId, zone);
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Associate IP address can only be called on the shared networks in the advanced zone" +
|
||||
" with Firewall/Source Nat/Static Nat/Port Forwarding/Load balancing services enabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2128,6 +2131,29 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
|||
return getNetwork(network.getId());
|
||||
}
|
||||
|
||||
|
||||
protected Set<Long> getAvailableIps(Network network, String requestedIp) {
|
||||
String[] cidr = network.getCidr().split("/");
|
||||
List<String> ips = _nicDao.listIpAddressInNetwork(network.getId());
|
||||
Set<Long> usedIps = new TreeSet<Long>();
|
||||
|
||||
for (String ip : ips) {
|
||||
if (requestedIp != null && requestedIp.equals(ip)) {
|
||||
s_logger.warn("Requested ip address " + requestedIp + " is already in use in network" + network);
|
||||
return null;
|
||||
}
|
||||
|
||||
usedIps.add(NetUtils.ip2Long(ip));
|
||||
}
|
||||
Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]), usedIps);
|
||||
|
||||
String gateway = network.getGateway();
|
||||
if ((gateway != null) && (allPossibleIps.contains(NetUtils.ip2Long(gateway))))
|
||||
allPossibleIps.remove(NetUtils.ip2Long(gateway));
|
||||
|
||||
return allPossibleIps;
|
||||
}
|
||||
|
||||
|
||||
protected boolean canUpgrade(Network network, long oldNetworkOfferingId, long newNetworkOfferingId) {
|
||||
NetworkOffering oldNetworkOffering = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
|
||||
|
|
@ -3379,8 +3405,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
|||
|
||||
|
||||
@Override @DB
|
||||
public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId,
|
||||
String vlan, String startIp, String endIp, String gateway, String netmask, long networkOwnerId, Long vpcId)
|
||||
public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId,
|
||||
String vlan, String startIp, String endIp, String gateway, String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat)
|
||||
throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
|
||||
|
||||
Account owner = _accountMgr.getAccount(networkOwnerId);
|
||||
|
|
@ -3448,7 +3474,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
|||
Long nextMac = mac + 1;
|
||||
dc.setMacAddress(nextMac);
|
||||
|
||||
privateIp = new PrivateIpVO(startIp, privateNetwork.getId(), nextMac, vpcId);
|
||||
privateIp = new PrivateIpVO(startIp, privateNetwork.getId(), nextMac, vpcId, sourceNat);
|
||||
_privateIpDao.persist(privateIp);
|
||||
|
||||
_dcDao.update(dc.getId(), dc);
|
||||
|
|
|
|||
|
|
@ -1178,8 +1178,8 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
|
|||
|
||||
for (final PrivateIpAddress ipAddr : ipAddrList) {
|
||||
Network network = _networkModel.getNetwork(ipAddr.getNetworkId());
|
||||
IpAddressTO ip = new IpAddressTO(Account.ACCOUNT_ID_SYSTEM, ipAddr.getIpAddress(), add, false,
|
||||
false, ipAddr.getVlanTag(), ipAddr.getGateway(), ipAddr.getNetmask(), ipAddr.getMacAddress(),
|
||||
IpAddressTO ip = new IpAddressTO(Account.ACCOUNT_ID_SYSTEM, ipAddr.getIpAddress(), add, false,
|
||||
ipAddr.getSourceNat(), ipAddr.getVlanTag(), ipAddr.getGateway(), ipAddr.getNetmask(), ipAddr.getMacAddress(),
|
||||
null, false);
|
||||
|
||||
ip.setTrafficType(network.getTrafficType());
|
||||
|
|
|
|||
|
|
@ -80,12 +80,14 @@ import com.cloud.utils.net.Ip;
|
|||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicSecondaryIp;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.Type;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.NicSecondaryIpDao;
|
||||
import com.cloud.vm.dao.NicSecondaryIpVO;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@Component
|
||||
@Local(value = { RulesManager.class, RulesService.class })
|
||||
|
|
@ -103,6 +105,8 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
|||
@Inject
|
||||
UserVmDao _vmDao;
|
||||
@Inject
|
||||
VMInstanceDao _vmInstanceDao;
|
||||
@Inject
|
||||
AccountManager _accountMgr;
|
||||
@Inject
|
||||
NetworkManager _networkMgr;
|
||||
|
|
@ -416,7 +420,12 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
|||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_ENABLE_STATIC_NAT, eventDescription = "enabling static nat")
|
||||
public boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm, String vmGuestIp)
|
||||
public boolean enableStaticNat(long ipId, long vmId, long networkId, String vmGuestIp)
|
||||
throws NetworkRuleConflictException, ResourceUnavailableException {
|
||||
return enableStaticNat(ipId, vmId, networkId, false, vmGuestIp);
|
||||
}
|
||||
|
||||
private boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm, String vmGuestIp)
|
||||
throws NetworkRuleConflictException, ResourceUnavailableException {
|
||||
UserContext ctx = UserContext.current();
|
||||
Account caller = ctx.getCaller();
|
||||
|
|
@ -1370,7 +1379,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
|||
throw new CloudRuntimeException("Ip address is not associated with any network");
|
||||
}
|
||||
|
||||
UserVmVO vm = _vmDao.findById(sourceIp.getAssociatedWithVmId());
|
||||
VMInstanceVO vm = _vmInstanceDao.findById(sourceIp.getAssociatedWithVmId());
|
||||
Network network = _networkModel.getNetwork(networkId);
|
||||
if (network == null) {
|
||||
CloudRuntimeException ex = new CloudRuntimeException("Unable to find an ip address to map to specified vm id");
|
||||
|
|
|
|||
|
|
@ -100,4 +100,9 @@ public class PrivateGatewayProfile implements PrivateGateway {
|
|||
public State getState() {
|
||||
return vpcGateway.getState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSourceNat() {
|
||||
return vpcGateway.getSourceNat();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ public class PrivateIpAddress implements PrivateIp{
|
|||
String ipAddress;
|
||||
String macAddress;
|
||||
long networkId;
|
||||
boolean sourceNat;
|
||||
|
||||
/**
|
||||
* @param privateIp
|
||||
|
|
@ -42,6 +43,7 @@ public class PrivateIpAddress implements PrivateIp{
|
|||
this.netmask = netmask;
|
||||
this.macAddress = macAddress;
|
||||
this.networkId = privateIp.getNetworkId();
|
||||
this.sourceNat = privateIp.getSourceNat();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -73,4 +75,9 @@ public class PrivateIpAddress implements PrivateIp{
|
|||
public long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSourceNat() {
|
||||
return sourceNat;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,15 +54,19 @@ public class PrivateIpVO implements InternalIdentity {
|
|||
|
||||
@Column(name="vpc_id")
|
||||
private Long vpcId;
|
||||
|
||||
@Column(name="source_nat")
|
||||
private boolean sourceNat;
|
||||
|
||||
public PrivateIpVO() {
|
||||
}
|
||||
}
|
||||
|
||||
public PrivateIpVO(String ipAddress, long networkId, long macAddress, long vpcId) {
|
||||
public PrivateIpVO(String ipAddress, long networkId, long macAddress, long vpcId, boolean sourceNat) {
|
||||
this.ipAddress = ipAddress;
|
||||
this.networkId = networkId;
|
||||
this.macAddress = macAddress;
|
||||
this.vpcId = vpcId;
|
||||
this.sourceNat = sourceNat;
|
||||
}
|
||||
|
||||
public void setTakenAt(Date takenDate) {
|
||||
|
|
@ -92,4 +96,8 @@ public class PrivateIpVO implements InternalIdentity {
|
|||
public Long getVpcId() {
|
||||
return vpcId;
|
||||
}
|
||||
public boolean getSourceNat() {
|
||||
return sourceNat;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import javax.persistence.Id;
|
|||
import javax.persistence.Table;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
|
||||
@Entity
|
||||
|
|
@ -84,7 +83,10 @@ public class VpcGatewayVO implements VpcGateway {
|
|||
@Column(name="state")
|
||||
@Enumerated(value=EnumType.STRING)
|
||||
State state;
|
||||
|
||||
|
||||
@Column(name="source_nat")
|
||||
boolean sourceNat;
|
||||
|
||||
protected VpcGatewayVO(){
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
|
@ -101,9 +103,10 @@ public class VpcGatewayVO implements VpcGateway {
|
|||
* @param accountId TODO
|
||||
* @param domainId TODO
|
||||
* @param account_id
|
||||
* @param sourceNat
|
||||
*/
|
||||
public VpcGatewayVO(String ip4Address, Type type, Long vpcId, long zoneId, Long networkId, String vlanTag,
|
||||
String gateway, String netmask, long accountId, long domainId) {
|
||||
String gateway, String netmask, long accountId, long domainId, boolean sourceNat) {
|
||||
this.ip4Address = ip4Address;
|
||||
this.type = type;
|
||||
this.vpcId = vpcId;
|
||||
|
|
@ -116,6 +119,7 @@ public class VpcGatewayVO implements VpcGateway {
|
|||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.state = State.Creating;
|
||||
this.sourceNat = sourceNat;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -193,4 +197,10 @@ public class VpcGatewayVO implements VpcGateway {
|
|||
public void setState(State state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSourceNat() {
|
||||
return this.sourceNat;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1288,8 +1288,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||
@Override
|
||||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_CREATE, eventDescription = "creating vpc private gateway", create=true)
|
||||
public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress,
|
||||
String gateway, String netmask, long gatewayOwnerId) throws ResourceAllocationException,
|
||||
public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress,
|
||||
String gateway, String netmask, long gatewayOwnerId, Boolean isSourceNat) throws ResourceAllocationException,
|
||||
ConcurrentOperationException, InsufficientCapacityException {
|
||||
|
||||
//Validate parameters
|
||||
|
|
@ -1315,11 +1315,11 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||
//1) create private network
|
||||
String networkName = "vpc-" + vpc.getName() + "-privateNetwork";
|
||||
Network privateNtwk = _ntwkSvc.createPrivateNetwork(networkName, networkName, physicalNetworkId,
|
||||
vlan, ipAddress, null, gateway, netmask, gatewayOwnerId, vpcId);
|
||||
vlan, ipAddress, null, gateway, netmask, gatewayOwnerId, vpcId, isSourceNat);
|
||||
|
||||
//2) create gateway entry
|
||||
VpcGatewayVO gatewayVO = new VpcGatewayVO(ipAddress, VpcGateway.Type.Private, vpcId, privateNtwk.getDataCenterId(),
|
||||
privateNtwk.getId(), vlan, gateway, netmask, vpc.getAccountId(), vpc.getDomainId());
|
||||
privateNtwk.getId(), vlan, gateway, netmask, vpc.getAccountId(), vpc.getDomainId(), isSourceNat);
|
||||
_vpcGatewayDao.persist(gatewayVO);
|
||||
|
||||
s_logger.debug("Created vpc gateway entry " + gatewayVO);
|
||||
|
|
|
|||
|
|
@ -582,7 +582,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||
}
|
||||
|
||||
//Convert max storage size from GiB to bytes
|
||||
if (resourceType == ResourceType.primary_storage || resourceType == ResourceType.secondary_storage) {
|
||||
if ((resourceType == ResourceType.primary_storage || resourceType == ResourceType.secondary_storage) && max >= 0) {
|
||||
max = max * ResourceType.bytesToGiB;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -358,7 +358,6 @@ import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd;
|
|||
import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.DeleteVolumeCmd;
|
||||
|
|
@ -409,6 +408,8 @@ import com.cloud.agent.api.GetVncPortAnswer;
|
|||
import com.cloud.agent.api.GetVncPortCommand;
|
||||
import com.cloud.agent.api.storage.CopyVolumeAnswer;
|
||||
import com.cloud.agent.api.storage.CopyVolumeCommand;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVAAnswer;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVACommand;
|
||||
import com.cloud.agent.manager.allocator.HostAllocator;
|
||||
import com.cloud.alert.Alert;
|
||||
import com.cloud.alert.AlertManager;
|
||||
|
|
@ -575,6 +576,81 @@ import com.cloud.vm.dao.VMInstanceDao;
|
|||
|
||||
import edu.emory.mathcs.backport.java.util.Arrays;
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd;
|
||||
import org.apache.cloudstack.api.command.admin.autoscale.DeleteCounterCmd;
|
||||
import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd;
|
||||
import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd;
|
||||
import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd;
|
||||
import org.apache.cloudstack.api.command.admin.cluster.UpdateClusterCmd;
|
||||
import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd;
|
||||
import org.apache.cloudstack.api.command.admin.config.ListHypervisorCapabilitiesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
|
||||
import org.apache.cloudstack.api.command.admin.config.UpdateHypervisorCapabilitiesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.ldap.LDAPConfigCmd;
|
||||
import org.apache.cloudstack.api.command.admin.ldap.LDAPRemoveCmd;
|
||||
import org.apache.cloudstack.api.command.admin.pod.CreatePodCmd;
|
||||
import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
|
||||
import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd;
|
||||
import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
|
||||
import org.apache.cloudstack.api.command.admin.region.AddRegionCmd;
|
||||
import org.apache.cloudstack.api.command.admin.region.RemoveRegionCmd;
|
||||
import org.apache.cloudstack.api.command.admin.region.UpdateRegionCmd;
|
||||
import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd;
|
||||
import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.template.PrepareTemplateCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vm.MigrateVirtualMachineWithVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.MarkDefaultZoneForAccountCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.AddAccountToProjectCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.DeleteAccountFromProjectCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
|
||||
import org.apache.cloudstack.api.command.user.address.AssociateIPAddrCmd;
|
||||
import org.apache.cloudstack.api.command.user.address.DisassociateIPAddrCmd;
|
||||
import org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd;
|
||||
import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd;
|
||||
import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
|
||||
import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd;
|
||||
import org.apache.cloudstack.api.command.user.event.ListEventTypesCmd;
|
||||
import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
|
||||
import org.apache.cloudstack.api.command.user.guest.ListGuestOsCategoriesCmd;
|
||||
import org.apache.cloudstack.api.command.user.guest.ListGuestOsCmd;
|
||||
import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
|
||||
import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
|
||||
import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
|
||||
import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
|
||||
import org.apache.cloudstack.api.command.user.region.ListRegionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.region.ha.gslb.*;
|
||||
import org.apache.cloudstack.api.command.user.ssh.CreateSSHKeyPairCmd;
|
||||
import org.apache.cloudstack.api.command.user.ssh.DeleteSSHKeyPairCmd;
|
||||
import org.apache.cloudstack.api.command.user.ssh.ListSSHKeyPairsCmd;
|
||||
import org.apache.cloudstack.api.command.user.ssh.RegisterSSHKeyPairCmd;
|
||||
import org.apache.cloudstack.api.command.user.tag.CreateTagsCmd;
|
||||
import org.apache.cloudstack.api.command.user.tag.DeleteTagsCmd;
|
||||
import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd;
|
||||
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;
|
||||
|
||||
|
||||
public class ManagementServerImpl extends ManagerBase implements ManagementServer {
|
||||
public static final Logger s_logger = Logger.getLogger(ManagementServerImpl.class.getName());
|
||||
|
|
@ -2837,7 +2913,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
cmdList.add(ListZonesByCmd.class);
|
||||
cmdList.add(ListVMSnapshotCmd.class);
|
||||
cmdList.add(CreateVMSnapshotCmd.class);
|
||||
cmdList.add(RevertToSnapshotCmd.class);
|
||||
cmdList.add(RevertToVMSnapshotCmd.class);
|
||||
cmdList.add(DeleteVMSnapshotCmd.class);
|
||||
cmdList.add(AddIpToVmNicCmd.class);
|
||||
cmdList.add(RemoveIpFromVmNicCmd.class);
|
||||
|
|
@ -3404,7 +3480,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
List<UploadVO> extractURLList = _uploadDao.listByTypeUploadStatus(volumeId, Upload.Type.VOLUME, UploadVO.Status.DOWNLOAD_URL_CREATED);
|
||||
|
||||
if (extractMode == Upload.Mode.HTTP_DOWNLOAD && extractURLList.size() > 0) {
|
||||
return extractURLList.get(0).getId(); // If download url already
|
||||
return extractURLList.get(0).getId(); // If download url already Note: volss
|
||||
// exists then return
|
||||
} else {
|
||||
UploadVO uploadJob = _uploadMonitor.createNewUploadEntry(sserver.getId(), volumeId, UploadVO.Status.COPY_IN_PROGRESS, Upload.Type.VOLUME,
|
||||
|
|
@ -3456,6 +3532,19 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
}
|
||||
|
||||
String volumeLocalPath = "volumes/" + volume.getId() + "/" + cvAnswer.getVolumePath() + "." + getFormatForPool(srcPool);
|
||||
//Fang: volss, handle the ova special case;
|
||||
if (getFormatForPool(srcPool) == "ova") {
|
||||
CreateVolumeOVACommand cvOVACmd = new CreateVolumeOVACommand(secondaryStorageURL, volumeLocalPath, cvAnswer.getVolumePath(), srcPool, copyvolumewait);
|
||||
CreateVolumeOVAAnswer OVAanswer = null;
|
||||
|
||||
try {
|
||||
cvOVACmd.setContextParam("hypervisor", HypervisorType.VMware.toString());
|
||||
OVAanswer = (CreateVolumeOVAAnswer) _storageMgr.sendToPool(srcPool, cvOVACmd); //Fang: for extract volume, create the ova file here;
|
||||
|
||||
} catch (StorageUnavailableException e) {
|
||||
s_logger.debug("Storage unavailable");
|
||||
}
|
||||
}
|
||||
// Update the DB that volume is copied and volumePath
|
||||
uploadJob.setUploadState(UploadVO.Status.COPY_COMPLETE);
|
||||
uploadJob.setLastUpdated(new Date());
|
||||
|
|
|
|||
|
|
@ -562,10 +562,15 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
|||
sql = SELECT_TEMPLATE_HOST_REF;
|
||||
groupByClause = " GROUP BY t.id, h.data_center_id ";
|
||||
}
|
||||
if (((templateFilter == TemplateFilter.featured) || (templateFilter == TemplateFilter.community)) ||(zoneType != null && zoneId != null)) {
|
||||
if ((templateFilter == TemplateFilter.featured) || (templateFilter == TemplateFilter.community)) {
|
||||
dataCenterJoin = " INNER JOIN data_center dc on (h.data_center_id = dc.id)";
|
||||
}
|
||||
|
||||
|
||||
if (zoneType != null) {
|
||||
dataCenterJoin = " INNER JOIN template_host_ref thr on (t.id = thr.template_id) INNER JOIN host h on (thr.host_id = h.id)";
|
||||
dataCenterJoin += " INNER JOIN data_center dc on (h.data_center_id = dc.id)";
|
||||
}
|
||||
|
||||
if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared ){
|
||||
lpjoin = " INNER JOIN launch_permission lp ON t.id = lp.template_id ";
|
||||
}
|
||||
|
|
@ -783,13 +788,15 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
|||
sql += " AND h.data_center_id = " +zoneId;
|
||||
}
|
||||
}else if (zoneId != null){
|
||||
sql += " AND tzr.zone_id = " +zoneId+ " AND tzr.removed is null" ;
|
||||
if (zoneType != null){
|
||||
sql += " AND dc.networktype = " + zoneType;
|
||||
}
|
||||
sql += " AND tzr.zone_id = " +zoneId+ " AND tzr.removed is null" ;
|
||||
}else{
|
||||
sql += " AND tzr.removed is null ";
|
||||
}
|
||||
|
||||
if (zoneType != null){
|
||||
sql += " AND dc.networktype = '" + zoneType + "'";
|
||||
}
|
||||
|
||||
if (!showDomr){
|
||||
sql += " AND t.type != '" +Storage.TemplateType.SYSTEM.toString() + "'";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ import javax.inject.Inject;
|
|||
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
|
||||
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
|
||||
import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
|
||||
import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingAnswer;
|
||||
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
|
|
@ -64,6 +67,10 @@ import com.cloud.utils.UriUtils;
|
|||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
|
||||
|
||||
@Local(value=TemplateAdapter.class)
|
||||
public class HypervisorTemplateAdapter extends TemplateAdapterBase implements TemplateAdapter {
|
||||
|
|
@ -188,6 +195,77 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
|
|||
return template;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateProfile prepareExtractTemplate(ExtractTemplateCmd extractcmd) {
|
||||
TemplateProfile profile = super.prepareExtractTemplate(extractcmd);
|
||||
VMTemplateVO template = (VMTemplateVO)profile.getTemplate();
|
||||
Long zoneId = profile.getZoneId();
|
||||
Long templateId = template.getId();
|
||||
|
||||
if (template.getHypervisorType() == HypervisorType.VMware) {
|
||||
PrepareOVAPackingCommand cmd = null;
|
||||
String zoneName="";
|
||||
List<HostVO> secondaryStorageHosts;
|
||||
if (!template.isCrossZones() && zoneId != null) {
|
||||
DataCenterVO zone = _dcDao.findById(zoneId);
|
||||
zoneName = zone.getName();
|
||||
secondaryStorageHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(zoneId);
|
||||
|
||||
s_logger.debug("Attempting to mark template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName);
|
||||
|
||||
// Make sure the template is downloaded to all the necessary secondary storage hosts
|
||||
|
||||
for (HostVO secondaryStorageHost : secondaryStorageHosts) {
|
||||
long hostId = secondaryStorageHost.getId();
|
||||
List<VMTemplateHostVO> templateHostVOs = _tmpltHostDao.listByHostTemplate(hostId, templateId);
|
||||
for (VMTemplateHostVO templateHostVO : templateHostVOs) {
|
||||
if (templateHostVO.getDownloadState() == Status.DOWNLOAD_IN_PROGRESS) {
|
||||
String errorMsg = "Please specify a template that is not currently being downloaded.";
|
||||
s_logger.debug("Template: " + template.getName() + " is currently being downloaded to secondary storage host: " + secondaryStorageHost.getName() + ".");
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
}
|
||||
String installPath = templateHostVO.getInstallPath();
|
||||
if (installPath != null) {
|
||||
HostVO ssvmhost = _ssvmMgr.pickSsvmHost(secondaryStorageHost);
|
||||
if( ssvmhost == null ) {
|
||||
s_logger.warn("prepareOVAPacking (hyervisorTemplateAdapter): There is no secondary storage VM for secondary storage host " + secondaryStorageHost.getName());
|
||||
throw new CloudRuntimeException("PrepareExtractTemplate: can't locate ssvm for SecStorage Host.");
|
||||
}
|
||||
//Answer answer = _agentMgr.sendToSecStorage(secondaryStorageHost, new PrepareOVAPackingCommand(secondaryStorageHost.getStorageUrl(), installPath));
|
||||
cmd = new PrepareOVAPackingCommand(secondaryStorageHost.getStorageUrl(), installPath);
|
||||
|
||||
if (cmd == null) {
|
||||
s_logger.debug("Fang: PrepareOVAPacking cmd can't created. cmd is null .");
|
||||
throw new CloudRuntimeException("PrepareExtractTemplate: can't create a new cmd to packing ova.");
|
||||
} else {
|
||||
cmd.setContextParam("hypervisor", HypervisorType.VMware.toString());
|
||||
}
|
||||
Answer answer = null;
|
||||
s_logger.debug("Fang: PrepareOVAPAcking cmd, before send out. cmd: " + cmd.toString());
|
||||
try {
|
||||
answer = _agentMgr.send(ssvmhost.getId(), cmd);
|
||||
} catch (AgentUnavailableException e) {
|
||||
s_logger.warn("Unable to packOVA for template: id: " + templateId + ", name " + ssvmhost.getName(), e);
|
||||
} catch (OperationTimedoutException e) {
|
||||
s_logger.warn("Unable to packOVA for template timeout. template id: " + templateId);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.debug("Failed to create OVA for template " + templateHostVO + " due to " + ((answer == null) ? "answer is null" : answer.getDetails()));
|
||||
throw new CloudRuntimeException("PrepareExtractTemplate: Failed to create OVA for template extraction. ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s_logger.debug("Failed to create OVA for template " + template + " due to zone non-existing.");
|
||||
throw new CloudRuntimeException("PrepareExtractTemplate: Failed to create OVA for template extraction. ");
|
||||
}
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
@Override @DB
|
||||
public boolean delete(TemplateProfile profile) {
|
||||
boolean success = true;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
|
|||
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
|
||||
import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
|
||||
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
|
||||
import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
|
|
@ -56,6 +57,8 @@ public interface TemplateAdapter extends Adapter {
|
|||
|
||||
public TemplateProfile prepareDelete(DeleteIsoCmd cmd);
|
||||
|
||||
public TemplateProfile prepareExtractTemplate(ExtractTemplateCmd cmd);
|
||||
|
||||
public boolean delete(TemplateProfile profile);
|
||||
|
||||
public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
|
|||
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
|
||||
import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
|
||||
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
|
||||
import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
|
||||
|
|
@ -340,6 +341,18 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
|
|||
return new TemplateProfile(userId, template, zoneId);
|
||||
}
|
||||
|
||||
public TemplateProfile prepareExtractTemplate(ExtractTemplateCmd cmd) {
|
||||
Long templateId = cmd.getId();
|
||||
Long userId = UserContext.current().getCallerUserId();
|
||||
Long zoneId = cmd.getZoneId();
|
||||
|
||||
VMTemplateVO template = _tmpltDao.findById(templateId.longValue());
|
||||
if (template == null) {
|
||||
throw new InvalidParameterValueException("unable to find template with id " + templateId);
|
||||
}
|
||||
return new TemplateProfile(userId, template, zoneId);
|
||||
}
|
||||
|
||||
public TemplateProfile prepareDelete(DeleteIsoCmd cmd) {
|
||||
Long templateId = cmd.getId();
|
||||
Long userId = UserContext.current().getCallerUserId();
|
||||
|
|
|
|||
|
|
@ -367,6 +367,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||
String mode = cmd.getMode();
|
||||
Long eventId = cmd.getStartEventId();
|
||||
|
||||
VirtualMachineTemplate template = getTemplate(templateId);
|
||||
if (template == null) {
|
||||
throw new InvalidParameterValueException("unable to find template with id " + templateId);
|
||||
}
|
||||
TemplateAdapter adapter = getAdapter(template.getHypervisorType());
|
||||
TemplateProfile profile = adapter.prepareExtractTemplate(cmd);
|
||||
|
||||
// FIXME: async job needs fixing
|
||||
Long uploadId = extract(caller, templateId, url, zoneId, mode, eventId, false, null, _asyncMgr);
|
||||
if (uploadId != null){
|
||||
|
|
|
|||
|
|
@ -629,8 +629,8 @@ public class Upgrade2214to30 extends Upgrade30xBase implements DbUpgrade {
|
|||
s_logger.debug("Updating XenSever System Vms");
|
||||
//XenServer
|
||||
try {
|
||||
//Get 3.0.0 xenserer system Vm template Id
|
||||
pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-xenserver-3.0.0' and removed is null");
|
||||
//Get 3.0.0 or later xenserer system Vm template Id
|
||||
pstmt = conn.prepareStatement("select max(id) from `cloud`.`vm_template` where name like 'systemvm-xenserver-%' and removed is null");
|
||||
rs = pstmt.executeQuery();
|
||||
if(rs.next()){
|
||||
long templateId = rs.getLong(1);
|
||||
|
|
@ -648,9 +648,9 @@ public class Upgrade2214to30 extends Upgrade30xBase implements DbUpgrade {
|
|||
pstmt.close();
|
||||
} else {
|
||||
if (xenserver){
|
||||
throw new CloudRuntimeException("3.0.0 XenServer SystemVm template not found. Cannot upgrade system Vms");
|
||||
throw new CloudRuntimeException("3.0.0 or later XenServer SystemVm template not found. Cannot upgrade system Vms");
|
||||
} else {
|
||||
s_logger.warn("3.0.0 XenServer SystemVm template not found. XenServer hypervisor is not used, so not failing upgrade");
|
||||
s_logger.warn("3.0.0 or later XenServer SystemVm template not found. XenServer hypervisor is not used, so not failing upgrade");
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
|
|
@ -660,8 +660,8 @@ public class Upgrade2214to30 extends Upgrade30xBase implements DbUpgrade {
|
|||
//KVM
|
||||
s_logger.debug("Updating KVM System Vms");
|
||||
try {
|
||||
//Get 3.0.0 KVM system Vm template Id
|
||||
pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-kvm-3.0.0' and removed is null");
|
||||
//Get 3.0.0 or later KVM system Vm template Id
|
||||
pstmt = conn.prepareStatement("select max(id) from `cloud`.`vm_template` where name like 'systemvm-kvm-%' and removed is null");
|
||||
rs = pstmt.executeQuery();
|
||||
if(rs.next()){
|
||||
long templateId = rs.getLong(1);
|
||||
|
|
@ -679,9 +679,9 @@ public class Upgrade2214to30 extends Upgrade30xBase implements DbUpgrade {
|
|||
pstmt.close();
|
||||
} else {
|
||||
if (kvm){
|
||||
throw new CloudRuntimeException("3.0.0 KVM SystemVm template not found. Cannot upgrade system Vms");
|
||||
throw new CloudRuntimeException("3.0.0 or later KVM SystemVm template not found. Cannot upgrade system Vms");
|
||||
} else {
|
||||
s_logger.warn("3.0.0 KVM SystemVm template not found. KVM hypervisor is not used, so not failing upgrade");
|
||||
s_logger.warn("3.0.0 or later KVM SystemVm template not found. KVM hypervisor is not used, so not failing upgrade");
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
|
|
@ -691,8 +691,8 @@ public class Upgrade2214to30 extends Upgrade30xBase implements DbUpgrade {
|
|||
//VMware
|
||||
s_logger.debug("Updating VMware System Vms");
|
||||
try {
|
||||
//Get 3.0.0 VMware system Vm template Id
|
||||
pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-vmware-3.0.0' and removed is null");
|
||||
//Get 3.0.0 or later VMware system Vm template Id
|
||||
pstmt = conn.prepareStatement("select max(id) from `cloud`.`vm_template` where name like 'systemvm-vmware-%' and removed is null");
|
||||
rs = pstmt.executeQuery();
|
||||
if(rs.next()){
|
||||
long templateId = rs.getLong(1);
|
||||
|
|
@ -710,9 +710,9 @@ public class Upgrade2214to30 extends Upgrade30xBase implements DbUpgrade {
|
|||
pstmt.close();
|
||||
} else {
|
||||
if (VMware){
|
||||
throw new CloudRuntimeException("3.0.0 VMware SystemVm template not found. Cannot upgrade system Vms");
|
||||
throw new CloudRuntimeException("3.0.0 or later VMware SystemVm template not found. Cannot upgrade system Vms");
|
||||
} else {
|
||||
s_logger.warn("3.0.0 VMware SystemVm template not found. VMware hypervisor is not used, so not failing upgrade");
|
||||
s_logger.warn("3.0.0 or later VMware SystemVm template not found. VMware hypervisor is not used, so not failing upgrade");
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
|
|
|
|||
|
|
@ -1050,7 +1050,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VM_SCALE, eventDescription = "scaling Vm")
|
||||
public UserVm
|
||||
public boolean
|
||||
upgradeVirtualMachine(ScaleVMCmd cmd) throws InvalidParameterValueException {
|
||||
Long vmId = cmd.getId();
|
||||
Long newServiceOfferingId = cmd.getServiceOfferingId();
|
||||
|
|
@ -1076,8 +1076,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
}
|
||||
|
||||
// Dynamically upgrade the running vms
|
||||
boolean success = false;
|
||||
if(vmInstance.getState().equals(State.Running)){
|
||||
boolean success = false;
|
||||
int retry = _scaleRetry;
|
||||
while (retry-- != 0) { // It's != so that it can match -1.
|
||||
try{
|
||||
|
|
@ -1095,7 +1095,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
vmInstance = _vmInstanceDao.findById(vmId);
|
||||
vmInstance = _itMgr.reConfigureVm(vmInstance, oldServiceOffering, existingHostHasCapacity);
|
||||
success = true;
|
||||
return _vmDao.findById(vmInstance.getId());
|
||||
return success;
|
||||
}catch(InsufficientCapacityException e ){
|
||||
s_logger.warn("Received exception while scaling ",e);
|
||||
} catch (ResourceUnavailableException e) {
|
||||
|
|
@ -1112,11 +1112,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!success)
|
||||
return null;
|
||||
}
|
||||
|
||||
return _vmDao.findById(vmInstance.getId());
|
||||
return success;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ import com.cloud.alert.AlertManager;
|
|||
import com.cloud.cluster.ClusterManager;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.configuration.Resource.ResourceType;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.DataCenter;
|
||||
|
|
@ -131,6 +132,7 @@ import com.cloud.storage.dao.StoragePoolHostDao;
|
|||
import com.cloud.storage.snapshot.SnapshotManager;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
|
|
@ -231,6 +233,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
protected VMSnapshotDao _vmSnapshotDao;
|
||||
@Inject
|
||||
protected VolumeDataFactory volFactory;
|
||||
@Inject
|
||||
protected ResourceLimitService _resourceLimitMgr;
|
||||
|
||||
protected List<DeploymentPlanner> _planners;
|
||||
public List<DeploymentPlanner> getPlanners() {
|
||||
|
|
@ -428,6 +432,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
s_logger.debug("Cleaning up NICS");
|
||||
_networkMgr.cleanupNics(profile);
|
||||
// Clean up volumes based on the vm's instance id
|
||||
List<VolumeVO> rootVol = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT);
|
||||
this.volumeMgr.cleanupVolumes(vm.getId());
|
||||
|
||||
VirtualMachineGuru<T> guru = getVmGuru(vm);
|
||||
|
|
@ -462,6 +467,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
s_logger.debug("Expunged " + vm);
|
||||
}
|
||||
|
||||
// Update Resource count
|
||||
if (vm.getAccountId() != Account.ACCOUNT_ID_SYSTEM && !rootVol.isEmpty()) {
|
||||
_resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.volume);
|
||||
_resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.primary_storage,
|
||||
new Long(rootVol.get(0).getSize()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,15 +64,23 @@ import com.cloud.user.Account;
|
|||
import com.cloud.user.User;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.NicSecondaryIp;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.*;
|
||||
import com.cloud.vm.VirtualMachine.Type;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
@Component
|
||||
@Local(value = { NetworkManager.class, NetworkService.class })
|
||||
|
|
@ -611,7 +619,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
|
|||
*/
|
||||
@Override
|
||||
public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan,
|
||||
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId)
|
||||
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat)
|
||||
throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -76,8 +76,7 @@ public class MockRulesManagerImpl extends ManagerBase implements RulesManager, R
|
|||
|
||||
@Override
|
||||
public boolean enableStaticNat(long ipAddressId, long vmId, long networkId,
|
||||
boolean isSystemVm, String ipAddr) throws NetworkRuleConflictException,
|
||||
ResourceUnavailableException {
|
||||
String ipAddr) throws NetworkRuleConflictException, ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -407,8 +407,8 @@ public class MockUserVmManagerImpl extends ManagerBase implements UserVmManager,
|
|||
}
|
||||
|
||||
@Override
|
||||
public UserVm upgradeVirtualMachine(ScaleVMCmd scaleVMCmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
public boolean upgradeVirtualMachine(ScaleVMCmd scaleVMCmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
|
||||
return false; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -79,15 +79,25 @@ import com.cloud.user.Account;
|
|||
import com.cloud.user.User;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.NicSecondaryIp;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.*;
|
||||
import com.cloud.vm.VirtualMachine.Type;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Component
|
||||
@Local(value = { NetworkManager.class, NetworkService.class })
|
||||
|
|
@ -625,7 +635,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
|
|||
*/
|
||||
@Override
|
||||
public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan,
|
||||
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId)
|
||||
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat)
|
||||
throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ public class MockVpcManagerImpl extends ManagerBase implements VpcManager {
|
|||
* @see com.cloud.network.vpc.VpcService#createVpcPrivateGateway(long, java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, long)
|
||||
*/
|
||||
@Override
|
||||
public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress, String gateway, String netmask, long gatewayOwnerId) throws ResourceAllocationException,
|
||||
public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress, String gateway, String netmask, long gatewayOwnerId, Boolean isSourceNat) throws ResourceAllocationException,
|
||||
ConcurrentOperationException, InsufficientCapacityException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -1158,3 +1158,6 @@ ALTER TABLE `cloud`.`account_details` MODIFY value varchar(255);
|
|||
|
||||
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'midonet.apiserver.address', 'http://localhost:8081', 'Specify the address at which the Midonet API server can be contacted (if using Midonet)');
|
||||
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'midonet.providerrouter.id', 'd7c5e6a3-e2f4-426b-b728-b7ce6a0448e5', 'Specifies the UUID of the Midonet provider router (if using Midonet)');
|
||||
|
||||
alter table cloud.vpc_gateways add column source_nat boolean default false;
|
||||
alter table cloud.private_ip_address add column source_nat boolean default false;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,308 @@
|
|||
# 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 Local Modules
|
||||
import marvin
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin.integration.lib.utils import *
|
||||
from marvin.integration.lib.base import *
|
||||
from marvin.integration.lib.common import *
|
||||
from marvin.remoteSSHClient import remoteSSHClient
|
||||
|
||||
class Services:
|
||||
"""Test Snapshots Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"account": {
|
||||
"email": "test@test.com",
|
||||
"firstname": "Test",
|
||||
"lastname": "User",
|
||||
"username": "test",
|
||||
# Random characters are appended for unique
|
||||
# username
|
||||
"password": "password",
|
||||
},
|
||||
"service_offering": {
|
||||
"name": "Tiny Instance",
|
||||
"displaytext": "Tiny Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 200, # in MHz
|
||||
"memory": 256, # In MBs
|
||||
},
|
||||
"server": {
|
||||
"displayname": "TestVM",
|
||||
"username": "root",
|
||||
"password": "password",
|
||||
"ssh_port": 22,
|
||||
"hypervisor": 'XenServer',
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"protocol": 'TCP',
|
||||
},
|
||||
"mgmt_server": {
|
||||
"ipaddress": '1.2.2.152',
|
||||
"username": "root",
|
||||
"password": "password",
|
||||
"port": 22,
|
||||
},
|
||||
"templates": {
|
||||
"displaytext": 'Template',
|
||||
"name": 'Template',
|
||||
"ostype": "CentOS 5.3 (64-bit)",
|
||||
"templatefilter": 'self',
|
||||
},
|
||||
"test_dir": "/tmp",
|
||||
"random_data": "random.data",
|
||||
"snapshot_name":"TestSnapshot",
|
||||
"snapshot_displaytext":"Test",
|
||||
"ostype": "CentOS 5.3 (64-bit)",
|
||||
"sleep": 60,
|
||||
"timeout": 10,
|
||||
"mode": 'advanced', # Networking mode: Advanced, Basic
|
||||
}
|
||||
|
||||
class TestVmSnapshot(cloudstackTestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.api_client = super(TestVmSnapshot, cls).getClsTestClient().getApiClient()
|
||||
cls.services = Services().services
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client, cls.services)
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
|
||||
template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"]
|
||||
)
|
||||
cls.services["domainid"] = cls.domain.id
|
||||
cls.services["server"]["zoneid"] = cls.zone.id
|
||||
cls.services["templates"]["ostypeid"] = template.ostypeid
|
||||
cls.services["zoneid"] = cls.zone.id
|
||||
|
||||
# Create VMs, NAT Rules etc
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
|
||||
cls.services["account"] = cls.account.name
|
||||
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
cls.virtual_machine = VirtualMachine.create(
|
||||
cls.api_client,
|
||||
cls.services["server"],
|
||||
templateid=template.id,
|
||||
accountid=cls.account.name,
|
||||
domainid=cls.account.domainid,
|
||||
serviceofferingid=cls.service_offering.id,
|
||||
mode=cls.services["mode"]
|
||||
)
|
||||
cls.random_data_0 = random_gen(100)
|
||||
cls._cleanup = [
|
||||
cls.service_offering,
|
||||
cls.account,
|
||||
]
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
# Clean up, terminate the created instance, volumes and snapshots
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "advancedns", "smoke"])
|
||||
def test_01_create_vm_snapshots(self):
|
||||
|
||||
try:
|
||||
# Login to VM and write data to file system
|
||||
ssh_client = self.virtual_machine.get_ssh_client()
|
||||
|
||||
cmds = [
|
||||
"echo %s > %s/%s" % (self.random_data_0, self.services["test_dir"], self.services["random_data"]),
|
||||
"cat %s/%s" % (self.services["test_dir"], self.services["random_data"])
|
||||
]
|
||||
|
||||
for c in cmds:
|
||||
self.debug(c)
|
||||
result = ssh_client.execute(c)
|
||||
self.debug(result)
|
||||
|
||||
except Exception:
|
||||
self.fail("SSH failed for Virtual machine: %s" %
|
||||
self.virtual_machine.ipaddress)
|
||||
self.assertEqual(
|
||||
self.random_data_0,
|
||||
result[0],
|
||||
"Check the random data has be write into temp file!"
|
||||
)
|
||||
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
vm_snapshot = VmSnapshot.create(
|
||||
self.apiclient,
|
||||
self.virtual_machine.id,
|
||||
"false",
|
||||
self.services["snapshot_name"],
|
||||
self.services["snapshot_displaytext"]
|
||||
)
|
||||
self.assertEqual(
|
||||
vm_snapshot.state,
|
||||
"Ready",
|
||||
"Check the snapshot of vm is ready!"
|
||||
)
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "advancedns", "smoke"])
|
||||
def test_02_revert_vm_snapshots(self):
|
||||
try:
|
||||
ssh_client = self.virtual_machine.get_ssh_client()
|
||||
|
||||
cmds = [
|
||||
"rm -rf %s/%s" % (self.services["test_dir"], self.services["random_data"]),
|
||||
"ls %s/%s" % (self.services["test_dir"], self.services["random_data"])
|
||||
]
|
||||
|
||||
for c in cmds:
|
||||
self.debug(c)
|
||||
result = ssh_client.execute(c)
|
||||
self.debug(result)
|
||||
|
||||
except Exception:
|
||||
self.fail("SSH failed for Virtual machine: %s" %
|
||||
self.virtual_machine.ipaddress)
|
||||
|
||||
if str(result[0]).index("No such file or directory") == -1:
|
||||
self.fail("Check the random data has be delete from temp file!")
|
||||
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
list_snapshot_response = VmSnapshot.list(self.apiclient,vmid=self.virtual_machine.id,listall=True)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_snapshot_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
list_snapshot_response,
|
||||
None,
|
||||
"Check if snapshot exists in ListSnapshot"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
list_snapshot_response[0].state,
|
||||
"Ready",
|
||||
"Check the snapshot of vm is ready!"
|
||||
)
|
||||
|
||||
VmSnapshot.revertToSnapshot(self.apiclient,list_snapshot_response[0].id)
|
||||
|
||||
list_vm_response = list_virtual_machines(
|
||||
self.apiclient,
|
||||
id=self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
list_vm_response[0].state,
|
||||
"Stopped",
|
||||
"Check the state of vm is Stopped!"
|
||||
)
|
||||
|
||||
cmd = startVirtualMachine.startVirtualMachineCmd()
|
||||
cmd.id = list_vm_response[0].id
|
||||
self.apiclient.startVirtualMachine(cmd)
|
||||
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
try:
|
||||
ssh_client = self.virtual_machine.get_ssh_client(reconnect=True)
|
||||
|
||||
cmds = [
|
||||
"cat %s/%s" % (self.services["test_dir"], self.services["random_data"])
|
||||
]
|
||||
|
||||
for c in cmds:
|
||||
self.debug(c)
|
||||
result = ssh_client.execute(c)
|
||||
self.debug(result)
|
||||
|
||||
except Exception:
|
||||
self.fail("SSH failed for Virtual machine: %s" %
|
||||
self.virtual_machine.ipaddress)
|
||||
|
||||
self.assertEqual(
|
||||
self.random_data_0,
|
||||
result[0],
|
||||
"Check the random data is equal with the ramdom file!"
|
||||
)
|
||||
@attr(tags=["advanced", "advancedns", "smoke"])
|
||||
def test_03_delete_vm_snapshots(self):
|
||||
|
||||
list_snapshot_response = VmSnapshot.list(self.apiclient,vmid=self.virtual_machine.id,listall=True)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_snapshot_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
list_snapshot_response,
|
||||
None,
|
||||
"Check if snapshot exists in ListSnapshot"
|
||||
)
|
||||
"""
|
||||
cmd = deleteVMSnapshot.deleteVMSnapshotCmd()
|
||||
cmd.vmsnapshotid = list_snapshot_response[0].id
|
||||
self.apiclient.deleteVMSnapshot(cmd)
|
||||
"""
|
||||
VmSnapshot.deleteVMSnapshot(self.apiclient,list_snapshot_response[0].id)
|
||||
|
||||
time.sleep(self.services["sleep"]*3)
|
||||
|
||||
list_snapshot_response = VmSnapshot.list(self.apiclient,vmid=self.virtual_machine.id,listall=True)
|
||||
|
||||
self.assertEqual(
|
||||
list_snapshot_response,
|
||||
None,
|
||||
"Check list vm snapshot has be deleted"
|
||||
)
|
||||
|
|
@ -1,31 +1,41 @@
|
|||
##############################################
|
||||
|
||||
Questions? Post'em @ dev@cloudstack.apache.org
|
||||
|
||||
##############################################
|
||||
|
||||
This files contains following:
|
||||
|
||||
1) Installation requirements
|
||||
2) Test Pre requisites
|
||||
3) Running the Test and Generating the report
|
||||
2) Testing pre-requisites
|
||||
3) Running the Tests and Generating the report
|
||||
##############################################
|
||||
|
||||
|
||||
|
||||
##########################################################################################################################################
|
||||
|
||||
1) Installtion Requirements
|
||||
1) Installation Requirements
|
||||
---------------------------
|
||||
|
||||
|
||||
1)Firefox depending on your OS (Good to have Firebug and Selenium IDE for troubleshooting and dev work)
|
||||
1) Firefox depending on your OS (Good to have Firebug and Selenium IDE for troubleshooting and dev work)
|
||||
|
||||
|
||||
2)Install Python 2.7. Recommend to use Active State Python
|
||||
2) Install Python 2.7.
|
||||
|
||||
|
||||
3) Now Open CMD/Terminal and type all of following
|
||||
|
||||
- pypm install pycrypto (Installs Pycrypto)
|
||||
- pypm install paramiko (Install paramiko)
|
||||
- pip install pycrypto (Installs Pycrypto)
|
||||
- pip install paramiko (Install paramiko)
|
||||
- pip install unittest-xml-reporting (Install XML Test Runner)
|
||||
- pip install -U selenium (Installs Selenium)
|
||||
|
||||
4) Get PhoantomJS for your OS from http://phantomjs.org/
|
||||
|
||||
- PhantomJS will run selenium test in headless mode. Follow the instruction on PhantomJS.org.
|
||||
- Make sure the executable is in PATH. (TIP: Drop it in Python27 folder :-))
|
||||
|
||||
5) Now get the HTMLTestRunner for nice looking report generation.
|
||||
- http://tungwaiyip.info/software/HTMLTestRunner.html
|
||||
|
|
@ -35,18 +45,22 @@ This files contains following:
|
|||
##########################################################################################################################################
|
||||
|
||||
2) Test Prerequisites
|
||||
---------------------
|
||||
|
||||
- Download and install CS. /cwiki.apache.org has links to Installation Guide and API reference.
|
||||
- Log into the management server and Add a Zone. (Must be Advance Zone and Hypervisor type must be Xen)
|
||||
|
||||
- Download and install CS
|
||||
- Log into the management server nad Add a Zone. (Must be Advance Zone and Hypervisor type must be Xen)
|
||||
|
||||
##########################################################################################################################################
|
||||
|
||||
3) Running the Test and Generating the report
|
||||
---------------------------------------------
|
||||
|
||||
- Folder smoke contains main.py
|
||||
- main.py is the file where all the tests are serialized.
|
||||
- main.py supports HTML and XML reporting. Please refer to end of file to choose either.
|
||||
- Typical usage is: python main.py for XML Reporting
|
||||
- And python main.py >> results.html for HTML Reporting.
|
||||
- Typical usage is: python main.py 10.1.1.10 >> result.xml for XML Reporting
|
||||
- And python main.py 10.1.1.10 >> result.html for HTML Reporting.
|
||||
- 10.1.1.10 (your management server IP) is an argument required for main.
|
||||
|
||||
##########################################################################################################################################
|
||||
|
|
|
|||
|
|
@ -21,11 +21,26 @@ This will help pass webdriver (Browser instance) across our test cases.
|
|||
|
||||
|
||||
from selenium import webdriver
|
||||
import sys
|
||||
|
||||
DRIVER = None
|
||||
MS_ip = None
|
||||
|
||||
|
||||
def getOrCreateWebdriver():
|
||||
global DRIVER
|
||||
DRIVER = DRIVER or webdriver.Firefox()
|
||||
DRIVER = DRIVER or webdriver.PhantomJS('phantomjs') # phantomjs executable must be in PATH.
|
||||
return DRIVER
|
||||
|
||||
|
||||
def getMSip():
|
||||
global MS_ip
|
||||
if len(sys.argv) >= 3:
|
||||
sys.exit("Only One argument is required .. Enter your Management Server IP")
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
sys.exit("Atleast One argument is required .. Enter your Management Server IP")
|
||||
|
||||
for arg in sys.argv[1:]:
|
||||
MS_ip = arg
|
||||
return MS_ip
|
||||
|
|
@ -34,11 +34,12 @@ class login(unittest.TestCase):
|
|||
|
||||
def setUp(self):
|
||||
|
||||
MS_URL = initialize.getMSip()
|
||||
self.driver = initialize.getOrCreateWebdriver()
|
||||
self.base_url = "http://10.223.49.206:8080/" # Your management Server IP goes here
|
||||
self.base_url = "http://"+ MS_URL +":8080/" # Your management Server IP goes here
|
||||
self.verificationErrors = []
|
||||
|
||||
|
||||
|
||||
def test_login(self):
|
||||
|
||||
# Here we will clear the test box for Username and Password and fill them with actual login data.
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import xmlrunner
|
|||
|
||||
|
||||
global DRIVER
|
||||
|
||||
global MS_ip
|
||||
|
||||
# Import test cases
|
||||
|
||||
|
|
|
|||
|
|
@ -3045,3 +3045,40 @@ class ASA1000V:
|
|||
cmd = listCiscoAsa1000vResources.listCiscoAsa1000vResourcesCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listCiscoAsa1000vResources(cmd))
|
||||
|
||||
class VmSnapshot:
|
||||
"""Manage VM Snapshot life cycle"""
|
||||
def __init__(self, items):
|
||||
self.__dict__.update(items)
|
||||
@classmethod
|
||||
def create(cls,apiclient,vmid,snapshotmemory="false",name=None,description=None):
|
||||
cmd = createVMSnapshot.createVMSnapshotCmd()
|
||||
cmd.virtualmachineid = vmid
|
||||
|
||||
if snapshotmemory:
|
||||
cmd.snapshotmemory = snapshotmemory
|
||||
if name:
|
||||
cmd.name = name
|
||||
if description:
|
||||
cmd.description = description
|
||||
return VmSnapshot(apiclient.createVMSnapshot(cmd).__dict__)
|
||||
|
||||
@classmethod
|
||||
def list(cls, apiclient, **kwargs):
|
||||
cmd = listVMSnapshot.listVMSnapshotCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listVMSnapshot(cmd))
|
||||
|
||||
@classmethod
|
||||
def revertToSnapshot(cls, apiclient,vmsnapshotid):
|
||||
cmd = revertToVMSnapshot.revertToVMSnapshotCmd()
|
||||
cmd.vmsnapshotid = vmsnapshotid
|
||||
|
||||
return apiclient.revertToVMSnapshot(cmd)
|
||||
|
||||
@classmethod
|
||||
def deleteVMSnapshot(cls,apiclient,vmsnapshotid):
|
||||
cmd = deleteVMSnapshot.deleteVMSnapshotCmd()
|
||||
cmd.vmsnapshotid = vmsnapshotid
|
||||
|
||||
return apiclient.deleteVMSnapshot(cmd)
|
||||
|
|
|
|||
|
|
@ -1662,6 +1662,7 @@ under the License.
|
|||
<script type="text/javascript" src="scripts/ui-custom/autoscaler.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui-custom/healthCheck.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/autoscaler.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui-custom/granularSettings.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui-custom/zoneChart.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui-custom/dashboard.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/installWizard.js?t=<%=now%>"></script>
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@
|
|||
|
||||
detailView: {
|
||||
name: 'Account details',
|
||||
isMaximized: true,
|
||||
viewAll: { path: 'accounts.users', label: 'label.users' },
|
||||
|
||||
actions: {
|
||||
|
|
@ -895,6 +896,56 @@
|
|||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// Granular settings for account
|
||||
settings: {
|
||||
title: 'Settings',
|
||||
custom: cloudStack.uiCustom.granularSettings({
|
||||
dataProvider: function(args) {
|
||||
$.ajax({
|
||||
url:createURL('listConfigurations&accountid=' + args.context.accounts[0].id),
|
||||
data: { page: args.page, pageSize: pageSize, listAll: true },
|
||||
success:function(json){
|
||||
args.response.success({
|
||||
data:json.listconfigurationsresponse.configuration
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
error:function(json){
|
||||
args.response.error(parseXMLHttpResponse(json));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
actions: {
|
||||
edit: function(args) {
|
||||
// call updateAccountLevelParameters
|
||||
var data = {
|
||||
name: args.data.jsonObj.name,
|
||||
value: args.data.value
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url:createURL('updateConfiguration&accountid=' + args.context.accounts[0].id),
|
||||
data:data,
|
||||
success:function(json){
|
||||
var item = json.updateconfigurationresponse.configuration;
|
||||
args.response.success({data:item});
|
||||
},
|
||||
|
||||
error: function(json) {
|
||||
args.response.error(parseXMLHttpResponse(json));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -317,7 +317,15 @@
|
|||
url: createURL('listAffinityGroups'),
|
||||
success: function(json) {
|
||||
var items = json.listaffinitygroupsresponse.affinitygroup;
|
||||
args.response.success({data: {affinityGroups: items}});
|
||||
var data = {
|
||||
affinityGroups: items
|
||||
};
|
||||
if('affinityGroups' in args.context) {
|
||||
$.extend(data, {
|
||||
selectedObj: args.context.affinityGroups[0]
|
||||
});
|
||||
}
|
||||
args.response.success({data: data});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -204,13 +204,7 @@
|
|||
affinitygroupid: args.context.affinityGroups[0].id
|
||||
});
|
||||
}
|
||||
|
||||
if(args.context.zoneType != null && args.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data, {
|
||||
zonetype: args.context.zoneType
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$.ajax({
|
||||
url: createURL('listVirtualMachines'),
|
||||
data: data,
|
||||
|
|
|
|||
|
|
@ -89,20 +89,7 @@
|
|||
dataType: "json",
|
||||
async: true,
|
||||
success: function(json) {
|
||||
var zoneObjs;
|
||||
if(args.context.zoneType == null || args.context.zoneType == '') { //all types
|
||||
zoneObjs = json.listzonesresponse.zone;
|
||||
}
|
||||
else { //Basic type or Advanced type
|
||||
zoneObjs = [];
|
||||
var items = json.listzonesresponse.zone;
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
if(items[i].networktype == args.context.zoneType)
|
||||
zoneObjs.push(items[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
var zoneObjs = json.listzonesresponse.zone;
|
||||
args.response.success({descriptionField: 'name', data: zoneObjs});
|
||||
}
|
||||
});
|
||||
|
|
@ -227,20 +214,7 @@
|
|||
dataType: "json",
|
||||
async: true,
|
||||
success: function(json) {
|
||||
var zoneObjs;
|
||||
if(args.context.zoneType == null || args.context.zoneType == '') { //all types
|
||||
zoneObjs = json.listzonesresponse.zone;
|
||||
}
|
||||
else { //Basic type or Advanced type
|
||||
zoneObjs = [];
|
||||
var items = json.listzonesresponse.zone;
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
if(items[i].networktype == args.context.zoneType)
|
||||
zoneObjs.push(items[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
var zoneObjs = json.listzonesresponse.zone;
|
||||
args.response.success({descriptionField: 'name', data: zoneObjs});
|
||||
}
|
||||
});
|
||||
|
|
@ -398,18 +372,12 @@
|
|||
|
||||
if(args.context != null) {
|
||||
if("instances" in args.context) {
|
||||
$.extend(data, {
|
||||
virtualMachineId: args.context.instances[0].id
|
||||
});
|
||||
$.extend(data, {
|
||||
virtualMachineId: args.context.instances[0].id
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(args.context.zoneType != null && args.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data, {
|
||||
zonetype: args.context.zoneType
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$.ajax({
|
||||
url: createURL('listVolumes'),
|
||||
data: data,
|
||||
|
|
|
|||
|
|
@ -184,16 +184,9 @@
|
|||
dashboard: {
|
||||
dataProvider: function(args) {
|
||||
var dataFns = {
|
||||
zoneCount: function(data) {
|
||||
var data = {};
|
||||
if(cloudStack.context.zoneType != null && cloudStack.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data, {
|
||||
networktype: cloudStack.context.zoneType
|
||||
});
|
||||
}
|
||||
zoneCount: function(data) {
|
||||
$.ajax({
|
||||
url: createURL('listZones'),
|
||||
data: data,
|
||||
url: createURL('listZones'),
|
||||
success: function(json) {
|
||||
dataFns.podCount($.extend(data, {
|
||||
zoneCount: json.listzonesresponse.count ?
|
||||
|
|
@ -250,12 +243,7 @@
|
|||
type: 'routing',
|
||||
page: 1,
|
||||
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
|
||||
};
|
||||
if(cloudStack.context.zoneType != null && cloudStack.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data2, {
|
||||
zonetype: cloudStack.context.zoneType
|
||||
});
|
||||
}
|
||||
};
|
||||
$.ajax({
|
||||
url: createURL('listHosts'),
|
||||
data: data2,
|
||||
|
|
@ -272,12 +260,7 @@
|
|||
var data2 = {
|
||||
page: 1,
|
||||
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
|
||||
};
|
||||
if(cloudStack.context.zoneType != null && cloudStack.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data2, {
|
||||
zonetype: cloudStack.context.zoneType
|
||||
});
|
||||
}
|
||||
};
|
||||
$.ajax({
|
||||
url: createURL('listStoragePools'),
|
||||
data: data2,
|
||||
|
|
@ -294,12 +277,7 @@
|
|||
type: 'SecondaryStorage',
|
||||
page: 1,
|
||||
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
|
||||
};
|
||||
if(cloudStack.context.zoneType != null && cloudStack.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data2, {
|
||||
zonetype: cloudStack.context.zoneType
|
||||
});
|
||||
}
|
||||
};
|
||||
$.ajax({
|
||||
url: createURL('listHosts'),
|
||||
data: data2,
|
||||
|
|
@ -333,12 +311,7 @@
|
|||
projectid: -1,
|
||||
page: 1,
|
||||
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
|
||||
};
|
||||
if(cloudStack.context.zoneType != null && cloudStack.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data2, {
|
||||
zonetype: cloudStack.context.zoneType
|
||||
});
|
||||
}
|
||||
};
|
||||
$.ajax({
|
||||
url: createURL('listRouters'),
|
||||
data: data2,
|
||||
|
|
@ -349,12 +322,7 @@
|
|||
listAll: true,
|
||||
page: 1,
|
||||
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
|
||||
};
|
||||
if(cloudStack.context.zoneType != null && cloudStack.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data3, {
|
||||
zonetype: cloudStack.context.zoneType
|
||||
});
|
||||
}
|
||||
};
|
||||
$.ajax({
|
||||
url: createURL('listRouters'),
|
||||
data: data3,
|
||||
|
|
@ -2332,12 +2300,7 @@
|
|||
|
||||
var data2 = {
|
||||
forvpc: false
|
||||
};
|
||||
if(cloudStack.context.zoneType != null && cloudStack.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data2, {
|
||||
zonetype: cloudStack.context.zoneType
|
||||
});
|
||||
}
|
||||
};
|
||||
var routers = [];
|
||||
$.ajax({
|
||||
url: createURL("listRouters&zoneid=" + selectedZoneObj.id + "&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")),
|
||||
|
|
@ -2817,12 +2780,7 @@
|
|||
|
||||
var data2 = {
|
||||
forvpc: true
|
||||
};
|
||||
if(cloudStack.context.zoneType != null && cloudStack.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data2, {
|
||||
zonetype: cloudStack.context.zoneType
|
||||
});
|
||||
}
|
||||
};
|
||||
var routers = [];
|
||||
$.ajax({
|
||||
url: createURL("listRouters&zoneid=" + selectedZoneObj.id + "&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")),
|
||||
|
|
@ -4708,12 +4666,7 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(args.context.zoneType != null && args.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
array1.push("&networktype=" + args.context.zoneType);
|
||||
}
|
||||
|
||||
}
|
||||
$.ajax({
|
||||
url: createURL("listZones&page=" + args.page + "&pagesize=" + pageSize + array1.join("")),
|
||||
dataType: "json",
|
||||
|
|
@ -5566,6 +5519,55 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Granular settings for zone
|
||||
settings: {
|
||||
title: 'Settings',
|
||||
custom: cloudStack.uiCustom.granularSettings({
|
||||
dataProvider: function(args) {
|
||||
$.ajax({
|
||||
url:createURL('listConfigurations&zoneid=' + args.context.physicalResources[0].id),
|
||||
data: { page: args.page, pageSize: pageSize, listAll: true },
|
||||
success:function(json){
|
||||
args.response.success({
|
||||
data:json.listconfigurationsresponse.configuration
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
error:function(json){
|
||||
args.response.error(parseXMLHttpResponse(json));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
actions: {
|
||||
edit: function(args) {
|
||||
// call updateZoneLevelParamter
|
||||
var data = {
|
||||
name: args.data.jsonObj.name,
|
||||
value: args.data.value
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url:createURL('updateConfiguration&zoneid=' + args.context.physicalResources[0].id),
|
||||
data:data,
|
||||
success:function(json){
|
||||
var item = json.updateconfigurationresponse.configuration;
|
||||
args.response.success({data:item});
|
||||
},
|
||||
|
||||
error: function(json) {
|
||||
args.response.error(parseXMLHttpResponse(json));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5660,12 +5662,12 @@
|
|||
var searchByArgs = args.filterBy.search.value.length ?
|
||||
'&name=' + args.filterBy.search.value : '';
|
||||
|
||||
var data = { page: args.page, pageSize: pageSize, type: 'routing', listAll: true };
|
||||
if(args.context.zoneType != null && args.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data, {
|
||||
zonetype: args.context.zoneType
|
||||
});
|
||||
}
|
||||
var data = {
|
||||
page: args.page,
|
||||
pageSize: pageSize,
|
||||
type: 'routing',
|
||||
listAll: true
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url: createURL('listHosts' + searchByArgs),
|
||||
|
|
@ -5714,11 +5716,7 @@
|
|||
pageSize: pageSize,
|
||||
listAll: true
|
||||
};
|
||||
if(args.context.zoneType != null && args.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data, {
|
||||
zonetype: args.context.zoneType
|
||||
});
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: createURL('listStoragePools' + searchByArgs),
|
||||
data: data,
|
||||
|
|
@ -5761,12 +5759,12 @@
|
|||
var searchByArgs = args.filterBy.search.value.length ?
|
||||
'&name=' + args.filterBy.search.value : '';
|
||||
|
||||
var data = { type: 'SecondaryStorage', page: args.page, pageSize: pageSize, listAll: true };
|
||||
if(args.context.zoneType != null && args.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data, {
|
||||
zonetype: args.context.zoneType
|
||||
});
|
||||
}
|
||||
var data = {
|
||||
type: 'SecondaryStorage',
|
||||
page: args.page,
|
||||
pageSize: pageSize,
|
||||
listAll: true
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url: createURL('listHosts' + searchByArgs),
|
||||
|
|
@ -5850,18 +5848,11 @@
|
|||
var listView = $.extend(true, {}, cloudStack.sections.system.subsections.virtualRouters.listView, {
|
||||
dataProvider: function (args) {
|
||||
var searchByArgs = args.filterBy.search.value.length ?
|
||||
'&name=' + args.filterBy.search.value : '';
|
||||
|
||||
var data2 = {};
|
||||
if(cloudStack.context.zoneType != null && cloudStack.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data2, {
|
||||
zonetype: cloudStack.context.zoneType
|
||||
});
|
||||
}
|
||||
'&name=' + args.filterBy.search.value : '';
|
||||
|
||||
var routers = [];
|
||||
$.ajax({
|
||||
url: createURL("listRouters&listAll=true&page=" + args.page + "&pagesize=" + pageSize + searchByArgs),
|
||||
data: data2,
|
||||
url: createURL("listRouters&listAll=true&page=" + args.page + "&pagesize=" + pageSize + searchByArgs),
|
||||
async: true,
|
||||
success: function(json) {
|
||||
var items = json.listroutersresponse.router ?
|
||||
|
|
@ -5873,8 +5864,7 @@
|
|||
|
||||
// Get project routers
|
||||
$.ajax({
|
||||
url: createURL("listRouters&listAll=true&page=" + args.page + "&pagesize=" + pageSize + "&projectid=-1"),
|
||||
data: data2,
|
||||
url: createURL("listRouters&listAll=true&page=" + args.page + "&pagesize=" + pageSize + "&projectid=-1"),
|
||||
async: true,
|
||||
success: function(json) {
|
||||
var items = json.listroutersresponse.router ?
|
||||
|
|
@ -5961,11 +5951,7 @@
|
|||
var data2 = {
|
||||
forvpc: false
|
||||
};
|
||||
if(cloudStack.context.zoneType != null && cloudStack.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data2, {
|
||||
zonetype: cloudStack.context.zoneType
|
||||
});
|
||||
}
|
||||
|
||||
var routers = [];
|
||||
$.ajax({
|
||||
url: createURL("listRouters&zoneid=" + selectedZoneObj.id + "&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")),
|
||||
|
|
@ -6278,6 +6264,80 @@
|
|||
}
|
||||
},
|
||||
|
||||
scaleUp:{
|
||||
label:'scaleUp Router VM',
|
||||
createForm: {
|
||||
title: 'label.change.service.offering',
|
||||
desc: '',
|
||||
fields: {
|
||||
|
||||
serviceOfferingId: {
|
||||
label: 'label.compute.offering',
|
||||
select: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('listServiceOfferings'),
|
||||
data: {
|
||||
issystem: true,
|
||||
systemvmtype: 'domainrouter'
|
||||
},
|
||||
success: function(json) {
|
||||
var serviceofferings = json.listserviceofferingsresponse.serviceoffering;
|
||||
var items = [];
|
||||
$(serviceofferings).each(function() {
|
||||
// if(this.id != args.context.routers[0].serviceofferingid) {
|
||||
items.push({id: this.id, description: this.name}); //default one (i.e. "System Offering For Software Router") doesn't have displaytext property. So, got to use name property instead.
|
||||
|
||||
});
|
||||
args.response.success({data: items});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
action: function(args) {
|
||||
$.ajax({
|
||||
url: createURL("scaleVirtualMachine&id=" + args.context.routers[0].id + "&serviceofferingid=" + args.data.serviceOfferingId),
|
||||
dataType: "json",
|
||||
async: true,
|
||||
success: function(json) {
|
||||
var jid = json.scalevirtualmachineresponse.jobid;
|
||||
args.response.success(
|
||||
{_custom:
|
||||
{jobId: jid,
|
||||
getUpdatedItem: function(json) {
|
||||
return json.queryasyncjobresultresponse.jobresult.virtualmachine;
|
||||
},
|
||||
getActionFilter: function() {
|
||||
return vmActionfilter;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
error:function(json){
|
||||
args.response.error(parseXMLHttpResponse(json));
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
messages: {
|
||||
confirm: function(args) {
|
||||
return 'Do you really want to scale up the Router VM ?';
|
||||
},
|
||||
notification: function(args) {
|
||||
|
||||
return 'Router VM Scaled Up';
|
||||
}
|
||||
},
|
||||
notification: {
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
viewConsole: {
|
||||
label: 'label.view.console',
|
||||
action: {
|
||||
|
|
@ -9085,6 +9145,57 @@
|
|||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Granular settings for cluster
|
||||
settings: {
|
||||
title: 'Settings',
|
||||
custom: cloudStack.uiCustom.granularSettings({
|
||||
dataProvider: function(args) {
|
||||
$.ajax({
|
||||
url:createURL('listConfigurations&clusterid=' + args.context.clusters[0].id),
|
||||
data: { page: args.page, pageSize: pageSize, listAll: true },
|
||||
success:function(json){
|
||||
args.response.success({
|
||||
data:json.listconfigurationsresponse.configuration
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
error:function(json){
|
||||
args.response.error(parseXMLHttpResponse(json));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
actions: {
|
||||
edit: function(args) {
|
||||
// call updateClusterLevelParameters
|
||||
|
||||
var data = {
|
||||
name: args.data.jsonObj.name,
|
||||
value: args.data.value
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url:createURL('updateConfiguration&clusterid=' + args.context.clusters[0].id),
|
||||
data:data,
|
||||
success:function(json){
|
||||
var item = json.updateconfigurationresponse.configuration;
|
||||
args.response.success({data:item});
|
||||
},
|
||||
|
||||
error: function(json) {
|
||||
args.response.error(parseXMLHttpResponse(json));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9135,11 +9246,7 @@
|
|||
} else {
|
||||
array1.push("&hostid=" + args.context.instances[0].hostid);
|
||||
}
|
||||
|
||||
if(args.context.zoneType != null && args.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
array1.push("&zonetype=" + args.context.zoneType);
|
||||
}
|
||||
|
||||
|
||||
$.ajax({
|
||||
url: createURL("listHosts&type=Routing" + array1.join("") + "&page=" + args.page + "&pagesize=" + pageSize),
|
||||
dataType: "json",
|
||||
|
|
@ -10524,6 +10631,7 @@
|
|||
|
||||
detailView: {
|
||||
name: "Primary storage details",
|
||||
isMaximized: true,
|
||||
actions: {
|
||||
edit: {
|
||||
label: 'label.edit',
|
||||
|
|
@ -10708,6 +10816,57 @@
|
|||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// Granular settings for storage pool
|
||||
settings: {
|
||||
title: 'Settings',
|
||||
custom: cloudStack.uiCustom.granularSettings({
|
||||
dataProvider: function(args) {
|
||||
|
||||
$.ajax({
|
||||
url:createURL('listConfigurations&storageid=' + args.context.primarystorages[0].id),
|
||||
data: { page: args.page, pageSize: pageSize, listAll: true },
|
||||
success:function(json){
|
||||
args.response.success({
|
||||
data:json.listconfigurationsresponse.configuration
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
error:function(json){
|
||||
args.response.error(parseXMLHttpResponse(json));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
actions: {
|
||||
edit: function(args) {
|
||||
// call updateStorageLevelParameters
|
||||
var data = {
|
||||
name: args.data.jsonObj.name,
|
||||
value: args.data.value
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url:createURL('updateConfiguration&storageid=' + args.context.primarystorages[0].id),
|
||||
data:data,
|
||||
success:function(json){
|
||||
var item = json.updateconfigurationresponse.configuration;
|
||||
args.response.success({data:item});
|
||||
},
|
||||
|
||||
error: function(json) {
|
||||
args.response.error(parseXMLHttpResponse(json));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10747,10 +10906,6 @@
|
|||
}
|
||||
array1.push("&zoneid=" + args.context.zones[0].id);
|
||||
|
||||
if(args.context.zoneType != null && args.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
array1.push("&zonetype=" + args.context.zoneType);
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: createURL("listHosts&type=SecondaryStorage&page=" + args.page + "&pagesize=" + pageSize + array1.join("")),
|
||||
dataType: "json",
|
||||
|
|
@ -10851,6 +11006,7 @@
|
|||
|
||||
detailView: {
|
||||
name: 'Secondary storage details',
|
||||
isMaximized: true,
|
||||
actions: {
|
||||
remove: {
|
||||
label: 'label.action.delete.secondary.storage' ,
|
||||
|
|
@ -10907,6 +11063,27 @@
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Granular settings for storage pool for secondary storage is not required
|
||||
/* settings: {
|
||||
title: 'label.menu.global.settings',
|
||||
custom: cloudStack.uiCustom.granularSettings({
|
||||
dataProvider: function(args) {
|
||||
args.response.success({
|
||||
data: [
|
||||
{ name: 'config.param.1', value: 1 },
|
||||
{ name: 'config.param.2', value: 2 }
|
||||
]
|
||||
});
|
||||
},
|
||||
actions: {
|
||||
edit: function(args) {
|
||||
// call updateStorageLevelParameters
|
||||
args.response.success();
|
||||
}
|
||||
}
|
||||
})
|
||||
} */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11816,9 +11993,9 @@
|
|||
|
||||
if (jsonObj.state == 'Running') {
|
||||
allowedActions.push("stop");
|
||||
|
||||
allowedActions.push("scaleUp");
|
||||
// if(jsonObj.vpcid != null)
|
||||
allowedActions.push("restart");
|
||||
allowedActions.push("restart");
|
||||
|
||||
allowedActions.push("viewConsole");
|
||||
if (isAdmin())
|
||||
|
|
@ -11826,7 +12003,8 @@
|
|||
}
|
||||
else if (jsonObj.state == 'Stopped') {
|
||||
allowedActions.push("start");
|
||||
allowedActions.push("remove");
|
||||
allowedActions.push("scaleUp");
|
||||
allowedActions.push("remove");
|
||||
|
||||
if(jsonObj.vpcid != null)
|
||||
allowedActions.push("changeService");
|
||||
|
|
|
|||
|
|
@ -116,27 +116,13 @@
|
|||
dataType: "json",
|
||||
async: true,
|
||||
success: function(json) {
|
||||
var zoneObjs;
|
||||
if(args.context.zoneType == null || args.context.zoneType == '') { //all types
|
||||
zoneObjs = [];
|
||||
var items = json.listzonesresponse.zone;
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
zoneObjs.push({id: items[i].id, description: items[i].name});
|
||||
}
|
||||
var zoneObjs= [];
|
||||
var items = json.listzonesresponse.zone;
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
zoneObjs.push({id: items[i].id, description: items[i].name});
|
||||
}
|
||||
}
|
||||
else { //Basic type or Advanced type
|
||||
zoneObjs = [];
|
||||
var items = json.listzonesresponse.zone;
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
if(items[i].networktype == args.context.zoneType) {
|
||||
zoneObjs.push({id: items[i].id, description: items[i].name});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isAdmin() && !(cloudStack.context.projects && cloudStack.context.projects[0])){
|
||||
zoneObjs.unshift({id: -1, description: "All Zones"});
|
||||
}
|
||||
|
|
@ -548,27 +534,14 @@
|
|||
async: true,
|
||||
success: function(json) {
|
||||
var zoneObjs = [];
|
||||
var items = json.listzonesresponse.zone;
|
||||
if(args.context.zoneType == null || args.context.zoneType == '') { //all types
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
if(items[i].id != args.context.templates[0].zoneid) { //destination zone must be different from source zone
|
||||
zoneObjs.push({id: items[i].id, description: items[i].name});
|
||||
}
|
||||
}
|
||||
var items = json.listzonesresponse.zone;
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
if(items[i].id != args.context.templates[0].zoneid) { //destination zone must be different from source zone
|
||||
zoneObjs.push({id: items[i].id, description: items[i].name});
|
||||
}
|
||||
}
|
||||
}
|
||||
else { //Basic type or Advanced type
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
if(items[i].networktype == args.context.zoneType) { //type must be matched
|
||||
if(items[i].id != args.context.templates[0].zoneid) { //destination zone must be different from source zone
|
||||
zoneObjs.push({id: items[i].id, description: items[i].name});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
args.response.success({data: zoneObjs});
|
||||
}
|
||||
});
|
||||
|
|
@ -894,27 +867,13 @@
|
|||
dataType: "json",
|
||||
async: true,
|
||||
success: function(json) {
|
||||
var zoneObjs;
|
||||
if(args.context.zoneType == null || args.context.zoneType == '') { //all types
|
||||
zoneObjs = [];
|
||||
var items = json.listzonesresponse.zone;
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
zoneObjs.push({id: items[i].id, description: items[i].name});
|
||||
}
|
||||
var zoneObjs = [];
|
||||
var items = json.listzonesresponse.zone;
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
zoneObjs.push({id: items[i].id, description: items[i].name});
|
||||
}
|
||||
}
|
||||
else { //Basic type or Advanced type
|
||||
zoneObjs = [];
|
||||
var items = json.listzonesresponse.zone;
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
if(items[i].networktype == args.context.zoneType) {
|
||||
zoneObjs.push({id: items[i].id, description: items[i].name});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isAdmin() && !(cloudStack.context.projects && cloudStack.context.projects[0])){
|
||||
zoneObjs.unshift({id: -1, description: "All Zones"});
|
||||
}
|
||||
|
|
@ -1224,27 +1183,14 @@
|
|||
async: true,
|
||||
success: function(json) {
|
||||
var zoneObjs = [];
|
||||
var items = json.listzonesresponse.zone;
|
||||
if(args.context.zoneType == null || args.context.zoneType == '') { //all types
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
if(items[i].id != args.context.isos[0].zoneid) { //destination zone must be different from source zone
|
||||
zoneObjs.push({id: items[i].id, description: items[i].name});
|
||||
}
|
||||
}
|
||||
var items = json.listzonesresponse.zone;
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
if(items[i].id != args.context.isos[0].zoneid) { //destination zone must be different from source zone
|
||||
zoneObjs.push({id: items[i].id, description: items[i].name});
|
||||
}
|
||||
}
|
||||
}
|
||||
else { //Basic type or Advanced type
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
if(items[i].networktype == args.context.zoneType) { //type must be matched
|
||||
if(items[i].id != args.context.isos[0].zoneid) { //destination zone must be different from source zone
|
||||
zoneObjs.push({id: items[i].id, description: items[i].name});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
args.response.success({data: zoneObjs});
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
(function($, cloudStack) {
|
||||
cloudStack.uiCustom.granularSettings = function(args) {
|
||||
var dataProvider = args.dataProvider;
|
||||
var actions = args.actions;
|
||||
|
||||
return function(args) {
|
||||
var context = args.context;
|
||||
|
||||
var listView = {
|
||||
id: 'settings',
|
||||
fields: {
|
||||
name: { label: 'label.name' },
|
||||
value: { label: 'label.value', editable: true }
|
||||
},
|
||||
actions: {
|
||||
edit: {
|
||||
label: 'label.change.value',
|
||||
action: actions.edit
|
||||
}
|
||||
},
|
||||
dataProvider: dataProvider
|
||||
};
|
||||
|
||||
var $listView = $('<div>').listView({ context: context, listView: listView });
|
||||
|
||||
return $listView;
|
||||
}
|
||||
};
|
||||
}(jQuery, cloudStack));
|
||||
|
|
@ -86,7 +86,7 @@
|
|||
});
|
||||
};
|
||||
|
||||
var makeSelects = function(name, data, fields, options) {
|
||||
var makeSelects = function(name, data, fields, options, selectedObj) {
|
||||
var $selects = $('<div>');
|
||||
options = options ? options : {};
|
||||
|
||||
|
|
@ -151,7 +151,11 @@
|
|||
.append($('<div>').addClass('desc').html(_s(this[fields.desc])))
|
||||
)
|
||||
.data('json-obj', this);
|
||||
|
||||
|
||||
if(selectedObj != null && selectedObj.id == item.id) {
|
||||
$select.find('input[type=checkbox]').attr('checked', 'checked');
|
||||
}
|
||||
|
||||
$selects.append($select);
|
||||
|
||||
if (item._singleSelect) {
|
||||
|
|
@ -493,14 +497,20 @@
|
|||
)
|
||||
);
|
||||
$step.find('.select-container').append(
|
||||
makeSelects('affinity-groups', args.data.affinityGroups, {
|
||||
name: 'name',
|
||||
desc: 'description',
|
||||
id: 'id'
|
||||
}, {
|
||||
type: 'checkbox',
|
||||
'wizard-field': 'affinity-groups'
|
||||
})
|
||||
makeSelects(
|
||||
'affinity-groups',
|
||||
args.data.affinityGroups,
|
||||
{
|
||||
name: 'name',
|
||||
desc: 'description',
|
||||
id: 'id'
|
||||
},
|
||||
{
|
||||
type: 'checkbox',
|
||||
'wizard-field': 'affinity-groups'
|
||||
},
|
||||
args.data.selectedObj
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$step.find('.select-container').append($('<p>').html(_l('message.no.affinity.groups')));
|
||||
|
|
|
|||
|
|
@ -653,6 +653,11 @@
|
|||
});
|
||||
});
|
||||
|
||||
var itemState=multiRule._itemState ? item[multiRule._itemState] :item.state;
|
||||
var $itemState = $('<span>').html(_s(itemState));
|
||||
$tr.append($('<td>').addClass('state').appendTo($tr).append("Application State - ").append($itemState));
|
||||
|
||||
|
||||
if (itemActions) {
|
||||
var $itemActions = $('<td>').addClass('actions item-actions');
|
||||
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@
|
|||
},
|
||||
action: function(args) {
|
||||
$.ajax({
|
||||
url: createURL("revertToSnapshot&vmsnapshotid=" + args.context.vmsnapshots[0].id),
|
||||
url: createURL("revertToVMSnapshot&vmsnapshotid=" + args.context.vmsnapshots[0].id),
|
||||
dataType: "json",
|
||||
async: true,
|
||||
success: function(json) {
|
||||
|
|
|
|||
|
|
@ -737,6 +737,12 @@
|
|||
actions:{
|
||||
add:{
|
||||
label:'Add Private Gateway',
|
||||
preFilter: function(args) {
|
||||
if(isAdmin() || isDomainAdmin() )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
},
|
||||
createForm:{
|
||||
title: 'label.add.new.gateway',
|
||||
desc: 'message.add.new.gateway.to.vpc',
|
||||
|
|
|
|||
|
|
@ -627,7 +627,7 @@ public class NetUtils {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static Set<Long> getAllIpsFromCidr(String cidr, long size) {
|
||||
public static Set<Long> getAllIpsFromCidr(String cidr, long size, Set<Long> usedIps) {
|
||||
assert (size < 32) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size;
|
||||
Set<Long> result = new TreeSet<Long>();
|
||||
long ip = ip2Long(cidr);
|
||||
|
|
@ -639,8 +639,12 @@ public class NetUtils {
|
|||
|
||||
end++;
|
||||
end = (end << (32 - size)) - 2;
|
||||
while (start <= end) {
|
||||
result.add(start);
|
||||
int maxIps = 255; // get 255 ips as maximum
|
||||
while (start <= end && maxIps > 0) {
|
||||
if (!usedIps.contains(start)){
|
||||
result.add(start);
|
||||
maxIps--;
|
||||
}
|
||||
start++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1281,6 +1281,7 @@ public class VirtualMachineMO extends BaseMO {
|
|||
long totalBytesDownloaded = 0;
|
||||
|
||||
List<HttpNfcLeaseDeviceUrl> deviceUrls = leaseInfo.getDeviceUrl();
|
||||
s_logger.info("volss: copy vmdk and ovf file starts " + System.currentTimeMillis());
|
||||
if(deviceUrls != null) {
|
||||
OvfFile[] ovfFiles = new OvfFile[deviceUrls.size()];
|
||||
for (int i = 0; i < deviceUrls.size(); i++) {
|
||||
|
|
@ -1328,7 +1329,7 @@ public class VirtualMachineMO extends BaseMO {
|
|||
|
||||
// tar files into OVA
|
||||
if(packToOva) {
|
||||
// Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature)
|
||||
// Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature)
|
||||
s_logger.info("Sync file system before we package OVA...");
|
||||
|
||||
Script commandSync = new Script(true, "sync", 0, s_logger);
|
||||
|
|
@ -1351,8 +1352,11 @@ public class VirtualMachineMO extends BaseMO {
|
|||
} else {
|
||||
s_logger.error(exportDir + File.separator + exportName + ".ova is not created as expected");
|
||||
}
|
||||
} else {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
s_logger.info("volss: copy vmdk and ovf file finishes " + System.currentTimeMillis());
|
||||
} catch(Throwable e) {
|
||||
s_logger.error("Unexpected exception ", e);
|
||||
} finally {
|
||||
|
|
|
|||
|
|
@ -528,7 +528,7 @@ public class VmwareClient {
|
|||
PropertySpec pSpec = new PropertySpec();
|
||||
pSpec.setType(type);
|
||||
pSpec.setAll(false);
|
||||
pSpec.getPathSet().add(name);
|
||||
pSpec.getPathSet().add("name");
|
||||
|
||||
ObjectSpec oSpec = new ObjectSpec();
|
||||
oSpec.setObj(root);
|
||||
|
|
|
|||
Loading…
Reference in New Issue