Merge branch 'master' into rbac.

This commit is contained in:
Min Chen 2013-11-04 15:49:29 -08:00
commit ce3638bb03
348 changed files with 68167 additions and 4774 deletions

View File

@ -115,5 +115,38 @@
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-antrun-plugin
</artifactId>
<versionRange>[1.7,)</versionRange>
<goals>
<goal>run</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -119,34 +119,33 @@ public class PropertiesStorage implements StorageComponent {
return true;
}
@Override
public void setName(String name) {
// TODO Auto-generated method stub
}
@Override
public void setName(String name) {
// TODO Auto-generated method stub
@Override
public void setConfigParams(Map<String, Object> params) {
// TODO Auto-generated method stub
}
}
@Override
public Map<String, Object> getConfigParams() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setConfigParams(Map<String, Object> params) {
// TODO Auto-generated method stub
@Override
public int getRunLevel() {
// TODO Auto-generated method stub
return 0;
}
}
@Override
public void setRunLevel(int level) {
// TODO Auto-generated method stub
}
@Override
public Map<String, Object> getConfigParams() {
// TODO Auto-generated method stub
return null;
}
@Override
public int getRunLevel() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void setRunLevel(int level) {
// TODO Auto-generated method stub
}
}

View File

@ -18,9 +18,6 @@ package com.cloud.agent.dhcp;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
@ -32,8 +29,6 @@ import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.utils.Pair;
import com.cloud.utils.net.NetUtils;

View File

@ -71,11 +71,4 @@ public class MockVm {
return vncPort;
}
public static void main(String[] args) {
long i = 10;
Long l = null;
if (i == l) {
System.out.print("fdfd");
}
}
}

View File

