mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
bug 9397 : CreateTemplate - generate MD5 checksum of the template. The code will calculate the checksum after the template has been created in the secondary storage. This code would be executed by ssvm. This would be agnostic of the way the template was created (not hypervisor specific).
This commit is contained in:
parent
029a9e6a8a
commit
d91999533b
42
api/src/com/cloud/agent/api/ComputeChecksumCommand.java
Executable file
42
api/src/com/cloud/agent/api/ComputeChecksumCommand.java
Executable file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.agent.api;
|
||||
|
||||
public class ComputeChecksumCommand extends Command {
|
||||
|
||||
public ComputeChecksumCommand() {
|
||||
super();
|
||||
}
|
||||
|
||||
private String templatePath;
|
||||
|
||||
public ComputeChecksumCommand(String templatePath) {
|
||||
super();
|
||||
this.templatePath = templatePath;
|
||||
}
|
||||
|
||||
public String getTemplatePath() {
|
||||
return templatePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -297,6 +297,10 @@ public class VMTemplateVO implements VirtualMachineTemplate {
|
||||
return checksum;
|
||||
}
|
||||
|
||||
public void setChecksum(String checksum) {
|
||||
this.checksum = checksum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayText() {
|
||||
return displayText;
|
||||
|
||||
@ -18,8 +18,14 @@
|
||||
package com.cloud.storage.resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -34,6 +40,7 @@ import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.CheckHealthAnswer;
|
||||
import com.cloud.agent.api.CheckHealthCommand;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.ComputeChecksumCommand;
|
||||
import com.cloud.agent.api.GetStorageStatsAnswer;
|
||||
import com.cloud.agent.api.GetStorageStatsCommand;
|
||||
import com.cloud.agent.api.PingCommand;
|
||||
@ -138,11 +145,71 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
return execute((SecStorageFirewallCfgCommand)cmd);
|
||||
} else if (cmd instanceof SecStorageSetupCommand){
|
||||
return execute((SecStorageSetupCommand)cmd);
|
||||
} else if (cmd instanceof ComputeChecksumCommand){
|
||||
return execute((ComputeChecksumCommand)cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
private Answer execute(ComputeChecksumCommand cmd) {
|
||||
|
||||
String relativeTemplatePath = cmd.getTemplatePath();
|
||||
String parent = _parent;
|
||||
|
||||
if (relativeTemplatePath.startsWith(File.separator)) {
|
||||
relativeTemplatePath = relativeTemplatePath.substring(1);
|
||||
}
|
||||
|
||||
if (!parent.endsWith(File.separator)) {
|
||||
parent += File.separator;
|
||||
}
|
||||
String absoluteTemplatePath = parent + relativeTemplatePath;
|
||||
MessageDigest digest;
|
||||
String checksum = null;
|
||||
File f = new File(absoluteTemplatePath);
|
||||
InputStream is = null;
|
||||
byte[] buffer = new byte[8192];
|
||||
int read = 0;
|
||||
if(s_logger.isDebugEnabled()){
|
||||
s_logger.debug("parent path " +parent+ " relative template path " +relativeTemplatePath );
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
digest = MessageDigest.getInstance("MD5");
|
||||
is = new FileInputStream(f);
|
||||
while( (read = is.read(buffer)) > 0) {
|
||||
digest.update(buffer, 0, read);
|
||||
}
|
||||
byte[] md5sum = digest.digest();
|
||||
BigInteger bigInt = new BigInteger(1, md5sum);
|
||||
checksum = bigInt.toString(16);
|
||||
if(s_logger.isDebugEnabled()){
|
||||
s_logger.debug("Successfully calculated checksum for file " +absoluteTemplatePath+ " - " +checksum );
|
||||
}
|
||||
|
||||
}catch(IOException e) {
|
||||
String logMsg = "Unable to process file for MD5 - " + absoluteTemplatePath;
|
||||
s_logger.error(logMsg);
|
||||
return new Answer(cmd, false, checksum);
|
||||
}catch (NoSuchAlgorithmException e) {
|
||||
return new Answer(cmd, false, checksum);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
if(s_logger.isDebugEnabled()){
|
||||
s_logger.debug("Could not close the file " +absoluteTemplatePath);
|
||||
}
|
||||
return new Answer(cmd, false, checksum);
|
||||
}
|
||||
}
|
||||
|
||||
return new Answer(cmd, true, checksum);
|
||||
}
|
||||
|
||||
private Answer execute(SecStorageSetupCommand cmd) {
|
||||
if (!_inSystemVM){
|
||||
return new Answer(cmd, true, null);
|
||||
|
||||
@ -1735,6 +1735,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
templateResponse.setZoneId(destZoneId);
|
||||
templateResponse.setZoneName(ApiDBUtils.findZoneById(destZoneId).getName());
|
||||
templateResponse.setSourceTemplateId(template.getSourceTemplateId());
|
||||
templateResponse.setChecksum(template.getChecksum());
|
||||
|
||||
GuestOS os = ApiDBUtils.findGuestOSById(template.getGuestOSId());
|
||||
if (os != null) {
|
||||
@ -1901,6 +1902,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
response.setPublic(template.isPublicTemplate());
|
||||
response.setPasswordEnabled(template.getEnablePassword());
|
||||
response.setCrossZones(template.isCrossZones());
|
||||
response.setChecksum(template.getChecksum());
|
||||
|
||||
VolumeVO volume = null;
|
||||
if (snapshotId != null) {
|
||||
|
||||
@ -37,6 +37,7 @@ import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.AttachIsoCommand;
|
||||
import com.cloud.agent.api.AttachVolumeAnswer;
|
||||
import com.cloud.agent.api.AttachVolumeCommand;
|
||||
import com.cloud.agent.api.ComputeChecksumCommand;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
|
||||
import com.cloud.agent.api.GetVmStatsAnswer;
|
||||
@ -94,6 +95,7 @@ import com.cloud.event.EventTypes;
|
||||
import com.cloud.event.UsageEventVO;
|
||||
import com.cloud.event.dao.EventDao;
|
||||
import com.cloud.event.dao.UsageEventDao;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
@ -1547,7 +1549,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
// Specify RAW format makes it unusable for snapshots.
|
||||
privateTemplate.setFormat(ImageFormat.RAW);
|
||||
}
|
||||
|
||||
String checkSum = getChecksum(secondaryStorageHost.getId(), answer.getPath());
|
||||
privateTemplate.setChecksum(checkSum);
|
||||
_templateDao.update(templateId, privateTemplate);
|
||||
|
||||
// add template zone ref for this template
|
||||
@ -1581,7 +1584,18 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
|
||||
return privateTemplate;
|
||||
}
|
||||
|
||||
private String getChecksum(Long hostId, String templatePath){
|
||||
Answer answer;
|
||||
try {
|
||||
answer = _agentMgr.send(hostId, new ComputeChecksumCommand(templatePath));
|
||||
return answer.getDetails();
|
||||
} catch (AgentUnavailableException e) {
|
||||
s_logger.error("Unable to send ComputeChecksumCommand to " + hostId, e);
|
||||
} catch (OperationTimedoutException e) {
|
||||
s_logger.error("Unable to send ComputeChecksumCommand to " + hostId, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// used for vm transitioning to error state
|
||||
private void updateVmStateForFailedVmCreation(Long vmId) {
|
||||
UserVmVO vm = _vmDao.findById(vmId);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user