@ -32,9 +32,12 @@ import java.util.Properties;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.log4j.Logger;
import com.google.gson.Gson;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import com.cloud.agent.Agent.ExitStatus;
import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.Answer;
@ -61,7 +64,6 @@ import com.cloud.resource.ServerResourceBase;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.net.NetUtils;
import com.cloud.utils.script.Script;
import com.google.gson.Gson;
/**
*
@ -130,19 +132,6 @@ public class ConsoleProxyResource extends ServerResourceBase implements
}
}
private boolean copyCertToDirectory(String certificate, String filePath)
throws IOException {
boolean success;
// copy cert to the dir
FileWriter fstream = new FileWriter(filePath);
BufferedWriter out = new BufferedWriter(fstream);
out.write(certificate);
// Close the output stream
out.close();
success = true;
return success;
}
protected Answer execute(final CheckConsoleProxyLoadCommand cmd) {
return executeProxyLoadScan(cmd, cmd.getProxyVmId(),
cmd.getProxyVmName(), cmd.getProxyManagementIp(),
@ -204,6 +193,7 @@ public class ConsoleProxyResource extends ServerResourceBase implements
return null;
}
@Override
public Type getType() {
return Host.Type.ConsoleProxy;
}

View File

@ -21,6 +21,7 @@ package com.cloud.agent.api.to;
import com.cloud.storage.DataStoreRole;
public interface DataStoreTO {
public DataStoreRole getRole();
public String getUuid();
DataStoreRole getRole();
String getUuid();
String getUrl();
}

View File

@ -39,6 +39,7 @@ public class NfsTO implements DataStoreTO {
}
@Override
public String getUrl() {
return _url;
}

View File

@ -181,6 +181,11 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO {
return this.uuid;
}
@Override
public String getUrl() {
return null;
}
public void setUuid(final String uuid) {
this.uuid = uuid;
}

View File

@ -114,6 +114,7 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
private static List<Provider> supportedProviders = new ArrayList<Provider>();
public static final Provider VirtualRouter = new Provider("VirtualRouter", false);
public static final Provider JuniperContrail = new Provider("JuniperContrail", false);
public static final Provider JuniperSRX = new Provider("JuniperSRX", true);
public static final Provider F5BigIp = new Provider("F5BigIp", true);
public static final Provider Netscaler = new Provider("Netscaler", true);

View File

@ -35,4 +35,5 @@ public interface Site2SiteVpnConnection extends ControlledEntity, InternalIdenti
public State getState();
public Date getCreated();
public Date getRemoved();
public boolean isPassive();
}

View File

@ -35,7 +35,7 @@ public interface VMSnapshotService {
VMSnapshot getVMSnapshotById(Long id);
VMSnapshot creatVMSnapshot(Long vmId, Long vmSnapshotId);
VMSnapshot creatVMSnapshot(Long vmId, Long vmSnapshotId, Boolean quiescevm);
VMSnapshot allocVMSnapshot(Long vmId, String vsDisplayName, String vsDescription, Boolean snapshotMemory)
throws ResourceAllocationException;

View File

@ -490,6 +490,7 @@ public class ApiConstants {
public static final String VM_SNAPSHOT_ID = "vmsnapshotid";
public static final String VM_SNAPSHOT_DISK_IDS = "vmsnapshotdiskids";
public static final String VM_SNAPSHOT_MEMORY = "snapshotmemory";
public static final String VM_SNAPSHOT_QUIESCEVM = "quiescevm";
public static final String IMAGE_STORE_UUID = "imagestoreuuid";
public static final String GUEST_VM_CIDR = "guestvmcidr";
public static final String NETWORK_CIDR = "networkcidr";
@ -536,6 +537,7 @@ public class ApiConstants {
public static final String RESOURCE_DETAILS = "resourcedetails";
public static final String EXPUNGE = "expunge";
public static final String FOR_DISPLAY = "fordisplay";
public static final String PASSIVE = "passive";
public enum HostDetails {

View File

@ -22,6 +22,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.BaseCmd.CommandType;
@Retention(RetentionPolicy.RUNTIME)
@ -48,4 +49,6 @@ public @interface Parameter {
String since() default "";
String retrieveMethod() default "getById";
RoleType[] authorized() default {};
}

View File

@ -19,7 +19,6 @@ package org.apache.cloudstack.api.command.admin.usage;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
@ -33,6 +32,8 @@ import org.apache.cloudstack.api.response.UsageRecordResponse;
import org.apache.cloudstack.usage.Usage;
import org.apache.log4j.Logger;
import com.cloud.utils.Pair;
@APICommand(name = "listUsageRecords", description="Lists usage records for accounts", responseObject=UsageRecordResponse.class)
public class GetUsageRecordsCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(GetUsageRecordsCmd.class.getName());
@ -110,16 +111,18 @@ public class GetUsageRecordsCmd extends BaseListCmd {
@Override
public void execute(){
List<? extends Usage> usageRecords = _usageService.getUsageRecords(this);
Pair<List<? extends Usage>, Integer> usageRecords = _usageService.getUsageRecords(this);
ListResponse<UsageRecordResponse> response = new ListResponse<UsageRecordResponse>();
List<UsageRecordResponse> usageResponses = new ArrayList<UsageRecordResponse>();
for(Usage usageRecord: usageRecords){
UsageRecordResponse usageResponse = _responseGenerator.createUsageResponse(usageRecord);
usageResponse.setObjectName("usagerecord");
usageResponses.add(usageResponse);
if (usageRecords != null) {
for(Usage usageRecord: usageRecords.first()){
UsageRecordResponse usageResponse = _responseGenerator.createUsageResponse(usageRecord);
usageResponse.setObjectName("usagerecord");
usageResponses.add(usageResponse);
}
response.setResponses(usageResponses, usageRecords.second());
}
response.setResponses(usageResponses);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}

View File

@ -53,6 +53,9 @@ public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd {
@Parameter(name = ApiConstants.VM_SNAPSHOT_MEMORY, type = CommandType.BOOLEAN, required = false, description = "snapshot memory if true")
private Boolean snapshotMemory;
@Parameter(name = ApiConstants.VM_SNAPSHOT_QUIESCEVM, type = CommandType.BOOLEAN, required = false, description = "quiesce vm if true")
private Boolean quiescevm;
public Boolean snapshotMemory() {
if (snapshotMemory == null) {
return false;
@ -61,6 +64,14 @@ public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd {
}
}
public Boolean getQuiescevm() {
if (quiescevm == null) {
return false;
} else {
return quiescevm;
}
}
public String getDisplayName() {
return displayName;
}
@ -97,7 +108,7 @@ public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd {
@Override
public void execute() {
CallContext.current().setEventDetails("VM Id: " + getVmId());
VMSnapshot result = _vmSnapshotService.creatVMSnapshot(getVmId(),getEntityId());
VMSnapshot result = _vmSnapshotService.creatVMSnapshot(getVmId(),getEntityId(), getQuiescevm());
if (result != null) {
VMSnapshotResponse response = _responseGenerator
.createVMSnapshotResponse(result);

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.user.volume;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandJobType;
import org.apache.cloudstack.api.ApiConstants;
@ -24,6 +25,7 @@ import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
@ -66,6 +68,10 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd {
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class,
description="the ID of the availability zone")
private Long zoneId;
@Parameter(name=ApiConstants.STORAGE_ID, type=CommandType.UUID, entityType=StoragePoolResponse.class,
description="the ID of the storage pool, available to ROOT admin only", since="4.3", authorized = { RoleType.Admin })
private Long storageId;
/////////////////////////////////////////////////////
@ -101,6 +107,9 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd {
return zoneId;
}
public Long getStorageId() {
return storageId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////

View File

@ -53,6 +53,9 @@ public class CreateVpnConnectionCmd extends BaseAsyncCreateCmd {
required=true, description="id of the customer gateway")
private Long customerGatewayId;
@Parameter(name=ApiConstants.PASSIVE, type=CommandType.BOOLEAN, required=false, description="connection is passive or not")
private Boolean passive;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -65,6 +68,13 @@ public class CreateVpnConnectionCmd extends BaseAsyncCreateCmd {
public Long getCustomerGatewayId() {
return customerGatewayId;
}
public boolean isPassive() {
if (passive == null) {
return false;
}
return passive;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////

View File

@ -68,6 +68,9 @@ public class Site2SiteVpnConnectionResponse extends BaseResponse implements Cont
@SerializedName(ApiConstants.STATE) @Param(description="State of vpn connection")
private String state;
@SerializedName(ApiConstants.PASSIVE) @Param(description="State of vpn connection")
private boolean passive;
@SerializedName(ApiConstants.ACCOUNT) @Param(description="the owner")
private String accountName;
@ -141,6 +144,10 @@ public class Site2SiteVpnConnectionResponse extends BaseResponse implements Cont
this.state = state;
}
public void setPassive(boolean passive) {
this.passive = passive;
}
public void setCreated(Date created) {
this.created = created;
}

View File

@ -23,6 +23,8 @@ import org.apache.cloudstack.api.command.admin.usage.GenerateUsageRecordsCmd;
import org.apache.cloudstack.api.command.admin.usage.GetUsageRecordsCmd;
import org.apache.cloudstack.api.response.UsageTypeResponse;
import com.cloud.utils.Pair;
public interface UsageService {
/**
* Generate Billing Records from the last time it was generated to the
@ -50,7 +52,7 @@ public interface UsageService {
* the appropriate page number)
* @return a list of usage records
*/
List<? extends Usage> getUsageRecords(GetUsageRecordsCmd cmd);
Pair<List<? extends Usage>, Integer> getUsageRecords(GetUsageRecordsCmd cmd);
/**
* Retrieves the timezone used for usage aggregation. One day is represented as midnight to 11:59:59pm

View File

@ -16,7 +16,11 @@
// under the License.
package org.apache.cloudstack.api.command.test;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.apache.cloudstack.api.command.admin.usage.GetUsageRecordsCmd;
import org.apache.cloudstack.usage.Usage;
import org.apache.cloudstack.usage.UsageService;
@ -26,8 +30,7 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.List;
import com.cloud.utils.Pair;
public class UsageCmdTest extends TestCase {
@ -56,7 +59,7 @@ public class UsageCmdTest extends TestCase {
UsageService usageService = Mockito.mock(UsageService.class);
List usageRecords = new ArrayList<Usage>();
Pair<List<? extends Usage>, Integer> usageRecords = new Pair<List<? extends Usage>, Integer>(new ArrayList<Usage>(), new Integer(0));
Mockito.when(usageService.getUsageRecords(getUsageRecordsCmd)).thenReturn(
usageRecords);

View File

@ -16,18 +16,11 @@
// under the License.
package com.cloud.bridge.persist.dao;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import org.apache.log4j.Logger;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.properties.EncryptableProperties;
import com.cloud.bridge.util.ConfigurationHelper;
import com.cloud.bridge.util.EncryptionSecretKeyCheckerUtil;
import com.cloud.utils.db.DbProperties;
@ -43,24 +36,9 @@ public class BaseDao {
static{
logger.info("Initializing DB props");
File propertiesFile = ConfigurationHelper.findConfigurationFile("db.properties");
Properties EC2Prop = null;
if (null != propertiesFile) {
if(EncryptionSecretKeyCheckerUtil.useEncryption()){
StandardPBEStringEncryptor encryptor = EncryptionSecretKeyCheckerUtil.getEncryptor();
EC2Prop = new EncryptableProperties(encryptor);
} else {
EC2Prop = new Properties();
}
Properties EC2Prop = DbProperties.getDbProperties();
try {
EC2Prop.load( new FileInputStream( propertiesFile ));
} catch (FileNotFoundException e) {
logger.warn("Unable to open properties file: " + propertiesFile.getAbsolutePath(), e);
} catch (IOException e) {
logger.warn("Unable to read properties file: " + propertiesFile.getAbsolutePath(), e);
}
if (EC2Prop.size() > 0) {
dbHost = EC2Prop.getProperty( "db.cloud.host" );
awsapi_dbName = EC2Prop.getProperty( "db.awsapi.name" );
cloud_dbName = EC2Prop.getProperty( "db.cloud.name" );

View File

@ -1,138 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.bridge.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;
import org.apache.log4j.Logger;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
public class EncryptionSecretKeyCheckerUtil {
private static final Logger s_logger = Logger.getLogger(EncryptionSecretKeyCheckerUtil.class);
private static final String s_keyFile = "/etc/cloudstack/management/key";
private static final String s_envKey = "CLOUD_SECRET_KEY";
private static StandardPBEStringEncryptor s_encryptor = new StandardPBEStringEncryptor();
private static boolean s_useEncryption = false;
static{
//Get encryption type from db.properties
final File dbPropsFile = ConfigurationHelper.findConfigurationFile("db.properties");
final Properties dbProps = new Properties();
try {
dbProps.load(new FileInputStream(dbPropsFile));
final String encryptionType = dbProps.getProperty("db.cloud.encryption.type");
s_logger.debug("Encryption Type: "+ encryptionType);
if(encryptionType != null && !encryptionType.equals("none")){
s_encryptor.setAlgorithm("PBEWithMD5AndDES");
String secretKey = null;
SimpleStringPBEConfig stringConfig = new SimpleStringPBEConfig();
if(encryptionType.equals("file")){
try {
BufferedReader in = new BufferedReader(new FileReader(s_keyFile));
secretKey = in.readLine();
//Check for null or empty secret key
} catch (FileNotFoundException e) {
throw new RuntimeException("File containing secret key not found: "+s_keyFile, e);
} catch (IOException e) {
throw new RuntimeException("Error while reading secret key from: "+s_keyFile, e);
}
if(secretKey == null || secretKey.isEmpty()){
throw new RuntimeException("Secret key is null or empty in file "+s_keyFile);
}
} else if(encryptionType.equals("env")){
secretKey = System.getenv(s_envKey);
if(secretKey == null || secretKey.isEmpty()){
throw new RuntimeException("Environment variable "+s_envKey+" is not set or empty");
}
} else if(encryptionType.equals("web")){
ServerSocket serverSocket = null;
int port = 8097;
try {
serverSocket = new ServerSocket(port);
} catch (IOException ioex) {
throw new RuntimeException("Error initializing secret key reciever", ioex);
}
s_logger.info("Waiting for admin to send secret key on port "+port);
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
throw new RuntimeException("Accept failed on "+port);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine, outputLine;
if ((inputLine = in.readLine()) != null) {
secretKey = inputLine;
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
} else {
throw new RuntimeException("Invalid encryption type: "+encryptionType);
}
stringConfig.setPassword(secretKey);
s_encryptor.setConfig(stringConfig);
s_useEncryption = true;
}
} catch (FileNotFoundException e) {
throw new RuntimeException("File db.properties not found", e);
} catch (IOException e) {
throw new RuntimeException("Error while reading db.properties", e);
}
}
public static StandardPBEStringEncryptor getEncryptor() {
return s_encryptor;
}
public static boolean useEncryption(){
return s_useEncryption;
}
//Initialize encryptor for migration during secret key change
public static void initEncryptorForMigration(String secretKey){
s_encryptor.setAlgorithm("PBEWithMD5AndDES");
SimpleStringPBEConfig stringConfig = new SimpleStringPBEConfig();
stringConfig.setPassword(secretKey);
s_encryptor.setConfig(stringConfig);
s_useEncryption = true;
}
}

View File

@ -1176,9 +1176,11 @@ label.virtual.machines=Virtual machines
label.virtual.network=Virtual Network
label.virtual.router=Virtual Router
label.virtual.routers=Virtual Routers
label.vlan.id=VLAN ID
label.vlan.range=VLAN Range
label.vlan=VLAN
label.vlan.id=VLAN/VNI ID
label.vlan.range=VLAN/VNI Range
label.vlan=VLAN/VNI
label.vnet=VLAN/VNI
label.vnet.id=VLAN/VNI ID
label.vxlan.id=VXLAN ID
label.vxlan.range=VXLAN Range
label.vxlan=VXLAN

View File

@ -90,6 +90,11 @@
<artifactId>cloud-plugin-network-nvp</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-contrail</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-ovs</artifactId>
@ -156,6 +161,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-hypervisor-hyperv</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-storage-allocator-random</artifactId>

View File

@ -19,9 +19,9 @@
### Please standardize naming conventions to camel-case (even for acronyms).
### Account commands
createAccount=3
deleteAccount=3
updateAccount=3
createAccount=7
deleteAccount=7
updateAccount=7
disableAccount=7
enableAccount=7
lockAccount=7
@ -29,8 +29,8 @@ listAccounts=15
markDefaultZoneForAccount=1
#### User commands
createUser=3
deleteUser=3
createUser=7
deleteUser=7
updateUser=15
listUsers=7
lockUser=7
@ -698,5 +698,6 @@ removeAccountFromAclGroup=7
grantPermissionToAclGroup=7
revokePermissionFromAclGroup=7
#### juniper-contrail commands
createServiceInstance=1

View File

@ -25,8 +25,9 @@
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
>
<bean class="org.apache.cloudstack.spring.lifecycle.CloudStackLog4jSetup" />
<bean class="com.cloud.utils.crypt.EncryptionSecretKeyChecker" />
</beans>

View File

@ -23,6 +23,8 @@ public class SetupCommand extends Command {
HostEnvironment env;
boolean multipath;
boolean needSetup;
String secondaryStorage;
String systemVmIso;
public boolean needSetup() {
return needSetup;
@ -36,6 +38,8 @@ public class SetupCommand extends Command {
this.env = env;
this.multipath = false;
this.needSetup = false;
secondaryStorage = null;
systemVmIso = null;
}
public HostEnvironment getEnvironment() {
@ -53,6 +57,22 @@ public class SetupCommand extends Command {
return multipath;
}
public void setSecondaryStorage(String secondaryStorage) {
this.secondaryStorage = secondaryStorage;
}
public String getSecondaryStorage() {
return this.secondaryStorage;
}
public void setSystemVmIso(String systemVmIso) {
this.systemVmIso = systemVmIso;
}
public String getSystemVmIso() {
return this.systemVmIso;
}
@Override
public boolean executeInSequence() {
return true;

View File

@ -16,6 +16,10 @@
// under the License.
package com.cloud.agent.api;
import java.util.List;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import com.cloud.vm.snapshot.VMSnapshot;
public class VMSnapshotTO {
@ -26,6 +30,7 @@ public class VMSnapshotTO {
private Boolean current;
private String description;
private VMSnapshotTO parent;
private List<VolumeObjectTO> volumes;
public Long getId() {
return id;
@ -87,4 +92,11 @@ public class VMSnapshotTO {
this.parent = parent;
}
public List<VolumeObjectTO> getVolumes() {
return this.volumes;
}
public void setVolumes(List<VolumeObjectTO> volumes) {
this.volumes = volumes;
}
}

View File

@ -30,6 +30,7 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand {
private long ikeLifetime;
private long espLifetime;
private boolean dpd;
private boolean passive;
@Override
public boolean executeInSequence() {
@ -41,7 +42,7 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand {
}
public Site2SiteVpnCfgCommand (boolean create, String localPublicIp, String localPublicGateway, String localGuestCidr, String peerGatewayIp,
String peerGuestCidrList, String ikePolicy, String espPolicy, String ipsecPsk, Long ikeLifetime, Long espLifetime, Boolean dpd) {
String peerGuestCidrList, String ikePolicy, String espPolicy, String ipsecPsk, Long ikeLifetime, Long espLifetime, Boolean dpd, boolean passive) {
this.create = create;
this.setLocalPublicIp(localPublicIp);
this.setLocalPublicGateway(localPublicGateway);
@ -54,6 +55,7 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand {
this.ikeLifetime = ikeLifetime;
this.espLifetime = espLifetime;
this.dpd = dpd;
this.passive = passive;
}
public boolean isCreate() {
@ -151,4 +153,12 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand {
public void setPeerGuestCidrList(String peerGuestCidrList) {
this.peerGuestCidrList = peerGuestCidrList;
}
public boolean isPassive() {
return passive;
}
public void setPassive(boolean passive) {
this.passive = passive;
}
}

View File

@ -761,6 +761,9 @@ public class VirtualRoutingResource implements Manager {
} else {
args += "0";
}
if (cmd.isPassive()) {
args += " -p ";
}
} else {
args = "-D";
args += " -r ";

View File

@ -18,6 +18,8 @@
*/
package com.cloud.storage.resource;
import org.apache.log4j.Logger;
import org.apache.cloudstack.storage.command.AttachCommand;
import org.apache.cloudstack.storage.command.CopyCommand;
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
@ -26,7 +28,6 @@ import org.apache.cloudstack.storage.command.DeleteCommand;
import org.apache.cloudstack.storage.command.DettachCommand;
import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
@ -67,7 +68,9 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma
DataStoreTO srcDataStore = srcData.getDataStore();
DataStoreTO destDataStore = destData.getDataStore();
if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcData.getDataStore().getRole() == DataStoreRole.Image && destData.getDataStore().getRole() == DataStoreRole.Primary) {
if (srcData.getObjectType() == DataObjectType.TEMPLATE
&& (srcData.getDataStore().getRole() == DataStoreRole.Image || srcData.getDataStore().getRole() == DataStoreRole.ImageCache)
&& destData.getDataStore().getRole() == DataStoreRole.Primary) {
//copy template to primary storage
return processor.copyTemplateToPrimaryStorage(cmd);
} else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) {

View File

@ -83,6 +83,11 @@ public class ImageStoreTO implements DataStoreTO {
return uuid;
}
@Override
public String getUrl() {
return getUri();
}
public void setUuid(String uuid) {
this.uuid = uuid;
}

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.storage.to;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
import com.cloud.agent.api.to.DataStoreTO;
@ -31,8 +32,9 @@ public class PrimaryDataStoreTO implements DataStoreTO {
private String host;
private String path;
private int port;
private final String url;
public PrimaryDataStoreTO(PrimaryDataStoreInfo dataStore) {
public PrimaryDataStoreTO(PrimaryDataStore dataStore) {
this.uuid = dataStore.getUuid();
this.name = dataStore.getName();
this.id = dataStore.getId();
@ -40,6 +42,7 @@ public class PrimaryDataStoreTO implements DataStoreTO {
this.setHost(dataStore.getHostAddress());
this.setPath(dataStore.getPath());
this.setPort(dataStore.getPort());
this.url = dataStore.getUri();
}
public long getId() {
@ -51,6 +54,11 @@ public class PrimaryDataStoreTO implements DataStoreTO {
return this.uuid;
}
@Override
public String getUrl() {
return this.url;
}
public String getName() {
return this.name;
}

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cloudstack.storage.datastore;
package org.apache.cloudstack.engine.subsystem.api.storage;
import java.util.List;

View File

@ -0,0 +1,30 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cloudstack.engine.subsystem.api.storage;
public class VMSnapshotOptions {
private final boolean quiesceVM;
public VMSnapshotOptions(boolean quiesceVM) {
this.quiesceVM = quiesceVM;
}
public boolean needQuiesceVM() {
return quiesceVM;
}
}

View File

@ -30,6 +30,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.log4j.Logger;
@ -107,7 +108,8 @@ public abstract class AgentAttache {
protected Long _currentSequence;
protected Status _status = Status.Connecting;
protected boolean _maintenance;
protected long _nextSequence;
protected long _nextSequence;
protected AtomicInteger _outstandingTaskCount;
protected AgentManagerImpl _agentMgr;
@ -131,6 +133,7 @@ public abstract class AgentAttache {
_requests = new LinkedList<Request>();
_agentMgr = agentMgr;
_nextSequence = s_rand.nextInt(Short.MAX_VALUE) << 48;
_outstandingTaskCount = new AtomicInteger(0);
}
public synchronized long getNextSequence() {

View File

@ -159,24 +159,28 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
protected ScheduledExecutorService _directAgentExecutor;
protected ScheduledExecutorService _monitorExecutor;
private int _directAgentThreadCap;
protected StateMachine2<Status, Status.Event, Host> _statusStateMachine = Status.getStateMachine();
private final Map<Long, Long> _pingMap = new ConcurrentHashMap<Long, Long>(10007);
@Inject ResourceManager _resourceMgr;
protected final ConfigKey<Integer> Workers = new ConfigKey<Integer>(Integer.class, "workers", "Advance", "5",
protected final ConfigKey<Integer> Workers = new ConfigKey<Integer>(Integer.class, "workers", "Advanced", "5",
"Number of worker threads handling remote agent connections.", false);
protected final ConfigKey<Integer> Port = new ConfigKey<Integer>(Integer.class, "port", "Advance", "8250", "Port to listen on for remote agent connections.", false);
protected final ConfigKey<Integer> PingInterval = new ConfigKey<Integer>(Integer.class, "ping.interval", "Advance", "60",
protected final ConfigKey<Integer> Port = new ConfigKey<Integer>(Integer.class, "port", "Advanced", "8250", "Port to listen on for remote agent connections.", false);
protected final ConfigKey<Integer> PingInterval = new ConfigKey<Integer>(Integer.class, "ping.interval", "Advanced", "60",
"Interval to send application level pings to make sure the connection is still working", false);
protected final ConfigKey<Float> PingTimeout = new ConfigKey<Float>(Float.class, "ping.timeout", "Advance", "2.5",
protected final ConfigKey<Float> PingTimeout = new ConfigKey<Float>(Float.class, "ping.timeout", "Advanced", "2.5",
"Multiplier to ping.interval before announcing an agent has timed out", true);
protected final ConfigKey<Integer> AlertWait = new ConfigKey<Integer>(Integer.class, "alert.wait", "Advance", "1800",
protected final ConfigKey<Integer> AlertWait = new ConfigKey<Integer>(Integer.class, "alert.wait", "Advanced", "1800",
"Seconds to wait before alerting on a disconnected agent", true);
protected final ConfigKey<Integer> DirectAgentLoadSize = new ConfigKey<Integer>(Integer.class, "direct.agent.load.size", "Advance", "16",
protected final ConfigKey<Integer> DirectAgentLoadSize = new ConfigKey<Integer>(Integer.class, "direct.agent.load.size", "Advanced", "16",
"The number of direct agents to load each time", false);
protected final ConfigKey<Integer> DirectAgentPoolSize = new ConfigKey<Integer>(Integer.class, "direct.agent.pool.size", "Advance", "500",
protected final ConfigKey<Integer> DirectAgentPoolSize = new ConfigKey<Integer>(Integer.class, "direct.agent.pool.size", "Advanced", "500",
"Default size for DirectAgentPool", false);
protected final ConfigKey<Float> DirectAgentThreadCap = new ConfigKey<Float>(Float.class, "direct.agent.thread.cap", "Advanced", "0.1",
"Percentage (as a value between 0 and 1) of direct.agent.pool.size to be used as upper thread cap for a single direct agent to process requests", false);
@Override
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
@ -202,10 +206,10 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
_connection = new NioServer("AgentManager", Port.value(), Workers.value() + 10, this);
s_logger.info("Listening on " + Port.value() + " with " + Workers.value() + " workers");
_directAgentExecutor = new ScheduledThreadPoolExecutor(DirectAgentPoolSize.value(), new NamedThreadFactory("DirectAgent"));
s_logger.debug("Created DirectAgentAttache pool with size: " + DirectAgentPoolSize.value());
_directAgentThreadCap = Math.round(DirectAgentPoolSize.value() * DirectAgentThreadCap.value()) + 1; // add 1 to always make the value > 0
_monitorExecutor = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("AgentMonitor"));
return true;
@ -1422,6 +1426,10 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
return _directAgentExecutor;
}
public int getDirectAgentThreadCap() {
return _directAgentThreadCap;
}
public Long getAgentPingTime(long agentId) {
return _pingMap.get(agentId);
}
@ -1568,7 +1576,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {Workers, Port, PingInterval, PingTimeout, Wait, AlertWait, DirectAgentLoadSize, DirectAgentPoolSize};
return new ConfigKey<?>[] {Workers, Port, PingInterval, PingTimeout, Wait, AlertWait, DirectAgentLoadSize, DirectAgentPoolSize, DirectAgentThreadCap};
}
}

View File

@ -132,6 +132,11 @@ public class DirectAgentAttache extends AgentAttache {
@Override
protected synchronized void runInContext() {
try {
if (_outstandingTaskCount.incrementAndGet() > _agentMgr.getDirectAgentThreadCap()) {
s_logger.warn("Task execution for direct attache(" + _id + ") has reached maximum outstanding limit(" + _agentMgr.getDirectAgentThreadCap() + "), bailing out");
return;
}
ServerResource resource = _resource;
if (resource != null) {
@ -156,6 +161,8 @@ public class DirectAgentAttache extends AgentAttache {
}
} catch (Exception e) {
s_logger.warn("Unable to complete the ping task", e);
} finally {
_outstandingTaskCount.decrementAndGet();
}
}
}
@ -168,10 +175,32 @@ public class DirectAgentAttache extends AgentAttache {
_req = req;
}
private void bailout() {
long seq = _req.getSequence();
try {
Command[] cmds = _req.getCommands();
ArrayList<Answer> answers = new ArrayList<Answer>(cmds.length);
for (Command cmd : cmds) {
Answer answer = new Answer(cmd, false, "Bailed out as maximum oustanding task limit reached");
answers.add(answer);
}
Response resp = new Response(_req, answers.toArray(new Answer[answers.size()]));
processAnswers(seq, resp);
} catch (Exception e) {
s_logger.warn(log(seq, "Exception caught in bailout "), e);
}
}
@Override
protected void runInContext() {
long seq = _req.getSequence();
try {
if (_outstandingTaskCount.incrementAndGet() > _agentMgr.getDirectAgentThreadCap()) {
s_logger.warn("Task execution for direct attache(" + _id + ") has reached maximum outstanding limit(" + _agentMgr.getDirectAgentThreadCap() + "), bailing out");
bailout();
return;
}
ServerResource resource = _resource;
Command[] cmds = _req.getCommands();
boolean stopOnError = _req.stopOnError();
@ -186,7 +215,7 @@ public class DirectAgentAttache extends AgentAttache {
if (resource != null) {
answer = resource.executeRequest(cmds[i]);
if(answer == null) {
s_logger.warn("Resource returned null answer!");
s_logger.warn("Resource returned null answer!");
answer = new Answer(cmds[i], false, "Resource returned null answer");
}
} else {
@ -213,6 +242,8 @@ public class DirectAgentAttache extends AgentAttache {
processAnswers(seq, resp);
} catch (Exception e) {
s_logger.warn(log(seq, "Exception caught "), e);
} finally {
_outstandingTaskCount.decrementAndGet();
}
}
}

View File

@ -2187,7 +2187,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
}
});
return false;
return true;
} catch ( CloudRuntimeException e ) {
s_logger.error("Failed to delete network", e);
return false;

View File

@ -1222,8 +1222,11 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
public void updateVolumeDiskChain(long volumeId, String path, String chainInfo) {
VolumeVO vol = _volsDao.findById(volumeId);
boolean needUpdate = false;
// Volume path is not getting updated in the DB, need to find reason and fix the issue.
if (vol.getPath() == null)
return;
if(!vol.getPath().equalsIgnoreCase(path))
needUpdate = true;
needUpdate = true;
if(chainInfo != null && (vol.getChainInfo() == null || !chainInfo.equalsIgnoreCase(vol.getChainInfo())))
needUpdate = true;

View File

@ -66,15 +66,19 @@ public class Site2SiteVpnConnectionVO implements Site2SiteVpnConnection, Interna
@Column(name=GenericDao.REMOVED_COLUMN)
private Date removed;
@Column(name="passive")
private boolean passive;
public Site2SiteVpnConnectionVO() { }
public Site2SiteVpnConnectionVO(long accountId, long domainId, long vpnGatewayId, long customerGatewayId) {
public Site2SiteVpnConnectionVO(long accountId, long domainId, long vpnGatewayId, long customerGatewayId, boolean passive) {
this.uuid = UUID.randomUUID().toString();
this.setVpnGatewayId(vpnGatewayId);
this.setCustomerGatewayId(customerGatewayId);
this.setState(State.Pending);
this.accountId = accountId;
this.domainId = domainId;
this.passive = passive;
}
@Override
@ -140,4 +144,12 @@ public class Site2SiteVpnConnectionVO implements Site2SiteVpnConnection, Interna
public long getAccountId() {
return accountId;
}
public boolean isPassive() {
return passive;
}
public void setPassive(boolean passive) {
this.passive = passive;
}
}

View File

@ -146,7 +146,7 @@ public class VolumeVO implements Volume {
private Storage.ImageFormat format;
@Column(name = "display_volume", updatable = true, nullable = false)
protected boolean displayVolume;
protected boolean displayVolume = true;
@Column(name = "iscsi_name")
private String _iScsiName;

View File

@ -18,7 +18,12 @@
*/
package com.cloud.upgrade;
import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
@ -33,7 +38,6 @@ import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.component.SystemIntegrityChecker;
import com.cloud.utils.db.ScriptRunner;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionLegacy;
// Creates the CloudStack Database by using the 4.0 schema and apply
@ -173,7 +177,9 @@ public class DatabaseCreator {
try {
TransactionLegacy.initDataSource(dbPropsFile);
} catch (NullPointerException e) {
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
initDB(dbPropsFile, rootPassword, databases, dryRun);

View File

@ -18,21 +18,16 @@
package com.cloud.upgrade.dao;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.crypt.EncryptionSecretKeyChecker;
import org.apache.log4j.Logger;
import com.cloud.utils.db.DbProperties;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.properties.EncryptableProperties;
public class Upgrade307to410 implements DbUpgrade {
final static Logger s_logger = Logger.getLogger(Upgrade307to410.class);
@ -68,23 +63,7 @@ public class Upgrade307to410 implements DbUpgrade {
}
private void updateRegionEntries(Connection conn) {
File dbPropsFile = PropertiesUtil.findConfigFile("db.properties");
final Properties dbProps;
if (EncryptionSecretKeyChecker.useEncryption()) {
StandardPBEStringEncryptor encryptor = EncryptionSecretKeyChecker.getEncryptor();
dbProps = new EncryptableProperties(encryptor);
} else {
dbProps = new Properties();
}
try {
dbProps.load(new FileInputStream(dbPropsFile));
} catch (IOException e) {
s_logger.fatal("Unable to load db properties file, pl. check the classpath and file path configuration", e);
return;
} catch (NullPointerException e) {
s_logger.fatal("Unable to locate db properties file within classpath or absolute path: db.properties");
return;
}
final Properties dbProps = DbProperties.getDbProperties();
int region_id = 1;
String regionId = dbProps.getProperty("region.id");
if(regionId != null){

View File

@ -19,9 +19,11 @@ package com.cloud.upgrade.dao;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.crypt.EncryptionSecretKeyChecker;
import com.cloud.utils.db.DbProperties;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
import org.apache.log4j.Logger;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.properties.EncryptableProperties;
@ -81,23 +83,7 @@ public class Upgrade40to41 implements DbUpgrade {
}
private void updateRegionEntries(Connection conn) {
File dbPropsFile = PropertiesUtil.findConfigFile("db.properties");
final Properties dbProps;
if (EncryptionSecretKeyChecker.useEncryption()) {
StandardPBEStringEncryptor encryptor = EncryptionSecretKeyChecker.getEncryptor();
dbProps = new EncryptableProperties(encryptor);
} else {
dbProps = new Properties();
}
try {
dbProps.load(new FileInputStream(dbPropsFile));
} catch (IOException e) {
s_logger.fatal("Unable to load db properties file, pl. check the classpath and file path configuration", e);
return;
} catch (NullPointerException e) {
s_logger.fatal("Unable to locate db properties file within classpath or absolute path: db.properties");
return;
}
final Properties dbProps = DbProperties.getDbProperties();
int region_id = 1;
String regionId = dbProps.getProperty("region.id");
if(regionId != null){

View File

@ -22,13 +22,14 @@ import com.cloud.usage.UsageVO;
import com.cloud.user.AccountVO;
import com.cloud.user.UserStatisticsVO;
import com.cloud.user.VmDiskStatisticsVO;
import com.cloud.utils.Pair;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.db.SearchCriteria;
public interface UsageDao extends GenericDao<UsageVO, Long> {
void deleteRecordsForAccount(Long accountId);
List<UsageVO> searchAllRecords(SearchCriteria<UsageVO> sc, Filter filter);
Pair<List<UsageVO>, Integer> searchAndCountAllRecords(SearchCriteria<UsageVO> sc, Filter filter);
void saveAccounts(List<AccountVO> accounts);
void updateAccounts(List<AccountVO> accounts);

View File

@ -35,6 +35,7 @@ import com.cloud.user.AccountVO;
import com.cloud.user.UserStatisticsVO;
import com.cloud.user.VmDiskStatisticsVO;
import com.cloud.utils.DateUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchCriteria;
@ -93,8 +94,8 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
}
@Override
public List<UsageVO> searchAllRecords(SearchCriteria<UsageVO> sc, Filter filter) {
return listIncludingRemovedBy(sc, filter);
public Pair<List<UsageVO>, Integer> searchAndCountAllRecords(SearchCriteria<UsageVO> sc, Filter filter) {
return listAndCountIncludingRemovedBy(sc, filter);
}
@Override

View File

@ -31,6 +31,9 @@ import javax.persistence.Table;
import javax.persistence.TableGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotOptions;
import com.cloud.utils.db.GenericDao;
@ -90,7 +93,18 @@ public class VMSnapshotVO implements VMSnapshot {
@Column(name="update_count", updatable = true, nullable=false)
protected long updatedCount;
@Transient
VMSnapshotOptions options;
public VMSnapshotOptions getOptions() {
return options;
}
public void setOptions(VMSnapshotOptions options) {
this.options = options;
}
public Long getParent() {
return parent;
}

View File

@ -25,7 +25,6 @@ import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
@ -46,10 +45,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.storage.command.CopyCommand;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
import com.cloud.agent.api.Answer;
@ -62,19 +57,11 @@ import com.cloud.agent.api.to.NfsTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.configuration.Config;
import com.cloud.host.Host;
import com.cloud.host.dao.HostDao;
import com.cloud.server.ManagementService;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.template.TemplateManager;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
@ -177,7 +164,13 @@ AncientDataMotionStrategy implements DataMotionStrategy {
CopyCommand cmd = new CopyCommand(srcForCopy.getTO(), destData.getTO(), _primaryStorageDownloadWait, _mgmtServer.getExecuteInSequence());
EndPoint ep = selector.select(srcForCopy, destData);
answer = ep.sendMessage(cmd);
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
if (cacheData != null) {
if (srcData.getType() == DataObjectType.VOLUME && destData.getType() == DataObjectType.VOLUME) {
@ -255,7 +248,14 @@ AncientDataMotionStrategy implements DataMotionStrategy {
}
CopyCommand cmd = new CopyCommand(srcData.getTO(), volObj.getTO(), _createVolumeFromSnapshotWait, _mgmtServer.getExecuteInSequence());
Answer answer = ep.sendMessage(cmd);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
return answer;
} catch (Exception e) {
@ -273,7 +273,14 @@ AncientDataMotionStrategy implements DataMotionStrategy {
CopyCommand cmd = new CopyCommand(template.getTO(), volume.getTO(), 0, _mgmtServer.getExecuteInSequence());
try {
EndPoint ep = selector.select(volume.getDataStore());
Answer answer = ep.sendMessage(cmd);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
return answer;
} catch (Exception e) {
s_logger.debug("Failed to send to storage pool", e);
@ -315,7 +322,13 @@ AncientDataMotionStrategy implements DataMotionStrategy {
CopyCommand cmd = new CopyCommand(objOnImageStore.getTO(), destData.getTO(), _copyvolumewait, _mgmtServer.getExecuteInSequence());
EndPoint ep = selector.select(objOnImageStore, destData);
answer = ep.sendMessage(cmd);
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
if (answer == null || !answer.getResult()) {
if (answer != null) {
@ -333,7 +346,14 @@ AncientDataMotionStrategy implements DataMotionStrategy {
DataObject cacheData = cacheMgr.createCacheObject(srcData, destScope);
CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait, _mgmtServer.getExecuteInSequence());
EndPoint ep = selector.select(cacheData, destData);
Answer answer = ep.sendMessage(cmd);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
// delete volume on cache store
if (cacheData != null) {
cacheMgr.deleteCacheObject(cacheData);
@ -348,7 +368,14 @@ AncientDataMotionStrategy implements DataMotionStrategy {
StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(destData.getDataStore().getId(), DataStoreRole.Primary);
MigrateVolumeCommand command = new MigrateVolumeCommand(volume.getId(), volume.getPath(), destPool);
EndPoint ep = selector.select(volume.getDataStore());
MigrateVolumeAnswer answer = (MigrateVolumeAnswer) ep.sendMessage(command);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(command, false, errMsg);
} else {
answer = ep.sendMessage(command);
}
if (answer == null || !answer.getResult()) {
throw new CloudRuntimeException("Failed to migrate volume " + volume + " to storage pool " + destPool);
@ -356,7 +383,7 @@ AncientDataMotionStrategy implements DataMotionStrategy {
// Update the volume details after migration.
VolumeVO volumeVo = volDao.findById(volume.getId());
Long oldPoolId = volume.getPoolId();
volumeVo.setPath(answer.getVolumePath());
volumeVo.setPath(((MigrateVolumeAnswer)answer).getVolumePath());
volumeVo.setFolder(destPool.getPath());
volumeVo.setPodId(destPool.getPodId());
volumeVo.setPoolId(destPool.getId());
@ -431,7 +458,14 @@ AncientDataMotionStrategy implements DataMotionStrategy {
}
CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _createprivatetemplatefromsnapshotwait, _mgmtServer.getExecuteInSequence());
Answer answer = ep.sendMessage(cmd);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
// clean up snapshot copied to staging
if (needCache && srcData != null) {
@ -455,11 +489,23 @@ AncientDataMotionStrategy implements DataMotionStrategy {
CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait, _mgmtServer.getExecuteInSequence());
cmd.setCacheTO(cacheData.getTO());
EndPoint ep = selector.select(srcData, destData);
answer = ep.sendMessage(cmd);
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
} else {
CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait, _mgmtServer.getExecuteInSequence());
EndPoint ep = selector.select(srcData, destData);
answer = ep.sendMessage(cmd);
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
}
// clean up cache entry in case of failure
if (answer == null || !answer.getResult()) {

View File

@ -172,12 +172,26 @@ public class TemplateServiceImpl implements TemplateService {
return;
}
TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(callback,
templateOnStore, null);
try {
TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(callback,
templateOnStore, null);
AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
store.getDriver().createAsync(store, templateOnStore, caller);
AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
store.getDriver().createAsync(store, templateOnStore, caller);
} catch (CloudRuntimeException ex) {
// clean up already persisted template_store_ref entry in case of createTemplateCallback is never called
TemplateDataStoreVO templateStoreVO = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
if (templateStoreVO != null) {
TemplateInfo tmplObj = _templateFactory.getTemplate(template, store);
tmplObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
}
TemplateApiResult result = new TemplateApiResult(template);
result.setResult(ex.getMessage());
if (callback != null) {
callback.complete(result);
}
}
}
@Override
@ -441,7 +455,14 @@ public class TemplateServiceImpl implements TemplateService {
tmplTO.setId(tInfo.getId());
DeleteCommand dtCommand = new DeleteCommand(tmplTO);
EndPoint ep = _epSelector.select(store);
Answer answer = ep.sendMessage(dtCommand);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(dtCommand, false, errMsg);
} else {
answer = ep.sendMessage(dtCommand);
}
if (answer == null || !answer.getResult()) {
s_logger.info("Failed to deleted template at store: " + store.getName());
@ -513,7 +534,14 @@ public class TemplateServiceImpl implements TemplateService {
private Map<String, TemplateProp> listTemplate(DataStore ssStore) {
ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO());
EndPoint ep = _epSelector.select(ssStore);
Answer answer = ep.sendMessage(cmd);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
if (answer != null && answer.getResult()) {
ListTemplateAnswer tanswer = (ListTemplateAnswer) answer;
return tanswer.getTemplateInfo();
@ -718,11 +746,23 @@ public class TemplateServiceImpl implements TemplateService {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Invoke datastore driver createAsync to create template on destination store");
}
TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(null,
(TemplateObject) templateOnStore, future);
AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().copyTemplateCrossZoneCallBack(null, null)).setContext(context);
destStore.getDriver().createAsync(destStore, templateOnStore, caller);
try {
TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(null,
(TemplateObject)templateOnStore, future);
AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().copyTemplateCrossZoneCallBack(null, null)).setContext(context);
destStore.getDriver().createAsync(destStore, templateOnStore, caller);
} catch (CloudRuntimeException ex) {
// clean up already persisted template_store_ref entry in case of createTemplateCallback is never called
TemplateDataStoreVO templateStoreVO = _vmTemplateStoreDao.findByStoreTemplate(destStore.getId(), srcTemplate.getId());
if (templateStoreVO != null) {
TemplateInfo tmplObj = _templateFactory.getTemplate(srcTemplate, destStore);
tmplObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
}
TemplateApiResult res = new TemplateApiResult((TemplateObject)templateOnStore);
res.setResult(ex.getMessage());
future.complete(res);
}
return future;
}

View File

@ -185,5 +185,38 @@
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-antrun-plugin
</artifactId>
<versionRange>[1.7,)</versionRange>
<goals>
<goal>run</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -85,10 +85,7 @@
<bean id="AccountGuestVlanMapDaoImpl" class="com.cloud.network.dao.AccountGuestVlanMapDaoImpl" />
<bean id="StorageCacheReplacementAlgorithm" class="org.apache.cloudstack.storage.cache.manager.StorageCacheReplacementAlgorithmLRU" />
<bean id="ServiceOfferingDetailsDao" class="com.cloud.service.dao.ServiceOfferingDetailsDaoImpl" />
<<<<<<< HEAD
<bean id="storageStrategyFactoryImpl" class="org.apache.cloudstack.storage.helper.StorageStrategyFactoryImpl" />
=======
<bean id="vmsnapshotDetailsDao" class="com.cloud.vm.snapshot.dao.VMSnapshotDetailsDaoImpl" />
<bean id="snapshotManager" class="com.cloud.storage.snapshot.SnapshotManagerImpl" />
>>>>>>> pluggable_vm_snapshot
</beans>

View File

@ -38,6 +38,9 @@
<bean id="hypervisorHelperImpl" class="org.apache.cloudstack.storage.helper.HypervisorHelperImpl" />
<bean id="VMSnapshotHelperImpl"
class="org.apache.cloudstack.storage.helper.VMSnapshotHelperImpl" />
<bean id="objectInDataStoreManagerImpl"
class="org.apache.cloudstack.storage.datastore.ObjectInDataStoreManagerImpl" />

View File

@ -33,6 +33,4 @@
<bean id="DefaultVMSnapshotStrategy"
class="org.apache.cloudstack.storage.vmsnapshot.DefaultVMSnapshotStrategy" />
<bean id="VMSnapshotHelperImpl"
class="org.apache.cloudstack.storage.vmsnapshot.VMSnapshotHelperImpl" />
</beans>

View File

@ -40,7 +40,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.framework.async.AsyncRpcContext;
import org.apache.cloudstack.storage.command.CommandResult;
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
import org.apache.log4j.Logger;

View File

@ -19,6 +19,7 @@
package org.apache.cloudstack.storage.datastore;
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
public interface PrimaryDataStoreProviderManager {

View File

@ -27,15 +27,17 @@ import java.util.List;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.storage.LocalHostEndpoint;
import org.apache.cloudstack.storage.RemoteHostEndPoint;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
@ -43,10 +45,10 @@ import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.ScopeType;
import com.cloud.storage.Storage.TemplateType;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.QueryBuilder;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.exception.CloudRuntimeException;
@ -185,6 +187,16 @@ public class DefaultEndPointSelector implements EndPointSelector {
selectedStore = destStore;
}
EndPoint ep = findEndpointForImageStorage(selectedStore);
if (ep != null) {
return ep;
}
// handle special case where it is used in deploying ssvm for S3
if (srcData instanceof TemplateInfo) {
TemplateInfo tmpl = (TemplateInfo)srcData;
if (tmpl.getTemplateType() == TemplateType.SYSTEM) {
ep = LocalHostEndpoint.getEndpoint();
}
}
return ep;
} else if (moveBetweenImages(srcStore, destStore)) {
EndPoint ep = findEndpointForImageStorage(destStore);
@ -209,9 +221,7 @@ public class DefaultEndPointSelector implements EndPointSelector {
// we can arbitrarily pick one ssvm to do that task
List<HostVO> ssAHosts = listUpAndConnectingSecondaryStorageVmHost(dcId);
if (ssAHosts == null || ssAHosts.isEmpty()) {
s_logger.info("No running ssvm is found, so command will be sent to LocalHostEndPoint");
return LocalHostEndpoint.getEndpoint(); // use local host as endpoint in
// case of no ssvm existing
return null;
}
Collections.shuffle(ssAHosts);
HostVO host = ssAHosts.get(0);
@ -232,7 +242,16 @@ public class DefaultEndPointSelector implements EndPointSelector {
@Override
public EndPoint select(DataObject object) {
DataStore store = object.getDataStore();
return select(store);
EndPoint ep = select(store);
if (ep != null)
return ep;
if (object instanceof TemplateInfo) {
TemplateInfo tmplInfo = (TemplateInfo)object;
if (store.getScope().getScopeType() == ScopeType.ZONE && store.getScope().getScopeId() == null && tmplInfo.getTemplateType() == TemplateType.SYSTEM) {
return LocalHostEndpoint.getEndpoint(); // for bootstrap system vm template downloading to region image store
}
}
return null;
}
@Override

View File

@ -18,14 +18,15 @@
*/
package org.apache.cloudstack.storage.helper;
import com.cloud.agent.api.to.DataTO;
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
import com.cloud.agent.api.VMSnapshotTO;
import com.cloud.agent.api.to.DataTO;
import com.cloud.vm.VirtualMachine;
public interface HypervisorHelper {
DataTO introduceObject(DataTO object, Scope scope, Long storeId);
boolean forgetObject(DataTO object, Scope scope, Long storeId);
SnapshotObjectTO takeSnapshot(SnapshotObjectTO snapshotObjectTO, Scope scope);
boolean revertSnapshot(SnapshotObjectTO snapshotObjectTO, Scope scope);
VMSnapshotTO quiesceVm(VirtualMachine virtualMachine);
boolean unquiesceVM(VirtualMachine virtualMachine, VMSnapshotTO vmSnapshotTO);
}

View File

@ -18,30 +18,63 @@
*/
package org.apache.cloudstack.storage.helper;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.to.DataTO;
import com.cloud.utils.exception.CloudRuntimeException;
import java.util.List;
import java.util.UUID;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.storage.command.ForgetObjectCmd;
import org.apache.cloudstack.storage.command.IntroduceObjectAnswer;
import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
import org.apache.log4j.Logger;
import org.apache.cloudstack.storage.vmsnapshot.VMSnapshotHelper;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import javax.inject.Inject;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CreateVMSnapshotAnswer;
import com.cloud.agent.api.CreateVMSnapshotCommand;
import com.cloud.agent.api.DeleteVMSnapshotCommand;
import com.cloud.agent.api.VMSnapshotTO;
import com.cloud.agent.api.to.DataTO;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.snapshot.VMSnapshot;
public class HypervisorHelperImpl implements HypervisorHelper {
private static final Logger s_logger = Logger.getLogger(HypervisorHelperImpl.class);
@Inject
EndPointSelector selector;
@Inject
VMSnapshotHelper vmSnapshotHelper;
@Inject
GuestOSDao guestOSDao;
@Inject
ConfigurationDao configurationDao;
@Inject
AgentManager agentMgr;
@Override
public DataTO introduceObject(DataTO object, Scope scope, Long storeId) {
EndPoint ep = selector.select(scope, storeId);
IntroduceObjectCmd cmd = new IntroduceObjectCmd(object);
Answer answer = ep.sendMessage(cmd);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
if (answer == null || !answer.getResult()) {
String errMsg = answer == null ? null : answer.getDetails();
throw new CloudRuntimeException("Failed to introduce object, due to " + errMsg);
@ -54,7 +87,14 @@ public class HypervisorHelperImpl implements HypervisorHelper {
public boolean forgetObject(DataTO object, Scope scope, Long storeId) {
EndPoint ep = selector.select(scope, storeId);
ForgetObjectCmd cmd = new ForgetObjectCmd(object);
Answer answer = ep.sendMessage(cmd);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
if (answer == null || !answer.getResult()) {
String errMsg = answer == null ? null : answer.getDetails();
if (errMsg != null) {
@ -66,12 +106,52 @@ public class HypervisorHelperImpl implements HypervisorHelper {
}
@Override
public SnapshotObjectTO takeSnapshot(SnapshotObjectTO snapshotObjectTO, Scope scope) {
return null; //To change body of implemented methods use File | Settings | File Templates.
public VMSnapshotTO quiesceVm(VirtualMachine virtualMachine) {
String value = configurationDao.getValue("vmsnapshot.create.wait");
int wait = NumbersUtil.parseInt(value, 1800);
Long hostId = vmSnapshotHelper.pickRunningHost(virtualMachine.getId());
VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(1L, UUID.randomUUID().toString(), VMSnapshot.Type.DiskAndMemory, null, null, false,
null);
GuestOSVO guestOS = guestOSDao.findById(virtualMachine.getGuestOSId());
List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(virtualMachine.getId());
CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(virtualMachine.getInstanceName(),vmSnapshotTO ,volumeTOs, guestOS.getDisplayName(),virtualMachine.getState());
ccmd.setWait(wait);
try {
Answer answer = agentMgr.send(hostId, ccmd);
if (answer != null && answer.getResult()) {
CreateVMSnapshotAnswer snapshotAnswer = (CreateVMSnapshotAnswer)answer;
vmSnapshotTO.setVolumes(snapshotAnswer.getVolumeTOs());
} else {
String errMsg = (answer != null) ? answer.getDetails() : null;
throw new CloudRuntimeException("Failed to quiesce vm, due to " + errMsg);
}
} catch (AgentUnavailableException e) {
throw new CloudRuntimeException("Failed to quiesce vm", e);
} catch (OperationTimedoutException e) {
throw new CloudRuntimeException("Failed to quiesce vm", e);
}
return vmSnapshotTO;
}
@Override
public boolean revertSnapshot(SnapshotObjectTO snapshotObjectTO, Scope scope) {
return false; //To change body of implemented methods use File | Settings | File Templates.
public boolean unquiesceVM(VirtualMachine virtualMachine, VMSnapshotTO vmSnapshotTO) {
Long hostId = vmSnapshotHelper.pickRunningHost(virtualMachine.getId());
List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(virtualMachine.getId());
GuestOSVO guestOS = guestOSDao.findById(virtualMachine.getGuestOSId());
DeleteVMSnapshotCommand deleteSnapshotCommand = new DeleteVMSnapshotCommand(virtualMachine.getInstanceName(), vmSnapshotTO, volumeTOs, guestOS.getDisplayName());
try {
Answer answer = agentMgr.send(hostId, deleteSnapshotCommand);
if (answer != null && answer.getResult()) {
return true;
} else {
String errMsg = (answer != null) ? answer.getDetails() : null;
throw new CloudRuntimeException("Failed to unquiesce vm, due to " + errMsg);
}
} catch (AgentUnavailableException e) {
throw new CloudRuntimeException("Failed to unquiesce vm", e);
} catch (OperationTimedoutException e) {
throw new CloudRuntimeException("Failed to unquiesce vm", e);
}
}
}

View File

@ -16,16 +16,27 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cloudstack.storage.vmsnapshot;
package org.apache.cloudstack.storage.helper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.cloudstack.storage.vmsnapshot.VMSnapshotHelper;
import com.cloud.agent.api.VMSnapshotTO;
import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.storage.StoragePool;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.utils.fsm.NoTransitionException;
@ -36,17 +47,6 @@ import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.snapshot.VMSnapshot;
import com.cloud.vm.snapshot.VMSnapshotVO;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class VMSnapshotHelperImpl implements VMSnapshotHelper {
@Inject

View File

@ -18,17 +18,13 @@
*/
package org.apache.cloudstack.storage.image;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.storage.DownloadAnswer;
import com.cloud.agent.api.storage.Proxy;
import com.cloud.agent.api.to.DataObjectType;
import com.cloud.agent.api.to.DataTO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.download.DownloadMonitor;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Date;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
@ -47,13 +43,17 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
import org.apache.log4j.Logger;
import javax.inject.Inject;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Date;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.storage.DownloadAnswer;
import com.cloud.agent.api.storage.Proxy;
import com.cloud.agent.api.to.DataObjectType;
import com.cloud.agent.api.to.DataTO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.download.DownloadMonitor;
public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
private static final Logger s_logger = Logger.getLogger(BaseImageStoreDriverImpl.class);
@ -239,7 +239,14 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
try {
DeleteCommand cmd = new DeleteCommand(data.getTO());
EndPoint ep = _epSelector.select(data);
Answer answer = ep.sendMessage(cmd);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
if (answer != null && !answer.getResult()) {
result.setResult(answer.getDetails());
}

View File

@ -18,14 +18,14 @@
*/
package org.apache.cloudstack.storage.vmsnapshot;
import java.util.List;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import com.cloud.agent.api.VMSnapshotTO;
import com.cloud.agent.api.to.DataTO;
import com.cloud.utils.fsm.NoTransitionException;
import com.cloud.vm.snapshot.VMSnapshot;
import com.cloud.vm.snapshot.VMSnapshotVO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import java.util.List;
public interface VMSnapshotHelper {
boolean vmSnapshotStateTransitTo(VMSnapshot vsnp, VMSnapshot.Event event) throws NoTransitionException;

View File

@ -19,7 +19,7 @@
package org.apache.cloudstack.storage.volume;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
public interface TemplateOnPrimaryDataStoreInfo {
public String getPath();

View File

@ -103,7 +103,7 @@
</display>
</class>
<interface id="9" corner="BOTTOM_RIGHT" language="java"
name="org.apache.cloudstack.storage.datastore.PrimaryDataStore" project="cloud-engine-storage"
name="org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore" project="cloud-engine-storage"
file="/cloud-engine-storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java" binary="false">
<position height="-1" width="-1" x="770" y="-4"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">

View File

@ -23,23 +23,9 @@ import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.engine.subsystem.api.storage.*;
import org.apache.log4j.Logger;
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;

View File

@ -29,7 +29,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManag
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;

View File

@ -18,6 +18,49 @@
*/
package org.apache.cloudstack.storage.volume;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.framework.async.AsyncRpcContext;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.storage.command.CommandResult;
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
import org.apache.cloudstack.storage.command.DeleteCommand;
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.storage.ListVolumeAnswer;
import com.cloud.agent.api.storage.ListVolumeCommand;
@ -49,46 +92,6 @@ import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.framework.async.AsyncRpcContext;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.storage.command.CommandResult;
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
import org.apache.cloudstack.storage.command.DeleteCommand;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
public class VolumeServiceImpl implements VolumeService {
@ -162,12 +165,24 @@ public class VolumeServiceImpl implements VolumeService {
DataObject volumeOnStore = dataStore.create(volume);
volumeOnStore.processEvent(Event.CreateOnlyRequested);
CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore,
future);
AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createVolumeCallback(null, null)).setContext(context);
try {
CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore,
future);
AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createVolumeCallback(null, null)).setContext(context);
dataStore.getDriver().createAsync(dataStore, volumeOnStore, caller);
dataStore.getDriver().createAsync(dataStore, volumeOnStore, caller);
} catch (CloudRuntimeException ex) {
// clean up already persisted volume_store_ref entry in case of createVolumeCallback is never called
VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(dataStore.getId(), volume.getId());
if (volStoreVO != null) {
VolumeInfo volObj = volFactory.getVolume(volume, dataStore);
volObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
}
VolumeApiResult volResult = new VolumeApiResult((VolumeObject)volumeOnStore);
volResult.setResult(ex.getMessage());
future.complete(volResult);
}
return future;
}
@ -438,6 +453,7 @@ public class VolumeServiceImpl implements VolumeService {
} catch (Throwable e) {
s_logger.debug("failed to create template on storage", e);
templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
dataStore.create(template); // make sure that template_spool_ref entry is still present so that the second thread can acquire the lock
VolumeApiResult result = new VolumeApiResult(volume);
result.setResult(e.toString());
future.complete(result);
@ -1019,13 +1035,25 @@ public class VolumeServiceImpl implements VolumeService {
volumeOnStore.processEvent(Event.CreateOnlyRequested);
CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore,
future);
AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().registerVolumeCallback(null, null));
caller.setContext(context);
try {
CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore,
future);
AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().registerVolumeCallback(null, null));
caller.setContext(context);
store.getDriver().createAsync(store, volumeOnStore, caller);
store.getDriver().createAsync(store, volumeOnStore, caller);
} catch (CloudRuntimeException ex) {
// clean up already persisted volume_store_ref entry in case of createVolumeCallback is never called
VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId());
if (volStoreVO != null) {
VolumeInfo volObj = volFactory.getVolume(volume, store);
volObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
}
VolumeApiResult res = new VolumeApiResult((VolumeObject)volumeOnStore);
res.setResult(ex.getMessage());
future.complete(res);
}
return future;
}
@ -1255,7 +1283,14 @@ public class VolumeServiceImpl implements VolumeService {
tmplTO.setId(tInfo.getId());
DeleteCommand dtCommand = new DeleteCommand(tmplTO);
EndPoint ep = _epSelector.select(store);
Answer answer = ep.sendMessage(dtCommand);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(dtCommand, false, errMsg);
} else {
answer = ep.sendMessage(dtCommand);
}
if (answer == null || !answer.getResult()) {
s_logger.info("Failed to deleted volume at store: " + store.getName());
@ -1280,7 +1315,14 @@ public class VolumeServiceImpl implements VolumeService {
private Map<Long, TemplateProp> listVolume(DataStore store) {
ListVolumeCommand cmd = new ListVolumeCommand(store.getTO(), store.getUri());
EndPoint ep = _epSelector.select(store);
Answer answer = ep.sendMessage(cmd);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
if (answer != null && answer.getResult()) {
ListVolumeAnswer tanswer = (ListVolumeAnswer) answer;
return tanswer.getTemplateInfo();

View File

@ -59,6 +59,7 @@ import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.ConnectionConcierge;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.DbProperties;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.db.TransactionLegacy;
@ -1029,15 +1030,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C
s_logger.info("Start configuring cluster manager : " + name);
}
File dbPropsFile = PropertiesUtil.findConfigFile("db.properties");
Properties dbProps = new Properties();
try {
PropertiesUtil.loadFromFile(dbProps, dbPropsFile);
} catch (FileNotFoundException e) {
throw new ConfigurationException("Unable to find db.properties");
} catch (IOException e) {
throw new ConfigurationException("Unable to load db.properties content");
}
Properties dbProps = DbProperties.getDbProperties();
_clusterNodeIP = dbProps.getProperty("cluster.node.IP");
if (_clusterNodeIP == null) {
_clusterNodeIP = "127.0.0.1";

View File

@ -16,9 +16,6 @@
// under the License.
package com.cloud.cluster;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Map;
import java.util.Properties;
@ -26,14 +23,13 @@ import java.util.Properties;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.cloudstack.framework.config.ConfigDepot;
import org.apache.log4j.Logger;
import com.cloud.cluster.dao.ManagementServerHostDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.db.DbProperties;
public class ClusterServiceServletAdapter extends AdapterBase implements ClusterServiceAdapter {
@ -122,15 +118,7 @@ public class ClusterServiceServletAdapter extends AdapterBase implements Cluster
if (_mshostDao != null)
return;
File dbPropsFile = PropertiesUtil.findConfigFile("db.properties");
Properties dbProps = new Properties();
try {
PropertiesUtil.loadFromFile(dbProps, dbPropsFile);
} catch (FileNotFoundException e) {
throw new ConfigurationException("Unable to find db.properties");
} catch (IOException e) {
throw new ConfigurationException("Unable to load db.properties content");
}
Properties dbProps = DbProperties.getDbProperties();
_clusterServicePort = NumbersUtil.parseInt(dbProps.getProperty("cluster.servlet.port"), DEFAULT_SERVICE_PORT);
if (s_logger.isInfoEnabled())

View File

@ -1864,4 +1864,11 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
return sql;
}
@DB()
protected Pair<List<T>, Integer> listAndCountIncludingRemovedBy(final SearchCriteria<T> sc, final Filter filter) {
List<T> objects = searchIncludingRemoved(sc, filter, null, false);
Integer count = getCount(sc);
return new Pair<List<T>, Integer>(objects, count);
}
}

View File

@ -93,12 +93,6 @@ public class TransactionLegacy {
} catch (Exception e) {
s_logger.error("Unable to register mbean for transaction", e);
}
/* FIXME: We need a better solution for this
* Initialize encryption if we need it for db.properties
*/
EncryptionSecretKeyChecker enc = new EncryptionSecretKeyChecker();
enc.check();
}
private final LinkedList<StackElement> _stack;
@ -1025,30 +1019,23 @@ public class TransactionLegacy {
static {
// Initialize with assumed db.properties file
initDataSource("db.properties");
initDataSource(DbProperties.getDbProperties());
}
public static void initDataSource(String propsFileName) {
try {
File dbPropsFile = PropertiesUtil.findConfigFile(propsFileName);
final Properties dbProps;
if (EncryptionSecretKeyChecker.useEncryption()) {
StandardPBEStringEncryptor encryptor = EncryptionSecretKeyChecker.getEncryptor();
dbProps = new EncryptableProperties(encryptor);
} else {
dbProps = new Properties();
}
try {
PropertiesUtil.loadFromFile(dbProps, dbPropsFile);
dbProps.load(new FileInputStream(dbPropsFile));
} catch (IOException e) {
s_logger.fatal("Unable to load db properties file, pl. check the classpath and file path configuration", e);
return;
} catch (NullPointerException e) {
s_logger.fatal("Unable to locate db properties file within classpath or absolute path: " + propsFileName);
return;
}
public static void initDataSource(String propsFileName) throws IOException {
Properties dbProps = new Properties();
File dbPropsFile = PropertiesUtil.findConfigFile(propsFileName);
if (dbPropsFile != null && dbPropsFile.exists()) {
PropertiesUtil.loadFromFile(dbProps, dbPropsFile);
initDataSource(dbProps);
}
}
public static void initDataSource(Properties dbProps) {
try {
if (dbProps.size() == 0)
return;
// FIXME: If params are missing...default them????
final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
final int cloudMaxIdle = Integer.parseInt(dbProps.getProperty("db.cloud.maxIdle"));

View File

@ -17,7 +17,6 @@
package org.apache.cloudstack.framework.jobs.impl;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
@ -34,7 +33,6 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.framework.config.ConfigDepot;
import org.apache.cloudstack.framework.config.ConfigKey;
@ -54,25 +52,26 @@ import org.apache.cloudstack.jobs.JobInfo;
import org.apache.cloudstack.jobs.JobInfo.Status;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.utils.identity.ManagementServerNode;
import org.apache.log4j.Logger;
import com.cloud.cluster.ClusterManagerListener;
import com.cloud.cluster.ManagementServerHost;
import com.cloud.utils.DateUtil;
import com.cloud.utils.Predicate;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.DbProperties;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.db.TransactionCallbackNoReturn;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.db.TransactionCallbackNoReturn;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExceptionUtil;
@ -865,10 +864,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
try {
final File dbPropsFile = PropertiesUtil.findConfigFile("db.properties");
final Properties dbProps = new Properties();
PropertiesUtil.loadFromFile(dbProps, dbPropsFile);
final Properties dbProps = DbProperties.getDbProperties();
final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
int poolSize = (cloudMaxActive * 2) / 3;

View File

@ -0,0 +1,21 @@
<!-- 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. -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>Apache CloudStack Checkstyle Configuration</name>
<artifactId>checkstyle</artifactId>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-maven-standard</artifactId>
<version>4.3.0-SNAPSHOT</version>
<relativePath>../../maven-standard/pom.xml</relativePath>
</parent>
</project>

View File

@ -0,0 +1,39 @@
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<module name="Checker">
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module>
<module name="RegexpSingleline">
<!-- \s matches whitespace character, $ matches end of line. -->
<property name="format" value="\s+$"/>
<property name="message" value="Line has trailing spaces."/>
</module>
<module name="TreeWalker">
<module name="RedundantImport"/>
<module name="UnusedImports"/>
</module>
</module>

View File

@ -0,0 +1,9 @@
packages
*.suo
*/obj/*
WmiWrappers/bin/*
AgentShell/bin/*
ServerResource*/bin/*
*.user
!.nuget/

View File

@ -0,0 +1,15 @@
<!-- 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. -->
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<solution>
<add key="disableSourceControlIntegration" value="true" />
</solution>
</configuration>

View File

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
<!-- Enable the restore command to run before builds -->
<RestorePackages Condition=" '$(RestorePackages)' == '' ">false</RestorePackages>
<!-- Property that enables building a package from a project -->
<BuildPackage Condition=" '$(BuildPackage)' == '' ">false</BuildPackage>
<!-- Determines if package restore consent is required to restore packages -->
<RequireRestoreConsent Condition=" '$(RequireRestoreConsent)' != 'false' ">true</RequireRestoreConsent>
<!-- Download NuGet.exe if it does not already exist -->
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false</DownloadNuGetExe>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageSources)' == '' ">
<!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
<!-- The official NuGet package source (https://www.nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
<!--
<PackageSource Include="https://www.nuget.org/api/v2/" />
<PackageSource Include="https://my-nuget-source/nuget/" />
-->
</ItemGroup>
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
<!-- Windows specific commands -->
<NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
<PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
<!-- We need to launch nuget.exe with the mono command if we're not on windows -->
<NuGetToolsPath>$(SolutionDir).nuget</NuGetToolsPath>
<PackagesConfig>packages.config</PackagesConfig>
</PropertyGroup>
<PropertyGroup>
<!-- NuGet command -->
<NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\NuGet.exe</NuGetExePath>
<PackageSources Condition=" $(PackageSources) == '' ">@(PackageSource)</PackageSources>
<NuGetCommand Condition=" '$(OS)' == 'Windows_NT'">"$(NuGetExePath)"</NuGetCommand>
<NuGetCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 $(NuGetExePath)</NuGetCommand>
<PackageOutputDir Condition="$(PackageOutputDir) == ''">$(TargetDir.Trim('\\'))</PackageOutputDir>
<RequireConsentSwitch Condition=" $(RequireRestoreConsent) == 'true' ">-RequireConsent</RequireConsentSwitch>
<NonInteractiveSwitch Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' ">-NonInteractive</NonInteractiveSwitch>
<PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT'">"$(SolutionDir) "</PaddedSolutionDir>
<PaddedSolutionDir Condition=" '$(OS)' != 'Windows_NT' ">"$(SolutionDir)"</PaddedSolutionDir>
<!-- Commands -->
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)</RestoreCommand>
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols</BuildCommand>
<!-- We need to ensure packages are restored prior to assembly resolve -->
<BuildDependsOn Condition="$(RestorePackages) == 'true'">
RestorePackages;
$(BuildDependsOn);
</BuildDependsOn>
<!-- Make the build depend on restore packages -->
<BuildDependsOn Condition="$(BuildPackage) == 'true'">
$(BuildDependsOn);
BuildPackage;
</BuildDependsOn>
</PropertyGroup>
<Target Name="CheckPrerequisites">
<!-- Raise an error if we're unable to locate nuget.exe -->
<Error Condition="'$(DownloadNuGetExe)' != 'true' AND !Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" />
<!--
Take advantage of MsBuild's build dependency tracking to make sure that we only ever download nuget.exe once.
This effectively acts as a lock that makes sure that the download operation will only happen once and all
parallel builds will have to wait for it to complete.
-->
<MsBuild Targets="_DownloadNuGet" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT;DownloadNuGetExe=$(DownloadNuGetExe)" />
</Target>
<Target Name="_DownloadNuGet">
<DownloadNuGet OutputFilename="$(NuGetExePath)" Condition=" '$(DownloadNuGetExe)' == 'true' AND !Exists('$(NuGetExePath)')" />
</Target>
<Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">
<Exec Command="$(RestoreCommand)"
Condition="'$(OS)' != 'Windows_NT' And Exists('$(PackagesConfig)')" />
<Exec Command="$(RestoreCommand)"
LogStandardErrorAsError="true"
Condition="'$(OS)' == 'Windows_NT' And Exists('$(PackagesConfig)')" />
</Target>
<Target Name="BuildPackage" DependsOnTargets="CheckPrerequisites">
<Exec Command="$(BuildCommand)"
Condition=" '$(OS)' != 'Windows_NT' " />
<Exec Command="$(BuildCommand)"
LogStandardErrorAsError="true"
Condition=" '$(OS)' == 'Windows_NT' " />
</Target>
<UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<OutputFilename ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Reference Include="System.Core" />
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Using Namespace="System.Net" />
<Using Namespace="Microsoft.Build.Framework" />
<Using Namespace="Microsoft.Build.Utilities" />
<Code Type="Fragment" Language="cs">
<![CDATA[
try {
OutputFilename = Path.GetFullPath(OutputFilename);
Log.LogMessage("Downloading latest version of NuGet.exe...");
WebClient webClient = new WebClient();
webClient.DownloadFile("https://www.nuget.org/nuget.exe", OutputFilename);
return true;
}
catch (Exception ex) {
Log.LogErrorFromException(ex);
return false;
}
]]>
</Code>
</Task>
</UsingTask>
</Project>

View File

@ -0,0 +1,53 @@
// 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.
namespace CloudStack.Plugin.AgentShell
{
partial class AgentService
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "CloudStack ServerResource";
}
#endregion
}
}

View File

@ -0,0 +1,132 @@
// 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.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http.SelfHost;
using System.Web.Http;
using log4net;
using HypervResource;
namespace CloudStack.Plugin.AgentShell
{
public partial class AgentService : ServiceBase
{
[System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
static extern bool AllocConsole();
[System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
static extern bool FreeConsole();
HttpSelfHostServer server;
private static ILog logger = LogManager.GetLogger(typeof(AgentService));
public AgentService()
{
logger.Info("Starting CloudStack agent");
InitializeComponent();
UriBuilder baseUri = new UriBuilder("http", AgentSettings.Default.private_ip_address, AgentSettings.Default.port);
var config = new HttpSelfHostConfiguration(baseUri.Uri);
// Allow ActionName to be applied to methods in ApiController, which allows it to serve multiple POST URLs
config.Routes.MapHttpRoute(
"API Default", "api/{controller}/{action}",
new { action = RouteParameter.Optional }
);
// Load controller assemblies that we want to config to route to.
ConfigServerResource();
AssertControllerAssemblyAvailable(config, typeof(HypervResourceController), "Cannot load Controller of type" + typeof(HypervResourceController));
server = new HttpSelfHostServer(config);
}
public static void ConfigServerResource()
{
// For simplicity, ServerResource config and settings file are tightly coupled.
// An alternative is to pass a dictionary to the server resource and let it find
// required settings. In contrast, the approach below is strongly typed and makes
// use of VisualStudio settings designer. The designer allows us to avoid
// accessing config using their key strings.
HypervResourceControllerConfig rsrcCnf = new HypervResourceControllerConfig();
rsrcCnf.PrivateIpAddress = AgentSettings.Default.private_ip_address;
rsrcCnf.GatewayIpAddress = AgentSettings.Default.gateway_ip_address;
rsrcCnf.RootDeviceReservedSpaceBytes = AgentSettings.Default.RootDeviceReservedSpaceBytes;
rsrcCnf.RootDeviceName = AgentSettings.Default.RootDeviceName;
rsrcCnf.ParentPartitionMinMemoryMb = AgentSettings.Default.dom0MinMemory;
rsrcCnf.LocalSecondaryStoragePath = AgentSettings.Default.local_secondary_storage_path;
rsrcCnf.systemVmIso = null;
// Side effect: loads the assembly containing HypervResourceController, which
// allows HttpSelfHostServer to route requests to the controller.
HypervResourceController.Configure(rsrcCnf);
}
// TODO: update to examine not the assembly resolver, but the list of available controllers themselves!
private static bool AssertControllerAssemblyAvailable(HttpSelfHostConfiguration config, Type controllerType, string errorMessage)
{
var assemblies = config.Services.GetAssembliesResolver().GetAssemblies();
foreach (var assembly in assemblies)
{
string name = assembly.GetName().Name;
if (controllerType.Assembly.GetName().Name.Equals(name))
{
logger.DebugFormat("Controller {0} is available", controllerType.Name);
return true;
}
}
logger.Error(errorMessage);
throw new AgentShellException(errorMessage);
}
protected override void OnStart(string[] args)
{
server.OpenAsync().Wait();
}
protected override void OnStop()
{
server.CloseAsync().Wait();
}
internal void RunConsole(string[] args)
{
OnStart(args);
AllocConsole();
Console.WriteLine("Service running ... press <ENTER> to stop");
Console.ReadLine();
FreeConsole();
OnStop();
}
}
}

View File

@ -0,0 +1,402 @@
// 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.
namespace CloudStack.Plugin.AgentShell {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
public sealed partial class AgentSettings : global::System.Configuration.ApplicationSettingsBase {
private static AgentSettings defaultInstance = ((AgentSettings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new AgentSettings())));
public static AgentSettings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("8")]
public int cpus {
get {
return ((int)(this["cpus"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("Routing")]
public string type {
get {
return ((string)(this["type"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("5fe2bad3-d785-394e-9949-89786b8a63d2")]
public global::System.Guid local_storage_uuid {
get {
return ((global::System.Guid)(this["local_storage_uuid"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("hvm")]
public string capabilities {
get {
return ((string)(this["capabilities"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("2130")]
public int Settingcpuspeed {
get {
return ((int)(this["Settingcpuspeed"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("8250")]
public int port {
get {
return ((int)(this["port"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("34359738368")]
public long memory {
get {
return ((long)(this["memory"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("camldonall01.citrite.net")]
public string host {
get {
return ((string)(this["host"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("1")]
public int pod {
get {
return ((int)(this["pod"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("10.1.1.1")]
public string gateway_ip_address {
get {
return ((string)(this["gateway_ip_address"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::System.Guid guid {
get {
return ((global::System.Guid)(this["guid"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("2")]
public int cluster {
get {
return ((int)(this["cluster"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("1")]
public int zone {
get {
return ((int)(this["zone"]));
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("c:\\Secondary")]
public string local_secondary_storage_path {
get {
return ((string)(this["local_secondary_storage_path"]));
}
set {
this["local_secondary_storage_path"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("E:\\Disks\\Disks")]
public string local_storage_path {
get {
return ((string)(this["local_storage_path"]));
}
set {
this["local_storage_path"] = value;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("5")]
public int workers {
get {
return ((int)(this["workers"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("255.255.240.0")]
public string private_ip_netmask {
get {
return ((string)(this["private_ip_netmask"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("4294967296")]
public long RootDeviceReservedSpaceBytes {
get {
return ((long)(this["RootDeviceReservedSpaceBytes"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("../../../../../")]
public string hyperv_plugin_root {
get {
return ((string)(this["hyperv_plugin_root"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("e:\\")]
public string RootDeviceName {
get {
return ((string)(this["RootDeviceName"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("101F742C6B88")]
public string private_mac_address {
get {
return ((string)(this["private_mac_address"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("systemvm.iso")]
public string system_vm_iso {
get {
return ((string)(this["system_vm_iso"]));
}
set {
this["system_vm_iso"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute(".\\var\\test\\storagepool")]
public string testLocalStorePath {
get {
return ((string)(this["testLocalStorePath"]));
}
set {
this["testLocalStorePath"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("testS3Bucket")]
public string testS3Bucket {
get {
return ((string)(this["testS3Bucket"]));
}
set {
this["testS3Bucket"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("testS3Endpoint")]
public string testS3Endpoint {
get {
return ((string)(this["testS3Endpoint"]));
}
set {
this["testS3Endpoint"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("testS3AccessKey")]
public string testS3AccessKey {
get {
return ((string)(this["testS3AccessKey"]));
}
set {
this["testS3AccessKey"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("testS3SecretKey")]
public string testS3SecretKey {
get {
return ((string)(this["testS3SecretKey"]));
}
set {
this["testS3SecretKey"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("206-2-73592258-559a-3b38-8f66-b667aab143eb")]
public string testS3TemplateName {
get {
return ((string)(this["testS3TemplateName"]));
}
set {
this["testS3TemplateName"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("5fe2bad3-d785-394e-9949-89786b8a63d2")]
public string testLocalStoreUUID {
get {
return ((string)(this["testLocalStoreUUID"]));
}
set {
this["testLocalStoreUUID"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("acton-systemvm-02062012.vhd.bz2")]
public string testSystemVMTemplateName {
get {
return ((string)(this["testSystemVMTemplateName"]));
}
set {
this["testSystemVMTemplateName"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("acton-systemvm-02062012")]
public string testSystemVMTemplateNameNoExt {
get {
return ((string)(this["testSystemVMTemplateNameNoExt"]));
}
set {
this["testSystemVMTemplateNameNoExt"] = value;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("2048")]
public ulong dom0MinMemory {
get {
return ((ulong)(this["dom0MinMemory"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("10.1.1.1")]
public string private_ip_address {
get {
return ((string)(this["private_ip_address"]));
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("cifs://10.1.1.1/secondary?user\\u003dadministrator\\u0026password\\u003d1pass%40w" +
"ord1")]
public string testCifsUrl {
get {
return ((string)(this["testCifsUrl"]));
}
set {
this["testCifsUrl"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("template/tmpl/2/201/61d5316a-3cc4-30cf-a557-78691ff5c143.vhd")]
public string testCifsPath {
get {
return ((string)(this["testCifsPath"]));
}
set {
this["testCifsPath"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("CentOS64")]
public string testKvpVmName {
get {
return ((string)(this["testKvpVmName"]));
}
set {
this["testKvpVmName"] = value;
}
}
}
}

View File

@ -0,0 +1,130 @@
<!--
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.
-->
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="CloudStack.Plugin.AgentShell" GeneratedClassName="AgentSettings">
<Profiles />
<Settings>
<Setting Name="cpus" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">8</Value>
</Setting>
<Setting Name="private_ip_address" Type="System.String" Scope="Application">
<Value Profile="(Default)">10.70.176.29</Value>
</Setting>
<Setting Name="type" Type="System.String" Scope="Application">
<Value Profile="(Default)">Routing</Value>
</Setting>
<Setting Name="local_storage_uuid" Type="System.Guid" Scope="Application">
<Value Profile="(Default)">5fe2bad3-d785-394e-9949-89786b8a63d2</Value>
</Setting>
<Setting Name="capabilities" Type="System.String" Scope="Application">
<Value Profile="(Default)">hvm</Value>
</Setting>
<Setting Name="Settingcpuspeed" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">2130</Value>
</Setting>
<Setting Name="port" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">8250</Value>
</Setting>
<Setting Name="memory" Type="System.Int64" Scope="Application">
<Value Profile="(Default)">34359738368</Value>
</Setting>
<Setting Name="host" Type="System.String" Scope="Application">
<Value Profile="(Default)">camldonall01.citrite.net</Value>
</Setting>
<Setting Name="pod" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">1</Value>
</Setting>
<Setting Name="gateway_ip_address" Type="System.String" Scope="Application">
<Value Profile="(Default)">10.70.176.1</Value>
</Setting>
<Setting Name="guid" Type="System.Guid" Scope="Application">
<Value Profile="(Default)" />
</Setting>
<Setting Name="cluster" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">2</Value>
</Setting>
<Setting Name="zone" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">1</Value>
</Setting>
<Setting Name="local_secondary_storage_path" Type="System.String" Scope="User">
<Value Profile="(Default)">c:\Secondary</Value>
</Setting>
<Setting Name="local_storage_path" Type="System.String" Scope="User">
<Value Profile="(Default)">E:\Disks\Disks</Value>
</Setting>
<Setting Name="workers" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">5</Value>
</Setting>
<Setting Name="private_ip_netmask" Type="System.String" Scope="Application">
<Value Profile="(Default)">255.255.240.0</Value>
</Setting>
<Setting Name="RootDeviceReservedSpaceBytes" Type="System.Int64" Scope="Application">
<Value Profile="(Default)">4294967296</Value>
</Setting>
<Setting Name="hyperv_plugin_root" Type="System.String" Scope="Application">
<Value Profile="(Default)">../../../../../</Value>
</Setting>
<Setting Name="RootDeviceName" Type="System.String" Scope="Application">
<Value Profile="(Default)">e:\</Value>
</Setting>
<Setting Name="private_mac_address" Type="System.String" Scope="Application">
<Value Profile="(Default)">101F742C6B88</Value>
</Setting>
<Setting Name="testLocalStorePath" Type="System.String" Scope="User">
<Value Profile="(Default)">.\var\test\storagepool</Value>
</Setting>
<Setting Name="testS3Bucket" Type="System.String" Scope="User">
<Value Profile="(Default)">testS3Bucket</Value>
</Setting>
<Setting Name="testS3Endpoint" Type="System.String" Scope="User">
<Value Profile="(Default)">testS3Endpoint</Value>
</Setting>
<Setting Name="testS3AccessKey" Type="System.String" Scope="User">
<Value Profile="(Default)">testS3AccessKey</Value>
</Setting>
<Setting Name="testS3SecretKey" Type="System.String" Scope="User">
<Value Profile="(Default)">testS3SecretKey</Value>
</Setting>
<Setting Name="testS3TemplateName" Type="System.String" Scope="User">
<Value Profile="(Default)">206-2-73592258-559a-3b38-8f66-b667aab143eb</Value>
</Setting>
<Setting Name="testLocalStoreUUID" Type="System.String" Scope="User">
<Value Profile="(Default)">5fe2bad3-d785-394e-9949-89786b8a63d2</Value>
</Setting>
<Setting Name="testSystemVMTemplateName" Type="System.String" Scope="User">
<Value Profile="(Default)">acton-systemvm-02062012.vhd.bz2</Value>
</Setting>
<Setting Name="testSystemVMTemplateNameNoExt" Type="System.String" Scope="User">
<Value Profile="(Default)">acton-systemvm-02062012</Value>
</Setting>
<Setting Name="dom0MinMemory" Type="System.UInt64" Scope="Application">
<Value Profile="(Default)">2048</Value>
</Setting>
<Setting Name="testCifsUrl" Type="System.String" Scope="User">
<Value Profile="(Default)">cifs://10.1.1.1/secondary?user\u003dadministrator\u0026password\u003d1pass%40word1</Value>
</Setting>
<Setting Name="testCifsPath" Type="System.String" Scope="User">
<Value Profile="(Default)">template/tmpl/2/201/61d5316a-3cc4-30cf-a557-78691ff5c143.vhd</Value>
</Setting>
<Setting Name="testKvpVmName" Type="System.String" Scope="User">
<Value Profile="(Default)">CentOS64</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{9060B539-62D0-4E71-A6C6-5944828774E9}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CloudStack.Plugin.AgentShell</RootNamespace>
<AssemblyName>AgentShell</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'NoUnitTestsDebug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\NoUnitTestsDebug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'NoUnitTests|AnyCPU'">
<OutputPath>bin\NoUnitTests\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="AWSSDK">
<HintPath>..\packages\AWSSDK.1.5.23.0\lib\AWSSDK.dll</HintPath>
</Reference>
<Reference Include="Ionic.Zip">
<HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.0\lib\net40-full\log4net.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NSubstitute">
<HintPath>..\packages\NSubstitute.1.6.1.0\lib\NET40\NSubstitute.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Management" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.4.0.20710.0\lib\net40\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.4.0.20710.0\lib\net40\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.SelfHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.SelfHost.4.0.20918.0\lib\net40\System.Web.Http.SelfHost.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml" />
<Reference Include="xunit">
<HintPath>..\packages\xunit.1.9.2\lib\net20\xunit.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AgentService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="AgentService.Designer.cs">
<DependentUpon>AgentService.cs</DependentUpon>
</Compile>
<Compile Include="AgentShellException.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="AgentSettings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>AgentSettings.settings</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config">
<SubType>Designer</SubType>
</None>
<None Include="AgentSettings.settings">
<Generator>PublicSettingsSingleFileGenerator</Generator>
<LastGenOutput>AgentSettings.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\HypervResource\HypervResource.csproj">
<Project>{c963dfff-65ba-4e71-ada5-526a4da4e0b2}</Project>
<Name>HypervResource</Name>
</ProjectReference>
<ProjectReference Include="..\WmiWrappers\WmiWrappers.csproj">
<Project>{db824727-bdc3-437c-a364-7a811d8a160f}</Project>
<Name>WmiWrappers</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,28 @@
// 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.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CloudStack.Plugin.AgentShell
{
class AgentShellException : Exception
{
public AgentShellException(string errMsg) : base(errMsg) { }
}
}

View File

@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="CloudStack.Plugin.AgentShell.AgentSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="CloudStack.Plugin.AgentShell.AgentSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="cloudstack-agent.log" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
</layout>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="FileAppender"/>
</root>
</log4net>
<applicationSettings>
<CloudStack.Plugin.AgentShell.AgentSettings>
<setting name="cpus" serializeAs="String">
<value>8</value>
</setting>
<setting name="type" serializeAs="String">
<value>Routing</value>
</setting>
<setting name="local_storage_uuid" serializeAs="String">
<value>5fe2bad3-d785-394e-9949-89786b8a63d2</value>
</setting>
<setting name="capabilities" serializeAs="String">
<value>hvm</value>
</setting>
<setting name="Settingcpuspeed" serializeAs="String">
<value>2130</value>
</setting>
<setting name="port" serializeAs="String">
<value>8250</value>
</setting>
<setting name="memory" serializeAs="String">
<value>34359738368</value>
</setting>
<setting name="host" serializeAs="String">
<value>camldonall01.citrite.net</value>
</setting>
<setting name="pod" serializeAs="String">
<value>1</value>
</setting>
<setting name="gateway_ip_address" serializeAs="String">
<value>10.102.192.1</value>
</setting>
<setting name="cluster" serializeAs="String">
<value>2</value>
</setting>
<setting name="zone" serializeAs="String">
<value>1</value>
</setting>
<setting name="workers" serializeAs="String">
<value>5</value>
</setting>
<setting name="private_ip_netmask" serializeAs="String">
<value>255.255.252.0</value>
</setting>
<setting name="RootDeviceReservedSpaceBytes" serializeAs="String">
<value>4294967296</value>
</setting>
<setting name="hyperv_plugin_root" serializeAs="String">
<value>..\..\..\..\..\</value>
</setting>
<setting name="RootDeviceName" serializeAs="String">
<value>e:\</value>
</setting>
<setting name="private_mac_address" serializeAs="String">
<value>101F742C6B88</value>
</setting>
<setting name="dom0MinMemory" serializeAs="String">
<value>2048</value>
</setting>
<setting name="private_ip_address" serializeAs="String">
<value>10.102.192.150</value>
</setting>
</CloudStack.Plugin.AgentShell.AgentSettings>
</applicationSettings>
<userSettings>
<CloudStack.Plugin.AgentShell.AgentSettings>
<setting name="local_secondary_storage_path" serializeAs="String">
<value>c:\Secondary</value>
</setting>
<setting name="local_storage_path" serializeAs="String">
<value>E:\Disks\Disks</value>
</setting>
<setting name="testLocalStorePath" serializeAs="String">
<value>.\var\test\storagepool</value>
</setting>
<setting name="testS3Bucket" serializeAs="String">
<value>testS3Bucket</value>
</setting>
<setting name="testS3Endpoint" serializeAs="String">
<value>testS3Endpoint</value>
</setting>
<setting name="testS3AccessKey" serializeAs="String">
<value>testS3AccessKey</value>
</setting>
<setting name="testS3SecretKey" serializeAs="String">
<value>testS3SecretKey</value>
</setting>
<setting name="testS3TemplateName" serializeAs="String">
<value>206-2-73592258-559a-3b38-8f66-b667aab143eb</value>
</setting>
<setting name="testLocalStoreUUID" serializeAs="String">
<value>5fe2bad3-d785-394e-9949-89786b8a63d2</value>
</setting>
<setting name="testSystemVMTemplateName" serializeAs="String">
<value>acton-systemvm-02062012.vhd.bz2</value>
</setting>
<setting name="testSystemVMTemplateNameNoExt" serializeAs="String">
<value>acton-systemvm-02062012</value>
</setting>
<setting name="testCifsUrl" serializeAs="String">
<value>cifs://10.70.1.1/secondary?user\u003dadministrator\u0026password\u003d1pass%40word1</value>
</setting>
<setting name="testCifsPath" serializeAs="String">
<value>template/tmpl/2/201/61d5316a-3cc4-30cf-a557-78691ff5c143.vhd</value>
</setting>
</CloudStack.Plugin.AgentShell.AgentSettings>
</userSettings>
</configuration>

View File

@ -0,0 +1,58 @@
// 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.
using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
namespace CloudStack.Plugin.AgentShell
{
static class Program
{
private static ILog logger = LogManager.GetLogger(typeof(Program));
/// <summary>
/// Application entry point allows service to run in console application or as a Windows service.
/// Add '--console' to the commandline for the former, the latter is the default.
/// </summary>
static void Main(params string[] args)
{
string arg1 = string.Empty;
if (args.Length > 0)
{
arg1 = args[0];
logger.DebugFormat("CloudStack ServerResource arg is ", arg1);
}
if (string.Compare(arg1, "--console", true) == 0)
{
logger.InfoFormat("CloudStack ServerResource running as console app");
new AgentService().RunConsole(args);
}
else
{
logger.InfoFormat("CloudStack ServerResource running as Windows Service");
ServiceBase[] ServicesToRun = new ServiceBase[] { new AgentService() };
ServiceBase.Run(ServicesToRun);
}
}
}
}

View File

@ -0,0 +1,56 @@
// 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.
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("AgentShell")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AgentShell")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("a6d8469a-c815-4765-a4a1-4927d4e3c583")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: log4net.Config.XmlConfigurator(Watch = true)]

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AWSSDK" version="1.5.23.0" targetFramework="net45" />
<package id="DotNetZip" version="1.9.1.8" targetFramework="net45" />
<package id="log4net" version="2.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="4.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="4.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.SelfHost" version="4.0.20918.0" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
<package id="NSubstitute" version="1.6.1.0" targetFramework="net45" />
<package id="xunit" version="1.9.2" targetFramework="net45" />
</packages>

View File

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Note: Add entries to the App.config file for configuration settings
that apply only to the Test project.
-->
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="CloudStack.Plugin.AgentShell.AgentSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="CloudStack.Plugin.AgentShell.AgentSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<appSettings>
</appSettings>
<connectionStrings>
</connectionStrings>
<applicationSettings>
<CloudStack.Plugin.AgentShell.AgentSettings>
<setting name="cpus" serializeAs="String">
<value>8</value>
</setting>
<setting name="private_ip_address" serializeAs="String">
<value>10.1.1.1</value>
</setting>
<setting name="type" serializeAs="String">
<value>Routing</value>
</setting>
<setting name="local_storage_uuid" serializeAs="String">
<value>5fe2bad3-d785-394e-9949-89786b8a63d2</value>
</setting>
<setting name="capabilities" serializeAs="String">
<value>hvm</value>
</setting>
<setting name="Settingcpuspeed" serializeAs="String">
<value>2130</value>
</setting>
<setting name="port" serializeAs="String">
<value>8250</value>
</setting>
<setting name="memory" serializeAs="String">
<value>34359738368</value>
</setting>
<setting name="host" serializeAs="String">
<value>camldonall01.citrite.net</value>
</setting>
<setting name="pod" serializeAs="String">
<value>1</value>
</setting>
<setting name="gateway_ip_address" serializeAs="String">
<value>10.70.176.1</value>
</setting>
<setting name="cluster" serializeAs="String">
<value>2</value>
</setting>
<setting name="zone" serializeAs="String">
<value>1</value>
</setting>
<setting name="local_storage_path" serializeAs="String">
<value>E:\Disks\Disks</value>
</setting>
<setting name="workers" serializeAs="String">
<value>5</value>
</setting>
<setting name="private_ip_netmask" serializeAs="String">
<value>255.255.240.0</value>
</setting>
<setting name="RootDeviceReservedSpaceBytes" serializeAs="String">
<value>4294967296</value>
</setting>
<setting name="hyperv_plugin_root" serializeAs="String">
<value>..\..\..\..\..\</value>
</setting>
<setting name="RootDeviceName" serializeAs="String">
<value>e:\</value>
</setting>
<setting name="dom0MinMemory" serializeAs="String">
<value>2048</value>
</setting>
<setting name="private_mac_address" serializeAs="String">
<value>101F742C6B88</value>
</setting>
</CloudStack.Plugin.AgentShell.AgentSettings>
</applicationSettings>
<userSettings>
<CloudStack.Plugin.AgentShell.AgentSettings>
<setting name="local_secondary_storage_path" serializeAs="String">
<value>c:\Secondary</value>
</setting>
<setting name="local_storage_path" serializeAs="String">
<value>E:\Disks\Disks</value>
</setting>
<setting name="testLocalStoreUUID" serializeAs="String">
<value>5fe2bad3-d785-394e-9949-89786b8a63d2</value>
</setting>
<setting name="testLocalStorePath" serializeAs="String">
<value>.\var\test\storagepool</value>
</setting>
<setting name="testS3Bucket" serializeAs="String">
<value>cshv3eu</value>
</setting>
<setting name="testS3Endpoint" serializeAs="String">
<value>s3.amazonaws.com</value>
</setting>
<setting name="testS3AccessKey" serializeAs="String">
<value>testS3AccessKey</value>
</setting>
<setting name="testS3SecretKey" serializeAs="String">
<value>testS3SecretKey</value>
</setting>
<setting name="testS3TemplateName" serializeAs="String">
<value>206-2-73592258-559a-3b38-8f66-b667aab143eb</value>
</setting>
<setting name="testCifsTemplateName" serializeAs="String">
<value>206-2-73592258-559a-3b38-8f66-b667aab143eb</value>
</setting>
<setting name="testCifsUrl" serializeAs="String">
<value>cifs://10.1.1.1/secondary?user\u003dadministrator\u0026password\u003d1pass%40word1</value>
</setting>
<setting name="testCifsPath" serializeAs="String">
<value>template/tmpl/2/201/6dda6631-4daa-3150-a49a-d5a4b0a4c4b6.vhd</value>
</setting>
</CloudStack.Plugin.AgentShell.AgentSettings>
</userSettings>
</configuration>

View File

@ -0,0 +1,642 @@
// 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.
using log4net;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// C# versions of certain CloudStack types to simplify JSON serialisation.
// Limit to the number of types, becasue they are written and maintained manually.
// JsonProperty used to identify property name when serialised, which allows
// later adoption of C# naming conventions if requried.
namespace HypervResource
{
public class PrimaryDataStoreTO
{
public string path;
public static PrimaryDataStoreTO ParseJson(dynamic json)
{
PrimaryDataStoreTO result = null;
if (json == null)
{
return result;
}
dynamic primaryDataStoreTOJson = json[CloudStackTypes.PrimaryDataStoreTO];
if (primaryDataStoreTOJson != null)
{
result = new PrimaryDataStoreTO()
{
path = (string)primaryDataStoreTOJson.path
};
}
return result;
}
}
public class VolumeObjectTO
{
private static ILog logger = LogManager.GetLogger(typeof(VolumeObjectTO));
public string FullFileName
{
get
{
String result = Path.Combine(this.primaryDataStore.path, this.name);
if (this.format != null)
{
result = result + "." + this.format.ToLowerInvariant();
}
return result;
}
}
public dynamic dataStore;
public string format;
public string name;
public string uuid;
public PrimaryDataStoreTO primaryDataStore;
public static VolumeObjectTO ParseJson(dynamic json)
{
VolumeObjectTO result = null;
if (json == null)
{
return result;
}
dynamic volumeObjectTOJson = json[CloudStackTypes.VolumeObjectTO];
if (volumeObjectTOJson != null)
{
result = new VolumeObjectTO()
{
dataStore = volumeObjectTOJson.dataStore,
format = ((string)volumeObjectTOJson.format),
name = (string)volumeObjectTOJson.name,
uuid = (string)volumeObjectTOJson.uuid
};
result.primaryDataStore = PrimaryDataStoreTO.ParseJson(volumeObjectTOJson.dataStore);
// Assert
if (result.dataStore == null || result.primaryDataStore == null)
{
String errMsg = "VolumeObjectTO missing primary dataStore in spec " + volumeObjectTOJson.ToString();
logger.Error(errMsg);
throw new ArgumentNullException(errMsg);
}
GuessFileExtension(result);
}
return result;
}
private static void GuessFileExtension(VolumeObjectTO volInfo)
{
if (String.IsNullOrEmpty(volInfo.format))
{
logger.Info("No image format in VolumeObjectTO, going to use format from first file that matches " + volInfo.FullFileName);
string[] choices = Directory.GetFiles(volInfo.primaryDataStore.path, volInfo.name + ".vhd*");
if (choices.Length != 1)
{
String errMsg = "Tried to guess file extension, but cannot find file corresponding to " + Path.Combine(volInfo.primaryDataStore.path, volInfo.name); // format being guessed.
logger.Debug(errMsg);
}
else
{
string[] splitFileName = choices[0].Split(new char[] { '.' });
volInfo.format = splitFileName[splitFileName.Length - 1];
}
logger.Debug("Going to use file " + volInfo.FullFileName);
}
}
}
public class TemplateObjectTO
{
/// <summary>
/// Full file name varies depending on whether the TemplateObjectTO has a path or not.
/// If it has a path, we use that. Otherwise, we build it from the name, extension and data store path.
/// </summary>
public string FullFileName
{
get
{
if (String.IsNullOrEmpty(this.path))
{
return Path.Combine(this.primaryDataStore.path, this.name) + '.' + this.format.ToLowerInvariant();
}
return this.path;
}
}
public dynamic imageDataStore;
public string format;
public string name;
public string uuid;
public S3TO s3DataStoreTO = null;
public NFSTO nfsDataStoreTO = null;
public PrimaryDataStoreTO primaryDataStore = null;
public string path;
public string checksum;
public static TemplateObjectTO ParseJson(dynamic json)
{
TemplateObjectTO result = null;
dynamic templateObjectTOJson = json[CloudStackTypes.TemplateObjectTO];
if (templateObjectTOJson != null)
{
result = new TemplateObjectTO()
{
imageDataStore = templateObjectTOJson.imageDataStore,
format = (string)templateObjectTOJson.format,
name = (string)templateObjectTOJson.name,
uuid = (string)templateObjectTOJson.uuid,
path = (string)templateObjectTOJson.path,
checksum = (string)templateObjectTOJson.checksum
};
result.s3DataStoreTO = S3TO.ParseJson(templateObjectTOJson.imageDataStore);
result.nfsDataStoreTO = NFSTO.ParseJson(templateObjectTOJson.imageDataStore);
result.primaryDataStore = PrimaryDataStoreTO.ParseJson(templateObjectTOJson.imageDataStore);
}
return result;
}
}
public class S3TO
{
public string bucketName;
public string secretKey;
public string accessKey;
public string endpoint;
public bool httpsFlag;
public static S3TO ParseJson(dynamic json)
{
S3TO result = null;
dynamic s3TOJson = json[CloudStackTypes.S3TO];
if (s3TOJson != null)
{
result = new S3TO()
{
bucketName = (string)s3TOJson.bucketName,
secretKey = (string)s3TOJson.secretKey,
accessKey = (string)s3TOJson.accessKey,
endpoint = (string)s3TOJson.endPoint,
httpsFlag = (bool)s3TOJson.httpsFlag
};
// Delete security credentials in original command. Prevents logger from spilling the beans, as it were.
s3TOJson.secretKey = string.Empty;
s3TOJson.accessKey = string.Empty;
}
return result;
}
}
public class NFSTO
{
public Uri uri;
public string _role;
public string UncPath
{
get
{
string uncPath = null;
if (uri.Scheme.Equals("cifs"))
{
uncPath = @"\\" + uri.Host + uri.LocalPath;
}
return uncPath;
}
}
public string User
{
get
{
var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
return System.Web.HttpUtility.UrlDecode(queryDictionary["user"]);
}
}
public string Password
{
get
{
var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
return System.Web.HttpUtility.UrlDecode(queryDictionary["password"]);
}
}
public string Domain
{
get
{
var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
if (queryDictionary["domain"] != null)
{
return System.Web.HttpUtility.UrlDecode(queryDictionary["domain"]);
}
else return uri.Host;
}
}
public static NFSTO ParseJson(dynamic json)
{
NFSTO result = null;
dynamic nfsTOJson = json[CloudStackTypes.NFSTO];
if (nfsTOJson != null)
{
result = new NFSTO()
{
_role = (string)nfsTOJson._role,
};
// Delete security credentials in original command. Prevents logger from spilling the beans, as it were.
String uriStr = (String)nfsTOJson._url;
result.uri = new Uri(uriStr);
}
return result;
}
}
enum VolumeType
{
UNKNOWN,
ROOT,
SWAP,
DATADISK,
ISO
};
public enum StoragePoolType
{
/// <summary>
/// local directory
/// </summary>
Filesystem,
/// <summary>
/// NFS or CIFS
/// </summary>
NetworkFilesystem,
/// <summary>
/// shared LUN, with a clusterfs overlay
/// </summary>
IscsiLUN,
/// <summary>
/// for e.g., ZFS Comstar
/// </summary>
Iscsi,
/// <summary>
/// for iso image
/// </summary>
ISO,
/// <summary>
/// XenServer local LVM SR
/// </summary>
LVM,
/// <summary>
///
/// </summary>
CLVM,
/// <summary>
///
/// </summary>
RBD,
/// <summary>
///
/// </summary>
SharedMountPoint,
/// <summary>
/// VMware VMFS storage
/// </summary>
VMFS,
/// <summary>
/// for XenServer, Storage Pool is set up by customers.
/// </summary>
PreSetup,
/// <summary>
/// XenServer local EXT SR
/// </summary>
EXT,
/// <summary>
///
/// </summary>
OCFS2
}
public enum StorageResourceType
{
STORAGE_POOL, STORAGE_HOST, SECONDARY_STORAGE, LOCAL_SECONDARY_STORAGE
}
public struct VolumeInfo
{
public long id;
public string type;
public string storagePoolType;
public string storagePoolUuid;
public string name;
public string mountPoint;
public string path;
long size;
string chainInfo;
public VolumeInfo(long id, string type, string poolType, String poolUuid, String name, String mountPoint, String path, long size, String chainInfo)
{
this.id = id;
this.name = name;
this.path = path;
this.size = size;
this.type = type;
this.storagePoolType = poolType;
this.storagePoolUuid = poolUuid;
this.mountPoint = mountPoint;
this.chainInfo = chainInfo;
}
}
public struct StoragePoolInfo
{
[JsonProperty("uuid")]
public String uuid;
[JsonProperty("host")]
String host;
[JsonProperty("localPath")]
String localPath;
[JsonProperty("hostPath")]
String hostPath;
[JsonProperty("poolType")]
string poolType;
[JsonProperty("capacityBytes")]
long capacityBytes;
// Management server copies this field to the 'used_byptes' in the database table 'storage_pool'.
[JsonProperty("availableBytes")]
long availableBytes;
[JsonProperty("details")]
Dictionary<String, String> details;
public StoragePoolInfo(String uuid, String host, String hostPath,
String localPath, string poolType, long capacityBytes,
long availableBytes)
{
this.uuid = uuid;
this.host = host;
this.localPath = localPath;
this.hostPath = hostPath;
this.poolType = poolType;
this.capacityBytes = capacityBytes;
this.availableBytes = availableBytes;
details = null;
}
public StoragePoolInfo(String uuid, String host, String hostPath,
String localPath, string poolType, long capacityBytes,
long availableBytes, Dictionary<String, String> details)
: this(uuid, host, hostPath, localPath, poolType, capacityBytes, availableBytes)
{
this.details = details;
}
}
public class VmStatsEntry
{
[JsonProperty("cpuUtilization")]
public double cpuUtilization;
[JsonProperty("networkReadKBs")]
public double networkReadKBs;
[JsonProperty("networkWriteKBs")]
public double networkWriteKBs;
[JsonProperty("numCPUs")]
public int numCPUs;
[JsonProperty("entityType")]
public String entityType;
}
/// <summary>
/// Fully qualified named for a number of types used in CloudStack. Used to specify the intended type for JSON serialised objects.
/// </summary>
public class CloudStackTypes
{
public const string Answer = "com.cloud.agent.api.Answer";
public const string AttachIsoCommand = "com.cloud.agent.api.AttachIsoCommand";
public const string AttachVolumeAnswer = "com.cloud.agent.api.AttachVolumeAnswer";
public const string AttachVolumeCommand = "com.cloud.agent.api.AttachVolumeCommand";
public const string AnsBackupSnapshotAnswerwer = "com.cloud.agent.api.BackupSnapshotAnswer";
public const string BackupSnapshotCommand = "com.cloud.agent.api.BackupSnapshotCommand";
public const string BumpUpPriorityCommand = "com.cloud.agent.api.BumpUpPriorityCommand";
public const string CheckHealthAnswer = "com.cloud.agent.api.CheckHealthAnswer";
public const string CheckHealthCommand = "com.cloud.agent.api.CheckHealthCommand";
public const string CheckNetworkAnswer = "com.cloud.agent.api.CheckNetworkAnswer";
public const string CheckNetworkCommand = "com.cloud.agent.api.CheckNetworkCommand";
public const string CheckOnHostAnswer = "com.cloud.agent.api.CheckOnHostAnswer";
public const string CheckOnHostCommand = "com.cloud.agent.api.CheckOnHostCommand";
public const string CheckRouterAnswer = "com.cloud.agent.api.CheckRouterAnswer";
public const string CheckRouterCommand = "com.cloud.agent.api.CheckRouterCommand";
public const string CheckS2SVpnConnectionsAnswer = "com.cloud.agent.api.CheckS2SVpnConnectionsAnswer";
public const string CheckS2SVpnConnectionsCommand = "com.cloud.agent.api.CheckS2SVpnConnectionsCommand";
public const string CheckVirtualMachineAnswer = "com.cloud.agent.api.CheckVirtualMachineAnswer";
public const string CheckVirtualMachineCommand = "com.cloud.agent.api.CheckVirtualMachineCommand";
public const string CleanupNetworkRulesCmd = "com.cloud.agent.api.CleanupNetworkRulesCmd";
public const string ClusterSyncAnswer = "com.cloud.agent.api.ClusterSyncAnswer";
public const string ClusterSyncCommand = "com.cloud.agent.api.ClusterSyncCommand";
public const string Command = "com.cloud.agent.api.Command";
public const string CreatePrivateTemplateFromSnapshotCommand = "com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand";
public const string CreatePrivateTemplateFromVolumeCommand = "com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand";
public const string CreateStoragePoolCommand = "com.cloud.agent.api.CreateStoragePoolCommand";
public const string CreateVMSnapshotAnswer = "com.cloud.agent.api.CreateVMSnapshotAnswer";
public const string CreateVMSnapshotCommand = "com.cloud.agent.api.CreateVMSnapshotCommand";
public const string CreateVolumeFromSnapshotAnswer = "com.cloud.agent.api.CreateVolumeFromSnapshotAnswer";
public const string CreateVolumeFromSnapshotCommand = "com.cloud.agent.api.CreateVolumeFromSnapshotCommand";
public const string DeleteStoragePoolCommand = "com.cloud.agent.api.DeleteStoragePoolCommand";
public const string DeleteVMSnapshotAnswer = "com.cloud.agent.api.DeleteVMSnapshotAnswer";
public const string DeleteVMSnapshotCommand = "com.cloud.agent.api.DeleteVMSnapshotCommand";
public const string GetDomRVersionAnswer = "com.cloud.agent.api.GetDomRVersionAnswer";
public const string GetDomRVersionCmd = "com.cloud.agent.api.GetDomRVersionCmd";
public const string GetHostStatsAnswer = "com.cloud.agent.api.GetHostStatsAnswer";
public const string GetHostStatsCommand = "com.cloud.agent.api.GetHostStatsCommand";
public const string GetStorageStatsAnswer = "com.cloud.agent.api.GetStorageStatsAnswer";
public const string GetStorageStatsCommand = "com.cloud.agent.api.GetStorageStatsCommand";
public const string GetVmDiskStatsAnswer = "com.cloud.agent.api.GetVmDiskStatsAnswer";
public const string GetVmDiskStatsCommand = "com.cloud.agent.api.GetVmDiskStatsCommand";
public const string GetVmStatsAnswer = "com.cloud.agent.api.GetVmStatsAnswer";
public const string GetVmStatsCommand = "com.cloud.agent.api.GetVmStatsCommand";
public const string GetVncPortAnswer = "com.cloud.agent.api.GetVncPortAnswer";
public const string GetVncPortCommand = "com.cloud.agent.api.GetVncPortCommand";
public const string HostStatsEntry = "com.cloud.agent.api.HostStatsEntry";
public const string MaintainAnswer = "com.cloud.agent.api.MaintainAnswer";
public const string MaintainCommand = "com.cloud.agent.api.MaintainCommand";
public const string ManageSnapshotAnswer = "com.cloud.agent.api.ManageSnapshotAnswer";
public const string ManageSnapshotCommand = "com.cloud.agent.api.ManageSnapshotCommand";
public const string MigrateAnswer = "com.cloud.agent.api.MigrateAnswer";
public const string MigrateCommand = "com.cloud.agent.api.MigrateCommand";
public const string ModifySshKeysCommand = "com.cloud.agent.api.ModifySshKeysCommand";
public const string ModifyStoragePoolAnswer = "com.cloud.agent.api.ModifyStoragePoolAnswer";
public const string ModifyStoragePoolCommand = "com.cloud.agent.api.ModifyStoragePoolCommand";
public const string NetworkRulesSystemVmCommand = "com.cloud.agent.api.NetworkRulesSystemVmCommand";
public const string NetworkRulesVmSecondaryIpCommand = "com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand";
public const string PingCommand = "com.cloud.agent.api.PingCommand";
public const string PingRoutingCommand = "com.cloud.agent.api.PingRoutingCommand";
public const string PingRoutingWithNwGroupsCommand = "com.cloud.agent.api.PingRoutingWithNwGroupsCommand";
public const string PingRoutingWithOvsCommand = "com.cloud.agent.api.PingRoutingWithOvsCommand";
public const string PingTestCommand = "com.cloud.agent.api.PingTestCommand";
public const string PlugNicAnswer = "com.cloud.agent.api.PlugNicAnswer";
public const string PlugNicCommand = "com.cloud.agent.api.PlugNicCommand";
public const string PoolEjectCommand = "com.cloud.agent.api.PoolEjectCommand";
public const string PrepareForMigrationAnswer = "com.cloud.agent.api.PrepareForMigrationAnswer";
public const string PrepareForMigrationCommand = "com.cloud.agent.api.PrepareForMigrationCommand";
public const string PvlanSetupCommand = "com.cloud.agent.api.PvlanSetupCommand";
public const string ReadyAnswer = "com.cloud.agent.api.ReadyAnswer";
public const string ReadyCommand = "com.cloud.agent.api.ReadyCommand";
public const string RebootAnswer = "com.cloud.agent.api.RebootAnswer";
public const string RebootCommand = "com.cloud.agent.api.RebootCommand";
public const string RebootRouterCommand = "com.cloud.agent.api.RebootRouterCommand";
public const string RevertToVMSnapshotAnswer = "com.cloud.agent.api.RevertToVMSnapshotAnswer";
public const string RevertToVMSnapshotCommand = "com.cloud.agent.api.RevertToVMSnapshotCommand";
public const string ScaleVmAnswer = "com.cloud.agent.api.ScaleVmAnswer";
public const string ScaleVmCommand = "com.cloud.agent.api.ScaleVmCommand";
public const string SecurityGroupRuleAnswer = "com.cloud.agent.api.SecurityGroupRuleAnswer";
public const string SecurityGroupRulesCmd = "com.cloud.agent.api.SecurityGroupRulesCmd";
public const string SetupAnswer = "com.cloud.agent.api.SetupAnswer";
public const string SetupCommand = "com.cloud.agent.api.SetupCommand";
public const string SetupGuestNetworkAnswer = "com.cloud.agent.api.SetupGuestNetworkAnswer";
public const string SetupGuestNetworkCommand = "com.cloud.agent.api.SetupGuestNetworkCommand";
public const string StartAnswer = "com.cloud.agent.api.StartAnswer";
public const string StartCommand = "com.cloud.agent.api.StartCommand";
public const string StartupCommand = "com.cloud.agent.api.StartupCommand";
public const string StartupRoutingCommand = "com.cloud.agent.api.StartupRoutingCommand";
public const string StartupStorageCommand = "com.cloud.agent.api.StartupStorageCommand";
public const string StopAnswer = "com.cloud.agent.api.StopAnswer";
public const string StopCommand = "com.cloud.agent.api.StopCommand";
public const string StoragePoolInfo = "com.cloud.agent.api.StoragePoolInfo";
public const string UnPlugNicAnswer = "com.cloud.agent.api.UnPlugNicAnswer";
public const string UnPlugNicCommand = "com.cloud.agent.api.UnPlugNicCommand";
public const string UpdateHostPasswordCommand = "com.cloud.agent.api.UpdateHostPasswordCommand";
public const string UpgradeSnapshotCommand = "com.cloud.agent.api.UpgradeSnapshotCommand";
public const string VmDiskStatsEntry = "com.cloud.agent.api.VmDiskStatsEntry";
public const string VmStatsEntry = "com.cloud.agent.api.VmStatsEntry";
public const string CheckSshAnswer = "com.cloud.agent.api.check.CheckSshAnswer";
public const string CheckSshCommand = "com.cloud.agent.api.check.CheckSshCommand";
public const string CheckConsoleProxyLoadCommand = "com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand";
public const string ConsoleProxyLoadAnswer = "com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer";
public const string WatchConsoleProxyLoadCommand = "com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand";
public const string CreateIpAliasCommand = "com.cloud.agent.api.routing.CreateIpAliasCommand";
public const string DeleteIpAliasCommand = "com.cloud.agent.api.routing.DeleteIpAliasCommand";
public const string DhcpEntryCommand = "com.cloud.agent.api.routing.DhcpEntryCommand";
public const string DnsMasqConfigCommand = "com.cloud.agent.api.routing.DnsMasqConfigCommand";
public const string IpAliasTO = "com.cloud.agent.api.routing.IpAliasTO";
public const string IpAssocAnswer = "com.cloud.agent.api.routing.IpAssocAnswer";
public const string IpAssocCommand = "com.cloud.agent.api.routing.IpAssocCommand";
public const string IpAssocVpcCommand = "com.cloud.agent.api.routing.IpAssocVpcCommand";
public const string LoadBalancerConfigCommand = "com.cloud.agent.api.routing.LoadBalancerConfigCommand";
public const string NetworkElementCommand = "com.cloud.agent.api.routing.NetworkElementCommand";
public const string RemoteAccessVpnCfgCommand = "com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand";
public const string SavePasswordCommand = "com.cloud.agent.api.routing.SavePasswordCommand";
public const string SetFirewallRulesAnswer = "com.cloud.agent.api.routing.SetFirewallRulesAnswer";
public const string SetFirewallRulesCommand = "com.cloud.agent.api.routing.SetFirewallRulesCommand";
public const string SetNetworkACLAnswer = "com.cloud.agent.api.routing.SetNetworkACLAnswer";
public const string SetNetworkACLCommand = "com.cloud.agent.api.routing.SetNetworkACLCommand";
public const string SetPortForwardingRulesAnswer = "com.cloud.agent.api.routing.SetPortForwardingRulesAnswer";
public const string SetPortForwardingRulesCommand = "com.cloud.agent.api.routing.SetPortForwardingRulesCommand";
public const string SetPortForwardingRulesVpcCommand = "com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand";
public const string SetSourceNatAnswer = "com.cloud.agent.api.routing.SetSourceNatAnswer";
public const string SetSourceNatCommand = "com.cloud.agent.api.routing.SetSourceNatCommand";
public const string SetStaticNatRulesAnswer = "com.cloud.agent.api.routing.SetStaticNatRulesAnswer";
public const string SetStaticNatRulesCommand = "com.cloud.agent.api.routing.SetStaticNatRulesCommand";
public const string SetStaticRouteAnswer = "com.cloud.agent.api.routing.SetStaticRouteAnswer";
public const string SetStaticRouteCommand = "com.cloud.agent.api.routing.SetStaticRouteCommand";
public const string Site2SiteVpnCfgCommand = "com.cloud.agent.api.routing.Site2SiteVpnCfgCommand";
public const string VmDataCommand = "com.cloud.agent.api.routing.VmDataCommand";
public const string VpnUsersCfgCommand = "com.cloud.agent.api.routing.VpnUsersCfgCommand";
public const string CopyVolumeAnswer = "com.cloud.agent.api.storage.CopyVolumeAnswer";
public const string CopyVolumeCommand = "com.cloud.agent.api.storage.CopyVolumeCommand";
public const string CreateAnswer = "com.cloud.agent.api.storage.CreateAnswer";
public const string CreateCommand = "com.cloud.agent.api.storage.CreateCommand";
public const string CreatePrivateTemplateAnswer = "com.cloud.agent.api.storage.CreatePrivateTemplateAnswer";
public const string DestroyCommand = "com.cloud.agent.api.storage.DestroyCommand";
public const string PrimaryStorageDownloadAnswer = "com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer";
public const string PrimaryStorageDownloadCommand = "com.cloud.agent.api.storage.PrimaryStorageDownloadCommand";
public const string ResizeVolumeAnswer = "com.cloud.agent.api.storage.ResizeVolumeAnswer";
public const string ResizeVolumeCommand = "com.cloud.agent.api.storage.ResizeVolumeCommand";
public const string FirewallRuleTO = "com.cloud.agent.api.to.FirewallRuleTO";
public const string IpAddressTO = "com.cloud.agent.api.to.IpAddressTO";
public const string NicTO = "com.cloud.agent.api.to.NicTO";
public const string PortForwardingRuleTO = "com.cloud.agent.api.to.PortForwardingRuleTO";
public const string S3TO = "com.cloud.agent.api.to.S3TO";
public const string NFSTO = "com.cloud.agent.api.to.NfsTO";
public const string StaticNatRuleTO = "com.cloud.agent.api.to.StaticNatRuleTO";
public const string StorageFilerTO = "com.cloud.agent.api.to.StorageFilerTO";
public const string SwiftTO = "com.cloud.agent.api.to.SwiftTO";
public const string VirtualMachineTO = "com.cloud.agent.api.to.VirtualMachineTO";
public const string VolumeTO = "com.cloud.agent.api.to.VolumeTO";
public const string InternalErrorException = "com.cloud.exception.InternalErrorException";
public const string HostType = "com.cloud.host.Host.Type";
public const string HypervisorType = "com.cloud.hypervisor.Hypervisor.HypervisorType";
public const string DnsMasqConfigurator = "com.cloud.network.DnsMasqConfigurator";
public const string HAProxyConfigurator = "com.cloud.network.HAProxyConfigurator";
public const string LoadBalancerConfigurator = "com.cloud.network.LoadBalancerConfigurator";
public const string Networks = "com.cloud.network.Networks";
public const string BroadcastDomainType = "com.cloud.network.Networks.BroadcastDomainType";
public const string IsolationType = "com.cloud.network.Networks.IsolationType";
public const string TrafficType = "com.cloud.network.Networks.TrafficType";
public const string PhysicalNetworkSetupInfo = "com.cloud.network.PhysicalNetworkSetupInfo";
public const string OvsCreateGreTunnelAnswer = "com.cloud.network.ovs.OvsCreateGreTunnelAnswer";
public const string OvsCreateGreTunnelCommand = "com.cloud.network.ovs.OvsCreateGreTunnelCommand";
public const string OvsCreateTunnelAnswer = "com.cloud.network.ovs.OvsCreateTunnelAnswer";
public const string OvsCreateTunnelCommand = "com.cloud.network.ovs.OvsCreateTunnelCommand";
public const string OvsDeleteFlowCommand = "com.cloud.network.ovs.OvsDeleteFlowCommand";
public const string OvsDestroyBridgeCommand = "com.cloud.network.ovs.OvsDestroyBridgeCommand";
public const string OvsDestroyTunnelCommand = "com.cloud.network.ovs.OvsDestroyTunnelCommand";
public const string OvsFetchInterfaceAnswer = "com.cloud.network.ovs.OvsFetchInterfaceAnswer";
public const string OvsFetchInterfaceCommand = "com.cloud.network.ovs.OvsFetchInterfaceCommand";
public const string OvsSetTagAndFlowAnswer = "com.cloud.network.ovs.OvsSetTagAndFlowAnswer";
public const string OvsSetTagAndFlowCommand = "com.cloud.network.ovs.OvsSetTagAndFlowCommand";
public const string OvsSetupBridgeCommand = "com.cloud.network.ovs.OvsSetupBridgeCommand";
public const string FirewallRule = "com.cloud.network.rules.FirewallRule";
public const string ServerResource = "com.cloud.resource.ServerResource";
public const string HypervisorResource = "com.cloud.resource.hypervisor.HypervisorResource";
public const string Storage = "com.cloud.storage.Storage";
public const string ImageFormat = "com.cloud.storage.Storage.ImageFormat";
public const string StoragePoolType = "com.cloud.storage.Storage.StoragePoolType";
public const string Volume = "com.cloud.storage.Volume";
public const string VolumeVO = "com.cloud.storage.VolumeVO";
public const string StorageSubsystemCommandHandler = "com.cloud.storage.resource.StorageSubsystemCommandHandler";
public const string StorageSubsystemCommandHandlerBase = "com.cloud.storage.resource.StorageSubsystemCommandHandlerBase";
public const string TemplateProp = "com.cloud.storage.template.TemplateProp";
public const string BootloaderType = "com.cloud.template.VirtualMachineTemplate.BootloaderType";
public const string VolumeObjectTO = "org.apache.cloudstack.storage.to.VolumeObjectTO";
public const string TemplateObjectTO = "org.apache.cloudstack.storage.to.TemplateObjectTO";
public const string PrimaryDataStoreTO = "org.apache.cloudstack.storage.to.PrimaryDataStoreTO";
public const string AttachAnswer = "org.apache.cloudstack.storage.command.AttachAnswer";
public const string AttachCommand = "org.apache.cloudstack.storage.command.AttachCommand";
public const string AttachPrimaryDataStoreAnswer = "org.apache.cloudstack.storage.command.AttachPrimaryDataStoreAnswer";
public const string AttachPrimaryDataStoreCmd = "org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd";
public const string CopyCmdAnswer = "org.apache.cloudstack.storage.command.CopyCmdAnswer";
public const string CopyCommand = "org.apache.cloudstack.storage.command.CopyCommand";
public const string CreateObjectAnswer = "org.apache.cloudstack.storage.command.CreateObjectAnswer";
public const string CreateObjectCommand = "org.apache.cloudstack.storage.command.CreateObjectCommand";
public const string DeleteCommand = "org.apache.cloudstack.storage.command.DeleteCommand";
public const string DettachAnswer = "org.apache.cloudstack.storage.command.DettachAnswer";
public const string DettachCommand = "org.apache.cloudstack.storage.command.DettachCommand";
}
}

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C963DFFF-65BA-4E71-ADA5-526A4DA4E0B2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>HypervResource</RootNamespace>
<AssemblyName>HypervResource</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'NoUnitTestsDebug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\NoUnitTestsDebug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'NoUnitTests|AnyCPU'">
<OutputPath>bin\NoUnitTests\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="AWSSDK">
<HintPath>..\packages\AWSSDK.1.5.23.0\lib\AWSSDK.dll</HintPath>
</Reference>
<Reference Include="Ionic.Zip">
<HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.0\lib\net40-full\log4net.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Management" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CloudStackTypes.cs" />
<Compile Include="IWmiCallsV2.cs" />
<Compile Include="WmiCallsV2.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="HypervResourceController.cs" />
<Compile Include="Utils.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WmiWrappers\WmiWrappers.csproj">
<Project>{db824727-bdc3-437c-a364-7a811d8a160f}</Project>
<Name>WmiWrappers</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,67 @@
// 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.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CloudStack.Plugin.WmiWrappers.ROOT.VIRTUALIZATION.V2;
using System.Management;
namespace HypervResource
{
public interface IWmiCallsV2
{
System.Management.ManagementPath AddDiskDriveToVm(ComputerSystem vm, string vhdfile, string cntrllerAddr, string driveResourceType);
ComputerSystem AddUserData(ComputerSystem vm, string userData);
void AttachIso(string displayName, string iso);
void CreateDynamicVirtualHardDisk(ulong MaxInternalSize, string Path);
SyntheticEthernetPortSettingData CreateNICforVm(ComputerSystem vm, string mac);
ComputerSystem CreateVM(string name, long memory_mb, int vcpus);
void DeleteHostKvpItem(ComputerSystem vm, string key);
void DeleteSwitchPort(string elementName);
ComputerSystem DeployVirtualMachine(dynamic jsonObj, string systemVmIso);
void DestroyVm(dynamic jsonObj);
void DestroyVm(string displayName);
void DetachDisk(string displayName, string diskFileName);
ComputerSystem GetComputerSystem(string displayName);
string GetDefaultDataRoot();
string GetDefaultVirtualDiskFolder();
ResourceAllocationSettingData GetDvdDriveSettings(VirtualSystemSettingData vmSettings);
EthernetPortAllocationSettingData[] GetEthernetConnections(ComputerSystem vm);
SyntheticEthernetPortSettingData[] GetEthernetPortSettings(ComputerSystem vm);
ResourceAllocationSettingData GetIDEControllerSettings(VirtualSystemSettingData vmSettings, string cntrllerAddr);
ImageManagementService GetImageManagementService();
KvpExchangeComponentSettingData GetKvpSettings(VirtualSystemSettingData vmSettings);
void GetMemoryResources(out ulong physicalRamKBs, out ulong freeMemoryKBs);
MemorySettingData GetMemSettings(VirtualSystemSettingData vmSettings);
void GetProcessorResources(out uint cores, out uint mhz);
void GetProcessorUsageInfo(out double cpuUtilization);
ProcessorSettingData GetProcSettings(VirtualSystemSettingData vmSettings);
ResourceAllocationSettingData.ResourceAllocationSettingDataCollection GetResourceAllocationSettings(VirtualSystemSettingData vmSettings);
void GetSummaryInfo(System.Collections.Generic.Dictionary<string, VmStatsEntry> vmProcessorInfo, System.Collections.Generic.List<System.Management.ManagementPath> vmsToInspect);
SyntheticEthernetPortSettingData GetSyntheticEthernetPortSettings(EthernetSwitchPort port);
VirtualSystemManagementService GetVirtualisationSystemManagementService();
VirtualEthernetSwitchManagementService GetVirtualSwitchManagementService();
EthernetSwitchPortVlanSettingData GetVlanSettings(EthernetPortAllocationSettingData ethernetConnection);
System.Collections.Generic.List<string> GetVmElementNames();
VirtualSystemSettingData GetVmSettings(ComputerSystem vm);
void patchSystemVmIso(string vmName, string systemVmIso);
void SetState(ComputerSystem vm, ushort requiredState);
}
}

View File

@ -0,0 +1,53 @@
// 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.
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("HypervResource")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HypervResource")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f1eb80c1-36fb-438c-a70d-0de5d5e295fb")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,131 @@
// 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.
using log4net;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
namespace HypervResource
{
public class Utils
{
private static ILog s_logger = LogManager.GetLogger(typeof(Utils));
/// <summary>
/// Associate CloudStack object's content with a fully qualified type name.
/// </summary>
/// <param name="objType">Fully qualified type name, e.g. "org.apache.cloudstack.storage.to.TemplateObjectTO"</param>
/// <param name="objValue">Object's data, can be an anonymous object, e.g. </param>
/// <returns></returns>
public static JObject CreateCloudStackObject(string objType, object objValue)
{
JToken objContent = JToken.FromObject(objValue);
JProperty objTypeValuePairing = new JProperty(objType, objContent);
return new JObject(objTypeValuePairing);
}
/// <summary>
/// Copy file on network share to local volume.
/// </summary>
/// <remarks>
/// Access to the network share is acheived by logging into the domain corresponding to the user credentials provided.
/// Windows impersonation does not suffice, because impersonation is limited to domains with an established trust relationship.
/// We have had to import Win32 API calls to allow login. There are a number of examples online. We follow the
/// one at http://stackoverflow.com/a/2541569/939250 </remarks>
/// <param name="filePathRelativeToShare"></param>
/// <param name="cifsShareDetails"></param>
/// <param name="destFile"></param>
public static void DownloadCifsFileToLocalFile(string filePathRelativeToShare, NFSTO cifsShareDetails, string destFile)
{
try
{
IntPtr token = IntPtr.Zero;
bool isSuccess = LogonUser(cifsShareDetails.User, cifsShareDetails.Domain, cifsShareDetails.Password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref token);
using (WindowsImpersonationContext remoteIdentity = new WindowsIdentity(token).Impersonate())
{
String dest = "";
if (filePathRelativeToShare.EndsWith(".iso") || filePathRelativeToShare.EndsWith(".vhd") || filePathRelativeToShare.EndsWith(".vhdx"))
{
dest = Path.Combine(cifsShareDetails.UncPath, filePathRelativeToShare);
dest = dest.Replace('/', Path.DirectorySeparatorChar);
}
// if the filePathRelativeToShare string don't have filename and only a dir point then find the vhd files in that folder and use
// In the clean setup, first copy command wont be having the filename it contains onlyu dir path.
// we need to scan the folder point and then copy the file to destination.
else if (!filePathRelativeToShare.EndsWith(".vhd") || !filePathRelativeToShare.EndsWith(".vhdx"))
{
// scan the folder and get the vhd filename.
String uncPath = Path.Combine(cifsShareDetails.UncPath, Path.Combine(filePathRelativeToShare.Split('/')));
//uncPath = uncPath.Replace("/", "\\");
DirectoryInfo dir = new DirectoryInfo(uncPath);
FileInfo[] vhdFiles = dir.GetFiles("*.vhd*");
if (vhdFiles.Length > 0)
{
FileInfo file = vhdFiles[0];
dest = file.FullName;
}
}
s_logger.Info(CloudStackTypes.CopyCommand + ": copy " + Path.Combine(cifsShareDetails.UncPath, filePathRelativeToShare) + " to " + destFile);
File.Copy(dest, destFile, true);
remoteIdentity.Undo();
}
}
catch (UnauthorizedAccessException ex)
{
string errMsg = "Invalid user or password for the share " + cifsShareDetails.UncPath;
s_logger.Error(errMsg);
throw new ArgumentException(errMsg, ex);
}
}
// from http://stackoverflow.com/a/2541569/939250
#region imports
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr existingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr duplicateTokenHandle);
#endregion
#region logon consts
// logon types
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
// logon providers
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT35 = 1;
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AWSSDK" version="1.5.23.0" targetFramework="net45" />
<package id="DotNetZip" version="1.9.1.8" targetFramework="net45" />
<package id="log4net" version="2.0.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
<package id="NSubstitute" version="1.6.1.0" targetFramework="net45" />
<package id="xunit" version="1.9.2" targetFramework="net45" />
</packages>

View File

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Note: Add entries to the App.config file for configuration settings
that apply only to the Test project.
-->
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="CloudStack.Plugin.AgentShell.AgentSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="CloudStack.Plugin.AgentShell.AgentSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<appSettings>
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
<connectionStrings>
</connectionStrings>
<applicationSettings>
<CloudStack.Plugin.AgentShell.AgentSettings>
<setting name="cpus" serializeAs="String">
<value>8</value>
</setting>
<setting name="private_ip_address" serializeAs="String">
<value>10.1.1.1</value>
</setting>
<setting name="type" serializeAs="String">
<value>Routing</value>
</setting>
<setting name="local_storage_uuid" serializeAs="String">
<value>5fe2bad3-d785-394e-9949-89786b8a63d2</value>
</setting>
<setting name="capabilities" serializeAs="String">
<value>hvm</value>
</setting>
<setting name="Settingcpuspeed" serializeAs="String">
<value>2130</value>
</setting>
<setting name="port" serializeAs="String">
<value>8250</value>
</setting>
<setting name="memory" serializeAs="String">
<value>34359738368</value>
</setting>
<setting name="host" serializeAs="String">
<value>camldonall01.citrite.net</value>
</setting>
<setting name="pod" serializeAs="String">
<value>1</value>
</setting>
<setting name="gateway_ip_address" serializeAs="String">
<value>10.70.176.1</value>
</setting>
<setting name="cluster" serializeAs="String">
<value>2</value>
</setting>
<setting name="zone" serializeAs="String">
<value>1</value>
</setting>
<setting name="local_storage_path" serializeAs="String">
<value>E:\Disks\Disks</value>
</setting>
<setting name="workers" serializeAs="String">
<value>5</value>
</setting>
<setting name="private_ip_netmask" serializeAs="String">
<value>255.255.240.0</value>
</setting>
<setting name="RootDeviceReservedSpaceBytes" serializeAs="String">
<value>4294967296</value>
</setting>
<setting name="hyperv_plugin_root" serializeAs="String">
<value>..\..\..\..\..\</value>
</setting>
<setting name="RootDeviceName" serializeAs="String">
<value>e:\</value>
</setting>
<setting name="dom0MinMemory" serializeAs="String">
<value>2048</value>
</setting>
<setting name="private_mac_address" serializeAs="String">
<value>101F742C6B88</value>
</setting>
</CloudStack.Plugin.AgentShell.AgentSettings>
</applicationSettings>
<userSettings>
<CloudStack.Plugin.AgentShell.AgentSettings>
<setting name="local_secondary_storage_path" serializeAs="String">
<value>c:\Secondary</value>
</setting>
<setting name="local_storage_path" serializeAs="String">
<value>E:\Disks\Disks</value>
</setting>
<setting name="testLocalStoreUUID" serializeAs="String">
<value>5fe2bad3-d785-394e-9949-89786b8a63d2</value>
</setting>
<setting name="testLocalStorePath" serializeAs="String">
<value>.\var\test\storagepool</value>
</setting>
<setting name="testS3Bucket" serializeAs="String">
<value>cshv3eu</value>
</setting>
<setting name="testS3Endpoint" serializeAs="String">
<value>s3.amazonaws.com</value>
</setting>
<setting name="testS3AccessKey" serializeAs="String">
<value>testS3AccessKey</value>
</setting>
<setting name="testS3SecretKey" serializeAs="String">
<value>testS3SecretKey</value>
</setting>
<setting name="testS3TemplateName" serializeAs="String">
<value>206-2-73592258-559a-3b38-8f66-b667aab143eb</value>
</setting>
<setting name="testCifsTemplateName" serializeAs="String">
<value>206-2-73592258-559a-3b38-8f66-b667aab143eb</value>
</setting>
<setting name="testCifsUrl" serializeAs="String">
<value>cifs://10.1.1.1/secondary?user\u003dadministrator\u0026password\u003d1pass%40word1</value>
</setting>
<setting name="testCifsPath" serializeAs="String">
<value>template/tmpl/2/201/6dda6631-4daa-3150-a49a-d5a4b0a4c4b6.vhd</value>
</setting>
</CloudStack.Plugin.AgentShell.AgentSettings>
</userSettings>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
</providers>
</roleManager>
</system.web>
</configuration>

View File

@ -0,0 +1,350 @@
// 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.
using System;
using CloudStack.Plugin.WmiWrappers.ROOT.VIRTUALIZATION.V2;
using System.Management;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.IO;
using log4net;
using HypervResource;
using CloudStack.Plugin.AgentShell;
using System.Collections.Generic;
using NSubstitute;
using System.Web.Http;
using Xunit;
namespace ServerResource.Tests
{
public class HypervResourceController1Test
{
protected static string testCifsUrl = AgentSettings.Default.testCifsUrl;
protected static string testCifsPath = AgentSettings.Default.testCifsPath;
protected static String testPrimaryDataStoreHost = HypervResourceController.config.StorageIpAddress;
protected static String testS3TemplateName = AgentSettings.Default.testS3TemplateName;
protected static String testCifsTemplateName = AgentSettings.Default.testS3TemplateName;
protected static String testSystemVMTemplateName = AgentSettings.Default.testSystemVMTemplateName;
protected static String testSystemVMTemplateNameNoExt = AgentSettings.Default.testSystemVMTemplateNameNoExt;
protected static String testLocalStoreUUID = "5fe2bad3-d785-394e-9949-89786b8a63d2";
protected static String testLocalStorePath = Path.Combine(AgentSettings.Default.hyperv_plugin_root, "var", "test", "storagepool");
protected static String testSecondaryStoreLocalPath = Path.Combine(AgentSettings.Default.hyperv_plugin_root, "var", "test", "secondary");
// TODO: differentiate between NFS and HTTP template URLs.
protected static String testSampleTemplateUUID = "TestCopiedLocalTemplate.vhdx";
protected static String testSampleTemplateURL = testSampleTemplateUUID;
// test volumes are both a minimal size vhdx. Changing the extension to .vhd makes on corrupt.
protected static String testSampleVolumeWorkingUUID = "TestVolumeLegit.vhdx";
protected static String testSampleVolumeCorruptUUID = "TestVolumeCorrupt.vhd";
protected static String testSampleVolumeTempUUID = "TestVolumeTemp.vhdx";
protected static String testSampleVolumeTempUUIDNoExt = "TestVolumeTemp";
protected static String testSampleVolumeWorkingURIJSON;
protected static String testSampleVolumeCorruptURIJSON;
protected static String testSampleVolumeTempURIJSON;
protected static String testSampleTemplateURLJSON;
protected static String testLocalStorePathJSON;
protected static IWmiCallsV2 wmiCallsV2;
private static ILog s_logger = LogManager.GetLogger(typeof(HypervResourceController1Test));
/// <summary>
/// Test WmiCalls to which incoming HTTP POST requests are dispatched.
///
/// TODO: revise beyond first approximation
/// First approximation is a quick port of the existing Java tests for Hyper-V server resource.
/// A second approximation would use the AgentShell settings files directly.
/// A third approximation would look to invoke ServerResource methods via an HTTP request
/// </summary>
public HypervResourceController1Test()
{
wmiCallsV2 = Substitute.For<IWmiCallsV2>();
//AgentService.ConfigServerResource();
HypervResourceController.config.PrivateMacAddress = AgentSettings.Default.private_mac_address;
HypervResourceController.config.PrivateNetmask = AgentSettings.Default.private_ip_netmask;
HypervResourceController.config.StorageIpAddress = HypervResourceController.config.PrivateIpAddress;
HypervResourceController.config.StorageMacAddress = HypervResourceController.config.PrivateMacAddress;
HypervResourceController.config.StorageNetmask = HypervResourceController.config.PrivateNetmask;
// Used to create existing StoragePool in preparation for the ModifyStoragePool
testLocalStoreUUID = AgentSettings.Default.local_storage_uuid.ToString();
// Make sure secondary store is available.
string fullPath = Path.GetFullPath(testSecondaryStoreLocalPath);
s_logger.Info("Test secondary storage in " + fullPath);
DirectoryInfo testSecondarStoreDir = new DirectoryInfo(fullPath);
if (!testSecondarStoreDir.Exists)
{
try
{
testSecondarStoreDir.Create();
}
catch (System.IO.IOException ex)
{
throw new NotImplementedException("Need to be able to create the folder " + testSecondarStoreDir.FullName + " failed due to " + ex.Message);
}
}
// Convert to secondary storage string to canonical path
testSecondaryStoreLocalPath = testSecondarStoreDir.FullName;
AgentSettings.Default.local_secondary_storage_path = testSecondaryStoreLocalPath;
// Make sure local primary storage is available
DirectoryInfo testPoolDir = new DirectoryInfo(testLocalStorePath);
//Assert.True(testPoolDir.Exists, "To simulate local file system Storage Pool, you need folder at " + testPoolDir.FullName);
// Convert to local primary storage string to canonical path
testLocalStorePath = testPoolDir.FullName;
AgentSettings.Default.local_storage_path = testLocalStorePath;
// Clean up old test files in local storage folder
FileInfo testVolWorks = new FileInfo(Path.Combine(testLocalStorePath, testSampleVolumeWorkingUUID));
// Assert.True(testVolWorks.Exists, "Create a working virtual disk at " + testVolWorks.FullName);
testSampleTemplateURLJSON = JsonConvert.SerializeObject(testSampleTemplateUUID);
s_logger.Info("Created " + testSampleTemplateURLJSON + " in local storage.");
// Capture other JSON encoded paths
testSampleVolumeWorkingURIJSON = Newtonsoft.Json.JsonConvert.SerializeObject(testVolWorks.FullName);
testLocalStorePathJSON = JsonConvert.SerializeObject(testLocalStorePath);
// TODO: may need to initialise the server resource in future.
// s_hypervresource.initialize();
// Verify sample template is in place storage pool
s_logger.Info("setUp complete, sample StoragePool at " + testLocalStorePathJSON
+ " sample template at " + testSampleTemplateURLJSON);
}
private String CreateTestDiskImageFromExistingImage(FileInfo srcFile,
String dstPath,
String dstFileName)
{
var newFullname = Path.Combine(dstPath, dstFileName);
var newFileInfo = new FileInfo(newFullname);
if (!newFileInfo.Exists)
{
newFileInfo = srcFile.CopyTo(newFullname);
}
newFileInfo.Refresh();
Assert.True(newFileInfo.Exists, "Attempted to create " + newFullname + " from " + newFileInfo.FullName);
return JsonConvert.SerializeObject(newFileInfo.FullName);
}
[Fact]
public void TestCreateCommand()
{
DirectoryInfo localStorePath = new DirectoryInfo(testLocalStorePath);
if (!localStorePath.Exists)
{
try
{
localStorePath.Create();
}
catch (System.IO.IOException ex)
{
throw new NotImplementedException("Need to be able to create the folder " + localStorePath.FullName + " failed due to " + ex.Message);
}
}
FileInfo sampleTemplateFile = new FileInfo(Path.Combine(testLocalStorePath, testSampleTemplateUUID));
if (!sampleTemplateFile.Exists)
{
//Create a file to write to.
using (StreamWriter sw = sampleTemplateFile.CreateText())
{
sw.WriteLine("This is fake template file for test");
}
}
var counter = 0;
wmiCallsV2.When(x => x.CreateDynamicVirtualHardDisk(Arg.Any<ulong>(), Arg.Any<String>())).Do(x => counter++);
// TODO: Need sample to update the test.
// Arrange
String createCmd = "{\"volId\":10,\"pool\":{\"id\":201,\"uuid\":\"" + testLocalStoreUUID + "\",\"host\":\"" + HypervResourceController.config.StorageIpAddress + "\"" +
",\"path\":" + testLocalStorePathJSON + ",\"port\":0,\"type\":\"Filesystem\"},\"diskCharacteristics\":{\"size\":0," +
"\"tags\":[],\"type\":\"ROOT\",\"name\":\"ROOT-9\",\"useLocalStorage\":true,\"recreatable\":true,\"diskOfferingId\":11," +
"\"volumeId\":10,\"hyperType\":\"Hyperv\"},\"templateUrl\":" + testSampleTemplateURLJSON + ",\"contextMap\":{},\"wait\":0}";
dynamic jsonCreateCmd = JsonConvert.DeserializeObject(createCmd);
HypervResourceController rsrcServer = new HypervResourceController();
HypervResourceController.wmiCallsV2 = wmiCallsV2;
Assert.True(Directory.Exists(testLocalStorePath), testLocalStorePath + " does not exist ");
string filePath = Path.Combine(testLocalStorePath, (string)JsonConvert.DeserializeObject(testSampleTemplateURLJSON));
Assert.True(File.Exists(filePath), "The template we make volumes from is missing from path " + filePath);
int fileCount = Directory.GetFiles(testLocalStorePath).Length;
s_logger.Debug(" test local store has " + fileCount + "files");
// Act
// Test requires there to be a template at the tempalteUrl, which is its location in the local file system.
dynamic jsonResult = rsrcServer.CreateCommand(jsonCreateCmd);
s_logger.Debug("CreateDynamicVirtualHardDisk method is called " + counter + " times");
//Assert.Equal(counter, 1);
JObject ansAsProperty2 = jsonResult[0];
dynamic ans = ansAsProperty2.GetValue(CloudStackTypes.CreateAnswer);
Assert.NotNull(ans);
Assert.True((bool)ans.result, "Failed to CreateCommand due to " + (string)ans.result);
Assert.Equal(Directory.GetFiles(testLocalStorePath).Length, fileCount + 1);
FileInfo newFile = new FileInfo((string)ans.volume.path);
Assert.True(newFile.Length > 0, "The new file should have a size greater than zero");
newFile.Delete();
sampleTemplateFile.Delete();
}
[Fact]
public void TestDestroyCommand()
{
testSampleVolumeTempURIJSON = "\"storagepool\"";
// Arrange
String destoryCmd = //"{\"volume\":" + getSampleVolumeObjectTO() + "}";
"{\"volume\":{\"name\":\"" + testSampleVolumeTempUUIDNoExt
+ "\",\"storagePoolType\":\"Filesystem\","
+ "\"mountPoint\":"
+ testLocalStorePathJSON
+ ",\"path\":" + testSampleVolumeTempURIJSON
+ ",\"storagePoolUuid\":\"" + testLocalStoreUUID
+ "\","
+ "\"type\":\"ROOT\",\"id\":9,\"size\":0}}";
ImageManagementService imgmgr = new ImageManagementService();
wmiCallsV2.GetImageManagementService().Returns(imgmgr);
HypervResourceController rsrcServer = new HypervResourceController();
HypervResourceController.wmiCallsV2 = wmiCallsV2;
dynamic jsonDestoryCmd = JsonConvert.DeserializeObject(destoryCmd);
// Act
dynamic destoryAns = rsrcServer.DestroyCommand(jsonDestoryCmd);
// Assert
JObject ansAsProperty2 = destoryAns[0];
dynamic ans = ansAsProperty2.GetValue(CloudStackTypes.Answer);
String path = jsonDestoryCmd.volume.path;
Assert.True((bool)ans.result, "DestroyCommand did not succeed " + ans.details);
Assert.True(!File.Exists(path), "Failed to delete file " + path);
}
[Fact]
public void TestStartCommand()
{
ComputerSystem system = new ComputerSystem();
wmiCallsV2.DeployVirtualMachine(Arg.Any<Object>(), Arg.Any<string>()).Returns(system);
// Arrange
HypervResourceController rsrcServer = new HypervResourceController();
HypervResourceController.wmiCallsV2 = wmiCallsV2;
String sample = getSampleStartCommand();
dynamic jsonStartCmd = JsonConvert.DeserializeObject(sample);
// Act
dynamic startAns = rsrcServer.StartCommand(jsonStartCmd);
// Assert
Assert.NotNull(startAns[0][CloudStackTypes.StartAnswer]);
Assert.True((bool)startAns[0][CloudStackTypes.StartAnswer].result, "StartCommand did not succeed " + startAns[0][CloudStackTypes.StartAnswer].details);
Assert.Null((string)startAns[0][CloudStackTypes.StartAnswer].details);
}
[Fact]
public void TestStopCommand()
{
//string vmName = "Test VM";
var counter = 0;
wmiCallsV2.When(x => x.DestroyVm(Arg.Any<Object>())).Do(x => counter++);
// Arrange
HypervResourceController rsrcServer = new HypervResourceController();
HypervResourceController.wmiCallsV2 = wmiCallsV2;
String sampleStop = "{\"isProxy\":false,\"vmName\":\"i-2-17-VM\",\"contextMap\":{},\"wait\":0}";
dynamic jsonStopCmd = JsonConvert.DeserializeObject(sampleStop);
// Act
dynamic stopAns = rsrcServer.StopCommand(jsonStopCmd);
// Assert VM is gone!
Assert.NotNull(stopAns[0][CloudStackTypes.StopAnswer]);
Assert.True((bool)stopAns[0][CloudStackTypes.StopAnswer].result, "StopCommand did not succeed " + stopAns[0][CloudStackTypes.StopAnswer].details);
Assert.Null((string)stopAns[0][CloudStackTypes.StopAnswer].details);
Assert.Equal<int>(counter, 1);
}
public static String getSamplePrimaryDataStoreInfo()
{
String samplePrimaryDataStoreInfo =
"{\"org.apache.cloudstack.storage.to.PrimaryDataStoreTO\":" +
"{\"uuid\":\"" + testLocalStoreUUID + "\"," +
"\"id\":201," +
"\"host\":\"" + testPrimaryDataStoreHost + "\"," +
"\"type\":\"Filesystem\"," + // Not used in PrimaryDataStoreTO
"\"poolType\":\"Filesystem\"," + // Not used in PrimaryDataStoreTO
"\"path\":" + testLocalStorePathJSON + "," +
"\"port\":0}" +
"}";
return samplePrimaryDataStoreInfo;
}
public static String getSampleVolumeObjectTO()
{
String sampleVolumeObjectTO =
"{\"org.apache.cloudstack.storage.to.VolumeObjectTO\":" +
"{\"uuid\":\"19ae8e67-cb2c-4ab4-901e-e0b864272b59\"," +
"\"volumeType\":\"ROOT\"," +
"\"format\":\"VHDX\"," +
"\"dataStore\":" + getSamplePrimaryDataStoreInfo() + "," +
"\"name\":\"" + testSampleVolumeTempUUIDNoExt + "\"," +
"\"size\":52428800," +
"\"volumeId\":10," +
// "\"vmName\":\"i-3-5-VM\"," + // TODO: do we have to fill in the vmName?
"\"accountId\":3,\"id\":10}" +
"}"; // end of destTO
return sampleVolumeObjectTO;
}
public static String getSampleStartCommand()
{
String sample = "{\"vm\":{\"id\":17,\"name\":\"i-2-17-VM\",\"type\":\"User\",\"cpus\":1,\"speed\":500," +
"\"minRam\":536870912,\"maxRam\":536870912,\"arch\":\"x86_64\"," +
"\"os\":\"CentOS 6.0 (64-bit)\",\"bootArgs\":\"\",\"rebootOnCrash\":false," +
"\"enableHA\":false,\"limitCpuUse\":false,\"vncPassword\":\"31f82f29aff646eb\"," +
"\"params\":{},\"uuid\":\"8b030b6a-0243-440a-8cc5-45d08815ca11\"" +
",\"disks\":[" +
"{\"data\":" + getSampleVolumeObjectTO() + ",\"diskSeq\":0,\"type\":\"ROOT\"}," +
"{\"diskSeq\":1,\"type\":\"ISO\"}" +
"]," +
"\"nics\":[" +
"{\"deviceId\":0,\"networkRateMbps\":100,\"defaultNic\":true,\"uuid\":\"99cb4813-23af-428c-a87a-2d1899be4f4b\"," +
"\"ip\":\"10.1.1.67\",\"netmask\":\"255.255.255.0\",\"gateway\":\"10.1.1.1\"," +
"\"mac\":\"02:00:51:2c:00:0e\",\"dns1\":\"4.4.4.4\",\"broadcastType\":\"Vlan\",\"type\":\"Guest\"," +
"\"broadcastUri\":\"vlan://261\",\"isolationUri\":\"vlan://261\",\"isSecurityGroupEnabled\":false}" +
"]},\"contextMap\":{},\"wait\":0}";
return sample;
}
}
}

View File

@ -0,0 +1,52 @@
// 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.
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ServerResource.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ServerResource.Tests")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("727beb1c-6e7c-49b2-8fbd-f03dbe481b08")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Some files were not shown because too many files have changed in this diff Show More