You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ah...@apache.org on 2014/02/05 02:39:39 UTC
[01/11] Moved the secondary storage service into its own server
directory
Updated Branches:
refs/heads/master aaa20947a -> 54f32a8e4
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
deleted file mode 100755
index cdbc52d..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
+++ /dev/null
@@ -1,550 +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 org.apache.cloudstack.storage.template;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
-
-import com.cloud.agent.api.storage.CreateEntityDownloadURLAnswer;
-import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLAnswer;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.UploadAnswer;
-import com.cloud.agent.api.storage.UploadCommand;
-import com.cloud.agent.api.storage.UploadProgressCommand;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.Upload;
-import com.cloud.storage.UploadVO;
-import com.cloud.storage.template.FtpTemplateUploader;
-import com.cloud.storage.template.TemplateUploader;
-import com.cloud.storage.template.TemplateUploader.Status;
-import com.cloud.storage.template.TemplateUploader.UploadCompleteCallback;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-
-public class UploadManagerImpl extends ManagerBase implements UploadManager {
-
- public class Completion implements UploadCompleteCallback {
- private final String jobId;
-
- public Completion(String jobId) {
- this.jobId = jobId;
- }
-
- @Override
- public void uploadComplete(Status status) {
- setUploadStatus(jobId, status);
- }
- }
-
- private static class UploadJob {
- private final TemplateUploader tu;
-
- public UploadJob(TemplateUploader tu, String jobId, long id, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
- String installPathPrefix) {
- super();
- this.tu = tu;
- }
-
- public TemplateUploader getTemplateUploader() {
- return tu;
- }
-
- public void cleanup() {
- if (tu != null) {
- String upldPath = tu.getUploadLocalPath();
- if (upldPath != null) {
- File f = new File(upldPath);
- f.delete();
- }
- }
- }
-
- }
-
- public static final Logger s_logger = Logger.getLogger(UploadManagerImpl.class);
- private ExecutorService threadPool;
- private final Map<String, UploadJob> jobs = new ConcurrentHashMap<String, UploadJob>();
- private String parentDir;
- private final String extractMountPoint = "/mnt/SecStorage/extractmnt";
- private StorageLayer _storage;
- private boolean hvm;
-
- @Override
- public String uploadPublicTemplate(long id, String url, String name, ImageFormat format, Long accountId, String descr, String cksum, String installPathPrefix,
- String userName, String passwd, long templateSizeInBytes) {
-
- UUID uuid = UUID.randomUUID();
- String jobId = uuid.toString();
-
- String completePath = parentDir + File.separator + installPathPrefix;
- s_logger.debug("Starting upload from " + completePath);
-
- URI uri;
- try {
- uri = new URI(url);
- } catch (URISyntaxException e) {
- s_logger.error("URI is incorrect: " + url);
- throw new CloudRuntimeException("URI is incorrect: " + url);
- }
- TemplateUploader tu;
- if ((uri != null) && (uri.getScheme() != null)) {
- if (uri.getScheme().equalsIgnoreCase("ftp")) {
- tu = new FtpTemplateUploader(completePath, url, new Completion(jobId), templateSizeInBytes);
- } else {
- s_logger.error("Scheme is not supported " + url);
- throw new CloudRuntimeException("Scheme is not supported " + url);
- }
- } else {
- s_logger.error("Unable to download from URL: " + url);
- throw new CloudRuntimeException("Unable to download from URL: " + url);
- }
- UploadJob uj = new UploadJob(tu, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix);
- jobs.put(jobId, uj);
- threadPool.execute(tu);
-
- return jobId;
-
- }
-
- @Override
- public String getUploadError(String jobId) {
- UploadJob uj = jobs.get(jobId);
- if (uj != null) {
- return uj.getTemplateUploader().getUploadError();
- }
- return null;
- }
-
- @Override
- public int getUploadPct(String jobId) {
- UploadJob uj = jobs.get(jobId);
- if (uj != null) {
- return uj.getTemplateUploader().getUploadPercent();
- }
- return 0;
- }
-
- @Override
- public Status getUploadStatus(String jobId) {
- UploadJob job = jobs.get(jobId);
- if (job != null) {
- TemplateUploader tu = job.getTemplateUploader();
- if (tu != null) {
- return tu.getStatus();
- }
- }
- return Status.UNKNOWN;
- }
-
- public static UploadVO.Status convertStatus(Status tds) {
- switch (tds) {
- case ABORTED:
- return UploadVO.Status.NOT_UPLOADED;
- case UPLOAD_FINISHED:
- return UploadVO.Status.UPLOAD_IN_PROGRESS;
- case IN_PROGRESS:
- return UploadVO.Status.UPLOAD_IN_PROGRESS;
- case NOT_STARTED:
- return UploadVO.Status.NOT_UPLOADED;
- case RECOVERABLE_ERROR:
- return UploadVO.Status.NOT_UPLOADED;
- case UNKNOWN:
- return UploadVO.Status.UNKNOWN;
- case UNRECOVERABLE_ERROR:
- return UploadVO.Status.UPLOAD_ERROR;
- case POST_UPLOAD_FINISHED:
- return UploadVO.Status.UPLOADED;
- default:
- return UploadVO.Status.UNKNOWN;
- }
- }
-
- @Override
- public com.cloud.storage.UploadVO.Status getUploadStatus2(String jobId) {
- return convertStatus(getUploadStatus(jobId));
- }
-
- @Override
- public String getPublicTemplateRepo() {
- // TODO Auto-generated method stub
- return null;
- }
-
- private UploadAnswer handleUploadProgressCmd(UploadProgressCommand cmd) {
- String jobId = cmd.getJobId();
- UploadAnswer answer;
- UploadJob uj = null;
- if (jobId != null)
- uj = jobs.get(jobId);
- if (uj == null) {
- return new UploadAnswer(null, 0, "Cannot find job", com.cloud.storage.UploadVO.Status.UNKNOWN, "", "", 0);
- }
- TemplateUploader td = uj.getTemplateUploader();
- switch (cmd.getRequest()) {
- case GET_STATUS:
- break;
- case ABORT:
- td.stopUpload();
- sleep();
- break;
- /*case RESTART:
- td.stopUpload();
- sleep();
- threadPool.execute(td);
- break;*/
- case PURGE:
- td.stopUpload();
- answer =
- new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId),
- getUploadTemplateSize(jobId));
- jobs.remove(jobId);
- return answer;
- default:
- break; // TODO
- }
- return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId),
- getUploadTemplateSize(jobId));
- }
-
- @Override
- public UploadAnswer handleUploadCommand(SecondaryStorageResource resource, UploadCommand cmd) {
- s_logger.warn("Handling the upload " + cmd.getInstallPath() + " " + cmd.getId());
- if (cmd instanceof UploadProgressCommand) {
- return handleUploadProgressCmd((UploadProgressCommand)cmd);
- }
-
- String user = null;
- String password = null;
- String jobId =
- uploadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(),
- cmd.getInstallPath(), user, password, cmd.getTemplateSizeInBytes());
- sleep();
- return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId),
- getUploadTemplateSize(jobId));
- }
-
- @Override
- public CreateEntityDownloadURLAnswer handleCreateEntityURLCommand(CreateEntityDownloadURLCommand cmd) {
-
- boolean isApacheUp = checkAndStartApache();
- if (!isApacheUp) {
- String errorString = "Error in starting Apache server ";
- s_logger.error(errorString);
- return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
- }
- // Create the directory structure so that its visible under apache server root
- String extractDir = "/var/www/html/userdata/";
- Script command = new Script("mkdir", s_logger);
- command.add("-p");
- command.add(extractDir);
- String result = command.execute();
- if (result != null) {
- String errorString = "Error in creating directory =" + result;
- s_logger.error(errorString);
- return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
- }
-
- // Create a random file under the directory for security reasons.
- String uuid = cmd.getExtractLinkUUID();
- command = new Script("touch", s_logger);
- command.add(extractDir + uuid);
- result = command.execute();
- if (result != null) {
- String errorString = "Error in creating file " + uuid + " ,error: " + result;
- s_logger.warn(errorString);
- return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
- }
-
- // Create a symbolic link from the actual directory to the template location. The entity would be directly visible under /var/www/html/userdata/cmd.getInstallPath();
- command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("ln -sf /mnt/SecStorage/" + cmd.getParent() + File.separator + cmd.getInstallPath() + " " + extractDir + uuid);
- result = command.execute();
- if (result != null) {
- String errorString = "Error in linking err=" + result;
- s_logger.error(errorString);
- return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
- }
-
- return new CreateEntityDownloadURLAnswer("", CreateEntityDownloadURLAnswer.RESULT_SUCCESS);
-
- }
-
- @Override
- public DeleteEntityDownloadURLAnswer handleDeleteEntityDownloadURLCommand(DeleteEntityDownloadURLCommand cmd) {
-
- //Delete the soft link. Example path = volumes/8/74eeb2c6-8ab1-4357-841f-2e9d06d1f360.vhd
- s_logger.warn("handleDeleteEntityDownloadURLCommand Path:" + cmd.getPath() + " Type:" + cmd.getType().toString());
- String path = cmd.getPath();
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
-
- //We just need to remove the UUID.vhd
- String extractUrl = cmd.getExtractUrl();
- command.add("unlink /var/www/html/userdata/" + extractUrl.substring(extractUrl.lastIndexOf(File.separator) + 1));
- String result = command.execute();
- if (result != null) {
- String errorString = "Error in deleting =" + result;
- s_logger.warn(errorString);
- return new DeleteEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
- }
-
- // If its a volume also delete the Hard link since it was created only for the purpose of download.
- if (cmd.getType() == Upload.Type.VOLUME) {
- command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("rm -f /mnt/SecStorage/" + cmd.getParentPath() + File.separator + path);
- s_logger.warn(" " + parentDir + File.separator + path);
- result = command.execute();
- if (result != null) {
- String errorString = "Error in linking err=" + result;
- s_logger.warn(errorString);
- return new DeleteEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
- }
- }
-
- return new DeleteEntityDownloadURLAnswer("", CreateEntityDownloadURLAnswer.RESULT_SUCCESS);
- }
-
- private String getInstallPath(String jobId) {
- // TODO Auto-generated method stub
- return null;
- }
-
- private String getUploadLocalPath(String jobId) {
- // TODO Auto-generated method stub
- return null;
- }
-
- private long getUploadTemplateSize(String jobId) {
- return 0;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-
- String value = null;
-
- _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
- if (_storage == null) {
- value = (String)params.get(StorageLayer.ClassConfigKey);
- if (value == null) {
- throw new ConfigurationException("Unable to find the storage layer");
- }
-
- Class<StorageLayer> clazz;
- try {
- clazz = (Class<StorageLayer>)Class.forName(value);
- _storage = clazz.newInstance();
- } catch (ClassNotFoundException e) {
- throw new ConfigurationException("Unable to instantiate " + value);
- } catch (InstantiationException e) {
- throw new ConfigurationException("Unable to instantiate " + value);
- } catch (IllegalAccessException e) {
- throw new ConfigurationException("Unable to instantiate " + value);
- }
- }
-
- String inSystemVM = (String)params.get("secondary.storage.vm");
- if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) {
- s_logger.info("UploadManager: starting additional services since we are inside system vm");
- startAdditionalServices();
- //blockOutgoingOnPrivate();
- }
-
- value = (String)params.get("install.numthreads");
- final int numInstallThreads = NumbersUtil.parseInt(value, 10);
-
- String scriptsDir = (String)params.get("template.scripts.dir");
- if (scriptsDir == null) {
- scriptsDir = "scripts/storage/secondary";
- }
-
- // Add more processors here.
- threadPool = Executors.newFixedThreadPool(numInstallThreads);
-
- return true;
- }
-
- private void startAdditionalServices() {
-
- Script command = new Script("rm", s_logger);
- command.add("-rf");
- command.add(extractMountPoint);
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Error in creating file " + extractMountPoint + " ,error: " + result);
- return;
- }
-
- command = new Script("touch", s_logger);
- command.add(extractMountPoint);
- result = command.execute();
- if (result != null) {
- s_logger.warn("Error in creating file " + extractMountPoint + " ,error: " + result);
- return;
- }
-
- command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("ln -sf " + parentDir + " " + extractMountPoint);
- result = command.execute();
- if (result != null) {
- s_logger.warn("Error in linking err=" + result);
- return;
- }
-
- }
-
- /**
- * Get notified of change of job status. Executed in context of uploader thread
- *
- * @param jobId
- * the id of the job
- * @param status
- * the status of the job
- */
- public void setUploadStatus(String jobId, Status status) {
- UploadJob uj = jobs.get(jobId);
- if (uj == null) {
- s_logger.warn("setUploadStatus for jobId: " + jobId + ", status=" + status + " no job found");
- return;
- }
- TemplateUploader tu = uj.getTemplateUploader();
- s_logger.warn("Upload Completion for jobId: " + jobId + ", status=" + status);
- s_logger.warn("UploadedBytes=" + tu.getUploadedBytes() + ", error=" + tu.getUploadError() + ", pct=" + tu.getUploadPercent());
-
- switch (status) {
- case ABORTED:
- case NOT_STARTED:
- case UNRECOVERABLE_ERROR:
- // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume.
- if (uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1) {
- uj.cleanup();
- }
- break;
- case UNKNOWN:
- return;
- case IN_PROGRESS:
- s_logger.info("Resuming jobId: " + jobId + ", status=" + status);
- tu.setResume(true);
- threadPool.execute(tu);
- break;
- case RECOVERABLE_ERROR:
- threadPool.execute(tu);
- break;
- case UPLOAD_FINISHED:
- tu.setUploadError("Upload success, starting install ");
- String result = postUpload(jobId);
- if (result != null) {
- s_logger.error("Failed post upload script: " + result);
- tu.setStatus(Status.UNRECOVERABLE_ERROR);
- tu.setUploadError("Failed post upload script: " + result);
- } else {
- s_logger.warn("Upload completed successfully at " + new SimpleDateFormat().format(new Date()));
- tu.setStatus(Status.POST_UPLOAD_FINISHED);
- tu.setUploadError("Upload completed successfully at " + new SimpleDateFormat().format(new Date()));
- }
- // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume.
- if (uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1) {
- uj.cleanup();
- }
- break;
- default:
- break;
- }
- }
-
- private String postUpload(String jobId) {
- return null;
- }
-
- private void sleep() {
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- // ignore
- }
- }
-
- private boolean checkAndStartApache() {
-
- //Check whether the Apache server is running
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("if [ -d /etc/apache2 ] ; then service apache2 status | grep pid; else service httpd status | grep pid; fi ");
- String result = command.execute();
-
- //Apache Server is not running. Try to start it.
- if (result != null) {
-
- /*s_logger.warn("Apache server not running, trying to start it");
- String port = Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
- String intf = TemplateConstants.DEFAULT_TMPLT_COPY_INTF;
-
- command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j DROP;" +
- "iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j HTTP;" +
- "iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j DROP;" +
- "iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j HTTP;" +
- "iptables -F HTTP;" +
- "iptables -X HTTP;" +
- "iptables -N HTTP;" +
- "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j DROP;" +
- "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j DROP;" +
- "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j HTTP;" +
- "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j HTTP;");
-
- result = command.execute();
- if (result != null) {
- s_logger.warn("Error in opening up httpd port err=" + result );
- return false;
- }*/
-
- command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("if [ -d /etc/apache2 ] ; then service apache2 start; else service httpd start; fi ");
- result = command.execute();
- if (result != null) {
- s_logger.warn("Error in starting httpd service err=" + result);
- return false;
- }
- }
-
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java b/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
deleted file mode 100644
index e0fcbae..0000000
--- a/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
+++ /dev/null
@@ -1,143 +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 org.apache.cloudstack.storage.resource;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Map;
-import java.util.Properties;
-import java.util.UUID;
-
-import javax.naming.ConfigurationException;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
-import org.apache.log4j.Logger;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.storage.ListTemplateAnswer;
-import com.cloud.agent.api.storage.ListTemplateCommand;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.SwiftTO;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Storage;
-import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class LocalNfsSecondaryStorageResourceTest extends TestCase {
- private static Map<String, Object> testParams;
-
- private static final Logger s_logger = Logger.getLogger(LocalNfsSecondaryStorageResourceTest.class.getName());
-
- LocalNfsSecondaryStorageResource resource;
-
- @Before
- @Override
- public void setUp() throws ConfigurationException {
- resource = new LocalNfsSecondaryStorageResource();
- resource.setInSystemVM(true);
-
- testParams = PropertiesUtil.toMap(loadProperties());
- resource.configureStorageLayerClass(testParams);
- Object testLocalRoot = testParams.get("testLocalRoot");
- resource.setParentPath("/mnt");
-
- if (testLocalRoot != null) {
- resource.setParentPath((String)testLocalRoot);
- }
-
- System.setProperty("paths.script", "/Users/edison/develop/asf-master/script");
- //resource.configure("test", new HashMap<String, Object>());
- }
-
- @Test
- public void testExecuteRequest() throws Exception {
- TemplateObjectTO template = Mockito.mock(TemplateObjectTO.class);
- NfsTO cacheStore = Mockito.mock(NfsTO.class);
- Mockito.when(cacheStore.getUrl()).thenReturn("nfs://nfs2.lab.vmops.com/export/home/edison/");
- SwiftTO swift = Mockito.mock(SwiftTO.class);
- Mockito.when(swift.getEndPoint()).thenReturn("https://objects.dreamhost.com/auth");
- Mockito.when(swift.getAccount()).thenReturn("cloudstack");
- Mockito.when(swift.getUserName()).thenReturn("images");
- Mockito.when(swift.getKey()).thenReturn("oxvELQaOD1U5_VyosGfA-wpZ7uBWEff-CUBGCM0u");
-
- Mockito.when(template.getDataStore()).thenReturn(swift);
- Mockito.when(template.getPath()).thenReturn("template/1/1/");
- Mockito.when(template.isRequiresHvm()).thenReturn(true);
- Mockito.when(template.getId()).thenReturn(1L);
- Mockito.when(template.getFormat()).thenReturn(Storage.ImageFormat.VHD);
- Mockito.when(template.getOrigUrl()).thenReturn("http://nfs1.lab.vmops.com/templates/test.bz2");
- Mockito.when(template.getName()).thenReturn(UUID.randomUUID().toString());
- Mockito.when(template.getObjectType()).thenReturn(DataObjectType.TEMPLATE);
-
- DownloadCommand cmd = new DownloadCommand(template, 100000L);
- cmd.setCacheStore(cacheStore);
- DownloadAnswer answer = (DownloadAnswer)resource.executeRequest(cmd);
- Assert.assertTrue(answer.getResult());
-
- Mockito.when(template.getPath()).thenReturn(answer.getInstallPath());
- Mockito.when(template.getDataStore()).thenReturn(swift);
- //download swift:
- Mockito.when(cacheStore.getRole()).thenReturn(DataStoreRole.ImageCache);
- TemplateObjectTO destTemplate = Mockito.mock(TemplateObjectTO.class);
- Mockito.when(destTemplate.getPath()).thenReturn("template/1/2");
- Mockito.when(destTemplate.getDataStore()).thenReturn(cacheStore);
- Mockito.when(destTemplate.getObjectType()).thenReturn(DataObjectType.TEMPLATE);
- CopyCommand cpyCmd = new CopyCommand(template, destTemplate, 10000, true);
- CopyCmdAnswer copyCmdAnswer = (CopyCmdAnswer)resource.executeRequest(cpyCmd);
- Assert.assertTrue(copyCmdAnswer.getResult());
-
- //list template
- ListTemplateCommand listCmd = new ListTemplateCommand(swift);
- ListTemplateAnswer listAnswer = (ListTemplateAnswer)resource.executeRequest(listCmd);
-
- Assert.assertTrue(listAnswer.getTemplateInfo().size() > 0);
- }
-
- public static Properties loadProperties() throws ConfigurationException {
- Properties properties = new Properties();
- final File file = PropertiesUtil.findConfigFile("agent.properties");
- if (file == null) {
- throw new ConfigurationException("Unable to find agent.properties.");
- }
-
- s_logger.info("agent.properties found at " + file.getAbsolutePath());
-
- try {
- properties.load(new FileInputStream(file));
- } catch (final FileNotFoundException ex) {
- throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
- } catch (final IOException ex) {
- throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
- }
- return properties;
- }
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java b/services/secondary-storage/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
deleted file mode 100644
index e0ae4c5..0000000
--- a/services/secondary-storage/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
+++ /dev/null
@@ -1,110 +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 org.apache.cloudstack.storage.resource;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URI;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.naming.ConfigurationException;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class NfsSecondaryStorageResourceTest extends TestCase {
- private static Map<String, Object> testParams;
-
- private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResourceTest.class.getName());
-
- NfsSecondaryStorageResource resource;
-
- @Before
- @Override
- public void setUp() throws ConfigurationException {
- s_logger.setLevel(Level.ALL);
- resource = new NfsSecondaryStorageResource();
- resource.setInSystemVM(true);
- testParams = PropertiesUtil.toMap(loadProperties());
- resource.configureStorageLayerClass(testParams);
- Object testLocalRoot = testParams.get("testLocalRoot");
- if (testLocalRoot != null) {
- resource.setParentPath((String)testLocalRoot);
- }
- }
-
- @Test
- public void testMount() throws Exception {
- String sampleUriStr = "cifs://192.168.1.128/CSHV3?user=administrator&password=1pass%40word1&foo=bar";
- URI sampleUri = new URI(sampleUriStr);
-
- s_logger.info("Check HostIp parsing");
- String hostIpStr = resource.getUriHostIp(sampleUri);
- Assert.assertEquals("Expected host IP " + sampleUri.getHost() + " and actual host IP " + hostIpStr + " differ.", sampleUri.getHost(), hostIpStr);
-
- s_logger.info("Check option parsing");
- String expected = "user=administrator,password=1pass@word1,foo=bar,";
- String actualOpts = resource.parseCifsMountOptions(sampleUri);
- Assert.assertEquals("Options should be " + expected + " and not " + actualOpts, expected, actualOpts);
-
- // attempt a configured mount
- final Map<String, Object> params = PropertiesUtil.toMap(loadProperties());
- String sampleMount = (String)params.get("testCifsMount");
- if (!sampleMount.isEmpty()) {
- s_logger.info("functional test, mount " + sampleMount);
- URI realMntUri = new URI(sampleMount);
- String mntSubDir = resource.mountUri(realMntUri);
- s_logger.info("functional test, umount " + mntSubDir);
- resource.umount(resource.getMountingRoot() + mntSubDir, realMntUri);
- } else {
- s_logger.info("no entry for testCifsMount in " + "./conf/agent.properties - skip functional test");
- }
- }
-
- public static Properties loadProperties() throws ConfigurationException {
- Properties properties = new Properties();
- final File file = PropertiesUtil.findConfigFile("agent.properties");
- if (file == null) {
- throw new ConfigurationException("Unable to find agent.properties.");
- }
-
- s_logger.info("agent.properties found at " + file.getAbsolutePath());
-
- try {
- properties.load(new FileInputStream(file));
- } catch (final FileNotFoundException ex) {
- throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
- } catch (final IOException ex) {
- throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
- }
- return properties;
- }
-
-}
[09/11] git commit: updated refs/heads/master to 54f32a8
Posted by ah...@apache.org.
Removed some useless imports
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/03a424e4
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/03a424e4
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/03a424e4
Branch: refs/heads/master
Commit: 03a424e45abe753cd0227efb10eb21e2b9fab53c
Parents: 7f34282
Author: Alex Huang <al...@citrix.com>
Authored: Wed Jan 29 16:21:33 2014 +0000
Committer: Alex Huang <al...@citrix.com>
Committed: Wed Feb 5 01:39:16 2014 +0000
----------------------------------------------------------------------
.../ConsoleProxyBalanceAllocator.java | 3 ---
.../consoleproxy/StaticConsoleProxyManager.java | 18 ------------------
2 files changed, 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03a424e4/server/src/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java b/server/src/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java
index 147063d..2cbd847 100644
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java
@@ -21,7 +21,6 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
-import java.util.Random;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
@@ -32,8 +31,6 @@ import com.cloud.vm.ConsoleProxy;
@Local(value = {ConsoleProxyAllocator.class})
public class ConsoleProxyBalanceAllocator extends AdapterBase implements ConsoleProxyAllocator {
- private final Random _rand = new Random(System.currentTimeMillis());
-
@Override
public Long allocProxy(List<? extends ConsoleProxy> candidates, final Map<Long, Integer> loadInfo, long dataCenterId) {
List<ConsoleProxy> allocationList = new ArrayList<ConsoleProxy>(candidates);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03a424e4/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
index 27bdcbe..8aa9b0d 100755
--- a/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
+++ b/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
@@ -18,23 +18,17 @@ package com.cloud.consoleproxy;
import java.util.List;
import java.util.Map;
-import java.util.Random;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
-import org.apache.log4j.Logger;
-
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.security.keystore.KeystoreDao;
-import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupProxyCommand;
import com.cloud.host.Host.Type;
import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
import com.cloud.info.ConsoleProxyInfo;
import com.cloud.resource.ResourceManager;
import com.cloud.resource.ResourceStateAdapter;
@@ -43,11 +37,9 @@ import com.cloud.resource.UnableDeleteHostException;
import com.cloud.utils.NumbersUtil;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.ConsoleProxyDao;
-import com.cloud.vm.dao.VMInstanceDao;
@Local(value = {ConsoleProxyManager.class})
public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager implements ConsoleProxyManager, ResourceStateAdapter {
- private static final Logger s_logger = Logger.getLogger(StaticConsoleProxyManager.class);
@Inject
ConsoleProxyDao _proxyDao;
@@ -55,16 +47,6 @@ public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager imp
ResourceManager _resourceMgr;
@Inject
ConfigurationDao _configDao;
- @Inject
- private VMInstanceDao _instanceDao;
- @Inject
- KeystoreDao _ksDao;
- @Inject
- private KeystoreManager _ksMgr;
- @Inject
- private HostDao _hostDao;
- private final Random _random = new Random(System.currentTimeMillis());
- private String _hashKey;
private String _ip = null;
public StaticConsoleProxyManager() {
[05/11] Moved the secondary storage service into its own server
directory
Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
new file mode 100755
index 0000000..ee50647
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
@@ -0,0 +1,312 @@
+// 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.storage.resource;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status.Event;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.resource.Discoverer;
+import com.cloud.resource.DiscovererBase;
+import com.cloud.resource.ServerResource;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VMTemplateZoneVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplateZoneDao;
+import com.cloud.storage.resource.DummySecondaryStorageResource;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.net.NfsUtils;
+import com.cloud.utils.script.Script;
+
+/**
+ * SecondaryStorageDiscoverer is used to discover secondary
+ * storage servers and make sure everything it can do is
+ * correct.
+ */
+@Local(value = Discoverer.class)
+public class SecondaryStorageDiscoverer extends DiscovererBase implements Discoverer {
+ private static final Logger s_logger = Logger.getLogger(SecondaryStorageDiscoverer.class);
+
+ long _timeout = 2 * 60 * 1000; // 2 minutes
+ String _mountParent;
+ boolean _useServiceVM = false;
+
+ Random _random = new Random(System.currentTimeMillis());
+ @Inject
+ protected VMTemplateDao _tmpltDao = null;
+ @Inject
+ protected VMTemplateZoneDao _vmTemplateZoneDao = null;
+ @Inject
+ protected VMTemplateDao _vmTemplateDao = null;
+ @Inject
+ protected AgentManager _agentMgr = null;
+
+ protected SecondaryStorageDiscoverer() {
+ }
+
+ @Override
+ public Map<? extends ServerResource, Map<String, String>>
+ find(long dcId, Long podId, Long clusterId, URI uri, String username, String password, List<String> hostTags) {
+ if (!uri.getScheme().equalsIgnoreCase("nfs") && !uri.getScheme().equalsIgnoreCase("cifs") && !uri.getScheme().equalsIgnoreCase("file") &&
+ !uri.getScheme().equalsIgnoreCase("iso") && !uri.getScheme().equalsIgnoreCase("dummy")) {
+ s_logger.debug("It's not NFS or file or ISO, so not a secondary storage server: " + uri.toString());
+ return null;
+ }
+
+ if (uri.getScheme().equalsIgnoreCase("nfs") || uri.getScheme().equalsIgnoreCase("cifs") || uri.getScheme().equalsIgnoreCase("iso")) {
+ return createNfsSecondaryStorageResource(dcId, podId, uri);
+ } else if (uri.getScheme().equalsIgnoreCase("file")) {
+ return createLocalSecondaryStorageResource(dcId, podId, uri);
+ } else if (uri.getScheme().equalsIgnoreCase("dummy")) {
+ return createDummySecondaryStorageResource(dcId, podId, uri);
+ } else {
+ return null;
+ }
+ }
+
+ protected Map<? extends ServerResource, Map<String, String>> createNfsSecondaryStorageResource(long dcId, Long podId, URI uri) {
+
+ if (_useServiceVM) {
+ return createDummySecondaryStorageResource(dcId, podId, uri);
+ }
+ String mountStr = NfsUtils.uri2Mount(uri);
+
+ Script script = new Script(true, "mount", _timeout, s_logger);
+ String mntPoint = null;
+ File file = null;
+ do {
+ mntPoint = _mountParent + File.separator + Integer.toHexString(_random.nextInt(Integer.MAX_VALUE));
+ file = new File(mntPoint);
+ } while (file.exists());
+
+ if (!file.mkdirs()) {
+ s_logger.warn("Unable to make directory: " + mntPoint);
+ return null;
+ }
+
+ script.add(mountStr, mntPoint);
+ String result = script.execute();
+ if (result != null && !result.contains("already mounted")) {
+ s_logger.warn("Unable to mount " + uri.toString() + " due to " + result);
+ file.delete();
+ return null;
+ }
+
+ script = new Script(true, "umount", 0, s_logger);
+ script.add(mntPoint);
+ script.execute();
+
+ file.delete();
+
+ Map<NfsSecondaryStorageResource, Map<String, String>> srs = new HashMap<NfsSecondaryStorageResource, Map<String, String>>();
+
+ NfsSecondaryStorageResource storage;
+ if (_configDao.isPremium()) {
+ Class<?> impl;
+ String name = "com.cloud.storage.resource.PremiumSecondaryStorageResource";
+ try {
+ impl = Class.forName(name);
+ final Constructor<?> constructor = impl.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ storage = (NfsSecondaryStorageResource)constructor.newInstance();
+ } catch (final ClassNotFoundException e) {
+ s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to ClassNotFoundException");
+ return null;
+ } catch (final SecurityException e) {
+ s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to SecurityException");
+ return null;
+ } catch (final NoSuchMethodException e) {
+ s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to NoSuchMethodException");
+ return null;
+ } catch (final IllegalArgumentException e) {
+ s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to IllegalArgumentException");
+ return null;
+ } catch (final InstantiationException e) {
+ s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to InstantiationException");
+ return null;
+ } catch (final IllegalAccessException e) {
+ s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to IllegalAccessException");
+ return null;
+ } catch (final InvocationTargetException e) {
+ s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to InvocationTargetException");
+ return null;
+ }
+ } else {
+ storage = new NfsSecondaryStorageResource();
+ }
+
+ Map<String, String> details = new HashMap<String, String>();
+ details.put("mount.path", mountStr);
+ details.put("orig.url", uri.toString());
+ details.put("mount.parent", _mountParent);
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.putAll(details);
+ params.put("zone", Long.toString(dcId));
+ if (podId != null) {
+ params.put("pod", podId.toString());
+ }
+ params.put("guid", uri.toString());
+ params.put("secondary.storage.vm", "false");
+ params.put("max.template.iso.size", _configDao.getValue("max.template.iso.size"));
+
+ try {
+ storage.configure("Storage", params);
+ } catch (ConfigurationException e) {
+ s_logger.warn("Unable to configure the storage ", e);
+ return null;
+ }
+ srs.put(storage, details);
+
+ return srs;
+ }
+
+ protected Map<? extends ServerResource, Map<String, String>> createLocalSecondaryStorageResource(long dcId, Long podId, URI uri) {
+ Map<LocalSecondaryStorageResource, Map<String, String>> srs = new HashMap<LocalSecondaryStorageResource, Map<String, String>>();
+
+ LocalSecondaryStorageResource storage = new LocalSecondaryStorageResource();
+ storage = ComponentContext.inject(storage);
+
+ Map<String, String> details = new HashMap<String, String>();
+
+ File file = new File(uri);
+ details.put("mount.path", file.getAbsolutePath());
+ details.put("orig.url", uri.toString());
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.putAll(details);
+ params.put("zone", Long.toString(dcId));
+ if (podId != null) {
+ params.put("pod", podId.toString());
+ }
+ params.put("guid", uri.toString());
+
+ try {
+ storage.configure("Storage", params);
+ } catch (ConfigurationException e) {
+ s_logger.warn("Unable to configure the storage ", e);
+ return null;
+ }
+ srs.put(storage, details);
+
+ return srs;
+ }
+
+ protected Map<ServerResource, Map<String, String>> createDummySecondaryStorageResource(long dcId, Long podId, URI uri) {
+ Map<ServerResource, Map<String, String>> srs = new HashMap<ServerResource, Map<String, String>>();
+
+ DummySecondaryStorageResource storage = new DummySecondaryStorageResource(_useServiceVM);
+ storage = ComponentContext.inject(storage);
+
+ Map<String, String> details = new HashMap<String, String>();
+
+ details.put("mount.path", uri.toString());
+ details.put("orig.url", uri.toString());
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.putAll(details);
+ params.put("zone", Long.toString(dcId));
+ if (podId != null) {
+ params.put("pod", podId.toString());
+ }
+ params.put("guid", uri.toString());
+
+ try {
+ storage.configure("Storage", params);
+ } catch (ConfigurationException e) {
+ s_logger.warn("Unable to configure the storage ", e);
+ return null;
+ }
+ srs.put(storage, details);
+
+ return srs;
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ super.configure(name, params);
+
+ _mountParent = _params.get("mount.parent");
+ if (_mountParent == null) {
+ _mountParent = "/mnt";
+ }
+
+ String useServiceVM = _params.get("secondary.storage.vm");
+ if ("true".equalsIgnoreCase(useServiceVM)) {
+ _useServiceVM = true;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean matchHypervisor(String hypervisor) {
+ if (hypervisor.equals("SecondaryStorage")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public Hypervisor.HypervisorType getHypervisorType() {
+ return Hypervisor.HypervisorType.None;
+ }
+
+ @Override
+ public void postDiscovery(List<HostVO> hosts, long msId) {
+ if (_useServiceVM) {
+ for (HostVO h : hosts) {
+ _agentMgr.agentStatusTransitTo(h, Event.AgentDisconnected, msId);
+ }
+ }
+ for (HostVO h : hosts) {
+ associateTemplatesToZone(h.getId(), h.getDataCenterId());
+ }
+
+ }
+
+ private void associateTemplatesToZone(long hostId, long dcId) {
+ VMTemplateZoneVO tmpltZone;
+
+ List<VMTemplateVO> allTemplates = _vmTemplateDao.listAll();
+ for (VMTemplateVO vt : allTemplates) {
+ if (vt.isCrossZones()) {
+ tmpltZone = _vmTemplateZoneDao.findByZoneTemplate(dcId, vt.getId());
+ if (tmpltZone == null) {
+ VMTemplateZoneVO vmTemplateZone = new VMTemplateZoneVO(dcId, vt.getId(), new Date());
+ _vmTemplateZoneDao.persist(vmTemplateZone);
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
new file mode 100755
index 0000000..93fd8ea
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
@@ -0,0 +1,29 @@
+// 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.storage.resource;
+
+import com.cloud.resource.ServerResource;
+
+/**
+ *
+ * SecondaryStorageServerResource is a generic container to execute commands sent
+ */
+public interface SecondaryStorageResource extends ServerResource {
+
+ public String getRootDir(String cmd);
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
new file mode 100644
index 0000000..14ebc71
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
@@ -0,0 +1,24 @@
+// 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.storage.resource;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+
+public interface SecondaryStorageResourceHandler {
+ Answer executeRequest(Command cmd);
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManager.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManager.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManager.java
new file mode 100644
index 0000000..d0abe2c
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManager.java
@@ -0,0 +1,108 @@
+// 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.storage.template;
+
+import java.util.Map;
+
+import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.Proxy;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.template.TemplateDownloader;
+import com.cloud.storage.template.TemplateProp;
+import com.cloud.utils.component.Manager;
+
+public interface DownloadManager extends Manager {
+
+ /**
+ * Initiate download of a public template
+ * @param id unique id.
+ * @param url the url from where to download from
+ * @param hvm whether the template is a hardware virtual machine
+ * @param accountId the accountId of the iso owner (null if public iso)
+ * @param descr description of the template
+ * @param user username used for authentication to the server
+ * @param password password used for authentication to the server
+ * @param maxDownloadSizeInBytes (optional) max download size for the template, in bytes.
+ * @param resourceType signifying the type of resource like template, volume etc.
+ * @return job-id that can be used to interrogate the status of the download.
+ */
+ public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
+ String installPathPrefix, String templatePath, String userName, String passwd, long maxDownloadSizeInBytes, Proxy proxy, ResourceType resourceType);
+
+ public String downloadS3Template(S3TO s3, long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
+ String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType);
+
+ /**
+ * Get the status of a download job
+ * @param jobId job Id
+ * @return status of the download job
+ */
+ public TemplateDownloader.Status getDownloadStatus(String jobId);
+
+ /**
+ * Get the status of a download job
+ * @param jobId job Id
+ * @return status of the download job
+ */
+ public VMTemplateHostVO.Status getDownloadStatus2(String jobId);
+
+ /**
+ * Get the download percent of a download job
+ * @param jobId job Id
+ * @return
+ */
+ public int getDownloadPct(String jobId);
+
+ /**
+ * Get the download error if any
+ * @param jobId job Id
+ * @return
+ */
+ public String getDownloadError(String jobId);
+
+ /**
+ * Get the local path for the download
+ * @param jobId job Id
+ * @return
+ public String getDownloadLocalPath(String jobId);
+ */
+
+ /** Handle download commands from the management server
+ * @param cmd cmd from server
+ * @return answer representing status of download.
+ */
+ public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd);
+
+ /**
+ /**
+ * @return list of template info for installed templates
+ */
+ public Map<String, TemplateProp> gatherTemplateInfo(String templateDir);
+
+ /**
+ /**
+ * @return list of volume info for installed volumes
+ */
+ public Map<Long, TemplateProp> gatherVolumeInfo(String volumeDir);
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
new file mode 100755
index 0000000..d45a6bb
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
@@ -0,0 +1,1080 @@
+// 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.storage.template;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
+import org.apache.cloudstack.storage.command.DownloadProgressCommand;
+import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType;
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.Proxy;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.template.HttpTemplateDownloader;
+import com.cloud.storage.template.IsoProcessor;
+import com.cloud.storage.template.LocalTemplateDownloader;
+import com.cloud.storage.template.OVAProcessor;
+import com.cloud.storage.template.Processor;
+import com.cloud.storage.template.Processor.FormatInfo;
+import com.cloud.storage.template.QCOW2Processor;
+import com.cloud.storage.template.RawImageProcessor;
+import com.cloud.storage.template.S3TemplateDownloader;
+import com.cloud.storage.template.ScpTemplateDownloader;
+import com.cloud.storage.template.TemplateConstants;
+import com.cloud.storage.template.TemplateDownloader;
+import com.cloud.storage.template.TemplateDownloader.DownloadCompleteCallback;
+import com.cloud.storage.template.TemplateDownloader.Status;
+import com.cloud.storage.template.TemplateLocation;
+import com.cloud.storage.template.TemplateProp;
+import com.cloud.storage.template.VhdProcessor;
+import com.cloud.storage.template.VmdkProcessor;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+
+@Local(value = DownloadManager.class)
+public class DownloadManagerImpl extends ManagerBase implements DownloadManager {
+ private String _name;
+ StorageLayer _storage;
+ Map<String, Processor> _processors;
+
+ public class Completion implements DownloadCompleteCallback {
+ private final String jobId;
+
+ public Completion(String jobId) {
+ this.jobId = jobId;
+ }
+
+ @Override
+ public void downloadComplete(Status status) {
+ setDownloadStatus(jobId, status);
+ }
+ }
+
+ private static class DownloadJob {
+ private final TemplateDownloader td;
+ private final String tmpltName;
+ private final boolean hvm;
+ private final ImageFormat format;
+ private String tmpltPath;
+ private final String description;
+ private String checksum;
+ private final String installPathPrefix;
+ private long templatesize;
+ private long templatePhysicalSize;
+ private final long id;
+ private final ResourceType resourceType;
+
+ public DownloadJob(TemplateDownloader td, String jobId, long id, String tmpltName, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
+ String installPathPrefix, ResourceType resourceType) {
+ super();
+ this.td = td;
+ this.tmpltName = tmpltName;
+ this.format = format;
+ this.hvm = hvm;
+ description = descr;
+ checksum = cksum;
+ this.installPathPrefix = installPathPrefix;
+ templatesize = 0;
+ this.id = id;
+ this.resourceType = resourceType;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getChecksum() {
+ return checksum;
+ }
+
+ public TemplateDownloader getTemplateDownloader() {
+ return td;
+ }
+
+ public String getTmpltName() {
+ return tmpltName;
+ }
+
+ public ImageFormat getFormat() {
+ return format;
+ }
+
+ public boolean isHvm() {
+ return hvm;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public ResourceType getResourceType() {
+ return resourceType;
+ }
+
+ public void setTmpltPath(String tmpltPath) {
+ this.tmpltPath = tmpltPath;
+ }
+
+ public String getTmpltPath() {
+ return tmpltPath;
+ }
+
+ public String getInstallPathPrefix() {
+ return installPathPrefix;
+ }
+
+ public void cleanup() {
+ if (td != null) {
+ String dnldPath = td.getDownloadLocalPath();
+ if (dnldPath != null) {
+ File f = new File(dnldPath);
+ File dir = f.getParentFile();
+ f.delete();
+ if (dir != null) {
+ dir.delete();
+ }
+ }
+ }
+
+ }
+
+ public void setTemplatesize(long templatesize) {
+ this.templatesize = templatesize;
+ }
+
+ public long getTemplatesize() {
+ return templatesize;
+ }
+
+ public void setTemplatePhysicalSize(long templatePhysicalSize) {
+ this.templatePhysicalSize = templatePhysicalSize;
+ }
+
+ public long getTemplatePhysicalSize() {
+ return templatePhysicalSize;
+ }
+
+ public void setCheckSum(String checksum) {
+ this.checksum = checksum;
+ }
+ }
+
+ public static final Logger s_logger = Logger.getLogger(DownloadManagerImpl.class);
+ private String _templateDir;
+ private String _volumeDir;
+ private String createTmpltScr;
+ private String createVolScr;
+
+ private ExecutorService threadPool;
+
+ private final Map<String, DownloadJob> jobs = new ConcurrentHashMap<String, DownloadJob>();
+ private String listTmpltScr;
+ private String listVolScr;
+ private int installTimeoutPerGig = 180 * 60 * 1000;
+
+ public void setThreadPool(ExecutorService threadPool) {
+ this.threadPool = threadPool;
+ }
+
+ public void setStorageLayer(StorageLayer storage) {
+ _storage = storage;
+ }
+
+ /**
+ * Get notified of change of job status. Executed in context of downloader
+ * thread
+ *
+ * @param jobId
+ * the id of the job
+ * @param status
+ * the status of the job
+ */
+ public void setDownloadStatus(String jobId, Status status) {
+ DownloadJob dj = jobs.get(jobId);
+ if (dj == null) {
+ s_logger.warn("setDownloadStatus for jobId: " + jobId + ", status=" + status + " no job found");
+ return;
+ }
+ TemplateDownloader td = dj.getTemplateDownloader();
+ s_logger.info("Download Completion for jobId: " + jobId + ", status=" + status);
+ s_logger.info("local: " + td.getDownloadLocalPath() + ", bytes=" + td.getDownloadedBytes() + ", error=" + td.getDownloadError() + ", pct=" +
+ td.getDownloadPercent());
+
+ switch (status) {
+ case ABORTED:
+ case NOT_STARTED:
+ case UNRECOVERABLE_ERROR:
+ // TODO
+ dj.cleanup();
+ break;
+ case UNKNOWN:
+ return;
+ case IN_PROGRESS:
+ s_logger.info("Resuming jobId: " + jobId + ", status=" + status);
+ td.setResume(true);
+ threadPool.execute(td);
+ break;
+ case RECOVERABLE_ERROR:
+ threadPool.execute(td);
+ break;
+ case DOWNLOAD_FINISHED:
+ if (!(td instanceof S3TemplateDownloader)) {
+ // we currently only create template.properties for NFS by
+ // running some post download script
+ td.setDownloadError("Download success, starting install ");
+ String result = postDownload(jobId);
+ if (result != null) {
+ s_logger.error("Failed post download script: " + result);
+ td.setStatus(Status.UNRECOVERABLE_ERROR);
+ td.setDownloadError("Failed post download script: " + result);
+ } else {
+ td.setStatus(Status.POST_DOWNLOAD_FINISHED);
+ td.setDownloadError("Install completed successfully at " + new SimpleDateFormat().format(new Date()));
+ }
+ } else {
+ // for s3 and swift, we skip post download step and just set
+ // status to trigger callback.
+ td.setStatus(Status.POST_DOWNLOAD_FINISHED);
+ // set template size for S3
+ S3TemplateDownloader std = (S3TemplateDownloader)td;
+ long size = std.totalBytes;
+ DownloadJob dnld = jobs.get(jobId);
+ dnld.setTemplatesize(size);
+ dnld.setTemplatePhysicalSize(size);
+ dnld.setTmpltPath(std.getDownloadLocalPath()); // update template path to include file name.
+ }
+ dj.cleanup();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private String computeCheckSum(File f) {
+ byte[] buffer = new byte[8192];
+ int read = 0;
+ MessageDigest digest;
+ String checksum = null;
+ InputStream is = null;
+ 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 = String.format("%032x", bigInt);
+ return checksum;
+ } catch (IOException e) {
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ return null;
+ } finally {
+ try {
+ if (is != null)
+ is.close();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Post download activity (install and cleanup). Executed in context of
+ * downloader thread
+ *
+ * @throws IOException
+ */
+ private String postDownload(String jobId) {
+ DownloadJob dnld = jobs.get(jobId);
+ TemplateDownloader td = dnld.getTemplateDownloader();
+ String resourcePath = dnld.getInstallPathPrefix(); // path with mount
+ // directory
+ String finalResourcePath = dnld.getTmpltPath(); // template download
+ // path on secondary
+ // storage
+ ResourceType resourceType = dnld.getResourceType();
+
+ File originalTemplate = new File(td.getDownloadLocalPath());
+ String checkSum = computeCheckSum(originalTemplate);
+ if (checkSum == null) {
+ s_logger.warn("Something wrong happened when try to calculate the checksum of downloaded template!");
+ }
+ dnld.setCheckSum(checkSum);
+
+ int imgSizeGigs = (int)Math.ceil(_storage.getSize(td.getDownloadLocalPath()) * 1.0d / (1024 * 1024 * 1024));
+ imgSizeGigs++; // add one just in case
+ long timeout = imgSizeGigs * installTimeoutPerGig;
+ Script scr = null;
+ String script = resourceType == ResourceType.TEMPLATE ? createTmpltScr : createVolScr;
+ scr = new Script(script, timeout, s_logger);
+ scr.add("-s", Integer.toString(imgSizeGigs));
+ scr.add("-S", Long.toString(td.getMaxTemplateSizeInBytes()));
+ if (dnld.getDescription() != null && dnld.getDescription().length() > 1) {
+ scr.add("-d", dnld.getDescription());
+ }
+ if (dnld.isHvm()) {
+ scr.add("-h");
+ }
+
+ // add options common to ISO and template
+ String extension = dnld.getFormat().getFileExtension();
+ String templateName = "";
+ if (extension.equals("iso")) {
+ templateName = jobs.get(jobId).getTmpltName().trim().replace(" ", "_");
+ } else {
+ templateName = java.util.UUID.nameUUIDFromBytes((jobs.get(jobId).getTmpltName() + System.currentTimeMillis()).getBytes()).toString();
+ }
+
+ // run script to mv the temporary template file to the final template
+ // file
+ String templateFilename = templateName + "." + extension;
+ dnld.setTmpltPath(finalResourcePath + "/" + templateFilename);
+ scr.add("-n", templateFilename);
+
+ scr.add("-t", resourcePath);
+ scr.add("-f", td.getDownloadLocalPath()); // this is the temporary
+ // template file downloaded
+ if (dnld.getChecksum() != null && dnld.getChecksum().length() > 1) {
+ scr.add("-c", dnld.getChecksum());
+ }
+ scr.add("-u"); // cleanup
+ String result;
+ result = scr.execute();
+
+ if (result != null) {
+ return result;
+ }
+
+ // Set permissions for the downloaded template
+ File downloadedTemplate = new File(resourcePath + "/" + templateFilename);
+ _storage.setWorldReadableAndWriteable(downloadedTemplate);
+
+ // Set permissions for template/volume.properties
+ String propertiesFile = resourcePath;
+ if (resourceType == ResourceType.TEMPLATE) {
+ propertiesFile += "/template.properties";
+ } else {
+ propertiesFile += "/volume.properties";
+ }
+ File templateProperties = new File(propertiesFile);
+ _storage.setWorldReadableAndWriteable(templateProperties);
+
+ TemplateLocation loc = new TemplateLocation(_storage, resourcePath);
+ try {
+ loc.create(dnld.getId(), true, dnld.getTmpltName());
+ } catch (IOException e) {
+ s_logger.warn("Something is wrong with template location " + resourcePath, e);
+ loc.purge();
+ return "Unable to download due to " + e.getMessage();
+ }
+
+ Iterator<Processor> en = _processors.values().iterator();
+ while (en.hasNext()) {
+ Processor processor = en.next();
+
+ FormatInfo info = null;
+ try {
+ info = processor.process(resourcePath, null, templateName);
+ } catch (InternalErrorException e) {
+ s_logger.error("Template process exception ", e);
+ return e.toString();
+ }
+ if (info != null) {
+ loc.addFormat(info);
+ dnld.setTemplatesize(info.virtualSize);
+ dnld.setTemplatePhysicalSize(info.size);
+ break;
+ }
+ }
+
+ if (!loc.save()) {
+ s_logger.warn("Cleaning up because we're unable to save the formats");
+ loc.purge();
+ }
+
+ return null;
+ }
+
+ @Override
+ public Status getDownloadStatus(String jobId) {
+ DownloadJob job = jobs.get(jobId);
+ if (job != null) {
+ TemplateDownloader td = job.getTemplateDownloader();
+ if (td != null) {
+ return td.getStatus();
+ }
+ }
+ return Status.UNKNOWN;
+ }
+
+ @Override
+ public String downloadS3Template(S3TO s3, long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
+ String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) {
+ UUID uuid = UUID.randomUUID();
+ String jobId = uuid.toString();
+
+ URI uri;
+ try {
+ uri = new URI(url);
+ } catch (URISyntaxException e) {
+ throw new CloudRuntimeException("URI is incorrect: " + url);
+ }
+ TemplateDownloader td;
+ if ((uri != null) && (uri.getScheme() != null)) {
+ if (uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")) {
+ td = new S3TemplateDownloader(s3, url, installPathPrefix, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType);
+ } else {
+ throw new CloudRuntimeException("Scheme is not supported " + url);
+ }
+ } else {
+ throw new CloudRuntimeException("Unable to download from URL: " + url);
+ }
+ DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType);
+ dj.setTmpltPath(installPathPrefix);
+ jobs.put(jobId, dj);
+ threadPool.execute(td);
+
+ return jobId;
+ }
+
+ @Override
+ public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
+ String installPathPrefix, String templatePath, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) {
+ UUID uuid = UUID.randomUUID();
+ String jobId = uuid.toString();
+ String tmpDir = installPathPrefix;
+
+ try {
+
+ if (!_storage.mkdirs(tmpDir)) {
+ s_logger.warn("Unable to create " + tmpDir);
+ return "Unable to create " + tmpDir;
+ }
+ // TO DO - define constant for volume properties.
+ File file =
+ ResourceType.TEMPLATE == resourceType ? _storage.getFile(tmpDir + File.separator + TemplateLocation.Filename) : _storage.getFile(tmpDir + File.separator +
+ "volume.properties");
+ if (file.exists()) {
+ file.delete();
+ }
+
+ if (!file.createNewFile()) {
+ s_logger.warn("Unable to create new file: " + file.getAbsolutePath());
+ return "Unable to create new file: " + file.getAbsolutePath();
+ }
+
+ URI uri;
+ try {
+ uri = new URI(url);
+ } catch (URISyntaxException e) {
+ throw new CloudRuntimeException("URI is incorrect: " + url);
+ }
+ TemplateDownloader td;
+ if ((uri != null) && (uri.getScheme() != null)) {
+ if (uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")) {
+ td = new HttpTemplateDownloader(_storage, url, tmpDir, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType);
+ } else if (uri.getScheme().equalsIgnoreCase("file")) {
+ td = new LocalTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId));
+ } else if (uri.getScheme().equalsIgnoreCase("scp")) {
+ td = new ScpTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId));
+ } else if (uri.getScheme().equalsIgnoreCase("nfs") || uri.getScheme().equalsIgnoreCase("cifs")) {
+ td = null;
+ // TODO: implement this.
+ throw new CloudRuntimeException("Scheme is not supported " + url);
+ } else {
+ throw new CloudRuntimeException("Scheme is not supported " + url);
+ }
+ } else {
+ throw new CloudRuntimeException("Unable to download from URL: " + url);
+ }
+ // NOTE the difference between installPathPrefix and templatePath
+ // here. instalPathPrefix is the absolute path for template
+ // including mount directory
+ // on ssvm, while templatePath is the final relative path on
+ // secondary storage.
+ DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType);
+ dj.setTmpltPath(templatePath);
+ jobs.put(jobId, dj);
+ threadPool.execute(td);
+
+ return jobId;
+ } catch (IOException e) {
+ s_logger.warn("Unable to download to " + tmpDir, e);
+ return null;
+ }
+ }
+
+ @Override
+ public String getDownloadError(String jobId) {
+ DownloadJob dj = jobs.get(jobId);
+ if (dj != null) {
+ return dj.getTemplateDownloader().getDownloadError();
+ }
+ return null;
+ }
+
+ public long getDownloadTemplateSize(String jobId) {
+ DownloadJob dj = jobs.get(jobId);
+ if (dj != null) {
+ return dj.getTemplatesize();
+ }
+ return 0;
+ }
+
+ public String getDownloadCheckSum(String jobId) {
+ DownloadJob dj = jobs.get(jobId);
+ if (dj != null) {
+ return dj.getChecksum();
+ }
+ return null;
+ }
+
+ public long getDownloadTemplatePhysicalSize(String jobId) {
+ DownloadJob dj = jobs.get(jobId);
+ if (dj != null) {
+ return dj.getTemplatePhysicalSize();
+ }
+ return 0;
+ }
+
+ // @Override
+ public String getDownloadLocalPath(String jobId) {
+ DownloadJob dj = jobs.get(jobId);
+ if (dj != null) {
+ return dj.getTemplateDownloader().getDownloadLocalPath();
+ }
+ return null;
+ }
+
+ @Override
+ public int getDownloadPct(String jobId) {
+ DownloadJob dj = jobs.get(jobId);
+ if (dj != null) {
+ return dj.getTemplateDownloader().getDownloadPercent();
+ }
+ return 0;
+ }
+
+ public static VMTemplateHostVO.Status convertStatus(Status tds) {
+ switch (tds) {
+ case ABORTED:
+ return VMTemplateHostVO.Status.NOT_DOWNLOADED;
+ case DOWNLOAD_FINISHED:
+ return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS;
+ case IN_PROGRESS:
+ return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS;
+ case NOT_STARTED:
+ return VMTemplateHostVO.Status.NOT_DOWNLOADED;
+ case RECOVERABLE_ERROR:
+ return VMTemplateHostVO.Status.NOT_DOWNLOADED;
+ case UNKNOWN:
+ return VMTemplateHostVO.Status.UNKNOWN;
+ case UNRECOVERABLE_ERROR:
+ return VMTemplateHostVO.Status.DOWNLOAD_ERROR;
+ case POST_DOWNLOAD_FINISHED:
+ return VMTemplateHostVO.Status.DOWNLOADED;
+ default:
+ return VMTemplateHostVO.Status.UNKNOWN;
+ }
+ }
+
+ @Override
+ public com.cloud.storage.VMTemplateHostVO.Status getDownloadStatus2(String jobId) {
+ return convertStatus(getDownloadStatus(jobId));
+ }
+
+ @Override
+ public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd) {
+ ResourceType resourceType = cmd.getResourceType();
+ if (cmd instanceof DownloadProgressCommand) {
+ return handleDownloadProgressCmd(resource, (DownloadProgressCommand)cmd);
+ }
+
+ if (cmd.getUrl() == null) {
+ return new DownloadAnswer(resourceType.toString() + " is corrupted on storage due to an invalid url , cannot download",
+ VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+ }
+
+ if (cmd.getName() == null) {
+ return new DownloadAnswer("Invalid Name", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+ }
+
+ DataStoreTO dstore = cmd.getDataStore();
+ String installPathPrefix = cmd.getInstallPath();
+ // for NFS, we need to get mounted path
+ if (dstore instanceof NfsTO) {
+ installPathPrefix = resource.getRootDir(((NfsTO)dstore).getUrl()) + File.separator + installPathPrefix;
+ }
+ String user = null;
+ String password = null;
+ if (cmd.getAuth() != null) {
+ user = cmd.getAuth().getUserName();
+ password = cmd.getAuth().getPassword();
+ }
+ // TO DO - Define Volume max size as well
+ long maxDownloadSizeInBytes =
+ (cmd.getMaxDownloadSizeInBytes() == null) ? TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES : (cmd.getMaxDownloadSizeInBytes());
+ String jobId = null;
+ if (dstore instanceof S3TO) {
+ jobId =
+ downloadS3Template((S3TO)dstore, cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(),
+ cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType);
+ } else {
+ jobId =
+ downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(),
+ cmd.getChecksum(), installPathPrefix, cmd.getInstallPath(), user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType);
+ }
+ sleep();
+ if (jobId == null) {
+ return new DownloadAnswer("Internal Error", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+ }
+ return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), getInstallPath(jobId),
+ getDownloadTemplateSize(jobId), getDownloadTemplateSize(jobId), getDownloadCheckSum(jobId));
+ }
+
+ private void sleep() {
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+
+ private DownloadAnswer handleDownloadProgressCmd(SecondaryStorageResource resource, DownloadProgressCommand cmd) {
+ String jobId = cmd.getJobId();
+ DownloadAnswer answer;
+ DownloadJob dj = null;
+ if (jobId != null) {
+ dj = jobs.get(jobId);
+ }
+ if (dj == null) {
+ if (cmd.getRequest() == RequestType.GET_OR_RESTART) {
+ DownloadCommand dcmd = new DownloadCommand(cmd);
+ return handleDownloadCommand(resource, dcmd);
+ } else {
+ return new DownloadAnswer("Cannot find job", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.UNKNOWN);
+ }
+ }
+ TemplateDownloader td = dj.getTemplateDownloader();
+ switch (cmd.getRequest()) {
+ case GET_STATUS:
+ break;
+ case ABORT:
+ td.stopDownload();
+ sleep();
+ break;
+ case RESTART:
+ td.stopDownload();
+ sleep();
+ threadPool.execute(td);
+ break;
+ case PURGE:
+ td.stopDownload();
+ answer =
+ new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId),
+ getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId));
+ jobs.remove(jobId);
+ return answer;
+ default:
+ break; // TODO
+ }
+ return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), getInstallPath(jobId),
+ getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId));
+ }
+
+ private String getInstallPath(String jobId) {
+ DownloadJob dj = jobs.get(jobId);
+ if (dj != null) {
+ return dj.getTmpltPath();
+ }
+ return null;
+ }
+
+ private List<String> listVolumes(String rootdir) {
+ List<String> result = new ArrayList<String>();
+
+ Script script = new Script(listVolScr, s_logger);
+ script.add("-r", rootdir);
+ ZfsPathParser zpp = new ZfsPathParser(rootdir);
+ script.execute(zpp);
+ result.addAll(zpp.getPaths());
+ s_logger.info("found " + zpp.getPaths().size() + " volumes" + zpp.getPaths());
+ return result;
+ }
+
+ private List<String> listTemplates(String rootdir) {
+ List<String> result = new ArrayList<String>();
+
+ Script script = new Script(listTmpltScr, s_logger);
+ script.add("-r", rootdir);
+ ZfsPathParser zpp = new ZfsPathParser(rootdir);
+ script.execute(zpp);
+ result.addAll(zpp.getPaths());
+ s_logger.info("found " + zpp.getPaths().size() + " templates" + zpp.getPaths());
+ return result;
+ }
+
+ @Override
+ public Map<String, TemplateProp> gatherTemplateInfo(String rootDir) {
+ Map<String, TemplateProp> result = new HashMap<String, TemplateProp>();
+ String templateDir = rootDir + File.separator + _templateDir;
+
+ if (!_storage.exists(templateDir)) {
+ _storage.mkdirs(templateDir);
+ }
+
+ List<String> publicTmplts = listTemplates(templateDir);
+ for (String tmplt : publicTmplts) {
+ String path = tmplt.substring(0, tmplt.lastIndexOf(File.separator));
+ TemplateLocation loc = new TemplateLocation(_storage, path);
+ try {
+ if (!loc.load()) {
+ s_logger.warn("Post download installation was not completed for " + path);
+ // loc.purge();
+ _storage.cleanup(path, templateDir);
+ continue;
+ }
+ } catch (IOException e) {
+ s_logger.warn("Unable to load template location " + path, e);
+ continue;
+ }
+
+ TemplateProp tInfo = loc.getTemplateInfo();
+
+ if ((tInfo.getSize() == tInfo.getPhysicalSize()) && (tInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
+ try {
+ Processor processor = _processors.get("OVA Processor");
+ OVAProcessor vmdkProcessor = (OVAProcessor)processor;
+ long vSize = vmdkProcessor.getTemplateVirtualSize(path, tInfo.getInstallPath().substring(tInfo.getInstallPath().lastIndexOf(File.separator) + 1));
+ tInfo.setSize(vSize);
+ loc.updateVirtualSize(vSize);
+ loc.save();
+ } catch (Exception e) {
+ s_logger.error("Unable to get the virtual size of the template: " + tInfo.getInstallPath() + " due to " + e.getMessage());
+ }
+ }
+
+ result.put(tInfo.getTemplateName(), tInfo);
+ s_logger.debug("Added template name: " + tInfo.getTemplateName() + ", path: " + tmplt);
+ }
+ /*
+ for (String tmplt : isoTmplts) {
+ String tmp[];
+ tmp = tmplt.split("/");
+ String tmpltName = tmp[tmp.length - 2];
+ tmplt = tmplt.substring(tmplt.lastIndexOf("iso/"));
+ TemplateInfo tInfo = new TemplateInfo(tmpltName, tmplt, false);
+ s_logger.debug("Added iso template name: " + tmpltName + ", path: " + tmplt);
+ result.put(tmpltName, tInfo);
+ }
+ */
+ return result;
+ }
+
+ @Override
+ public Map<Long, TemplateProp> gatherVolumeInfo(String rootDir) {
+ Map<Long, TemplateProp> result = new HashMap<Long, TemplateProp>();
+ String volumeDir = rootDir + File.separator + _volumeDir;
+
+ if (!_storage.exists(volumeDir)) {
+ _storage.mkdirs(volumeDir);
+ }
+
+ List<String> vols = listVolumes(volumeDir);
+ for (String vol : vols) {
+ String path = vol.substring(0, vol.lastIndexOf(File.separator));
+ TemplateLocation loc = new TemplateLocation(_storage, path);
+ try {
+ if (!loc.load()) {
+ s_logger.warn("Post download installation was not completed for " + path);
+ // loc.purge();
+ _storage.cleanup(path, volumeDir);
+ continue;
+ }
+ } catch (IOException e) {
+ s_logger.warn("Unable to load volume location " + path, e);
+ continue;
+ }
+
+ TemplateProp vInfo = loc.getTemplateInfo();
+
+ if ((vInfo.getSize() == vInfo.getPhysicalSize()) && (vInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
+ try {
+ Processor processor = _processors.get("OVA Processor");
+ OVAProcessor vmdkProcessor = (OVAProcessor)processor;
+ long vSize = vmdkProcessor.getTemplateVirtualSize(path, vInfo.getInstallPath().substring(vInfo.getInstallPath().lastIndexOf(File.separator) + 1));
+ vInfo.setSize(vSize);
+ loc.updateVirtualSize(vSize);
+ loc.save();
+ } catch (Exception e) {
+ s_logger.error("Unable to get the virtual size of the volume: " + vInfo.getInstallPath() + " due to " + e.getMessage());
+ }
+ }
+
+ result.put(vInfo.getId(), vInfo);
+ s_logger.debug("Added volume name: " + vInfo.getTemplateName() + ", path: " + vol);
+ }
+ return result;
+ }
+
+ public static class ZfsPathParser extends OutputInterpreter {
+ String _parent;
+ List<String> paths = new ArrayList<String>();
+
+ public ZfsPathParser(String parent) {
+ _parent = parent;
+ }
+
+ @Override
+ public String interpret(BufferedReader reader) throws IOException {
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ paths.add(line);
+ }
+ return null;
+ }
+
+ public List<String> getPaths() {
+ return paths;
+ }
+
+ @Override
+ public boolean drain() {
+ return true;
+ }
+ }
+
+ public DownloadManagerImpl() {
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ _name = name;
+
+ String value = null;
+
+ _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
+ if (_storage == null) {
+ value = (String)params.get(StorageLayer.ClassConfigKey);
+ if (value == null) {
+ throw new ConfigurationException("Unable to find the storage layer");
+ }
+
+ Class<StorageLayer> clazz;
+ try {
+ clazz = (Class<StorageLayer>)Class.forName(value);
+ _storage = clazz.newInstance();
+ } catch (ClassNotFoundException e) {
+ throw new ConfigurationException("Unable to instantiate " + value);
+ } catch (InstantiationException e) {
+ throw new ConfigurationException("Unable to instantiate " + value);
+ } catch (IllegalAccessException e) {
+ throw new ConfigurationException("Unable to instantiate " + value);
+ }
+ }
+
+ String inSystemVM = (String)params.get("secondary.storage.vm");
+ if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) {
+ s_logger.info("DownloadManager: starting additional services since we are inside system vm");
+ startAdditionalServices();
+ blockOutgoingOnPrivate();
+ }
+
+ value = (String)params.get("install.timeout.pergig");
+ installTimeoutPerGig = NumbersUtil.parseInt(value, 15 * 60) * 1000;
+
+ value = (String)params.get("install.numthreads");
+ final int numInstallThreads = NumbersUtil.parseInt(value, 10);
+
+ String scriptsDir = (String)params.get("template.scripts.dir");
+ if (scriptsDir == null) {
+ scriptsDir = "scripts/storage/secondary";
+ }
+
+ listTmpltScr = Script.findScript(scriptsDir, "listvmtmplt.sh");
+ if (listTmpltScr == null) {
+ throw new ConfigurationException("Unable to find the listvmtmplt.sh");
+ }
+ s_logger.info("listvmtmplt.sh found in " + listTmpltScr);
+
+ createTmpltScr = Script.findScript(scriptsDir, "createtmplt.sh");
+ if (createTmpltScr == null) {
+ throw new ConfigurationException("Unable to find createtmplt.sh");
+ }
+ s_logger.info("createtmplt.sh found in " + createTmpltScr);
+
+ listVolScr = Script.findScript(scriptsDir, "listvolume.sh");
+ if (listVolScr == null) {
+ throw new ConfigurationException("Unable to find the listvolume.sh");
+ }
+ s_logger.info("listvolume.sh found in " + listVolScr);
+
+ createVolScr = Script.findScript(scriptsDir, "createvolume.sh");
+ if (createVolScr == null) {
+ throw new ConfigurationException("Unable to find createvolume.sh");
+ }
+ s_logger.info("createvolume.sh found in " + createVolScr);
+
+ _processors = new HashMap<String, Processor>();
+
+ Processor processor = new VhdProcessor();
+ processor.configure("VHD Processor", params);
+ _processors.put("VHD Processor", processor);
+
+ processor = new IsoProcessor();
+ processor.configure("ISO Processor", params);
+ _processors.put("ISO Processor", processor);
+
+ processor = new QCOW2Processor();
+ processor.configure("QCOW2 Processor", params);
+ _processors.put("QCOW2 Processor", processor);
+
+ processor = new OVAProcessor();
+ processor.configure("OVA Processor", params);
+ _processors.put("OVA Processor", processor);
+
+ processor = new VmdkProcessor();
+ processor.configure("VMDK Processor", params);
+ _processors.put("VMDK Processor", processor);
+
+ processor = new RawImageProcessor();
+ processor.configure("Raw Image Processor", params);
+ _processors.put("Raw Image Processor", processor);
+
+ _templateDir = (String)params.get("public.templates.root.dir");
+ if (_templateDir == null) {
+ _templateDir = TemplateConstants.DEFAULT_TMPLT_ROOT_DIR;
+ }
+ _templateDir += File.separator + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR;
+ _volumeDir = TemplateConstants.DEFAULT_VOLUME_ROOT_DIR + File.separator;
+ // Add more processors here.
+ threadPool = Executors.newFixedThreadPool(numInstallThreads);
+ return true;
+ }
+
+ private void blockOutgoingOnPrivate() {
+ Script command = new Script("/bin/bash", s_logger);
+ String intf = "eth1";
+ command.add("-c");
+ command.add("iptables -A OUTPUT -o " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "80" + " -j REJECT;" + "iptables -A OUTPUT -o " + intf +
+ " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j REJECT;");
+
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in blocking outgoing to port 80/443 err=" + result);
+ return;
+ }
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ private void startAdditionalServices() {
+
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("if [ -d /etc/apache2 ] ; then service apache2 stop; else service httpd stop; fi ");
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in stopping httpd service err=" + result);
+ }
+ String port = Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
+ String intf = TemplateConstants.DEFAULT_TMPLT_COPY_INTF;
+
+ command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j ACCEPT;" + "iptables -I INPUT -i " + intf +
+ " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j ACCEPT;");
+
+ result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in opening up httpd port err=" + result);
+ return;
+ }
+
+ command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("if [ -d /etc/apache2 ] ; then service apache2 start; else service httpd start; fi ");
+ result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in starting httpd service err=" + result);
+ return;
+ }
+ command = new Script("mkdir", s_logger);
+ command.add("-p");
+ command.add("/var/www/html/copy/template");
+ result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in creating directory =" + result);
+ return;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java
new file mode 100755
index 0000000..be99fea
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java
@@ -0,0 +1,82 @@
+// 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.storage.template;
+
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+
+import com.cloud.agent.api.storage.CreateEntityDownloadURLAnswer;
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLAnswer;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.UploadAnswer;
+import com.cloud.agent.api.storage.UploadCommand;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Upload.Status;
+import com.cloud.storage.template.TemplateUploader;
+import com.cloud.utils.component.Manager;
+
+public interface UploadManager extends Manager {
+
+ /**
+ * @param jobId job Id
+ * @return status of the upload job
+ */
+ public TemplateUploader.Status getUploadStatus(String jobId);
+
+ /**
+ * @param jobId job Id
+ * @return status of the upload job
+ */
+ public Status getUploadStatus2(String jobId);
+
+ /**
+ * Get the upload percent of a upload job
+ * @param jobId job Id
+ * @return
+ */
+ public int getUploadPct(String jobId);
+
+ /**
+ * Get the upload error if any
+ * @param jobId job Id
+ * @return
+ */
+ public String getUploadError(String jobId);
+
+ /**
+ * Get the local path for the upload
+ * @param jobId job Id
+ * @return
+ public String getUploadLocalPath(String jobId);
+ */
+
+ /** Handle upload commands from the management server
+ * @param cmd cmd from server
+ * @return answer representing status of upload.
+ */
+ public UploadAnswer handleUploadCommand(SecondaryStorageResource resource, UploadCommand cmd);
+
+ public String getPublicTemplateRepo();
+
+ String uploadPublicTemplate(long id, String url, String name, ImageFormat format, Long accountId, String descr, String cksum, String installPathPrefix, String user,
+ String password, long maxTemplateSizeInBytes);
+
+ CreateEntityDownloadURLAnswer handleCreateEntityURLCommand(CreateEntityDownloadURLCommand cmd);
+
+ DeleteEntityDownloadURLAnswer handleDeleteEntityDownloadURLCommand(DeleteEntityDownloadURLCommand cmd);
+
+}
[02/11] Moved the secondary storage service into its own server
directory
Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
deleted file mode 100755
index ee50647..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
+++ /dev/null
@@ -1,312 +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 org.apache.cloudstack.storage.resource;
-
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URI;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status.Event;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.resource.Discoverer;
-import com.cloud.resource.DiscovererBase;
-import com.cloud.resource.ServerResource;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.VMTemplateZoneVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateZoneDao;
-import com.cloud.storage.resource.DummySecondaryStorageResource;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.net.NfsUtils;
-import com.cloud.utils.script.Script;
-
-/**
- * SecondaryStorageDiscoverer is used to discover secondary
- * storage servers and make sure everything it can do is
- * correct.
- */
-@Local(value = Discoverer.class)
-public class SecondaryStorageDiscoverer extends DiscovererBase implements Discoverer {
- private static final Logger s_logger = Logger.getLogger(SecondaryStorageDiscoverer.class);
-
- long _timeout = 2 * 60 * 1000; // 2 minutes
- String _mountParent;
- boolean _useServiceVM = false;
-
- Random _random = new Random(System.currentTimeMillis());
- @Inject
- protected VMTemplateDao _tmpltDao = null;
- @Inject
- protected VMTemplateZoneDao _vmTemplateZoneDao = null;
- @Inject
- protected VMTemplateDao _vmTemplateDao = null;
- @Inject
- protected AgentManager _agentMgr = null;
-
- protected SecondaryStorageDiscoverer() {
- }
-
- @Override
- public Map<? extends ServerResource, Map<String, String>>
- find(long dcId, Long podId, Long clusterId, URI uri, String username, String password, List<String> hostTags) {
- if (!uri.getScheme().equalsIgnoreCase("nfs") && !uri.getScheme().equalsIgnoreCase("cifs") && !uri.getScheme().equalsIgnoreCase("file") &&
- !uri.getScheme().equalsIgnoreCase("iso") && !uri.getScheme().equalsIgnoreCase("dummy")) {
- s_logger.debug("It's not NFS or file or ISO, so not a secondary storage server: " + uri.toString());
- return null;
- }
-
- if (uri.getScheme().equalsIgnoreCase("nfs") || uri.getScheme().equalsIgnoreCase("cifs") || uri.getScheme().equalsIgnoreCase("iso")) {
- return createNfsSecondaryStorageResource(dcId, podId, uri);
- } else if (uri.getScheme().equalsIgnoreCase("file")) {
- return createLocalSecondaryStorageResource(dcId, podId, uri);
- } else if (uri.getScheme().equalsIgnoreCase("dummy")) {
- return createDummySecondaryStorageResource(dcId, podId, uri);
- } else {
- return null;
- }
- }
-
- protected Map<? extends ServerResource, Map<String, String>> createNfsSecondaryStorageResource(long dcId, Long podId, URI uri) {
-
- if (_useServiceVM) {
- return createDummySecondaryStorageResource(dcId, podId, uri);
- }
- String mountStr = NfsUtils.uri2Mount(uri);
-
- Script script = new Script(true, "mount", _timeout, s_logger);
- String mntPoint = null;
- File file = null;
- do {
- mntPoint = _mountParent + File.separator + Integer.toHexString(_random.nextInt(Integer.MAX_VALUE));
- file = new File(mntPoint);
- } while (file.exists());
-
- if (!file.mkdirs()) {
- s_logger.warn("Unable to make directory: " + mntPoint);
- return null;
- }
-
- script.add(mountStr, mntPoint);
- String result = script.execute();
- if (result != null && !result.contains("already mounted")) {
- s_logger.warn("Unable to mount " + uri.toString() + " due to " + result);
- file.delete();
- return null;
- }
-
- script = new Script(true, "umount", 0, s_logger);
- script.add(mntPoint);
- script.execute();
-
- file.delete();
-
- Map<NfsSecondaryStorageResource, Map<String, String>> srs = new HashMap<NfsSecondaryStorageResource, Map<String, String>>();
-
- NfsSecondaryStorageResource storage;
- if (_configDao.isPremium()) {
- Class<?> impl;
- String name = "com.cloud.storage.resource.PremiumSecondaryStorageResource";
- try {
- impl = Class.forName(name);
- final Constructor<?> constructor = impl.getDeclaredConstructor();
- constructor.setAccessible(true);
- storage = (NfsSecondaryStorageResource)constructor.newInstance();
- } catch (final ClassNotFoundException e) {
- s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to ClassNotFoundException");
- return null;
- } catch (final SecurityException e) {
- s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to SecurityException");
- return null;
- } catch (final NoSuchMethodException e) {
- s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to NoSuchMethodException");
- return null;
- } catch (final IllegalArgumentException e) {
- s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to IllegalArgumentException");
- return null;
- } catch (final InstantiationException e) {
- s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to InstantiationException");
- return null;
- } catch (final IllegalAccessException e) {
- s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to IllegalAccessException");
- return null;
- } catch (final InvocationTargetException e) {
- s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to InvocationTargetException");
- return null;
- }
- } else {
- storage = new NfsSecondaryStorageResource();
- }
-
- Map<String, String> details = new HashMap<String, String>();
- details.put("mount.path", mountStr);
- details.put("orig.url", uri.toString());
- details.put("mount.parent", _mountParent);
-
- Map<String, Object> params = new HashMap<String, Object>();
- params.putAll(details);
- params.put("zone", Long.toString(dcId));
- if (podId != null) {
- params.put("pod", podId.toString());
- }
- params.put("guid", uri.toString());
- params.put("secondary.storage.vm", "false");
- params.put("max.template.iso.size", _configDao.getValue("max.template.iso.size"));
-
- try {
- storage.configure("Storage", params);
- } catch (ConfigurationException e) {
- s_logger.warn("Unable to configure the storage ", e);
- return null;
- }
- srs.put(storage, details);
-
- return srs;
- }
-
- protected Map<? extends ServerResource, Map<String, String>> createLocalSecondaryStorageResource(long dcId, Long podId, URI uri) {
- Map<LocalSecondaryStorageResource, Map<String, String>> srs = new HashMap<LocalSecondaryStorageResource, Map<String, String>>();
-
- LocalSecondaryStorageResource storage = new LocalSecondaryStorageResource();
- storage = ComponentContext.inject(storage);
-
- Map<String, String> details = new HashMap<String, String>();
-
- File file = new File(uri);
- details.put("mount.path", file.getAbsolutePath());
- details.put("orig.url", uri.toString());
-
- Map<String, Object> params = new HashMap<String, Object>();
- params.putAll(details);
- params.put("zone", Long.toString(dcId));
- if (podId != null) {
- params.put("pod", podId.toString());
- }
- params.put("guid", uri.toString());
-
- try {
- storage.configure("Storage", params);
- } catch (ConfigurationException e) {
- s_logger.warn("Unable to configure the storage ", e);
- return null;
- }
- srs.put(storage, details);
-
- return srs;
- }
-
- protected Map<ServerResource, Map<String, String>> createDummySecondaryStorageResource(long dcId, Long podId, URI uri) {
- Map<ServerResource, Map<String, String>> srs = new HashMap<ServerResource, Map<String, String>>();
-
- DummySecondaryStorageResource storage = new DummySecondaryStorageResource(_useServiceVM);
- storage = ComponentContext.inject(storage);
-
- Map<String, String> details = new HashMap<String, String>();
-
- details.put("mount.path", uri.toString());
- details.put("orig.url", uri.toString());
-
- Map<String, Object> params = new HashMap<String, Object>();
- params.putAll(details);
- params.put("zone", Long.toString(dcId));
- if (podId != null) {
- params.put("pod", podId.toString());
- }
- params.put("guid", uri.toString());
-
- try {
- storage.configure("Storage", params);
- } catch (ConfigurationException e) {
- s_logger.warn("Unable to configure the storage ", e);
- return null;
- }
- srs.put(storage, details);
-
- return srs;
- }
-
- @Override
- public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
- super.configure(name, params);
-
- _mountParent = _params.get("mount.parent");
- if (_mountParent == null) {
- _mountParent = "/mnt";
- }
-
- String useServiceVM = _params.get("secondary.storage.vm");
- if ("true".equalsIgnoreCase(useServiceVM)) {
- _useServiceVM = true;
- }
- return true;
- }
-
- @Override
- public boolean matchHypervisor(String hypervisor) {
- if (hypervisor.equals("SecondaryStorage")) {
- return true;
- } else {
- return false;
- }
- }
-
- @Override
- public Hypervisor.HypervisorType getHypervisorType() {
- return Hypervisor.HypervisorType.None;
- }
-
- @Override
- public void postDiscovery(List<HostVO> hosts, long msId) {
- if (_useServiceVM) {
- for (HostVO h : hosts) {
- _agentMgr.agentStatusTransitTo(h, Event.AgentDisconnected, msId);
- }
- }
- for (HostVO h : hosts) {
- associateTemplatesToZone(h.getId(), h.getDataCenterId());
- }
-
- }
-
- private void associateTemplatesToZone(long hostId, long dcId) {
- VMTemplateZoneVO tmpltZone;
-
- List<VMTemplateVO> allTemplates = _vmTemplateDao.listAll();
- for (VMTemplateVO vt : allTemplates) {
- if (vt.isCrossZones()) {
- tmpltZone = _vmTemplateZoneDao.findByZoneTemplate(dcId, vt.getId());
- if (tmpltZone == null) {
- VMTemplateZoneVO vmTemplateZone = new VMTemplateZoneVO(dcId, vt.getId(), new Date());
- _vmTemplateZoneDao.persist(vmTemplateZone);
- }
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
deleted file mode 100755
index 93fd8ea..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
+++ /dev/null
@@ -1,29 +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 org.apache.cloudstack.storage.resource;
-
-import com.cloud.resource.ServerResource;
-
-/**
- *
- * SecondaryStorageServerResource is a generic container to execute commands sent
- */
-public interface SecondaryStorageResource extends ServerResource {
-
- public String getRootDir(String cmd);
-
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
deleted file mode 100644
index 14ebc71..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
+++ /dev/null
@@ -1,24 +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 org.apache.cloudstack.storage.resource;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-
-public interface SecondaryStorageResourceHandler {
- Answer executeRequest(Command cmd);
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManager.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManager.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManager.java
deleted file mode 100644
index d0abe2c..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManager.java
+++ /dev/null
@@ -1,108 +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 org.apache.cloudstack.storage.template;
-
-import java.util.Map;
-
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
-import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
-
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.storage.Proxy;
-import com.cloud.agent.api.to.S3TO;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.template.TemplateDownloader;
-import com.cloud.storage.template.TemplateProp;
-import com.cloud.utils.component.Manager;
-
-public interface DownloadManager extends Manager {
-
- /**
- * Initiate download of a public template
- * @param id unique id.
- * @param url the url from where to download from
- * @param hvm whether the template is a hardware virtual machine
- * @param accountId the accountId of the iso owner (null if public iso)
- * @param descr description of the template
- * @param user username used for authentication to the server
- * @param password password used for authentication to the server
- * @param maxDownloadSizeInBytes (optional) max download size for the template, in bytes.
- * @param resourceType signifying the type of resource like template, volume etc.
- * @return job-id that can be used to interrogate the status of the download.
- */
- public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
- String installPathPrefix, String templatePath, String userName, String passwd, long maxDownloadSizeInBytes, Proxy proxy, ResourceType resourceType);
-
- public String downloadS3Template(S3TO s3, long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
- String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType);
-
- /**
- * Get the status of a download job
- * @param jobId job Id
- * @return status of the download job
- */
- public TemplateDownloader.Status getDownloadStatus(String jobId);
-
- /**
- * Get the status of a download job
- * @param jobId job Id
- * @return status of the download job
- */
- public VMTemplateHostVO.Status getDownloadStatus2(String jobId);
-
- /**
- * Get the download percent of a download job
- * @param jobId job Id
- * @return
- */
- public int getDownloadPct(String jobId);
-
- /**
- * Get the download error if any
- * @param jobId job Id
- * @return
- */
- public String getDownloadError(String jobId);
-
- /**
- * Get the local path for the download
- * @param jobId job Id
- * @return
- public String getDownloadLocalPath(String jobId);
- */
-
- /** Handle download commands from the management server
- * @param cmd cmd from server
- * @return answer representing status of download.
- */
- public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd);
-
- /**
- /**
- * @return list of template info for installed templates
- */
- public Map<String, TemplateProp> gatherTemplateInfo(String templateDir);
-
- /**
- /**
- * @return list of volume info for installed volumes
- */
- public Map<Long, TemplateProp> gatherVolumeInfo(String volumeDir);
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
deleted file mode 100755
index d45a6bb..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
+++ /dev/null
@@ -1,1080 +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 org.apache.cloudstack.storage.template;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import javax.ejb.Local;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
-import org.apache.cloudstack.storage.command.DownloadProgressCommand;
-import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType;
-import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
-
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.storage.Proxy;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.S3TO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.template.HttpTemplateDownloader;
-import com.cloud.storage.template.IsoProcessor;
-import com.cloud.storage.template.LocalTemplateDownloader;
-import com.cloud.storage.template.OVAProcessor;
-import com.cloud.storage.template.Processor;
-import com.cloud.storage.template.Processor.FormatInfo;
-import com.cloud.storage.template.QCOW2Processor;
-import com.cloud.storage.template.RawImageProcessor;
-import com.cloud.storage.template.S3TemplateDownloader;
-import com.cloud.storage.template.ScpTemplateDownloader;
-import com.cloud.storage.template.TemplateConstants;
-import com.cloud.storage.template.TemplateDownloader;
-import com.cloud.storage.template.TemplateDownloader.DownloadCompleteCallback;
-import com.cloud.storage.template.TemplateDownloader.Status;
-import com.cloud.storage.template.TemplateLocation;
-import com.cloud.storage.template.TemplateProp;
-import com.cloud.storage.template.VhdProcessor;
-import com.cloud.storage.template.VmdkProcessor;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.OutputInterpreter;
-import com.cloud.utils.script.Script;
-
-@Local(value = DownloadManager.class)
-public class DownloadManagerImpl extends ManagerBase implements DownloadManager {
- private String _name;
- StorageLayer _storage;
- Map<String, Processor> _processors;
-
- public class Completion implements DownloadCompleteCallback {
- private final String jobId;
-
- public Completion(String jobId) {
- this.jobId = jobId;
- }
-
- @Override
- public void downloadComplete(Status status) {
- setDownloadStatus(jobId, status);
- }
- }
-
- private static class DownloadJob {
- private final TemplateDownloader td;
- private final String tmpltName;
- private final boolean hvm;
- private final ImageFormat format;
- private String tmpltPath;
- private final String description;
- private String checksum;
- private final String installPathPrefix;
- private long templatesize;
- private long templatePhysicalSize;
- private final long id;
- private final ResourceType resourceType;
-
- public DownloadJob(TemplateDownloader td, String jobId, long id, String tmpltName, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
- String installPathPrefix, ResourceType resourceType) {
- super();
- this.td = td;
- this.tmpltName = tmpltName;
- this.format = format;
- this.hvm = hvm;
- description = descr;
- checksum = cksum;
- this.installPathPrefix = installPathPrefix;
- templatesize = 0;
- this.id = id;
- this.resourceType = resourceType;
- }
-
- public String getDescription() {
- return description;
- }
-
- public String getChecksum() {
- return checksum;
- }
-
- public TemplateDownloader getTemplateDownloader() {
- return td;
- }
-
- public String getTmpltName() {
- return tmpltName;
- }
-
- public ImageFormat getFormat() {
- return format;
- }
-
- public boolean isHvm() {
- return hvm;
- }
-
- public long getId() {
- return id;
- }
-
- public ResourceType getResourceType() {
- return resourceType;
- }
-
- public void setTmpltPath(String tmpltPath) {
- this.tmpltPath = tmpltPath;
- }
-
- public String getTmpltPath() {
- return tmpltPath;
- }
-
- public String getInstallPathPrefix() {
- return installPathPrefix;
- }
-
- public void cleanup() {
- if (td != null) {
- String dnldPath = td.getDownloadLocalPath();
- if (dnldPath != null) {
- File f = new File(dnldPath);
- File dir = f.getParentFile();
- f.delete();
- if (dir != null) {
- dir.delete();
- }
- }
- }
-
- }
-
- public void setTemplatesize(long templatesize) {
- this.templatesize = templatesize;
- }
-
- public long getTemplatesize() {
- return templatesize;
- }
-
- public void setTemplatePhysicalSize(long templatePhysicalSize) {
- this.templatePhysicalSize = templatePhysicalSize;
- }
-
- public long getTemplatePhysicalSize() {
- return templatePhysicalSize;
- }
-
- public void setCheckSum(String checksum) {
- this.checksum = checksum;
- }
- }
-
- public static final Logger s_logger = Logger.getLogger(DownloadManagerImpl.class);
- private String _templateDir;
- private String _volumeDir;
- private String createTmpltScr;
- private String createVolScr;
-
- private ExecutorService threadPool;
-
- private final Map<String, DownloadJob> jobs = new ConcurrentHashMap<String, DownloadJob>();
- private String listTmpltScr;
- private String listVolScr;
- private int installTimeoutPerGig = 180 * 60 * 1000;
-
- public void setThreadPool(ExecutorService threadPool) {
- this.threadPool = threadPool;
- }
-
- public void setStorageLayer(StorageLayer storage) {
- _storage = storage;
- }
-
- /**
- * Get notified of change of job status. Executed in context of downloader
- * thread
- *
- * @param jobId
- * the id of the job
- * @param status
- * the status of the job
- */
- public void setDownloadStatus(String jobId, Status status) {
- DownloadJob dj = jobs.get(jobId);
- if (dj == null) {
- s_logger.warn("setDownloadStatus for jobId: " + jobId + ", status=" + status + " no job found");
- return;
- }
- TemplateDownloader td = dj.getTemplateDownloader();
- s_logger.info("Download Completion for jobId: " + jobId + ", status=" + status);
- s_logger.info("local: " + td.getDownloadLocalPath() + ", bytes=" + td.getDownloadedBytes() + ", error=" + td.getDownloadError() + ", pct=" +
- td.getDownloadPercent());
-
- switch (status) {
- case ABORTED:
- case NOT_STARTED:
- case UNRECOVERABLE_ERROR:
- // TODO
- dj.cleanup();
- break;
- case UNKNOWN:
- return;
- case IN_PROGRESS:
- s_logger.info("Resuming jobId: " + jobId + ", status=" + status);
- td.setResume(true);
- threadPool.execute(td);
- break;
- case RECOVERABLE_ERROR:
- threadPool.execute(td);
- break;
- case DOWNLOAD_FINISHED:
- if (!(td instanceof S3TemplateDownloader)) {
- // we currently only create template.properties for NFS by
- // running some post download script
- td.setDownloadError("Download success, starting install ");
- String result = postDownload(jobId);
- if (result != null) {
- s_logger.error("Failed post download script: " + result);
- td.setStatus(Status.UNRECOVERABLE_ERROR);
- td.setDownloadError("Failed post download script: " + result);
- } else {
- td.setStatus(Status.POST_DOWNLOAD_FINISHED);
- td.setDownloadError("Install completed successfully at " + new SimpleDateFormat().format(new Date()));
- }
- } else {
- // for s3 and swift, we skip post download step and just set
- // status to trigger callback.
- td.setStatus(Status.POST_DOWNLOAD_FINISHED);
- // set template size for S3
- S3TemplateDownloader std = (S3TemplateDownloader)td;
- long size = std.totalBytes;
- DownloadJob dnld = jobs.get(jobId);
- dnld.setTemplatesize(size);
- dnld.setTemplatePhysicalSize(size);
- dnld.setTmpltPath(std.getDownloadLocalPath()); // update template path to include file name.
- }
- dj.cleanup();
- break;
- default:
- break;
- }
- }
-
- private String computeCheckSum(File f) {
- byte[] buffer = new byte[8192];
- int read = 0;
- MessageDigest digest;
- String checksum = null;
- InputStream is = null;
- 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 = String.format("%032x", bigInt);
- return checksum;
- } catch (IOException e) {
- return null;
- } catch (NoSuchAlgorithmException e) {
- return null;
- } finally {
- try {
- if (is != null)
- is.close();
- } catch (IOException e) {
- return null;
- }
- }
- }
-
- /**
- * Post download activity (install and cleanup). Executed in context of
- * downloader thread
- *
- * @throws IOException
- */
- private String postDownload(String jobId) {
- DownloadJob dnld = jobs.get(jobId);
- TemplateDownloader td = dnld.getTemplateDownloader();
- String resourcePath = dnld.getInstallPathPrefix(); // path with mount
- // directory
- String finalResourcePath = dnld.getTmpltPath(); // template download
- // path on secondary
- // storage
- ResourceType resourceType = dnld.getResourceType();
-
- File originalTemplate = new File(td.getDownloadLocalPath());
- String checkSum = computeCheckSum(originalTemplate);
- if (checkSum == null) {
- s_logger.warn("Something wrong happened when try to calculate the checksum of downloaded template!");
- }
- dnld.setCheckSum(checkSum);
-
- int imgSizeGigs = (int)Math.ceil(_storage.getSize(td.getDownloadLocalPath()) * 1.0d / (1024 * 1024 * 1024));
- imgSizeGigs++; // add one just in case
- long timeout = imgSizeGigs * installTimeoutPerGig;
- Script scr = null;
- String script = resourceType == ResourceType.TEMPLATE ? createTmpltScr : createVolScr;
- scr = new Script(script, timeout, s_logger);
- scr.add("-s", Integer.toString(imgSizeGigs));
- scr.add("-S", Long.toString(td.getMaxTemplateSizeInBytes()));
- if (dnld.getDescription() != null && dnld.getDescription().length() > 1) {
- scr.add("-d", dnld.getDescription());
- }
- if (dnld.isHvm()) {
- scr.add("-h");
- }
-
- // add options common to ISO and template
- String extension = dnld.getFormat().getFileExtension();
- String templateName = "";
- if (extension.equals("iso")) {
- templateName = jobs.get(jobId).getTmpltName().trim().replace(" ", "_");
- } else {
- templateName = java.util.UUID.nameUUIDFromBytes((jobs.get(jobId).getTmpltName() + System.currentTimeMillis()).getBytes()).toString();
- }
-
- // run script to mv the temporary template file to the final template
- // file
- String templateFilename = templateName + "." + extension;
- dnld.setTmpltPath(finalResourcePath + "/" + templateFilename);
- scr.add("-n", templateFilename);
-
- scr.add("-t", resourcePath);
- scr.add("-f", td.getDownloadLocalPath()); // this is the temporary
- // template file downloaded
- if (dnld.getChecksum() != null && dnld.getChecksum().length() > 1) {
- scr.add("-c", dnld.getChecksum());
- }
- scr.add("-u"); // cleanup
- String result;
- result = scr.execute();
-
- if (result != null) {
- return result;
- }
-
- // Set permissions for the downloaded template
- File downloadedTemplate = new File(resourcePath + "/" + templateFilename);
- _storage.setWorldReadableAndWriteable(downloadedTemplate);
-
- // Set permissions for template/volume.properties
- String propertiesFile = resourcePath;
- if (resourceType == ResourceType.TEMPLATE) {
- propertiesFile += "/template.properties";
- } else {
- propertiesFile += "/volume.properties";
- }
- File templateProperties = new File(propertiesFile);
- _storage.setWorldReadableAndWriteable(templateProperties);
-
- TemplateLocation loc = new TemplateLocation(_storage, resourcePath);
- try {
- loc.create(dnld.getId(), true, dnld.getTmpltName());
- } catch (IOException e) {
- s_logger.warn("Something is wrong with template location " + resourcePath, e);
- loc.purge();
- return "Unable to download due to " + e.getMessage();
- }
-
- Iterator<Processor> en = _processors.values().iterator();
- while (en.hasNext()) {
- Processor processor = en.next();
-
- FormatInfo info = null;
- try {
- info = processor.process(resourcePath, null, templateName);
- } catch (InternalErrorException e) {
- s_logger.error("Template process exception ", e);
- return e.toString();
- }
- if (info != null) {
- loc.addFormat(info);
- dnld.setTemplatesize(info.virtualSize);
- dnld.setTemplatePhysicalSize(info.size);
- break;
- }
- }
-
- if (!loc.save()) {
- s_logger.warn("Cleaning up because we're unable to save the formats");
- loc.purge();
- }
-
- return null;
- }
-
- @Override
- public Status getDownloadStatus(String jobId) {
- DownloadJob job = jobs.get(jobId);
- if (job != null) {
- TemplateDownloader td = job.getTemplateDownloader();
- if (td != null) {
- return td.getStatus();
- }
- }
- return Status.UNKNOWN;
- }
-
- @Override
- public String downloadS3Template(S3TO s3, long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
- String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) {
- UUID uuid = UUID.randomUUID();
- String jobId = uuid.toString();
-
- URI uri;
- try {
- uri = new URI(url);
- } catch (URISyntaxException e) {
- throw new CloudRuntimeException("URI is incorrect: " + url);
- }
- TemplateDownloader td;
- if ((uri != null) && (uri.getScheme() != null)) {
- if (uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")) {
- td = new S3TemplateDownloader(s3, url, installPathPrefix, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType);
- } else {
- throw new CloudRuntimeException("Scheme is not supported " + url);
- }
- } else {
- throw new CloudRuntimeException("Unable to download from URL: " + url);
- }
- DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType);
- dj.setTmpltPath(installPathPrefix);
- jobs.put(jobId, dj);
- threadPool.execute(td);
-
- return jobId;
- }
-
- @Override
- public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
- String installPathPrefix, String templatePath, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) {
- UUID uuid = UUID.randomUUID();
- String jobId = uuid.toString();
- String tmpDir = installPathPrefix;
-
- try {
-
- if (!_storage.mkdirs(tmpDir)) {
- s_logger.warn("Unable to create " + tmpDir);
- return "Unable to create " + tmpDir;
- }
- // TO DO - define constant for volume properties.
- File file =
- ResourceType.TEMPLATE == resourceType ? _storage.getFile(tmpDir + File.separator + TemplateLocation.Filename) : _storage.getFile(tmpDir + File.separator +
- "volume.properties");
- if (file.exists()) {
- file.delete();
- }
-
- if (!file.createNewFile()) {
- s_logger.warn("Unable to create new file: " + file.getAbsolutePath());
- return "Unable to create new file: " + file.getAbsolutePath();
- }
-
- URI uri;
- try {
- uri = new URI(url);
- } catch (URISyntaxException e) {
- throw new CloudRuntimeException("URI is incorrect: " + url);
- }
- TemplateDownloader td;
- if ((uri != null) && (uri.getScheme() != null)) {
- if (uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")) {
- td = new HttpTemplateDownloader(_storage, url, tmpDir, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType);
- } else if (uri.getScheme().equalsIgnoreCase("file")) {
- td = new LocalTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId));
- } else if (uri.getScheme().equalsIgnoreCase("scp")) {
- td = new ScpTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId));
- } else if (uri.getScheme().equalsIgnoreCase("nfs") || uri.getScheme().equalsIgnoreCase("cifs")) {
- td = null;
- // TODO: implement this.
- throw new CloudRuntimeException("Scheme is not supported " + url);
- } else {
- throw new CloudRuntimeException("Scheme is not supported " + url);
- }
- } else {
- throw new CloudRuntimeException("Unable to download from URL: " + url);
- }
- // NOTE the difference between installPathPrefix and templatePath
- // here. instalPathPrefix is the absolute path for template
- // including mount directory
- // on ssvm, while templatePath is the final relative path on
- // secondary storage.
- DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType);
- dj.setTmpltPath(templatePath);
- jobs.put(jobId, dj);
- threadPool.execute(td);
-
- return jobId;
- } catch (IOException e) {
- s_logger.warn("Unable to download to " + tmpDir, e);
- return null;
- }
- }
-
- @Override
- public String getDownloadError(String jobId) {
- DownloadJob dj = jobs.get(jobId);
- if (dj != null) {
- return dj.getTemplateDownloader().getDownloadError();
- }
- return null;
- }
-
- public long getDownloadTemplateSize(String jobId) {
- DownloadJob dj = jobs.get(jobId);
- if (dj != null) {
- return dj.getTemplatesize();
- }
- return 0;
- }
-
- public String getDownloadCheckSum(String jobId) {
- DownloadJob dj = jobs.get(jobId);
- if (dj != null) {
- return dj.getChecksum();
- }
- return null;
- }
-
- public long getDownloadTemplatePhysicalSize(String jobId) {
- DownloadJob dj = jobs.get(jobId);
- if (dj != null) {
- return dj.getTemplatePhysicalSize();
- }
- return 0;
- }
-
- // @Override
- public String getDownloadLocalPath(String jobId) {
- DownloadJob dj = jobs.get(jobId);
- if (dj != null) {
- return dj.getTemplateDownloader().getDownloadLocalPath();
- }
- return null;
- }
-
- @Override
- public int getDownloadPct(String jobId) {
- DownloadJob dj = jobs.get(jobId);
- if (dj != null) {
- return dj.getTemplateDownloader().getDownloadPercent();
- }
- return 0;
- }
-
- public static VMTemplateHostVO.Status convertStatus(Status tds) {
- switch (tds) {
- case ABORTED:
- return VMTemplateHostVO.Status.NOT_DOWNLOADED;
- case DOWNLOAD_FINISHED:
- return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS;
- case IN_PROGRESS:
- return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS;
- case NOT_STARTED:
- return VMTemplateHostVO.Status.NOT_DOWNLOADED;
- case RECOVERABLE_ERROR:
- return VMTemplateHostVO.Status.NOT_DOWNLOADED;
- case UNKNOWN:
- return VMTemplateHostVO.Status.UNKNOWN;
- case UNRECOVERABLE_ERROR:
- return VMTemplateHostVO.Status.DOWNLOAD_ERROR;
- case POST_DOWNLOAD_FINISHED:
- return VMTemplateHostVO.Status.DOWNLOADED;
- default:
- return VMTemplateHostVO.Status.UNKNOWN;
- }
- }
-
- @Override
- public com.cloud.storage.VMTemplateHostVO.Status getDownloadStatus2(String jobId) {
- return convertStatus(getDownloadStatus(jobId));
- }
-
- @Override
- public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd) {
- ResourceType resourceType = cmd.getResourceType();
- if (cmd instanceof DownloadProgressCommand) {
- return handleDownloadProgressCmd(resource, (DownloadProgressCommand)cmd);
- }
-
- if (cmd.getUrl() == null) {
- return new DownloadAnswer(resourceType.toString() + " is corrupted on storage due to an invalid url , cannot download",
- VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
- }
-
- if (cmd.getName() == null) {
- return new DownloadAnswer("Invalid Name", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
- }
-
- DataStoreTO dstore = cmd.getDataStore();
- String installPathPrefix = cmd.getInstallPath();
- // for NFS, we need to get mounted path
- if (dstore instanceof NfsTO) {
- installPathPrefix = resource.getRootDir(((NfsTO)dstore).getUrl()) + File.separator + installPathPrefix;
- }
- String user = null;
- String password = null;
- if (cmd.getAuth() != null) {
- user = cmd.getAuth().getUserName();
- password = cmd.getAuth().getPassword();
- }
- // TO DO - Define Volume max size as well
- long maxDownloadSizeInBytes =
- (cmd.getMaxDownloadSizeInBytes() == null) ? TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES : (cmd.getMaxDownloadSizeInBytes());
- String jobId = null;
- if (dstore instanceof S3TO) {
- jobId =
- downloadS3Template((S3TO)dstore, cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(),
- cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType);
- } else {
- jobId =
- downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(),
- cmd.getChecksum(), installPathPrefix, cmd.getInstallPath(), user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType);
- }
- sleep();
- if (jobId == null) {
- return new DownloadAnswer("Internal Error", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
- }
- return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), getInstallPath(jobId),
- getDownloadTemplateSize(jobId), getDownloadTemplateSize(jobId), getDownloadCheckSum(jobId));
- }
-
- private void sleep() {
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- // ignore
- }
- }
-
- private DownloadAnswer handleDownloadProgressCmd(SecondaryStorageResource resource, DownloadProgressCommand cmd) {
- String jobId = cmd.getJobId();
- DownloadAnswer answer;
- DownloadJob dj = null;
- if (jobId != null) {
- dj = jobs.get(jobId);
- }
- if (dj == null) {
- if (cmd.getRequest() == RequestType.GET_OR_RESTART) {
- DownloadCommand dcmd = new DownloadCommand(cmd);
- return handleDownloadCommand(resource, dcmd);
- } else {
- return new DownloadAnswer("Cannot find job", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.UNKNOWN);
- }
- }
- TemplateDownloader td = dj.getTemplateDownloader();
- switch (cmd.getRequest()) {
- case GET_STATUS:
- break;
- case ABORT:
- td.stopDownload();
- sleep();
- break;
- case RESTART:
- td.stopDownload();
- sleep();
- threadPool.execute(td);
- break;
- case PURGE:
- td.stopDownload();
- answer =
- new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId),
- getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId));
- jobs.remove(jobId);
- return answer;
- default:
- break; // TODO
- }
- return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), getInstallPath(jobId),
- getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId));
- }
-
- private String getInstallPath(String jobId) {
- DownloadJob dj = jobs.get(jobId);
- if (dj != null) {
- return dj.getTmpltPath();
- }
- return null;
- }
-
- private List<String> listVolumes(String rootdir) {
- List<String> result = new ArrayList<String>();
-
- Script script = new Script(listVolScr, s_logger);
- script.add("-r", rootdir);
- ZfsPathParser zpp = new ZfsPathParser(rootdir);
- script.execute(zpp);
- result.addAll(zpp.getPaths());
- s_logger.info("found " + zpp.getPaths().size() + " volumes" + zpp.getPaths());
- return result;
- }
-
- private List<String> listTemplates(String rootdir) {
- List<String> result = new ArrayList<String>();
-
- Script script = new Script(listTmpltScr, s_logger);
- script.add("-r", rootdir);
- ZfsPathParser zpp = new ZfsPathParser(rootdir);
- script.execute(zpp);
- result.addAll(zpp.getPaths());
- s_logger.info("found " + zpp.getPaths().size() + " templates" + zpp.getPaths());
- return result;
- }
-
- @Override
- public Map<String, TemplateProp> gatherTemplateInfo(String rootDir) {
- Map<String, TemplateProp> result = new HashMap<String, TemplateProp>();
- String templateDir = rootDir + File.separator + _templateDir;
-
- if (!_storage.exists(templateDir)) {
- _storage.mkdirs(templateDir);
- }
-
- List<String> publicTmplts = listTemplates(templateDir);
- for (String tmplt : publicTmplts) {
- String path = tmplt.substring(0, tmplt.lastIndexOf(File.separator));
- TemplateLocation loc = new TemplateLocation(_storage, path);
- try {
- if (!loc.load()) {
- s_logger.warn("Post download installation was not completed for " + path);
- // loc.purge();
- _storage.cleanup(path, templateDir);
- continue;
- }
- } catch (IOException e) {
- s_logger.warn("Unable to load template location " + path, e);
- continue;
- }
-
- TemplateProp tInfo = loc.getTemplateInfo();
-
- if ((tInfo.getSize() == tInfo.getPhysicalSize()) && (tInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
- try {
- Processor processor = _processors.get("OVA Processor");
- OVAProcessor vmdkProcessor = (OVAProcessor)processor;
- long vSize = vmdkProcessor.getTemplateVirtualSize(path, tInfo.getInstallPath().substring(tInfo.getInstallPath().lastIndexOf(File.separator) + 1));
- tInfo.setSize(vSize);
- loc.updateVirtualSize(vSize);
- loc.save();
- } catch (Exception e) {
- s_logger.error("Unable to get the virtual size of the template: " + tInfo.getInstallPath() + " due to " + e.getMessage());
- }
- }
-
- result.put(tInfo.getTemplateName(), tInfo);
- s_logger.debug("Added template name: " + tInfo.getTemplateName() + ", path: " + tmplt);
- }
- /*
- for (String tmplt : isoTmplts) {
- String tmp[];
- tmp = tmplt.split("/");
- String tmpltName = tmp[tmp.length - 2];
- tmplt = tmplt.substring(tmplt.lastIndexOf("iso/"));
- TemplateInfo tInfo = new TemplateInfo(tmpltName, tmplt, false);
- s_logger.debug("Added iso template name: " + tmpltName + ", path: " + tmplt);
- result.put(tmpltName, tInfo);
- }
- */
- return result;
- }
-
- @Override
- public Map<Long, TemplateProp> gatherVolumeInfo(String rootDir) {
- Map<Long, TemplateProp> result = new HashMap<Long, TemplateProp>();
- String volumeDir = rootDir + File.separator + _volumeDir;
-
- if (!_storage.exists(volumeDir)) {
- _storage.mkdirs(volumeDir);
- }
-
- List<String> vols = listVolumes(volumeDir);
- for (String vol : vols) {
- String path = vol.substring(0, vol.lastIndexOf(File.separator));
- TemplateLocation loc = new TemplateLocation(_storage, path);
- try {
- if (!loc.load()) {
- s_logger.warn("Post download installation was not completed for " + path);
- // loc.purge();
- _storage.cleanup(path, volumeDir);
- continue;
- }
- } catch (IOException e) {
- s_logger.warn("Unable to load volume location " + path, e);
- continue;
- }
-
- TemplateProp vInfo = loc.getTemplateInfo();
-
- if ((vInfo.getSize() == vInfo.getPhysicalSize()) && (vInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
- try {
- Processor processor = _processors.get("OVA Processor");
- OVAProcessor vmdkProcessor = (OVAProcessor)processor;
- long vSize = vmdkProcessor.getTemplateVirtualSize(path, vInfo.getInstallPath().substring(vInfo.getInstallPath().lastIndexOf(File.separator) + 1));
- vInfo.setSize(vSize);
- loc.updateVirtualSize(vSize);
- loc.save();
- } catch (Exception e) {
- s_logger.error("Unable to get the virtual size of the volume: " + vInfo.getInstallPath() + " due to " + e.getMessage());
- }
- }
-
- result.put(vInfo.getId(), vInfo);
- s_logger.debug("Added volume name: " + vInfo.getTemplateName() + ", path: " + vol);
- }
- return result;
- }
-
- public static class ZfsPathParser extends OutputInterpreter {
- String _parent;
- List<String> paths = new ArrayList<String>();
-
- public ZfsPathParser(String parent) {
- _parent = parent;
- }
-
- @Override
- public String interpret(BufferedReader reader) throws IOException {
- String line = null;
- while ((line = reader.readLine()) != null) {
- paths.add(line);
- }
- return null;
- }
-
- public List<String> getPaths() {
- return paths;
- }
-
- @Override
- public boolean drain() {
- return true;
- }
- }
-
- public DownloadManagerImpl() {
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
- _name = name;
-
- String value = null;
-
- _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
- if (_storage == null) {
- value = (String)params.get(StorageLayer.ClassConfigKey);
- if (value == null) {
- throw new ConfigurationException("Unable to find the storage layer");
- }
-
- Class<StorageLayer> clazz;
- try {
- clazz = (Class<StorageLayer>)Class.forName(value);
- _storage = clazz.newInstance();
- } catch (ClassNotFoundException e) {
- throw new ConfigurationException("Unable to instantiate " + value);
- } catch (InstantiationException e) {
- throw new ConfigurationException("Unable to instantiate " + value);
- } catch (IllegalAccessException e) {
- throw new ConfigurationException("Unable to instantiate " + value);
- }
- }
-
- String inSystemVM = (String)params.get("secondary.storage.vm");
- if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) {
- s_logger.info("DownloadManager: starting additional services since we are inside system vm");
- startAdditionalServices();
- blockOutgoingOnPrivate();
- }
-
- value = (String)params.get("install.timeout.pergig");
- installTimeoutPerGig = NumbersUtil.parseInt(value, 15 * 60) * 1000;
-
- value = (String)params.get("install.numthreads");
- final int numInstallThreads = NumbersUtil.parseInt(value, 10);
-
- String scriptsDir = (String)params.get("template.scripts.dir");
- if (scriptsDir == null) {
- scriptsDir = "scripts/storage/secondary";
- }
-
- listTmpltScr = Script.findScript(scriptsDir, "listvmtmplt.sh");
- if (listTmpltScr == null) {
- throw new ConfigurationException("Unable to find the listvmtmplt.sh");
- }
- s_logger.info("listvmtmplt.sh found in " + listTmpltScr);
-
- createTmpltScr = Script.findScript(scriptsDir, "createtmplt.sh");
- if (createTmpltScr == null) {
- throw new ConfigurationException("Unable to find createtmplt.sh");
- }
- s_logger.info("createtmplt.sh found in " + createTmpltScr);
-
- listVolScr = Script.findScript(scriptsDir, "listvolume.sh");
- if (listVolScr == null) {
- throw new ConfigurationException("Unable to find the listvolume.sh");
- }
- s_logger.info("listvolume.sh found in " + listVolScr);
-
- createVolScr = Script.findScript(scriptsDir, "createvolume.sh");
- if (createVolScr == null) {
- throw new ConfigurationException("Unable to find createvolume.sh");
- }
- s_logger.info("createvolume.sh found in " + createVolScr);
-
- _processors = new HashMap<String, Processor>();
-
- Processor processor = new VhdProcessor();
- processor.configure("VHD Processor", params);
- _processors.put("VHD Processor", processor);
-
- processor = new IsoProcessor();
- processor.configure("ISO Processor", params);
- _processors.put("ISO Processor", processor);
-
- processor = new QCOW2Processor();
- processor.configure("QCOW2 Processor", params);
- _processors.put("QCOW2 Processor", processor);
-
- processor = new OVAProcessor();
- processor.configure("OVA Processor", params);
- _processors.put("OVA Processor", processor);
-
- processor = new VmdkProcessor();
- processor.configure("VMDK Processor", params);
- _processors.put("VMDK Processor", processor);
-
- processor = new RawImageProcessor();
- processor.configure("Raw Image Processor", params);
- _processors.put("Raw Image Processor", processor);
-
- _templateDir = (String)params.get("public.templates.root.dir");
- if (_templateDir == null) {
- _templateDir = TemplateConstants.DEFAULT_TMPLT_ROOT_DIR;
- }
- _templateDir += File.separator + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR;
- _volumeDir = TemplateConstants.DEFAULT_VOLUME_ROOT_DIR + File.separator;
- // Add more processors here.
- threadPool = Executors.newFixedThreadPool(numInstallThreads);
- return true;
- }
-
- private void blockOutgoingOnPrivate() {
- Script command = new Script("/bin/bash", s_logger);
- String intf = "eth1";
- command.add("-c");
- command.add("iptables -A OUTPUT -o " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "80" + " -j REJECT;" + "iptables -A OUTPUT -o " + intf +
- " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j REJECT;");
-
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Error in blocking outgoing to port 80/443 err=" + result);
- return;
- }
- }
-
- @Override
- public String getName() {
- return _name;
- }
-
- @Override
- public boolean start() {
- return true;
- }
-
- @Override
- public boolean stop() {
- return true;
- }
-
- private void startAdditionalServices() {
-
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("if [ -d /etc/apache2 ] ; then service apache2 stop; else service httpd stop; fi ");
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Error in stopping httpd service err=" + result);
- }
- String port = Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
- String intf = TemplateConstants.DEFAULT_TMPLT_COPY_INTF;
-
- command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j ACCEPT;" + "iptables -I INPUT -i " + intf +
- " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j ACCEPT;");
-
- result = command.execute();
- if (result != null) {
- s_logger.warn("Error in opening up httpd port err=" + result);
- return;
- }
-
- command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("if [ -d /etc/apache2 ] ; then service apache2 start; else service httpd start; fi ");
- result = command.execute();
- if (result != null) {
- s_logger.warn("Error in starting httpd service err=" + result);
- return;
- }
- command = new Script("mkdir", s_logger);
- command.add("-p");
- command.add("/var/www/html/copy/template");
- result = command.execute();
- if (result != null) {
- s_logger.warn("Error in creating directory =" + result);
- return;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManager.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManager.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManager.java
deleted file mode 100755
index be99fea..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManager.java
+++ /dev/null
@@ -1,82 +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 org.apache.cloudstack.storage.template;
-
-import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
-
-import com.cloud.agent.api.storage.CreateEntityDownloadURLAnswer;
-import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLAnswer;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.UploadAnswer;
-import com.cloud.agent.api.storage.UploadCommand;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Upload.Status;
-import com.cloud.storage.template.TemplateUploader;
-import com.cloud.utils.component.Manager;
-
-public interface UploadManager extends Manager {
-
- /**
- * @param jobId job Id
- * @return status of the upload job
- */
- public TemplateUploader.Status getUploadStatus(String jobId);
-
- /**
- * @param jobId job Id
- * @return status of the upload job
- */
- public Status getUploadStatus2(String jobId);
-
- /**
- * Get the upload percent of a upload job
- * @param jobId job Id
- * @return
- */
- public int getUploadPct(String jobId);
-
- /**
- * Get the upload error if any
- * @param jobId job Id
- * @return
- */
- public String getUploadError(String jobId);
-
- /**
- * Get the local path for the upload
- * @param jobId job Id
- * @return
- public String getUploadLocalPath(String jobId);
- */
-
- /** Handle upload commands from the management server
- * @param cmd cmd from server
- * @return answer representing status of upload.
- */
- public UploadAnswer handleUploadCommand(SecondaryStorageResource resource, UploadCommand cmd);
-
- public String getPublicTemplateRepo();
-
- String uploadPublicTemplate(long id, String url, String name, ImageFormat format, Long accountId, String descr, String cksum, String installPathPrefix, String user,
- String password, long maxTemplateSizeInBytes);
-
- CreateEntityDownloadURLAnswer handleCreateEntityURLCommand(CreateEntityDownloadURLCommand cmd);
-
- DeleteEntityDownloadURLAnswer handleDeleteEntityDownloadURLCommand(DeleteEntityDownloadURLCommand cmd);
-
-}
[11/11] git commit: updated refs/heads/master to 54f32a8
Posted by ah...@apache.org.
Moved the controlling logic for secondary storage vm into place
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/54f32a8e
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/54f32a8e
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/54f32a8e
Branch: refs/heads/master
Commit: 54f32a8e46247e2f354a70f52fef4835159887fd
Parents: 03a424e
Author: Alex Huang <al...@citrix.com>
Authored: Wed Feb 5 01:38:04 2014 +0000
Committer: Alex Huang <al...@citrix.com>
Committed: Wed Feb 5 01:39:17 2014 +0000
----------------------------------------------------------------------
client/pom.xml | 5 +
.../spring-server-core-managers-context.xml | 6 -
.../PremiumSecondaryStorageManagerImpl.java | 185 ---
.../secondary/SecondaryStorageManagerImpl.java | 1386 -----------------
.../ConsoleProxyThumbnailHandler.java | 1 +
...econdary-storage-controller-core-context.xml | 33 +
.../PremiumSecondaryStorageManagerImpl.java | 186 +++
.../SecondaryStorageManagerImpl.java | 1388 ++++++++++++++++++
8 files changed, 1613 insertions(+), 1577 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 5215e0c..06a6db0 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -268,6 +268,11 @@
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-controller-secondary-storage</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine-storage-image</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
----------------------------------------------------------------------
diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
index 53a294e..cf04cc3 100644
--- a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
+++ b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
@@ -86,12 +86,6 @@
<bean id="securityGroupManagerImpl2" class="com.cloud.network.security.SecurityGroupManagerImpl2" />
- <bean id="premiumSecondaryStorageManagerImpl"
- class="com.cloud.secstorage.PremiumSecondaryStorageManagerImpl">
- <property name="secondaryStorageVmAllocators"
- value="#{secondaryStorageVmAllocatorsRegistry.registered}" />
- </bean>
-
<bean id="ipv6AddressManagerImpl" class="com.cloud.network.Ipv6AddressManagerImpl" />
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/server/src/com/cloud/secstorage/PremiumSecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/secstorage/PremiumSecondaryStorageManagerImpl.java b/server/src/com/cloud/secstorage/PremiumSecondaryStorageManagerImpl.java
deleted file mode 100755
index ec2af2a..0000000
--- a/server/src/com/cloud/secstorage/PremiumSecondaryStorageManagerImpl.java
+++ /dev/null
@@ -1,185 +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.secstorage;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.Command;
-import com.cloud.configuration.Config;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.storage.secondary.SecondaryStorageManagerImpl;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.vm.SecondaryStorageVm;
-import com.cloud.vm.SecondaryStorageVmVO;
-import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.SecondaryStorageVmDao;
-
-@Local(value = {SecondaryStorageVmManager.class})
-public class PremiumSecondaryStorageManagerImpl extends SecondaryStorageManagerImpl {
- private static final Logger s_logger = Logger.getLogger(PremiumSecondaryStorageManagerImpl.class);
-
- private int _capacityPerSSVM = SecondaryStorageVmManager.DEFAULT_SS_VM_CAPACITY;
- private int _standbyCapacity = SecondaryStorageVmManager.DEFAULT_STANDBY_CAPACITY;
- private int _maxExecutionTimeMs = 1800000;
-
- @Inject
- SecondaryStorageVmDao _secStorageVmDao;
- @Inject
- CommandExecLogDao _cmdExecLogDao;
- @Inject
- HostDao _hostDao;
- @Inject
- ResourceManager _resourceMgr;
- protected SearchBuilder<CommandExecLogVO> ActiveCommandSearch;
- protected SearchBuilder<HostVO> HostSearch;
-
- @Override
- public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
- super.configure(name, params);
-
- _capacityPerSSVM = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageSessionMax.key()), DEFAULT_SS_VM_CAPACITY);
- _standbyCapacity = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageCapacityStandby.key()), DEFAULT_STANDBY_CAPACITY);
-
- int nMaxExecutionMinutes = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageCmdExecutionTimeMax.key()), 30);
- _maxExecutionTimeMs = nMaxExecutionMinutes * 60 * 1000;
-
- HostSearch = _hostDao.createSearchBuilder();
- HostSearch.and("dc", HostSearch.entity().getDataCenterId(), Op.EQ);
- HostSearch.and("status", HostSearch.entity().getStatus(), Op.EQ);
-
- ActiveCommandSearch = _cmdExecLogDao.createSearchBuilder();
- ActiveCommandSearch.and("created", ActiveCommandSearch.entity().getCreated(), Op.GTEQ);
- ActiveCommandSearch.join("hostSearch", HostSearch, ActiveCommandSearch.entity().getInstanceId(), HostSearch.entity().getId(), JoinType.INNER);
-
- HostSearch.done();
- ActiveCommandSearch.done();
- return true;
- }
-
- @Override
- public Pair<AfterScanAction, Object> scanPool(Long pool) {
- long dataCenterId = pool.longValue();
- if (!isSecondaryStorageVmRequired(dataCenterId)) {
- return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
- }
-
- Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - _maxExecutionTimeMs);
-
- _cmdExecLogDao.expungeExpiredRecords(cutTime);
-
- boolean suspendAutoLoading = !reserveStandbyCapacity();
- if (!suspendAutoLoading) {
- // this is a hacking, has nothing to do with console proxy, it is just a flag that primary storage is being under maintenance mode
- String restart = _configDao.getValue("consoleproxy.restart");
- if (restart != null && restart.equalsIgnoreCase("false")) {
- s_logger.debug("Capacity scan disabled purposefully, consoleproxy.restart = false. This happens when the primarystorage is in maintenance mode");
- suspendAutoLoading = true;
- }
- }
-
- List<SecondaryStorageVmVO> alreadyRunning =
- _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting);
- if (alreadyRunning.size() == 0) {
- s_logger.info("No running secondary storage vms found in datacenter id=" + dataCenterId + ", starting one");
-
- List<SecondaryStorageVmVO> stopped =
- _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Stopped, State.Stopping);
- if (stopped.size() == 0 || !suspendAutoLoading) {
- List<SecondaryStorageVmVO> stopping = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, State.Stopping);
- if (stopping.size() > 0) {
- s_logger.info("Found SSVMs that are currently at stopping state, wait until they are settled");
- return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
- }
-
- expandPool(pool, SecondaryStorageVm.Role.templateProcessor);
- }
- }
-
- if (!suspendAutoLoading) {
- // this is to avoid surprises that people may accidently see two SSVMs being launched, capacity expanding only happens when we have at least the primary SSVM is up
- if (alreadyRunning.size() == 0) {
- s_logger.info("Primary secondary storage is not even started, wait until next turn");
- return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
- }
-
- alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, dataCenterId, State.Running, State.Migrating, State.Starting);
-
- List<CommandExecLogVO> activeCmds = listActiveCommands(dataCenterId, cutTime);
- if (alreadyRunning.size() * _capacityPerSSVM - activeCmds.size() < _standbyCapacity) {
- s_logger.info("secondary storage command execution standby capactiy low (running VMs: " + alreadyRunning.size() + ", active cmds: " + activeCmds.size() +
- "), starting a new one");
- return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.commandExecutor);
- }
- }
-
- return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
- }
-
- @Override
- public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd) {
-
- // TODO, need performance optimization
- List<Long> vms = _secStorageVmDao.listRunningSecStorageOrderByLoad(null, zoneId);
- for (Long vmId : vms) {
- SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(vmId);
- HostVO host;
- host = _resourceMgr.findHostByName(secStorageVm.getHostName());
- if (host != null && host.getStatus() == Status.Up)
- return new Pair<HostVO, SecondaryStorageVmVO>(host, secStorageVm);
- }
-
- return null;
- }
-
- private List<CommandExecLogVO> listActiveCommands(long dcId, Date cutTime) {
- SearchCriteria<CommandExecLogVO> sc = ActiveCommandSearch.create();
-
- sc.setParameters("created", cutTime);
- sc.setJoinParameters("hostSearch", "dc", dcId);
- sc.setJoinParameters("hostSearch", "status", Status.Up);
-
- return _cmdExecLogDao.search(sc, null);
- }
-
- private boolean reserveStandbyCapacity() {
- String value = _configDao.getValue(Config.SystemVMAutoReserveCapacity.key());
- if (value != null && value.equalsIgnoreCase("true")) {
- return true;
- }
-
- return false;
- }
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
deleted file mode 100755
index 484dfbd..0000000
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ /dev/null
@@ -1,1386 +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.storage.secondary;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.config.ApiServiceConfiguration;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.RebootCommand;
-import com.cloud.agent.api.SecStorageFirewallCfgCommand;
-import com.cloud.agent.api.SecStorageSetupAnswer;
-import com.cloud.agent.api.SecStorageSetupCommand;
-import com.cloud.agent.api.SecStorageVMSetupCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupSecondaryStorageCommand;
-import com.cloud.agent.api.check.CheckSshAnswer;
-import com.cloud.agent.api.check.CheckSshCommand;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.manager.Commands;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.cluster.ClusterManager;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ZoneConfig;
-import com.cloud.consoleproxy.ConsoleProxyManager;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.info.RunningHostCountInfo;
-import com.cloud.info.RunningHostInfoAgregator;
-import com.cloud.info.RunningHostInfoAgregator.ZoneHostInfo;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceStateAdapter;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.UnableDeleteHostException;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.UploadVO;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.UploadDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.template.TemplateConstants;
-import com.cloud.template.TemplateManager;
-import com.cloud.user.Account;
-import com.cloud.user.AccountService;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.events.SubscriptionMgr;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.SecondaryStorageVm;
-import com.cloud.vm.SecondaryStorageVmVO;
-import com.cloud.vm.SystemVmLoadScanHandler;
-import com.cloud.vm.SystemVmLoadScanner;
-import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineGuru;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineName;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.SecondaryStorageVmDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-//
-// Possible secondary storage vm state transition cases
-// Creating -> Destroyed
-// Creating -> Stopped --> Starting -> Running
-// HA -> Stopped -> Starting -> Running
-// Migrating -> Running (if previous state is Running before it enters into Migrating state
-// Migrating -> Stopped (if previous state is not Running before it enters into Migrating state)
-// Running -> HA (if agent lost connection)
-// Stopped -> Destroyed
-//
-// Creating state indicates of record creating and IP address allocation are ready, it is a transient
-// state which will soon be switching towards Running if everything goes well.
-// Stopped state indicates the readiness of being able to start (has storage and IP resources allocated)
-// Starting state can only be entered from Stopped states
-//
-// Starting, HA, Migrating, Creating and Running state are all counted as "Open" for available capacity calculation
-// because sooner or later, it will be driven into Running state
-//
-@Local(value = {SecondaryStorageVmManager.class})
-public class SecondaryStorageManagerImpl extends ManagerBase implements SecondaryStorageVmManager, VirtualMachineGuru, SystemVmLoadScanHandler<Long>,
- ResourceStateAdapter {
- private static final Logger s_logger = Logger.getLogger(SecondaryStorageManagerImpl.class);
-
- private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30
- // seconds
- private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC = 180; // 3
- // minutes
-
- private static final int STARTUP_DELAY = 60000; // 60 seconds
-
- private int _mgmtPort = 8250;
-
- private List<SecondaryStorageVmAllocator> _ssVmAllocators;
-
- @Inject
- protected SecondaryStorageVmDao _secStorageVmDao;
- @Inject
- private DataCenterDao _dcDao;
- @Inject
- private VMTemplateDao _templateDao;
- @Inject
- private HostDao _hostDao;
- @Inject
- private StoragePoolHostDao _storagePoolHostDao;
- @Inject
- private AgentManager _agentMgr;
- @Inject
- protected NetworkOrchestrationService _networkMgr;
- @Inject
- protected NetworkModel _networkModel;
- @Inject
- protected SnapshotDao _snapshotDao;
- @Inject
- private ClusterManager _clusterMgr;
-
- private SecondaryStorageListener _listener;
-
- private ServiceOfferingVO _serviceOffering;
-
- @Inject
- protected ConfigurationDao _configDao;
- @Inject
- private ServiceOfferingDao _offeringDao;
- @Inject
- private AccountService _accountMgr;
- @Inject
- private VirtualMachineManager _itMgr;
- @Inject
- protected VMInstanceDao _vmDao;
- @Inject
- protected CapacityDao _capacityDao;
- @Inject
- UserVmDetailsDao _vmDetailsDao;
- @Inject
- protected ResourceManager _resourceMgr;
- @Inject
- NetworkDao _networkDao;
- @Inject
- NetworkOfferingDao _networkOfferingDao;
- @Inject
- protected IPAddressDao _ipAddressDao = null;
- @Inject
- protected RulesManager _rulesMgr;
- @Inject
- TemplateManager templateMgr;
- @Inject
- UploadDao _uploadDao;
-
- @Inject
- KeystoreManager _keystoreMgr;
- @Inject
- DataStoreManager _dataStoreMgr;
- @Inject
- ImageStoreDao _imageStoreDao;
- @Inject
- TemplateDataStoreDao _tmplStoreDao;
- private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL;
- private int _secStorageVmMtuSize;
-
- private String _instance;
- private boolean _useLocalStorage;
- private boolean _useSSlCopy;
- private String _httpProxy;
- private String _allowedInternalSites;
- protected long _nodeId = ManagementServerNode.getManagementServerId();
-
- private SystemVmLoadScanner<Long> _loadScanner;
- private Map<Long, ZoneHostInfo> _zoneHostInfoMap; // map <zone id, info about running host in zone>
-
- private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName());
-
- public SecondaryStorageManagerImpl() {
- }
-
- @Override
- public SecondaryStorageVmVO startSecStorageVm(long secStorageVmId) {
- try {
- SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
- _itMgr.advanceStart(secStorageVm.getUuid(), null, null);
- return _secStorageVmDao.findById(secStorageVm.getId());
- } catch (StorageUnavailableException e) {
- s_logger.warn("Exception while trying to start secondary storage vm", e);
- return null;
- } catch (InsufficientCapacityException e) {
- s_logger.warn("Exception while trying to start secondary storage vm", e);
- return null;
- } catch (ResourceUnavailableException e) {
- s_logger.warn("Exception while trying to start secondary storage vm", e);
- return null;
- } catch (Exception e) {
- s_logger.warn("Exception while trying to start secondary storage vm", e);
- return null;
- }
- }
-
- SecondaryStorageVmVO getSSVMfromHost(HostVO ssAHost) {
- if (ssAHost.getType() == Host.Type.SecondaryStorageVM) {
- return _secStorageVmDao.findByInstanceName(ssAHost.getName());
- }
- return null;
- }
-
- @Override
- public boolean generateSetupCommand(Long ssHostId) {
- HostVO cssHost = _hostDao.findById(ssHostId);
- Long zoneId = cssHost.getDataCenterId();
- if (cssHost.getType() == Host.Type.SecondaryStorageVM) {
-
- SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(cssHost.getName());
- if (secStorageVm == null) {
- s_logger.warn("secondary storage VM " + cssHost.getName() + " doesn't exist");
- return false;
- }
-
- List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
- for (DataStore ssStore : ssStores) {
- if (!(ssStore.getTO() instanceof NfsTO)) {
- continue; // only do this for Nfs
- }
- String secUrl = ssStore.getUri();
- SecStorageSetupCommand setupCmd = null;
- if (!_useSSlCopy) {
- setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, null);
- } else {
- KeystoreManager.Certificates certs = _keystoreMgr.getCertificates(ConsoleProxyManager.CERTIFICATE_NAME);
- setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, certs);
- }
-
- Answer answer = _agentMgr.easySend(ssHostId, setupCmd);
- if (answer != null && answer.getResult()) {
- SecStorageSetupAnswer an = (SecStorageSetupAnswer)answer;
- if (an.get_dir() != null) {
- // update the parent path in image_store table for this image store
- ImageStoreVO svo = _imageStoreDao.findById(ssStore.getId());
- svo.setParent(an.get_dir());
- _imageStoreDao.update(ssStore.getId(), svo);
- }
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
- }
- } else {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
- }
- return false;
- }
- }
- }
- /* After removing SecondaryStorage entries from host table, control should never come here!!
- else if( cssHost.getType() == Host.Type.SecondaryStorage ) {
- List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, zoneId, State.Running);
- String secUrl = cssHost.getStorageUrl();
- SecStorageSetupCommand setupCmd = new SecStorageSetupCommand(secUrl, null);
- for ( SecondaryStorageVmVO ssVm : alreadyRunning ) {
- HostVO host = _resourceMgr.findHostByName(ssVm.getInstanceName());
- Answer answer = _agentMgr.easySend(host.getId(), setupCmd);
- if (answer != null && answer.getResult()) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
- }
- } else {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
- }
- return false;
- }
- }
- }
- */
- return true;
- }
-
- @Override
- public boolean generateVMSetupCommand(Long ssAHostId) {
- HostVO ssAHost = _hostDao.findById(ssAHostId);
- if (ssAHost.getType() != Host.Type.SecondaryStorageVM) {
- return false;
- }
- SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
- if (secStorageVm == null) {
- s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
- return false;
- }
-
- SecStorageVMSetupCommand setupCmd = new SecStorageVMSetupCommand();
- if (_allowedInternalSites != null) {
- List<String> allowedCidrs = new ArrayList<String>();
- String[] cidrs = _allowedInternalSites.split(",");
- for (String cidr : cidrs) {
- if (NetUtils.isValidCIDR(cidr) || NetUtils.isValidIp(cidr) || !cidr.startsWith("0.0.0.0")) {
- allowedCidrs.add(cidr);
- }
- }
- List<? extends Nic> nics = _networkModel.getNicsForTraffic(secStorageVm.getId(), TrafficType.Management);
- setupCmd.setAllowedInternalSites(allowedCidrs.toArray(new String[allowedCidrs.size()]));
- }
- String copyPasswd = _configDao.getValue("secstorage.copy.password");
- setupCmd.setCopyPassword(copyPasswd);
- setupCmd.setCopyUserName(TemplateConstants.DEFAULT_HTTP_AUTH_USER);
- Answer answer = _agentMgr.easySend(ssAHostId, setupCmd);
- if (answer != null && answer.getResult()) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Successfully programmed http auth into " + secStorageVm.getHostName());
- }
- return true;
- } else {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("failed to program http auth into secondary storage vm : " + secStorageVm.getHostName());
- }
- return false;
- }
- }
-
- @Override
- public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd) {
- return null;
- }
-
- @Override
- public boolean generateFirewallConfiguration(Long ssAHostId) {
- if (ssAHostId == null) {
- return true;
- }
- HostVO ssAHost = _hostDao.findById(ssAHostId);
- SecondaryStorageVmVO thisSecStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
-
- if (thisSecStorageVm == null) {
- s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
- return false;
- }
-
- String copyPort = _useSSlCopy ? "443" : Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
- SecStorageFirewallCfgCommand thiscpc = new SecStorageFirewallCfgCommand(true);
- thiscpc.addPortConfig(thisSecStorageVm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
-
- QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
- sc.and(sc.entity().getType(), Op.EQ, Host.Type.SecondaryStorageVM);
- sc.and(sc.entity().getStatus(), Op.IN, Status.Up, Status.Connecting);
- List<HostVO> ssvms = sc.list();
- for (HostVO ssvm : ssvms) {
- if (ssvm.getId() == ssAHostId) {
- continue;
- }
- Answer answer = _agentMgr.easySend(ssvm.getId(), thiscpc);
- if (answer != null && answer.getResult()) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Successfully programmed firewall rules into SSVM " + ssvm.getName());
- }
- } else {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("failed to program firewall rules into secondary storage vm : " + ssvm.getName());
- }
- return false;
- }
- }
-
- SecStorageFirewallCfgCommand allSSVMIpList = new SecStorageFirewallCfgCommand(false);
- for (HostVO ssvm : ssvms) {
- if (ssvm.getId() == ssAHostId) {
- continue;
- }
- allSSVMIpList.addPortConfig(ssvm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
- }
-
- Answer answer = _agentMgr.easySend(ssAHostId, allSSVMIpList);
- if (answer != null && answer.getResult()) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Successfully programmed firewall rules into " + thisSecStorageVm.getHostName());
- }
- } else {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("failed to program firewall rules into secondary storage vm : " + thisSecStorageVm.getHostName());
- }
- return false;
- }
-
- return true;
-
- }
-
- protected boolean isSecondaryStorageVmRequired(long dcId) {
- DataCenterVO dc = _dcDao.findById(dcId);
- _dcDao.loadDetails(dc);
- String ssvmReq = dc.getDetail(ZoneConfig.EnableSecStorageVm.key());
- if (ssvmReq != null) {
- return Boolean.parseBoolean(ssvmReq);
- }
- return true;
- }
-
- public SecondaryStorageVmVO startNew(long dataCenterId, SecondaryStorageVm.Role role) {
-
- if (!isSecondaryStorageVmRequired(dataCenterId)) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " acc. to zone config");
- }
- return null;
- }
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Assign secondary storage vm from a newly started instance for request from data center : " + dataCenterId);
- }
-
- Map<String, Object> context = createSecStorageVmInstance(dataCenterId, role);
-
- long secStorageVmId = (Long)context.get("secStorageVmId");
- if (secStorageVmId == 0) {
- if (s_logger.isTraceEnabled()) {
- s_logger.trace("Creating secondary storage vm instance failed, data center id : " + dataCenterId);
- }
-
- return null;
- }
-
- SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
- // SecondaryStorageVmVO secStorageVm =
- // allocSecStorageVmStorage(dataCenterId, secStorageVmId);
- if (secStorageVm != null) {
- SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
- new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATED, dataCenterId, secStorageVmId, secStorageVm, null));
- return secStorageVm;
- } else {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Unable to allocate secondary storage vm storage, remove the secondary storage vm record from DB, secondary storage vm id: " +
- secStorageVmId);
- }
-
- SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
- new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATE_FAILURE, dataCenterId, secStorageVmId, null, "Unable to allocate storage"));
- }
- return null;
- }
-
- protected Map<String, Object> createSecStorageVmInstance(long dataCenterId, SecondaryStorageVm.Role role) {
- DataStore secStore = _dataStoreMgr.getImageStore(dataCenterId);
- if (secStore == null) {
- String msg = "No secondary storage available in zone " + dataCenterId + ", cannot create secondary storage vm";
- s_logger.warn(msg);
- throw new CloudRuntimeException(msg);
- }
-
- long id = _secStorageVmDao.getNextInSequence(Long.class, "id");
- String name = VirtualMachineName.getSystemVmName(id, _instance, "s").intern();
- Account systemAcct = _accountMgr.getSystemAccount();
-
- DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
- DataCenter dc = _dcDao.findById(plan.getDataCenterId());
-
- NetworkVO defaultNetwork = null;
- if (dc.getNetworkType() == NetworkType.Advanced && dc.isSecurityGroupEnabled()) {
- List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dataCenterId);
- if (networks == null || networks.size() == 0) {
- throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc);
- }
- defaultNetwork = networks.get(0);
- } else {
- TrafficType defaultTrafficType = TrafficType.Public;
-
- if (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()) {
- defaultTrafficType = TrafficType.Guest;
- }
- List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, defaultTrafficType);
- // api should never allow this situation to happen
- if (defaultNetworks.size() != 1) {
- throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
- }
- defaultNetwork = defaultNetworks.get(0);
- }
-
- List<? extends NetworkOffering> offerings =
- _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork, NetworkOffering.SystemManagementNetwork,
- NetworkOffering.SystemStorageNetwork);
- LinkedHashMap<Network, NicProfile> networks = new LinkedHashMap<Network, NicProfile>(offerings.size() + 1);
- NicProfile defaultNic = new NicProfile();
- defaultNic.setDefaultNic(true);
- defaultNic.setDeviceId(2);
- try {
- networks.put(_networkMgr.setupNetwork(systemAcct, _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0),
- defaultNic);
- for (NetworkOffering offering : offerings) {
- networks.put(_networkMgr.setupNetwork(systemAcct, offering, plan, null, null, false).get(0), null);
- }
- } catch (ConcurrentOperationException e) {
- s_logger.info("Unable to setup due to concurrent operation. " + e);
- return new HashMap<String, Object>();
- }
-
- VMTemplateVO template = null;
- HypervisorType availableHypervisor = _resourceMgr.getAvailableHypervisor(dataCenterId);
- template = _templateDao.findSystemVMReadyTemplate(dataCenterId, availableHypervisor);
- if (template == null) {
- throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId);
- }
-
- SecondaryStorageVmVO secStorageVm =
- new SecondaryStorageVmVO(id, _serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,
- systemAcct.getDomainId(), systemAcct.getId(), role, _serviceOffering.getOfferHA());
- secStorageVm.setDynamicallyScalable(template.isDynamicallyScalable());
- secStorageVm = _secStorageVmDao.persist(secStorageVm);
- try {
- _itMgr.allocate(name, template, _serviceOffering, networks, plan, null);
- secStorageVm = _secStorageVmDao.findById(secStorageVm.getId());
- } catch (InsufficientCapacityException e) {
- s_logger.warn("InsufficientCapacity", e);
- throw new CloudRuntimeException("Insufficient capacity exception", e);
- }
-
- Map<String, Object> context = new HashMap<String, Object>();
- context.put("secStorageVmId", secStorageVm.getId());
- return context;
- }
-
- private SecondaryStorageVmAllocator getCurrentAllocator() {
-
- // for now, only one adapter is supported
- if (_ssVmAllocators.size() > 0) {
- return _ssVmAllocators.get(0);
- }
-
- return null;
- }
-
- protected String connect(String ipAddress, int port) {
- return null;
- }
-
- public SecondaryStorageVmVO assignSecStorageVmFromRunningPool(long dataCenterId, SecondaryStorageVm.Role role) {
-
- if (s_logger.isTraceEnabled()) {
- s_logger.trace("Assign secondary storage vm from running pool for request from data center : " + dataCenterId);
- }
-
- SecondaryStorageVmAllocator allocator = getCurrentAllocator();
- assert (allocator != null);
- List<SecondaryStorageVmVO> runningList = _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Running);
- if (runningList != null && runningList.size() > 0) {
- if (s_logger.isTraceEnabled()) {
- s_logger.trace("Running secondary storage vm pool size : " + runningList.size());
- for (SecondaryStorageVmVO secStorageVm : runningList) {
- s_logger.trace("Running secStorageVm instance : " + secStorageVm.getHostName());
- }
- }
-
- Map<Long, Integer> loadInfo = new HashMap<Long, Integer>();
-
- return allocator.allocSecondaryStorageVm(runningList, loadInfo, dataCenterId);
- } else {
- if (s_logger.isTraceEnabled()) {
- s_logger.trace("Empty running secStorageVm pool for now in data center : " + dataCenterId);
- }
- }
- return null;
- }
-
- public SecondaryStorageVmVO assignSecStorageVmFromStoppedPool(long dataCenterId, SecondaryStorageVm.Role role) {
- List<SecondaryStorageVmVO> l = _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Starting, State.Stopped, State.Migrating);
- if (l != null && l.size() > 0) {
- return l.get(0);
- }
-
- return null;
- }
-
- private void allocCapacity(long dataCenterId, SecondaryStorageVm.Role role) {
- if (s_logger.isTraceEnabled()) {
- s_logger.trace("Allocate secondary storage vm standby capacity for data center : " + dataCenterId);
- }
-
- if (!isSecondaryStorageVmRequired(dataCenterId)) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " acc. to zone config");
- }
- return;
- }
-
- boolean secStorageVmFromStoppedPool = false;
- SecondaryStorageVmVO secStorageVm = assignSecStorageVmFromStoppedPool(dataCenterId, role);
- if (secStorageVm == null) {
- if (s_logger.isInfoEnabled()) {
- s_logger.info("No stopped secondary storage vm is available, need to allocate a new secondary storage vm");
- }
-
- if (_allocLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
- try {
- secStorageVm = startNew(dataCenterId, role);
- for (UploadVO upload : _uploadDao.listAll()) {
- _uploadDao.expunge(upload.getId());
- }
- } finally {
- _allocLock.unlock();
- }
- } else {
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Unable to acquire synchronization lock to allocate secStorageVm resource for standby capacity, wait for next scan");
- }
- return;
- }
- } else {
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Found a stopped secondary storage vm, bring it up to running pool. secStorageVm vm id : " + secStorageVm.getId());
- }
- secStorageVmFromStoppedPool = true;
- }
-
- if (secStorageVm != null) {
- long secStorageVmId = secStorageVm.getId();
- GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVmId));
- try {
- if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
- try {
- secStorageVm = startSecStorageVm(secStorageVmId);
- } finally {
- secStorageVmLock.unlock();
- }
- } else {
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Unable to acquire synchronization lock to start secStorageVm for standby capacity, secStorageVm vm id : " + secStorageVm.getId());
- }
- return;
- }
- } finally {
- secStorageVmLock.releaseRef();
- }
-
- if (secStorageVm == null) {
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Unable to start secondary storage vm for standby capacity, secStorageVm vm Id : " + secStorageVmId +
- ", will recycle it and start a new one");
- }
-
- if (secStorageVmFromStoppedPool) {
- destroySecStorageVm(secStorageVmId);
- }
- } else {
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Secondary storage vm " + secStorageVm.getHostName() + " is started");
- }
- }
- }
- }
-
- public boolean isZoneReady(Map<Long, ZoneHostInfo> zoneHostInfoMap, long dataCenterId) {
- ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
- if (zoneHostInfo != null && (zoneHostInfo.getFlags() & RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK) != 0) {
- VMTemplateVO template = _templateDao.findSystemVMReadyTemplate(dataCenterId, HypervisorType.Any);
- if (template == null) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("System vm template is not ready at data center " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
- }
- return false;
- }
-
- List<DataStore> stores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId));
- if (stores.size() < 1) {
- s_logger.debug("No image store added in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
- return false;
- }
-
- DataStore store = templateMgr.getImageStore(dataCenterId, template.getId());
- if (store == null) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("No secondary storage available in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
- }
- return false;
- }
-
- List<Pair<Long, Integer>> l = _storagePoolHostDao.getDatacenterStoragePoolHostInfo(dataCenterId, !_useLocalStorage);
- if (l != null && l.size() > 0 && l.get(0).second().intValue() > 0) {
- return true;
- } else {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Primary storage is not ready, wait until it is ready to launch secondary storage vm. dcId: " + dataCenterId +
- " system.vm.use.local.storage: " + _useLocalStorage +
- "If you want to use local storage to start ssvm, need to set system.vm.use.local.storage to true");
- }
- }
-
- }
- return false;
- }
-
- private synchronized Map<Long, ZoneHostInfo> getZoneHostInfo() {
- Date cutTime = DateUtil.currentGMTTime();
- List<RunningHostCountInfo> l = _hostDao.getRunningHostCounts(new Date(cutTime.getTime() - ClusterManager.HeartbeatThreshold.value()));
-
- RunningHostInfoAgregator aggregator = new RunningHostInfoAgregator();
- if (l.size() > 0) {
- for (RunningHostCountInfo countInfo : l) {
- aggregator.aggregate(countInfo);
- }
- }
-
- return aggregator.getZoneHostInfoMap();
- }
-
- @Override
- public boolean start() {
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Start secondary storage vm manager");
- }
-
- return true;
- }
-
- @Override
- public boolean stop() {
- _loadScanner.stop();
- _allocLock.releaseRef();
- _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
- return true;
- }
-
- @Override
- public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Start configuring secondary storage vm manager : " + name);
- }
-
- Map<String, String> configs = _configDao.getConfiguration("management-server", params);
-
- _secStorageVmMtuSize = NumbersUtil.parseInt(configs.get("secstorage.vm.mtu.size"), DEFAULT_SS_VM_MTUSIZE);
- String useServiceVM = _configDao.getValue("secondary.storage.vm");
- boolean _useServiceVM = false;
- if ("true".equalsIgnoreCase(useServiceVM)) {
- _useServiceVM = true;
- }
-
- String sslcopy = _configDao.getValue("secstorage.encrypt.copy");
- if ("true".equalsIgnoreCase(sslcopy)) {
- _useSSlCopy = true;
- }
-
- _allowedInternalSites = _configDao.getValue("secstorage.allowed.internal.sites");
-
- String value = configs.get("secstorage.capacityscan.interval");
- _capacityScanInterval = NumbersUtil.parseLong(value, DEFAULT_CAPACITY_SCAN_INTERVAL);
-
- _instance = configs.get("instance.name");
- if (_instance == null) {
- _instance = "DEFAULT";
- }
-
- Map<String, String> agentMgrConfigs = _configDao.getConfiguration("AgentManager", params);
-
- value = agentMgrConfigs.get("port");
- _mgmtPort = NumbersUtil.parseInt(value, 8250);
-
- _listener = new SecondaryStorageListener(this);
- _agentMgr.registerForHostEvents(_listener, true, false, true);
-
- _itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this);
-
- //check if there is a default service offering configured
- String ssvmSrvcOffIdStr = configs.get(Config.SecondaryStorageServiceOffering.key());
- if (ssvmSrvcOffIdStr != null) {
- Long ssvmSrvcOffId = Long.parseLong(ssvmSrvcOffIdStr);
- _serviceOffering = _offeringDao.findById(ssvmSrvcOffId);
- if (_serviceOffering == null || !_serviceOffering.getSystemUse()) {
- String msg = "Can't find system service offering id=" + ssvmSrvcOffId + " for secondary storage vm";
- s_logger.error(msg);
- throw new ConfigurationException(msg);
- }
- } else {
- int ramSize = NumbersUtil.parseInt(_configDao.getValue("ssvm.ram.size"), DEFAULT_SS_VM_RAMSIZE);
- int cpuFreq = NumbersUtil.parseInt(_configDao.getValue("ssvm.cpu.mhz"), DEFAULT_SS_VM_CPUMHZ);
- _useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key()));
- _serviceOffering =
- new ServiceOfferingVO("System Offering For Secondary Storage VM", 1, ramSize, cpuFreq, null, null, false, null, _useLocalStorage, true, null, true,
- VirtualMachine.Type.SecondaryStorageVm, true);
- _serviceOffering.setUniqueName(ServiceOffering.ssvmDefaultOffUniqueName);
- _serviceOffering = _offeringDao.persistSystemServiceOffering(_serviceOffering);
-
- // this can sometimes happen, if DB is manually or programmatically manipulated
- if (_serviceOffering == null) {
- String msg = "Data integrity problem : System Offering For Secondary Storage VM has been removed?";
- s_logger.error(msg);
- throw new ConfigurationException(msg);
- }
- }
-
- if (_useServiceVM) {
- _loadScanner = new SystemVmLoadScanner<Long>(this);
- _loadScanner.initScan(STARTUP_DELAY, _capacityScanInterval);
- }
-
- _httpProxy = configs.get(Config.SecStorageProxy.key());
- if (_httpProxy != null) {
- boolean valid = true;
- String errMsg = null;
- try {
- URI uri = new URI(_httpProxy);
- if (!"http".equalsIgnoreCase(uri.getScheme())) {
- errMsg = "Only support http proxy";
- valid = false;
- } else if (uri.getHost() == null) {
- errMsg = "host can not be null";
- valid = false;
- } else if (uri.getPort() == -1) {
- _httpProxy = _httpProxy + ":3128";
- }
- } catch (URISyntaxException e) {
- errMsg = e.toString();
- } finally {
- if (!valid) {
- s_logger.debug("ssvm http proxy " + _httpProxy + " is invalid: " + errMsg);
- throw new ConfigurationException("ssvm http proxy " + _httpProxy + "is invalid: " + errMsg);
- }
- }
- }
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Secondary storage vm Manager is configured.");
- }
- _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
- return true;
- }
-
- @Override
- public boolean stopSecStorageVm(long secStorageVmId) {
- SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
- if (secStorageVm == null) {
- String msg = "Stopping secondary storage vm failed: secondary storage vm " + secStorageVmId + " no longer exists";
- if (s_logger.isDebugEnabled()) {
- s_logger.debug(msg);
- }
- return false;
- }
- try {
- if (secStorageVm.getHostId() != null) {
- GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVm.getId()));
- try {
- if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
- try {
- _itMgr.stop(secStorageVm.getUuid());
- return true;
- } finally {
- secStorageVmLock.unlock();
- }
- } else {
- String msg = "Unable to acquire secondary storage vm lock : " + secStorageVm.toString();
- s_logger.debug(msg);
- return false;
- }
- } finally {
- secStorageVmLock.releaseRef();
- }
- }
-
- // vm was already stopped, return true
- return true;
- } catch (ResourceUnavailableException e) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Stopping secondary storage vm " + secStorageVm.getHostName() + " faled : exception " + e.toString());
- }
- return false;
- }
- }
-
- @Override
- public boolean rebootSecStorageVm(long secStorageVmId) {
- final SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
-
- if (secStorageVm == null || secStorageVm.getState() == State.Destroyed) {
- return false;
- }
-
- if (secStorageVm.getState() == State.Running && secStorageVm.getHostId() != null) {
- final RebootCommand cmd = new RebootCommand(secStorageVm.getInstanceName());
- final Answer answer = _agentMgr.easySend(secStorageVm.getHostId(), cmd);
-
- if (answer != null && answer.getResult()) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Successfully reboot secondary storage vm " + secStorageVm.getHostName());
- }
-
- SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
- new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_REBOOTED, secStorageVm.getDataCenterId(), secStorageVm.getId(), secStorageVm, null));
-
- return true;
- } else {
- String msg = "Rebooting Secondary Storage VM failed - " + secStorageVm.getHostName();
- if (s_logger.isDebugEnabled()) {
- s_logger.debug(msg);
- }
- return false;
- }
- } else {
- return startSecStorageVm(secStorageVmId) != null;
- }
- }
-
- @Override
- public boolean destroySecStorageVm(long vmId) {
- SecondaryStorageVmVO ssvm = _secStorageVmDao.findById(vmId);
-
- try {
- _itMgr.expunge(ssvm.getUuid());
- _secStorageVmDao.remove(ssvm.getId());
- HostVO host = _hostDao.findByTypeNameAndZoneId(ssvm.getDataCenterId(), ssvm.getHostName(), Host.Type.SecondaryStorageVM);
- if (host != null) {
- s_logger.debug("Removing host entry for ssvm id=" + vmId);
- _hostDao.remove(host.getId());
- }
-
- return true;
- } catch (ResourceUnavailableException e) {
- s_logger.warn("Unable to expunge " + ssvm, e);
- return false;
- }
- }
-
- @Override
- public void onAgentConnect(Long dcId, StartupCommand cmd) {
- }
-
- private String getAllocLockName() {
- // to improve security, it may be better to return a unique mashed
- // name(for example MD5 hashed)
- return "secStorageVm.alloc";
- }
-
- private String getSecStorageVmLockName(long id) {
- return "secStorageVm." + id;
- }
-
- @Override
- public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
-
- SecondaryStorageVmVO vm = _secStorageVmDao.findById(profile.getId());
- Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
- vm.setDetails(details);
-
- DataStore secStore = _dataStoreMgr.getImageStore(dest.getDataCenter().getId());
- assert (secStore != null);
-
- StringBuilder buf = profile.getBootArgsBuilder();
- buf.append(" template=domP type=secstorage");
- buf.append(" host=").append(ApiServiceConfiguration.ManagementHostIPAdr.value());
- buf.append(" port=").append(_mgmtPort);
- buf.append(" name=").append(profile.getVirtualMachine().getHostName());
-
- buf.append(" zone=").append(dest.getDataCenter().getId());
- buf.append(" pod=").append(dest.getPod().getId());
-
- buf.append(" guid=").append(profile.getVirtualMachine().getHostName());
-
- if (_configDao.isPremium()) {
- s_logger.debug("VmWare hypervisor configured, telling the ssvm to load the PremiumSecondaryStorageResource");
- buf.append(" resource=com.cloud.storage.resource.PremiumSecondaryStorageResource");
- } else {
- buf.append(" resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource");
- }
- buf.append(" instance=SecStorage");
- buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));
- buf.append(" role=").append(vm.getRole().toString());
- buf.append(" mtu=").append(_secStorageVmMtuSize);
-
- boolean externalDhcp = false;
- String externalDhcpStr = _configDao.getValue("direct.attach.network.externalIpAllocator.enabled");
- if (externalDhcpStr != null && externalDhcpStr.equalsIgnoreCase("true")) {
- externalDhcp = true;
- }
-
- if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
- buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
- }
-
- for (NicProfile nic : profile.getNics()) {
- int deviceId = nic.getDeviceId();
- if (nic.getIp4Address() == null) {
- buf.append(" eth").append(deviceId).append("mask=").append("0.0.0.0");
- buf.append(" eth").append(deviceId).append("ip=").append("0.0.0.0");
- } else {
- buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address());
- buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask());
- }
-
- if (nic.isDefaultNic()) {
- buf.append(" gateway=").append(nic.getGateway());
- }
- if (nic.getTrafficType() == TrafficType.Management) {
- String mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key());
- if (NetUtils.isValidCIDR(mgmt_cidr)) {
- buf.append(" mgmtcidr=").append(mgmt_cidr);
- }
- buf.append(" localgw=").append(dest.getPod().getGateway());
- buf.append(" private.network.device=").append("eth").append(deviceId);
- } else if (nic.getTrafficType() == TrafficType.Public) {
- buf.append(" public.network.device=").append("eth").append(deviceId);
- } else if (nic.getTrafficType() == TrafficType.Storage) {
- buf.append(" storageip=").append(nic.getIp4Address());
- buf.append(" storagenetmask=").append(nic.getNetmask());
- buf.append(" storagegateway=").append(nic.getGateway());
- }
- }
-
- /* External DHCP mode */
- if (externalDhcp) {
- buf.append(" bootproto=dhcp");
- }
-
- DataCenterVO dc = _dcDao.findById(profile.getVirtualMachine().getDataCenterId());
- buf.append(" internaldns1=").append(dc.getInternalDns1());
- if (dc.getInternalDns2() != null) {
- buf.append(" internaldns2=").append(dc.getInternalDns2());
- }
- buf.append(" dns1=").append(dc.getDns1());
- if (dc.getDns2() != null) {
- buf.append(" dns2=").append(dc.getDns2());
- }
-
- String bootArgs = buf.toString();
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Boot Args for " + profile + ": " + bootArgs);
- }
-
- return true;
- }
-
- @Override
- public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
-
- finalizeCommandsOnStart(cmds, profile);
-
- SecondaryStorageVmVO secVm = _secStorageVmDao.findById(profile.getId());
- DataCenter dc = dest.getDataCenter();
- List<NicProfile> nics = profile.getNics();
- for (NicProfile nic : nics) {
- if ((nic.getTrafficType() == TrafficType.Public && dc.getNetworkType() == NetworkType.Advanced) ||
- (nic.getTrafficType() == TrafficType.Guest && (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()))) {
- secVm.setPublicIpAddress(nic.getIp4Address());
- secVm.setPublicNetmask(nic.getNetmask());
- secVm.setPublicMacAddress(nic.getMacAddress());
- } else if (nic.getTrafficType() == TrafficType.Management) {
- secVm.setPrivateIpAddress(nic.getIp4Address());
- secVm.setPrivateMacAddress(nic.getMacAddress());
- }
- }
- _secStorageVmDao.update(secVm.getId(), secVm);
- return true;
- }
-
- @Override
- public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
-
- NicProfile managementNic = null;
- NicProfile controlNic = null;
- for (NicProfile nic : profile.getNics()) {
- if (nic.getTrafficType() == TrafficType.Management) {
- managementNic = nic;
- } else if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != null) {
- controlNic = nic;
- }
- }
-
- if (controlNic == null) {
- if (managementNic == null) {
- s_logger.error("Management network doesn't exist for the secondaryStorageVm " + profile.getVirtualMachine());
- return false;
- }
- controlNic = managementNic;
- }
-
- // verify ssh access on management nic for system vm running on HyperV
- if(profile.getHypervisorType() == HypervisorType.Hyperv) {
- controlNic = managementNic;
- }
-
- CheckSshCommand check = new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922);
- cmds.addCommand("checkSsh", check);
-
- return true;
- }
-
- @Override
- public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
- CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
- if (!answer.getResult()) {
- s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
- return false;
- }
-
- try {
- //get system ip and create static nat rule for the vm in case of basic networking with EIP/ELB
- _rulesMgr.getSystemIpAndEnableStaticNatForVm(profile.getVirtualMachine(), false);
- IPAddressVO ipaddr = _ipAddressDao.findByAssociatedVmId(profile.getVirtualMachine().getId());
- if (ipaddr != null && ipaddr.getSystem()) {
- SecondaryStorageVmVO secVm = _secStorageVmDao.findById(profile.getId());
- // override SSVM guest IP with EIP, so that download url's with be prepared with EIP
- secVm.setPublicIpAddress(ipaddr.getAddress().addr());
- _secStorageVmDao.update(secVm.getId(), secVm);
- }
- } catch (Exception ex) {
- s_logger.warn("Failed to get system ip and enable static nat for the vm " + profile.getVirtualMachine() + " due to exception ", ex);
- return false;
- }
-
- return true;
- }
-
- @Override
- public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
- //release elastic IP here
- IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(profile.getId());
- if (ip != null && ip.getSystem()) {
- CallContext ctx = CallContext.current();
- try {
- _rulesMgr.disableStaticNat(ip.getId(), ctx.getCallingAccount(), ctx.getCallingUserId(), true);
- } catch (Exception ex) {
- s_logger.warn("Failed to disable static nat and release system ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ",
- ex);
- }
- }
- }
-
- @Override
- public void finalizeExpunge(VirtualMachine vm) {
- SecondaryStorageVmVO ssvm = _secStorageVmDao.findByUuid(vm.getUuid());
-
- ssvm.setPublicIpAddress(null);
- ssvm.setPublicMacAddress(null);
- ssvm.setPublicNetmask(null);
- _secStorageVmDao.update(ssvm.getId(), ssvm);
- }
-
- @Override
- public String getScanHandlerName() {
- return "secstorage";
- }
-
- @Override
- public boolean canScan() {
- return true;
- }
-
- @Override
- public void onScanStart() {
- _zoneHostInfoMap = getZoneHostInfo();
- }
-
- @Override
- public Long[] getScannablePools() {
- List<DataCenterVO> zones = _dcDao.listEnabledZones();
-
- Long[] dcIdList = new Long[zones.size()];
- int i = 0;
- for (DataCenterVO dc : zones) {
- dcIdList[i++] = dc.getId();
- }
-
- return dcIdList;
- }
-
- @Override
- public boolean isPoolReadyForScan(Long pool) {
- // pool is at zone basis
- long dataCenterId = pool.longValue();
-
- if (!isZoneReady(_zoneHostInfoMap, dataCenterId)) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Zone " + dataCenterId + " is not ready to launch secondary storage VM yet");
- }
- return false;
- }
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Zone " + dataCenterId + " is ready to launch secondary storage VM");
- }
- return true;
- }
-
- @Override
- public Pair<AfterScanAction, Object> scanPool(Long pool) {
- long dataCenterId = pool.longValue();
-
- List<SecondaryStorageVmVO> ssVms =
- _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting,
- State.Stopped, State.Stopping);
- int vmSize = (ssVms == null) ? 0 : ssVms.size();
- List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId));
- int storeSize = (ssStores == null) ? 0 : ssStores.size();
- if (storeSize > vmSize) {
- s_logger.info("No secondary storage vms found in datacenter id=" + dataCenterId + ", starting a new one");
- return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.templateProcessor);
- }
-
- return new Pair<AfterScanAction, Object>(AfterScanAction.nop, SecondaryStorageVm.Role.templateProcessor);
- }
-
- @Override
- public void expandPool(Long pool, Object actionArgs) {
- long dataCenterId = pool.longValue();
- allocCapacity(dataCenterId, (SecondaryStorageVm.Role)actionArgs);
- }
-
- @Override
- public void shrinkPool(Long pool, Object actionArgs) {
- }
-
- @Override
- public void onScanEnd() {
- }
-
- @Override
- public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
- /* Called when Secondary Storage VM connected */
- StartupCommand firstCmd = cmd[0];
- if (!(firstCmd instanceof StartupSecondaryStorageCommand)) {
- return null;
- }
-
- host.setType(com.cloud.host.Host.Type.SecondaryStorageVM);
- return host;
- }
-
- @Override
- public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
- // Used to be Called when add secondary storage on UI through DummySecondaryStorageResource to update that host entry for Secondary Storage.
- // Now since we move secondary storage from host table, this code is not needed to be invoked anymore.
- /*
- StartupCommand firstCmd = startup[0];
- if (!(firstCmd instanceof StartupStorageCommand)) {
- return null;
- }
-
- com.cloud.host.Host.Type type = null;
- StartupStorageCommand ssCmd = ((StartupStorageCommand) firstCmd);
- if (ssCmd.getHostType() == Host.Type.SecondaryStorageCmdExecutor) {
- type = ssCmd.getHostType();
- } else {
- if (ssCmd.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE) {
- type = Host.Type.SecondaryStorage;
- if (resource != null && resource instanceof DummySecondaryStorageResource) {
- host.setResource(null);
- }
- } else if (ssCmd.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE) {
- type = Host.Type.LocalSecondaryStorage;
- } else {
- type = Host.Type.Storage;
- }
-
- final Map<String, String> hostDetails = ssCmd.getHostDetails();
- if (hostDetails != null) {
- if (details != null) {
- details.putAll(hostDetails);
- } else {
- details = hostDetails;
- }
- }
-
- host.setDetails(details);
- host.setParent(ssCmd.getParent());
- host.setTotalSize(ssCmd.getTotalSize());
- host.setHypervisorType(HypervisorType.None);
- host.setType(type);
- if (ssCmd.getNfsShare() != null) {
- host.setStorageUrl(ssCmd.getNfsShare());
- }
- }
- */
- return null; // no need to handle this event anymore since secondary storage is not in host table anymore.
- }
-
- @Override
- public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
- // Since secondary storage is moved out of host table, this class should not handle delete secondary storage anymore.
- return null;
- }
-
- @Override
- public List<HostVO> listUpAndConnectingSecondaryStorageVmHost(Long dcId) {
- QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
- if (dcId != null) {
- sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
- }
- sc.and(sc.entity().getState(), Op.IN, Status.Up, Status.Connecting);
- sc.and(sc.entity().getType(), Op.EQ, Host.Type.SecondaryStorageVM);
- return sc.list();
- }
-
- @Override
- public HostVO pickSsvmHost(HostVO ssHost) {
- if (ssHost.getType() == Host.Type.LocalSecondaryStorage) {
- return ssHost;
- } else if (ssHost.getType() == Host.Type.SecondaryStorage) {
- Long dcId = ssHost.getDataCenterId();
- List<HostVO> ssAHosts = listUpAndConnectingSecondaryStorageVmHost(dcId);
- if (ssAHosts == null || ssAHosts.isEmpty()) {
- return null;
- }
- Collections.shuffle(ssAHosts);
- return ssAHosts.get(0);
- }
- return null;
- }
-
- @Override
- public void prepareStop(VirtualMachineProfile profile) {
-
- }
-
- public List<SecondaryStorageVmAllocator> getSecondaryStorageVmAllocators() {
- return _ssVmAllocators;
- }
-
- @Inject
- public void setSecondaryStorageVmAllocators(List<SecondaryStorageVmAllocator> ssVmAllocators) {
- _ssVmAllocators = ssVmAllocators;
- }
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java
index 4a02968..06f21d3 100644
--- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java
+++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java
@@ -41,6 +41,7 @@ public class ConsoleProxyThumbnailHandler implements HttpHandler {
}
@Override
+ @SuppressWarnings("access")
public void handle(HttpExchange t) throws IOException {
try {
Thread.currentThread().setName("JPG Thread " + Thread.currentThread().getId() + " " + t.getRemoteAddress());
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/services/secondary-storage/controller/resources/META-INF/cloudstack/core/spring-services-secondary-storage-controller-core-context.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/controller/resources/META-INF/cloudstack/core/spring-services-secondary-storage-controller-core-context.xml b/services/secondary-storage/controller/resources/META-INF/cloudstack/core/spring-services-secondary-storage-controller-core-context.xml
new file mode 100644
index 0000000..a62fede
--- /dev/null
+++ b/services/secondary-storage/controller/resources/META-INF/cloudstack/core/spring-services-secondary-storage-controller-core-context.xml
@@ -0,0 +1,33 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ 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 id="premiumSecondaryStorageManagerImpl" class="org.apache.cloudstack.secondarystorage.PremiumSecondaryStorageManagerImpl">
+ <property name="secondaryStorageVmAllocators"
+ value="#{secondaryStorageVmAllocatorsRegistry.registered}" />
+ </bean>
+</beans>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java
new file mode 100755
index 0000000..af96ed2
--- /dev/null
+++ b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java
@@ -0,0 +1,186 @@
+// 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.secondarystorage;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Command;
+import com.cloud.configuration.Config;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.secstorage.CommandExecLogDao;
+import com.cloud.secstorage.CommandExecLogVO;
+import com.cloud.storage.secondary.SecondaryStorageVmManager;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.JoinBuilder.JoinType;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.vm.SecondaryStorageVm;
+import com.cloud.vm.SecondaryStorageVmVO;
+import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.SecondaryStorageVmDao;
+
+@Local(value = {SecondaryStorageVmManager.class})
+public class PremiumSecondaryStorageManagerImpl extends SecondaryStorageManagerImpl {
+ private static final Logger s_logger = Logger.getLogger(PremiumSecondaryStorageManagerImpl.class);
+
+ private int _capacityPerSSVM = SecondaryStorageVmManager.DEFAULT_SS_VM_CAPACITY;
+ private int _standbyCapacity = SecondaryStorageVmManager.DEFAULT_STANDBY_CAPACITY;
+ private int _maxExecutionTimeMs = 1800000;
+
+ @Inject
+ SecondaryStorageVmDao _secStorageVmDao;
+ @Inject
+ CommandExecLogDao _cmdExecLogDao;
+ @Inject
+ HostDao _hostDao;
+ @Inject
+ ResourceManager _resourceMgr;
+ protected SearchBuilder<CommandExecLogVO> ActiveCommandSearch;
+ protected SearchBuilder<HostVO> HostSearch;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ super.configure(name, params);
+
+ _capacityPerSSVM = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageSessionMax.key()), DEFAULT_SS_VM_CAPACITY);
+ _standbyCapacity = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageCapacityStandby.key()), DEFAULT_STANDBY_CAPACITY);
+
+ int nMaxExecutionMinutes = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageCmdExecutionTimeMax.key()), 30);
+ _maxExecutionTimeMs = nMaxExecutionMinutes * 60 * 1000;
+
+ HostSearch = _hostDao.createSearchBuilder();
+ HostSearch.and("dc", HostSearch.entity().getDataCenterId(), Op.EQ);
+ HostSearch.and("status", HostSearch.entity().getStatus(), Op.EQ);
+
+ ActiveCommandSearch = _cmdExecLogDao.createSearchBuilder();
+ ActiveCommandSearch.and("created", ActiveCommandSearch.entity().getCreated(), Op.GTEQ);
+ ActiveCommandSearch.join("hostSearch", HostSearch, ActiveCommandSearch.entity().getInstanceId(), HostSearch.entity().getId(), JoinType.INNER);
+
+ HostSearch.done();
+ ActiveCommandSearch.done();
+ return true;
+ }
+
+ @Override
+ public Pair<AfterScanAction, Object> scanPool(Long pool) {
+ long dataCenterId = pool.longValue();
+ if (!isSecondaryStorageVmRequired(dataCenterId)) {
+ return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+ }
+
+ Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - _maxExecutionTimeMs);
+
+ _cmdExecLogDao.expungeExpiredRecords(cutTime);
+
+ boolean suspendAutoLoading = !reserveStandbyCapacity();
+ if (!suspendAutoLoading) {
+ // this is a hacking, has nothing to do with console proxy, it is just a flag that primary storage is being under maintenance mode
+ String restart = _configDao.getValue("consoleproxy.restart");
+ if (restart != null && restart.equalsIgnoreCase("false")) {
+ s_logger.debug("Capacity scan disabled purposefully, consoleproxy.restart = false. This happens when the primarystorage is in maintenance mode");
+ suspendAutoLoading = true;
+ }
+ }
+
+ List<SecondaryStorageVmVO> alreadyRunning =
+ _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting);
+ if (alreadyRunning.size() == 0) {
+ s_logger.info("No running secondary storage vms found in datacenter id=" + dataCenterId + ", starting one");
+
+ List<SecondaryStorageVmVO> stopped =
+ _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Stopped, State.Stopping);
+ if (stopped.size() == 0 || !suspendAutoLoading) {
+ List<SecondaryStorageVmVO> stopping = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, State.Stopping);
+ if (stopping.size() > 0) {
+ s_logger.info("Found SSVMs that are currently at stopping state, wait until they are settled");
+ return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+ }
+
+ expandPool(pool, SecondaryStorageVm.Role.templateProcessor);
+ }
+ }
+
+ if (!suspendAutoLoading) {
+ // this is to avoid surprises that people may accidently see two SSVMs being launched, capacity expanding only happens when we have at least the primary SSVM is up
+ if (alreadyRunning.size() == 0) {
+ s_logger.info("Primary secondary storage is not even started, wait until next turn");
+ return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+ }
+
+ alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, dataCenterId, State.Running, State.Migrating, State.Starting);
+
+ List<CommandExecLogVO> activeCmds = listActiveCommands(dataCenterId, cutTime);
+ if (alreadyRunning.size() * _capacityPerSSVM - activeCmds.size() < _standbyCapacity) {
+ s_logger.info("secondary storage command execution standby capactiy low (running VMs: " + alreadyRunning.size() + ", active cmds: " + activeCmds.size() +
+ "), starting a new one");
+ return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.commandExecutor);
+ }
+ }
+
+ return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+ }
+
+ @Override
+ public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd) {
+
+ // TODO, need performance optimization
+ List<Long> vms = _secStorageVmDao.listRunningSecStorageOrderByLoad(null, zoneId);
+ for (Long vmId : vms) {
+ SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(vmId);
+ HostVO host;
+ host = _resourceMgr.findHostByName(secStorageVm.getHostName());
+ if (host != null && host.getStatus() == Status.Up)
+ return new Pair<HostVO, SecondaryStorageVmVO>(host, secStorageVm);
+ }
+
+ return null;
+ }
+
+ private List<CommandExecLogVO> listActiveCommands(long dcId, Date cutTime) {
+ SearchCriteria<CommandExecLogVO> sc = ActiveCommandSearch.create();
+
+ sc.setParameters("created", cutTime);
+ sc.setJoinParameters("hostSearch", "dc", dcId);
+ sc.setJoinParameters("hostSearch", "status", Status.Up);
+
+ return _cmdExecLogDao.search(sc, null);
+ }
+
+ private boolean reserveStandbyCapacity() {
+ String value = _configDao.getValue(Config.SystemVMAutoReserveCapacity.key());
+ if (value != null && value.equalsIgnoreCase("true")) {
+ return true;
+ }
+
+ return false;
+ }
+}
[04/11] Moved the secondary storage service into its own server
directory
Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
new file mode 100755
index 0000000..cdbc52d
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
@@ -0,0 +1,550 @@
+// 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.storage.template;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+
+import com.cloud.agent.api.storage.CreateEntityDownloadURLAnswer;
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLAnswer;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.UploadAnswer;
+import com.cloud.agent.api.storage.UploadCommand;
+import com.cloud.agent.api.storage.UploadProgressCommand;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.Upload;
+import com.cloud.storage.UploadVO;
+import com.cloud.storage.template.FtpTemplateUploader;
+import com.cloud.storage.template.TemplateUploader;
+import com.cloud.storage.template.TemplateUploader.Status;
+import com.cloud.storage.template.TemplateUploader.UploadCompleteCallback;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+
+public class UploadManagerImpl extends ManagerBase implements UploadManager {
+
+ public class Completion implements UploadCompleteCallback {
+ private final String jobId;
+
+ public Completion(String jobId) {
+ this.jobId = jobId;
+ }
+
+ @Override
+ public void uploadComplete(Status status) {
+ setUploadStatus(jobId, status);
+ }
+ }
+
+ private static class UploadJob {
+ private final TemplateUploader tu;
+
+ public UploadJob(TemplateUploader tu, String jobId, long id, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
+ String installPathPrefix) {
+ super();
+ this.tu = tu;
+ }
+
+ public TemplateUploader getTemplateUploader() {
+ return tu;
+ }
+
+ public void cleanup() {
+ if (tu != null) {
+ String upldPath = tu.getUploadLocalPath();
+ if (upldPath != null) {
+ File f = new File(upldPath);
+ f.delete();
+ }
+ }
+ }
+
+ }
+
+ public static final Logger s_logger = Logger.getLogger(UploadManagerImpl.class);
+ private ExecutorService threadPool;
+ private final Map<String, UploadJob> jobs = new ConcurrentHashMap<String, UploadJob>();
+ private String parentDir;
+ private final String extractMountPoint = "/mnt/SecStorage/extractmnt";
+ private StorageLayer _storage;
+ private boolean hvm;
+
+ @Override
+ public String uploadPublicTemplate(long id, String url, String name, ImageFormat format, Long accountId, String descr, String cksum, String installPathPrefix,
+ String userName, String passwd, long templateSizeInBytes) {
+
+ UUID uuid = UUID.randomUUID();
+ String jobId = uuid.toString();
+
+ String completePath = parentDir + File.separator + installPathPrefix;
+ s_logger.debug("Starting upload from " + completePath);
+
+ URI uri;
+ try {
+ uri = new URI(url);
+ } catch (URISyntaxException e) {
+ s_logger.error("URI is incorrect: " + url);
+ throw new CloudRuntimeException("URI is incorrect: " + url);
+ }
+ TemplateUploader tu;
+ if ((uri != null) && (uri.getScheme() != null)) {
+ if (uri.getScheme().equalsIgnoreCase("ftp")) {
+ tu = new FtpTemplateUploader(completePath, url, new Completion(jobId), templateSizeInBytes);
+ } else {
+ s_logger.error("Scheme is not supported " + url);
+ throw new CloudRuntimeException("Scheme is not supported " + url);
+ }
+ } else {
+ s_logger.error("Unable to download from URL: " + url);
+ throw new CloudRuntimeException("Unable to download from URL: " + url);
+ }
+ UploadJob uj = new UploadJob(tu, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix);
+ jobs.put(jobId, uj);
+ threadPool.execute(tu);
+
+ return jobId;
+
+ }
+
+ @Override
+ public String getUploadError(String jobId) {
+ UploadJob uj = jobs.get(jobId);
+ if (uj != null) {
+ return uj.getTemplateUploader().getUploadError();
+ }
+ return null;
+ }
+
+ @Override
+ public int getUploadPct(String jobId) {
+ UploadJob uj = jobs.get(jobId);
+ if (uj != null) {
+ return uj.getTemplateUploader().getUploadPercent();
+ }
+ return 0;
+ }
+
+ @Override
+ public Status getUploadStatus(String jobId) {
+ UploadJob job = jobs.get(jobId);
+ if (job != null) {
+ TemplateUploader tu = job.getTemplateUploader();
+ if (tu != null) {
+ return tu.getStatus();
+ }
+ }
+ return Status.UNKNOWN;
+ }
+
+ public static UploadVO.Status convertStatus(Status tds) {
+ switch (tds) {
+ case ABORTED:
+ return UploadVO.Status.NOT_UPLOADED;
+ case UPLOAD_FINISHED:
+ return UploadVO.Status.UPLOAD_IN_PROGRESS;
+ case IN_PROGRESS:
+ return UploadVO.Status.UPLOAD_IN_PROGRESS;
+ case NOT_STARTED:
+ return UploadVO.Status.NOT_UPLOADED;
+ case RECOVERABLE_ERROR:
+ return UploadVO.Status.NOT_UPLOADED;
+ case UNKNOWN:
+ return UploadVO.Status.UNKNOWN;
+ case UNRECOVERABLE_ERROR:
+ return UploadVO.Status.UPLOAD_ERROR;
+ case POST_UPLOAD_FINISHED:
+ return UploadVO.Status.UPLOADED;
+ default:
+ return UploadVO.Status.UNKNOWN;
+ }
+ }
+
+ @Override
+ public com.cloud.storage.UploadVO.Status getUploadStatus2(String jobId) {
+ return convertStatus(getUploadStatus(jobId));
+ }
+
+ @Override
+ public String getPublicTemplateRepo() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ private UploadAnswer handleUploadProgressCmd(UploadProgressCommand cmd) {
+ String jobId = cmd.getJobId();
+ UploadAnswer answer;
+ UploadJob uj = null;
+ if (jobId != null)
+ uj = jobs.get(jobId);
+ if (uj == null) {
+ return new UploadAnswer(null, 0, "Cannot find job", com.cloud.storage.UploadVO.Status.UNKNOWN, "", "", 0);
+ }
+ TemplateUploader td = uj.getTemplateUploader();
+ switch (cmd.getRequest()) {
+ case GET_STATUS:
+ break;
+ case ABORT:
+ td.stopUpload();
+ sleep();
+ break;
+ /*case RESTART:
+ td.stopUpload();
+ sleep();
+ threadPool.execute(td);
+ break;*/
+ case PURGE:
+ td.stopUpload();
+ answer =
+ new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId),
+ getUploadTemplateSize(jobId));
+ jobs.remove(jobId);
+ return answer;
+ default:
+ break; // TODO
+ }
+ return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId),
+ getUploadTemplateSize(jobId));
+ }
+
+ @Override
+ public UploadAnswer handleUploadCommand(SecondaryStorageResource resource, UploadCommand cmd) {
+ s_logger.warn("Handling the upload " + cmd.getInstallPath() + " " + cmd.getId());
+ if (cmd instanceof UploadProgressCommand) {
+ return handleUploadProgressCmd((UploadProgressCommand)cmd);
+ }
+
+ String user = null;
+ String password = null;
+ String jobId =
+ uploadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(),
+ cmd.getInstallPath(), user, password, cmd.getTemplateSizeInBytes());
+ sleep();
+ return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId),
+ getUploadTemplateSize(jobId));
+ }
+
+ @Override
+ public CreateEntityDownloadURLAnswer handleCreateEntityURLCommand(CreateEntityDownloadURLCommand cmd) {
+
+ boolean isApacheUp = checkAndStartApache();
+ if (!isApacheUp) {
+ String errorString = "Error in starting Apache server ";
+ s_logger.error(errorString);
+ return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
+ }
+ // Create the directory structure so that its visible under apache server root
+ String extractDir = "/var/www/html/userdata/";
+ Script command = new Script("mkdir", s_logger);
+ command.add("-p");
+ command.add(extractDir);
+ String result = command.execute();
+ if (result != null) {
+ String errorString = "Error in creating directory =" + result;
+ s_logger.error(errorString);
+ return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
+ }
+
+ // Create a random file under the directory for security reasons.
+ String uuid = cmd.getExtractLinkUUID();
+ command = new Script("touch", s_logger);
+ command.add(extractDir + uuid);
+ result = command.execute();
+ if (result != null) {
+ String errorString = "Error in creating file " + uuid + " ,error: " + result;
+ s_logger.warn(errorString);
+ return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
+ }
+
+ // Create a symbolic link from the actual directory to the template location. The entity would be directly visible under /var/www/html/userdata/cmd.getInstallPath();
+ command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("ln -sf /mnt/SecStorage/" + cmd.getParent() + File.separator + cmd.getInstallPath() + " " + extractDir + uuid);
+ result = command.execute();
+ if (result != null) {
+ String errorString = "Error in linking err=" + result;
+ s_logger.error(errorString);
+ return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
+ }
+
+ return new CreateEntityDownloadURLAnswer("", CreateEntityDownloadURLAnswer.RESULT_SUCCESS);
+
+ }
+
+ @Override
+ public DeleteEntityDownloadURLAnswer handleDeleteEntityDownloadURLCommand(DeleteEntityDownloadURLCommand cmd) {
+
+ //Delete the soft link. Example path = volumes/8/74eeb2c6-8ab1-4357-841f-2e9d06d1f360.vhd
+ s_logger.warn("handleDeleteEntityDownloadURLCommand Path:" + cmd.getPath() + " Type:" + cmd.getType().toString());
+ String path = cmd.getPath();
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+
+ //We just need to remove the UUID.vhd
+ String extractUrl = cmd.getExtractUrl();
+ command.add("unlink /var/www/html/userdata/" + extractUrl.substring(extractUrl.lastIndexOf(File.separator) + 1));
+ String result = command.execute();
+ if (result != null) {
+ String errorString = "Error in deleting =" + result;
+ s_logger.warn(errorString);
+ return new DeleteEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
+ }
+
+ // If its a volume also delete the Hard link since it was created only for the purpose of download.
+ if (cmd.getType() == Upload.Type.VOLUME) {
+ command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("rm -f /mnt/SecStorage/" + cmd.getParentPath() + File.separator + path);
+ s_logger.warn(" " + parentDir + File.separator + path);
+ result = command.execute();
+ if (result != null) {
+ String errorString = "Error in linking err=" + result;
+ s_logger.warn(errorString);
+ return new DeleteEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
+ }
+ }
+
+ return new DeleteEntityDownloadURLAnswer("", CreateEntityDownloadURLAnswer.RESULT_SUCCESS);
+ }
+
+ private String getInstallPath(String jobId) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ private String getUploadLocalPath(String jobId) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ private long getUploadTemplateSize(String jobId) {
+ return 0;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+
+ String value = null;
+
+ _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
+ if (_storage == null) {
+ value = (String)params.get(StorageLayer.ClassConfigKey);
+ if (value == null) {
+ throw new ConfigurationException("Unable to find the storage layer");
+ }
+
+ Class<StorageLayer> clazz;
+ try {
+ clazz = (Class<StorageLayer>)Class.forName(value);
+ _storage = clazz.newInstance();
+ } catch (ClassNotFoundException e) {
+ throw new ConfigurationException("Unable to instantiate " + value);
+ } catch (InstantiationException e) {
+ throw new ConfigurationException("Unable to instantiate " + value);
+ } catch (IllegalAccessException e) {
+ throw new ConfigurationException("Unable to instantiate " + value);
+ }
+ }
+
+ String inSystemVM = (String)params.get("secondary.storage.vm");
+ if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) {
+ s_logger.info("UploadManager: starting additional services since we are inside system vm");
+ startAdditionalServices();
+ //blockOutgoingOnPrivate();
+ }
+
+ value = (String)params.get("install.numthreads");
+ final int numInstallThreads = NumbersUtil.parseInt(value, 10);
+
+ String scriptsDir = (String)params.get("template.scripts.dir");
+ if (scriptsDir == null) {
+ scriptsDir = "scripts/storage/secondary";
+ }
+
+ // Add more processors here.
+ threadPool = Executors.newFixedThreadPool(numInstallThreads);
+
+ return true;
+ }
+
+ private void startAdditionalServices() {
+
+ Script command = new Script("rm", s_logger);
+ command.add("-rf");
+ command.add(extractMountPoint);
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in creating file " + extractMountPoint + " ,error: " + result);
+ return;
+ }
+
+ command = new Script("touch", s_logger);
+ command.add(extractMountPoint);
+ result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in creating file " + extractMountPoint + " ,error: " + result);
+ return;
+ }
+
+ command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("ln -sf " + parentDir + " " + extractMountPoint);
+ result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in linking err=" + result);
+ return;
+ }
+
+ }
+
+ /**
+ * Get notified of change of job status. Executed in context of uploader thread
+ *
+ * @param jobId
+ * the id of the job
+ * @param status
+ * the status of the job
+ */
+ public void setUploadStatus(String jobId, Status status) {
+ UploadJob uj = jobs.get(jobId);
+ if (uj == null) {
+ s_logger.warn("setUploadStatus for jobId: " + jobId + ", status=" + status + " no job found");
+ return;
+ }
+ TemplateUploader tu = uj.getTemplateUploader();
+ s_logger.warn("Upload Completion for jobId: " + jobId + ", status=" + status);
+ s_logger.warn("UploadedBytes=" + tu.getUploadedBytes() + ", error=" + tu.getUploadError() + ", pct=" + tu.getUploadPercent());
+
+ switch (status) {
+ case ABORTED:
+ case NOT_STARTED:
+ case UNRECOVERABLE_ERROR:
+ // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume.
+ if (uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1) {
+ uj.cleanup();
+ }
+ break;
+ case UNKNOWN:
+ return;
+ case IN_PROGRESS:
+ s_logger.info("Resuming jobId: " + jobId + ", status=" + status);
+ tu.setResume(true);
+ threadPool.execute(tu);
+ break;
+ case RECOVERABLE_ERROR:
+ threadPool.execute(tu);
+ break;
+ case UPLOAD_FINISHED:
+ tu.setUploadError("Upload success, starting install ");
+ String result = postUpload(jobId);
+ if (result != null) {
+ s_logger.error("Failed post upload script: " + result);
+ tu.setStatus(Status.UNRECOVERABLE_ERROR);
+ tu.setUploadError("Failed post upload script: " + result);
+ } else {
+ s_logger.warn("Upload completed successfully at " + new SimpleDateFormat().format(new Date()));
+ tu.setStatus(Status.POST_UPLOAD_FINISHED);
+ tu.setUploadError("Upload completed successfully at " + new SimpleDateFormat().format(new Date()));
+ }
+ // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume.
+ if (uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1) {
+ uj.cleanup();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ private String postUpload(String jobId) {
+ return null;
+ }
+
+ private void sleep() {
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+
+ private boolean checkAndStartApache() {
+
+ //Check whether the Apache server is running
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("if [ -d /etc/apache2 ] ; then service apache2 status | grep pid; else service httpd status | grep pid; fi ");
+ String result = command.execute();
+
+ //Apache Server is not running. Try to start it.
+ if (result != null) {
+
+ /*s_logger.warn("Apache server not running, trying to start it");
+ String port = Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
+ String intf = TemplateConstants.DEFAULT_TMPLT_COPY_INTF;
+
+ command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j DROP;" +
+ "iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j HTTP;" +
+ "iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j DROP;" +
+ "iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j HTTP;" +
+ "iptables -F HTTP;" +
+ "iptables -X HTTP;" +
+ "iptables -N HTTP;" +
+ "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j DROP;" +
+ "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j DROP;" +
+ "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j HTTP;" +
+ "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j HTTP;");
+
+ result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in opening up httpd port err=" + result );
+ return false;
+ }*/
+
+ command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("if [ -d /etc/apache2 ] ; then service apache2 start; else service httpd start; fi ");
+ result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in starting httpd service err=" + result);
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java b/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
new file mode 100644
index 0000000..e0fcbae
--- /dev/null
+++ b/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.storage.resource;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+
+import javax.naming.ConfigurationException;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.log4j.Logger;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.ListTemplateAnswer;
+import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.SwiftTO;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Storage;
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class LocalNfsSecondaryStorageResourceTest extends TestCase {
+ private static Map<String, Object> testParams;
+
+ private static final Logger s_logger = Logger.getLogger(LocalNfsSecondaryStorageResourceTest.class.getName());
+
+ LocalNfsSecondaryStorageResource resource;
+
+ @Before
+ @Override
+ public void setUp() throws ConfigurationException {
+ resource = new LocalNfsSecondaryStorageResource();
+ resource.setInSystemVM(true);
+
+ testParams = PropertiesUtil.toMap(loadProperties());
+ resource.configureStorageLayerClass(testParams);
+ Object testLocalRoot = testParams.get("testLocalRoot");
+ resource.setParentPath("/mnt");
+
+ if (testLocalRoot != null) {
+ resource.setParentPath((String)testLocalRoot);
+ }
+
+ System.setProperty("paths.script", "/Users/edison/develop/asf-master/script");
+ //resource.configure("test", new HashMap<String, Object>());
+ }
+
+ @Test
+ public void testExecuteRequest() throws Exception {
+ TemplateObjectTO template = Mockito.mock(TemplateObjectTO.class);
+ NfsTO cacheStore = Mockito.mock(NfsTO.class);
+ Mockito.when(cacheStore.getUrl()).thenReturn("nfs://nfs2.lab.vmops.com/export/home/edison/");
+ SwiftTO swift = Mockito.mock(SwiftTO.class);
+ Mockito.when(swift.getEndPoint()).thenReturn("https://objects.dreamhost.com/auth");
+ Mockito.when(swift.getAccount()).thenReturn("cloudstack");
+ Mockito.when(swift.getUserName()).thenReturn("images");
+ Mockito.when(swift.getKey()).thenReturn("oxvELQaOD1U5_VyosGfA-wpZ7uBWEff-CUBGCM0u");
+
+ Mockito.when(template.getDataStore()).thenReturn(swift);
+ Mockito.when(template.getPath()).thenReturn("template/1/1/");
+ Mockito.when(template.isRequiresHvm()).thenReturn(true);
+ Mockito.when(template.getId()).thenReturn(1L);
+ Mockito.when(template.getFormat()).thenReturn(Storage.ImageFormat.VHD);
+ Mockito.when(template.getOrigUrl()).thenReturn("http://nfs1.lab.vmops.com/templates/test.bz2");
+ Mockito.when(template.getName()).thenReturn(UUID.randomUUID().toString());
+ Mockito.when(template.getObjectType()).thenReturn(DataObjectType.TEMPLATE);
+
+ DownloadCommand cmd = new DownloadCommand(template, 100000L);
+ cmd.setCacheStore(cacheStore);
+ DownloadAnswer answer = (DownloadAnswer)resource.executeRequest(cmd);
+ Assert.assertTrue(answer.getResult());
+
+ Mockito.when(template.getPath()).thenReturn(answer.getInstallPath());
+ Mockito.when(template.getDataStore()).thenReturn(swift);
+ //download swift:
+ Mockito.when(cacheStore.getRole()).thenReturn(DataStoreRole.ImageCache);
+ TemplateObjectTO destTemplate = Mockito.mock(TemplateObjectTO.class);
+ Mockito.when(destTemplate.getPath()).thenReturn("template/1/2");
+ Mockito.when(destTemplate.getDataStore()).thenReturn(cacheStore);
+ Mockito.when(destTemplate.getObjectType()).thenReturn(DataObjectType.TEMPLATE);
+ CopyCommand cpyCmd = new CopyCommand(template, destTemplate, 10000, true);
+ CopyCmdAnswer copyCmdAnswer = (CopyCmdAnswer)resource.executeRequest(cpyCmd);
+ Assert.assertTrue(copyCmdAnswer.getResult());
+
+ //list template
+ ListTemplateCommand listCmd = new ListTemplateCommand(swift);
+ ListTemplateAnswer listAnswer = (ListTemplateAnswer)resource.executeRequest(listCmd);
+
+ Assert.assertTrue(listAnswer.getTemplateInfo().size() > 0);
+ }
+
+ public static Properties loadProperties() throws ConfigurationException {
+ Properties properties = new Properties();
+ final File file = PropertiesUtil.findConfigFile("agent.properties");
+ if (file == null) {
+ throw new ConfigurationException("Unable to find agent.properties.");
+ }
+
+ s_logger.info("agent.properties found at " + file.getAbsolutePath());
+
+ try {
+ properties.load(new FileInputStream(file));
+ } catch (final FileNotFoundException ex) {
+ throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
+ } catch (final IOException ex) {
+ throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
+ }
+ return properties;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java b/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
new file mode 100644
index 0000000..e0ae4c5
--- /dev/null
+++ b/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.storage.resource;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.ConfigurationException;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class NfsSecondaryStorageResourceTest extends TestCase {
+ private static Map<String, Object> testParams;
+
+ private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResourceTest.class.getName());
+
+ NfsSecondaryStorageResource resource;
+
+ @Before
+ @Override
+ public void setUp() throws ConfigurationException {
+ s_logger.setLevel(Level.ALL);
+ resource = new NfsSecondaryStorageResource();
+ resource.setInSystemVM(true);
+ testParams = PropertiesUtil.toMap(loadProperties());
+ resource.configureStorageLayerClass(testParams);
+ Object testLocalRoot = testParams.get("testLocalRoot");
+ if (testLocalRoot != null) {
+ resource.setParentPath((String)testLocalRoot);
+ }
+ }
+
+ @Test
+ public void testMount() throws Exception {
+ String sampleUriStr = "cifs://192.168.1.128/CSHV3?user=administrator&password=1pass%40word1&foo=bar";
+ URI sampleUri = new URI(sampleUriStr);
+
+ s_logger.info("Check HostIp parsing");
+ String hostIpStr = resource.getUriHostIp(sampleUri);
+ Assert.assertEquals("Expected host IP " + sampleUri.getHost() + " and actual host IP " + hostIpStr + " differ.", sampleUri.getHost(), hostIpStr);
+
+ s_logger.info("Check option parsing");
+ String expected = "user=administrator,password=1pass@word1,foo=bar,";
+ String actualOpts = resource.parseCifsMountOptions(sampleUri);
+ Assert.assertEquals("Options should be " + expected + " and not " + actualOpts, expected, actualOpts);
+
+ // attempt a configured mount
+ final Map<String, Object> params = PropertiesUtil.toMap(loadProperties());
+ String sampleMount = (String)params.get("testCifsMount");
+ if (!sampleMount.isEmpty()) {
+ s_logger.info("functional test, mount " + sampleMount);
+ URI realMntUri = new URI(sampleMount);
+ String mntSubDir = resource.mountUri(realMntUri);
+ s_logger.info("functional test, umount " + mntSubDir);
+ resource.umount(resource.getMountingRoot() + mntSubDir, realMntUri);
+ } else {
+ s_logger.info("no entry for testCifsMount in " + "./conf/agent.properties - skip functional test");
+ }
+ }
+
+ public static Properties loadProperties() throws ConfigurationException {
+ Properties properties = new Properties();
+ final File file = PropertiesUtil.findConfigFile("agent.properties");
+ if (file == null) {
+ throw new ConfigurationException("Unable to find agent.properties.");
+ }
+
+ s_logger.info("agent.properties found at " + file.getAbsolutePath());
+
+ try {
+ properties.load(new FileInputStream(file));
+ } catch (final FileNotFoundException ex) {
+ throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
+ } catch (final IOException ex) {
+ throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
+ }
+ return properties;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
deleted file mode 100644
index 9393ee2..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
+++ /dev/null
@@ -1,95 +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 org.apache.cloudstack.storage.resource;
-
-import java.net.URI;
-import java.util.concurrent.Executors;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.storage.template.DownloadManagerImpl;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.storage.JavaStorageLayer;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-
-@Component
-public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResource {
-
- private static final Logger s_logger = Logger.getLogger(LocalNfsSecondaryStorageResource.class);
-
- public LocalNfsSecondaryStorageResource() {
- this._dlMgr = new DownloadManagerImpl();
- ((DownloadManagerImpl)_dlMgr).setThreadPool(Executors.newFixedThreadPool(10));
- _storage = new JavaStorageLayer();
- this._inSystemVM = false;
- }
-
- @Override
- public void setParentPath(String path) {
- this._parent = path;
- }
-
- @Override
- public Answer executeRequest(Command cmd) {
- return super.executeRequest(cmd);
- }
-
- @Override
- synchronized public String getRootDir(String secUrl) {
- try {
- URI uri = new URI(secUrl);
- String dir = mountUri(uri);
- return _parent + "/" + dir;
- } catch (Exception e) {
- String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
- s_logger.error(msg, e);
- throw new CloudRuntimeException(msg);
- }
- }
-
- @Override
- protected void mount(String localRootPath, String remoteDevice, URI uri) {
- ensureLocalRootPathExists(localRootPath, uri);
-
- if (mountExists(localRootPath, uri)) {
- return;
- }
-
- attemptMount(localRootPath, remoteDevice, uri);
-
- // Change permissions for the mountpoint - seems to bypass authentication
- Script script = new Script(true, "chmod", _timeout, s_logger);
- script.add("777", localRootPath);
- String result = script.execute();
- if (result != null) {
- String errMsg = "Unable to set permissions for " + localRootPath + " due to " + result;
- s_logger.error(errMsg);
- throw new CloudRuntimeException(errMsg);
- }
- s_logger.debug("Successfully set 777 permission for " + localRootPath);
-
- // XXX: Adding the check for creation of snapshots dir here. Might have
- // to move it somewhere more logical later.
- checkForSnapshotsDir(localRootPath);
- checkForVolumesDir(localRootPath);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
deleted file mode 100644
index bdfe7e8..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
+++ /dev/null
@@ -1,240 +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 org.apache.cloudstack.storage.resource;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.command.DownloadProgressCommand;
-import org.apache.cloudstack.storage.template.DownloadManager;
-import org.apache.cloudstack.storage.template.DownloadManagerImpl;
-
-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.PingCommand;
-import com.cloud.agent.api.PingStorageCommand;
-import com.cloud.agent.api.ReadyAnswer;
-import com.cloud.agent.api.ReadyCommand;
-import com.cloud.agent.api.SecStorageSetupCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupStorageCommand;
-import com.cloud.agent.api.storage.ListTemplateAnswer;
-import com.cloud.agent.api.storage.ListTemplateCommand;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.resource.ServerResourceBase;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.template.TemplateProp;
-import com.cloud.utils.component.ComponentContext;
-
-public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
- private static final Logger s_logger = Logger.getLogger(LocalSecondaryStorageResource.class);
- int _timeout;
-
- String _instance;
- String _parent;
-
- String _dc;
- String _pod;
- String _guid;
-
- StorageLayer _storage;
-
- DownloadManager _dlMgr;
-
- @Override
- public void disconnected() {
- }
-
- @Override
- public String getRootDir(String url) {
- return getRootDir();
-
- }
-
- public String getRootDir() {
- return _parent;
- }
-
- @Override
- public Answer executeRequest(Command cmd) {
- if (cmd instanceof DownloadProgressCommand) {
- return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
- } else if (cmd instanceof DownloadCommand) {
- return _dlMgr.handleDownloadCommand(this, (DownloadCommand)cmd);
- } else if (cmd instanceof CheckHealthCommand) {
- return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
- } else if (cmd instanceof SecStorageSetupCommand) {
- return new Answer(cmd, true, "success");
- } else if (cmd instanceof ReadyCommand) {
- return new ReadyAnswer((ReadyCommand)cmd);
- } else if (cmd instanceof ListTemplateCommand) {
- return execute((ListTemplateCommand)cmd);
- } else if (cmd instanceof ComputeChecksumCommand) {
- return execute((ComputeChecksumCommand)cmd);
- } else {
- return Answer.createUnsupportedCommandAnswer(cmd);
- }
- }
-
- private Answer execute(ComputeChecksumCommand cmd) {
- return new Answer(cmd, false, null);
- }
-
- private Answer execute(ListTemplateCommand cmd) {
- String root = getRootDir();
- Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
- return new ListTemplateAnswer(((NfsTO)cmd.getDataStore()).getUrl(), templateInfos);
- }
-
- @Override
- public Type getType() {
- return Host.Type.LocalSecondaryStorage;
- }
-
- @Override
- public PingCommand getCurrentStatus(final long id) {
- return new PingStorageCommand(Host.Type.Storage, id, new HashMap<String, Boolean>());
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
- super.configure(name, params);
-
- _guid = (String)params.get("guid");
- if (_guid == null) {
- throw new ConfigurationException("Unable to find the guid");
- }
-
- _dc = (String)params.get("zone");
- if (_dc == null) {
- throw new ConfigurationException("Unable to find the zone");
- }
- _pod = (String)params.get("pod");
-
- _instance = (String)params.get("instance");
-
- _parent = (String)params.get("mount.path");
- if (_parent == null) {
- throw new ConfigurationException("No directory specified.");
- }
-
- _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
- if (_storage == null) {
- String value = (String)params.get(StorageLayer.ClassConfigKey);
- if (value == null) {
- value = "com.cloud.storage.JavaStorageLayer";
- }
-
- try {
- Class<StorageLayer> clazz = (Class<StorageLayer>)Class.forName(value);
- _storage = ComponentContext.inject(clazz);
- } catch (ClassNotFoundException e) {
- throw new ConfigurationException("Unable to find class " + value);
- }
- }
-
- if (!_storage.mkdirs(_parent)) {
- s_logger.warn("Unable to create the directory " + _parent);
- throw new ConfigurationException("Unable to create the directory " + _parent);
- }
-
- s_logger.info("Mount point established at " + _parent);
-
- params.put("template.parent", _parent);
- params.put(StorageLayer.InstanceConfigKey, _storage);
-
- _dlMgr = new DownloadManagerImpl();
- _dlMgr.configure("DownloadManager", params);
-
- return true;
- }
-
- @Override
- public boolean start() {
- return true;
- }
-
- @Override
- public boolean stop() {
- return true;
- }
-
- @Override
- public StartupCommand[] initialize() {
-
- final StartupStorageCommand cmd =
- new StartupStorageCommand(_parent, StoragePoolType.Filesystem, 1024l * 1024l * 1024l * 1024l, _dlMgr.gatherTemplateInfo(_parent));
- cmd.setResourceType(Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE);
- cmd.setIqn("local://");
- fillNetworkInformation(cmd);
- cmd.setDataCenter(_dc);
- cmd.setPod(_pod);
- cmd.setGuid(_guid);
- cmd.setName(_guid);
- cmd.setVersion(LocalSecondaryStorageResource.class.getPackage().getImplementationVersion());
-
- return new StartupCommand[] {cmd};
- }
-
- @Override
- protected String getDefaultScriptsDir() {
- return "scripts/storage/secondary";
- }
-
- @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 int getRunLevel() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public void setRunLevel(int level) {
- // TODO Auto-generated method stub
-
- }
-}
[08/11] git commit: updated refs/heads/master to 54f32a8
Posted by ah...@apache.org.
Removed references to secondarystoragevmmanager from code that doesn't use it.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/7f34282d
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/7f34282d
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/7f34282d
Branch: refs/heads/master
Commit: 7f34282dfa276909a537bd4a65155e99a1e2f04f
Parents: 4be3b99
Author: Alex Huang <al...@citrix.com>
Authored: Wed Jan 15 17:56:57 2014 -0800
Committer: Alex Huang <al...@citrix.com>
Committed: Wed Feb 5 01:39:15 2014 +0000
----------------------------------------------------------------------
.../storage/test/ChildTestConfiguration.java | 6 -
.../com/cloud/hypervisor/guru/VMwareGuru.java | 36 ++--
.../vmware/manager/VmwareManagerImpl.java | 94 ++++------
.../vmware/VmwareDatacenterApiUnitTest.java | 6 -
.../IntegrationTestConfiguration.java | 6 -
.../com/cloud/resource/ResourceManagerImpl.java | 66 ++++---
.../com/cloud/server/ManagementServerImpl.java | 40 ++---
.../com/cloud/storage/VolumeApiServiceImpl.java | 178 ++++---------------
.../storage/download/DownloadMonitorImpl.java | 29 +--
.../secondary/SecondaryStorageListener.java | 5 +-
.../secondary/SecondaryStorageManagerImpl.java | 5 +-
.../storage/snapshot/SnapshotManagerImpl.java | 66 +++----
.../cloud/storage/upload/UploadMonitorImpl.java | 27 ++-
.../com/cloud/template/TemplateManagerImpl.java | 133 ++++----------
.../networkoffering/ChildTestConfiguration.java | 6 -
15 files changed, 207 insertions(+), 496 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
index 69d60c2..3af7df7 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
@@ -79,7 +79,6 @@ import com.cloud.storage.dao.VMTemplateZoneDaoImpl;
import com.cloud.storage.dao.VolumeDaoImpl;
import com.cloud.storage.dao.VolumeHostDaoImpl;
import com.cloud.storage.download.DownloadMonitorImpl;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.tags.dao.ResourceTagsDaoImpl;
import com.cloud.template.TemplateManager;
import com.cloud.user.AccountManager;
@@ -111,11 +110,6 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl;
public class ChildTestConfiguration extends TestConfiguration {
@Bean
- public SecondaryStorageVmManager secondaryStoreageMgr() {
- return Mockito.mock(SecondaryStorageVmManager.class);
- }
-
- @Bean
public HostDao hostDao() {
return Mockito.spy(new HostDaoImpl());
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
index d72787c..9a30f18 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
@@ -27,8 +27,6 @@ import java.util.UUID;
import javax.ejb.Local;
import javax.inject.Inject;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.vm.dao.VMInstanceDao;
import org.apache.log4j.Logger;
import org.apache.cloudstack.framework.config.ConfigKey;
@@ -71,7 +69,6 @@ import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
import com.cloud.secstorage.CommandExecLogDao;
@@ -95,41 +92,38 @@ import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VmDetailConstants;
import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.VMInstanceDao;
@Local(value = HypervisorGuru.class)
public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Configurable {
private static final Logger s_logger = Logger.getLogger(VMwareGuru.class);
@Inject
- NetworkDao _networkDao;
- @Inject
- GuestOSDao _guestOsDao;
- @Inject
- HostDao _hostDao;
+ private NetworkDao _networkDao;
@Inject
- HostDetailsDao _hostDetailsDao;
+ private GuestOSDao _guestOsDao;
@Inject
- CommandExecLogDao _cmdExecLogDao;
+ private HostDao _hostDao;
@Inject
- VmwareManager _vmwareMgr;
+ private HostDetailsDao _hostDetailsDao;
@Inject
- SecondaryStorageVmManager _secStorageMgr;
+ private CommandExecLogDao _cmdExecLogDao;
@Inject
- NetworkModel _networkMgr;
+ private VmwareManager _vmwareMgr;
@Inject
- ConfigurationDao _configDao;
+ private SecondaryStorageVmManager _secStorageMgr;
@Inject
- NicDao _nicDao;
+ private NetworkModel _networkMgr;
@Inject
- PhysicalNetworkDao _physicalNetworkDao;
+ private ConfigurationDao _configDao;
@Inject
- PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
+ private NicDao _nicDao;
@Inject
- VMInstanceDao _vmDao;
+ private PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
@Inject
- ClusterDao _clusterDao;
+ private VMInstanceDao _vmDao;
@Inject
- ClusterManager _clusterMgr;
+ private ClusterManager _clusterMgr;
protected VMwareGuru() {
super();
@@ -204,7 +198,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
}
}
- long clusterId = this.getClusterId(vm.getId());
+ long clusterId = getClusterId(vm.getId());
details.put(Config.VmwareReserveCpu.key(), VmwareReserveCpu.valueIn(clusterId).toString());
details.put(Config.VmwareReserveMem.key(), VmwareReserveMemory.valueIn(clusterId).toString());
to.setDetails(details);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
index 482e8a6..4f443bb 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@ -38,7 +38,6 @@ import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
-import com.google.gson.Gson;
import com.vmware.vim25.AboutInfo;
import com.vmware.vim25.ManagedObjectReference;
@@ -75,7 +74,6 @@ import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.host.Host;
import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
import com.cloud.hypervisor.vmware.LegacyZoneVO;
@@ -104,11 +102,9 @@ import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
import com.cloud.org.Cluster.ClusterType;
import com.cloud.secstorage.CommandExecLogDao;
-import com.cloud.serializer.GsonHelper;
import com.cloud.server.ConfigurationServer;
import com.cloud.storage.JavaStorageLayer;
import com.cloud.storage.StorageLayer;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.utils.FileUtil;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
@@ -132,85 +128,77 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
private static final long DEFAULT_HOST_SCAN_INTERVAL = 600000; // every 10 minutes
private long _hostScanInterval = DEFAULT_HOST_SCAN_INTERVAL;
- int _timeout;
+ private int _timeout;
private String _instance;
@Inject
- AgentManager _agentMgr;
+ private AgentManager _agentMgr;
@Inject
- protected NetworkModel _netMgr;
+ private NetworkModel _netMgr;
@Inject
- HostDao _hostDao;
+ private ClusterDao _clusterDao;
@Inject
- ClusterDao _clusterDao;
+ private ClusterDetailsDao _clusterDetailsDao;
@Inject
- ClusterDetailsDao _clusterDetailsDao;
+ private CommandExecLogDao _cmdExecLogDao;
@Inject
- CommandExecLogDao _cmdExecLogDao;
+ private DataStoreManager _dataStoreMgr;
@Inject
- SecondaryStorageVmManager _ssvmMgr;
+ private CiscoNexusVSMDeviceDao _nexusDao;
@Inject
- DataStoreManager _dataStoreMgr;
+ private ClusterVSMMapDao _vsmMapDao;
@Inject
- CiscoNexusVSMDeviceDao _nexusDao;
+ private ConfigurationDao _configDao;
@Inject
- ClusterVSMMapDao _vsmMapDao;
+ private ConfigurationServer _configServer;
@Inject
- ConfigurationDao _configDao;
+ private HypervisorCapabilitiesDao _hvCapabilitiesDao;
@Inject
- ConfigurationServer _configServer;
+ private DataCenterDao _dcDao;
@Inject
- HypervisorCapabilitiesDao _hvCapabilitiesDao;
+ private VmwareDatacenterDao _vmwareDcDao;
@Inject
- DataCenterDao _dcDao;
+ private VmwareDatacenterZoneMapDao _vmwareDcZoneMapDao;
@Inject
- VmwareDatacenterDao _vmwareDcDao;
+ private LegacyZoneDao _legacyZoneDao;
@Inject
- VmwareDatacenterZoneMapDao _vmwareDcZoneMapDao;
+ private ManagementServerHostPeerDao _mshostPeerDao;
@Inject
- LegacyZoneDao _legacyZoneDao;
- @Inject
- ManagementServerHostPeerDao _mshostPeerDao;
- @Inject
- ClusterManager _clusterMgr;
+ private ClusterManager _clusterMgr;
- String _mountParent;
- StorageLayer _storage;
- String _privateNetworkVSwitchName = "vSwitch0";
+ private String _mountParent;
+ private StorageLayer _storage;
+ private final String _privateNetworkVSwitchName = "vSwitch0";
- int _portsPerDvPortGroup = 256;
- boolean _nexusVSwitchActive;
- boolean _fullCloneFlag;
- boolean _instanceNameFlag;
- String _serviceConsoleName;
- String _managemetPortGroupName;
- String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
- String _recycleHungWorker = "false";
- long _hungWorkerTimeout = 7200000; // 2 hour
- int _additionalPortRangeStart;
- int _additionalPortRangeSize;
- int _routerExtraPublicNics = 2;
- int _vCenterSessionTimeout = 1200000; // Timeout in milliseconds
+ private int _portsPerDvPortGroup = 256;
+ private boolean _fullCloneFlag;
+ private boolean _instanceNameFlag;
+ private String _serviceConsoleName;
+ private String _managemetPortGroupName;
+ private String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
+ private String _recycleHungWorker = "false";
+ private int _additionalPortRangeStart;
+ private int _additionalPortRangeSize;
+ private int _routerExtraPublicNics = 2;
+ private int _vCenterSessionTimeout = 1200000; // Timeout in milliseconds
- String _reserveCpu = "false";
+ private String _reserveCpu = "false";
- String _reserveMem = "false";
+ private String _reserveMem = "false";
- String _rootDiskController = DiskControllerType.ide.toString();
+ private String _rootDiskController = DiskControllerType.ide.toString();
- Map<String, String> _storageMounts = new HashMap<String, String>();
+ private final Map<String, String> _storageMounts = new HashMap<String, String>();
- Random _rand = new Random(System.currentTimeMillis());
- Gson _gson;
+ private final Random _rand = new Random(System.currentTimeMillis());
- VmwareStorageManager _storageMgr;
- GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
+ private final VmwareStorageManager _storageMgr;
+ private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
private final ScheduledExecutorService _hostScanScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-Host-Scan"));
public VmwareManagerImpl() {
- _gson = GsonHelper.getGsonLogger();
_storageMgr = new VmwareStorageManagerImpl(this);
}
@@ -310,10 +298,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
_recycleHungWorker = "false";
}
- value = _configDao.getValue(Config.VmwareHungWorkerTimeout.key());
- if (value != null)
- _hungWorkerTimeout = Long.parseLong(value) * 1000;
-
_rootDiskController = _configDao.getValue(Config.VmwareRootDiskControllerType.key());
if (_rootDiskController == null || _rootDiskController.isEmpty()) {
_rootDiskController = DiskControllerType.ide.toString();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
index 4a00489..c2002ff 100644
--- a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
+++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
@@ -85,7 +85,6 @@ import com.cloud.org.Cluster.ClusterType;
import com.cloud.org.Managed.ManagedState;
import com.cloud.secstorage.CommandExecLogDao;
import com.cloud.server.ConfigurationServer;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountService;
@@ -364,11 +363,6 @@ public class VmwareDatacenterApiUnitTest {
}
@Bean
- public SecondaryStorageVmManager secondaryStorageVmManager() {
- return Mockito.mock(SecondaryStorageVmManager.class);
- }
-
- @Bean
public CommandExecLogDao commandExecLogDao() {
return Mockito.mock(CommandExecLogDao.class);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
index 1a53c17..954a37e 100644
--- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
@@ -259,7 +259,6 @@ import com.cloud.storage.dao.VMTemplateHostDaoImpl;
import com.cloud.storage.dao.VMTemplateZoneDaoImpl;
import com.cloud.storage.dao.VolumeDaoImpl;
import com.cloud.storage.dao.VolumeHostDaoImpl;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.storage.snapshot.SnapshotApiService;
import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.tags.dao.ResourceTagDao;
@@ -624,11 +623,6 @@ public class IntegrationTestConfiguration {
}
@Bean
- public SecondaryStorageVmManager secondaryStorageVmManager() {
- return Mockito.mock(SecondaryStorageVmManager.class);
- }
-
- @Bean
public Site2SiteVpnManager site2SiteVpnManager() {
return Mockito.mock(Site2SiteVpnManager.class);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java
index c9e2e7a..79eb1cb 100755
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@ -47,7 +47,6 @@ import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd;
import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.region.dao.RegionDao;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.utils.identity.ManagementServerNode;
@@ -129,7 +128,6 @@ import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.GuestOSCategoryDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.User;
@@ -168,55 +166,51 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
Gson _gson;
@Inject
- AccountManager _accountMgr;
+ private AccountManager _accountMgr;
@Inject
- AgentManager _agentMgr;
+ private AgentManager _agentMgr;
@Inject
- StorageManager _storageMgr;
+ private StorageManager _storageMgr;
@Inject
- protected SecondaryStorageVmManager _secondaryStorageMgr;
+ private DataCenterDao _dcDao;
@Inject
- protected RegionDao _regionDao;
+ private HostPodDao _podDao;
@Inject
- protected DataCenterDao _dcDao;
+ private ClusterDetailsDao _clusterDetailsDao;
@Inject
- protected HostPodDao _podDao;
+ private ClusterDao _clusterDao;
@Inject
- protected ClusterDetailsDao _clusterDetailsDao;
+ private CapacityDao _capacityDao;
@Inject
- protected ClusterDao _clusterDao;
+ private HostDao _hostDao;
@Inject
- protected CapacityDao _capacityDao;
+ private HostDetailsDao _hostDetailsDao;
@Inject
- protected HostDao _hostDao;
+ private ConfigurationDao _configDao;
@Inject
- protected HostDetailsDao _hostDetailsDao;
+ private HostTagsDao _hostTagsDao;
@Inject
- protected ConfigurationDao _configDao;
+ private GuestOSCategoryDao _guestOSCategoryDao;
@Inject
- protected HostTagsDao _hostTagsDao;
+ private PrimaryDataStoreDao _storagePoolDao;
@Inject
- protected GuestOSCategoryDao _guestOSCategoryDao;
+ private DataCenterIpAddressDao _privateIPAddressDao;
@Inject
- protected PrimaryDataStoreDao _storagePoolDao;
+ private IPAddressDao _publicIPAddressDao;
@Inject
- protected DataCenterIpAddressDao _privateIPAddressDao;
+ private VirtualMachineManager _vmMgr;
@Inject
- protected IPAddressDao _publicIPAddressDao;
+ private VMInstanceDao _vmDao;
@Inject
- protected VirtualMachineManager _vmMgr;
+ private HighAvailabilityManager _haMgr;
@Inject
- protected VMInstanceDao _vmDao;
- @Inject
- protected HighAvailabilityManager _haMgr;
- @Inject
- protected StorageService _storageSvr;
+ private StorageService _storageSvr;
@Inject
PlannerHostReservationDao _plannerHostReserveDao;
@Inject
- protected DedicatedResourceDao _dedicatedDao;
+ private DedicatedResourceDao _dedicatedDao;
- protected List<? extends Discoverer> _discoverers;
+ private List<? extends Discoverer> _discoverers;
public List<? extends Discoverer> getDiscoverers() {
return _discoverers;
@@ -227,22 +221,22 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
}
@Inject
- protected ClusterManager _clusterMgr;
+ private ClusterManager _clusterMgr;
@Inject
- protected StoragePoolHostDao _storagePoolHostDao;
+ private StoragePoolHostDao _storagePoolHostDao;
@Inject
- protected VMTemplateDao _templateDao;
+ private VMTemplateDao _templateDao;
@Inject
- protected ConfigurationManager _configMgr;
+ private ConfigurationManager _configMgr;
@Inject
- protected ClusterVSMMapDao _clusterVSMMapDao;
+ private ClusterVSMMapDao _clusterVSMMapDao;
- protected long _nodeId = ManagementServerNode.getManagementServerId();
+ private final long _nodeId = ManagementServerNode.getManagementServerId();
- protected HashMap<String, ResourceStateAdapter> _resourceStateAdapters = new HashMap<String, ResourceStateAdapter>();
+ private final HashMap<String, ResourceStateAdapter> _resourceStateAdapters = new HashMap<String, ResourceStateAdapter>();
- protected HashMap<Integer, List<ResourceListener>> _lifeCycleListeners = new HashMap<Integer, List<ResourceListener>>();
+ private final HashMap<Integer, List<ResourceListener>> _lifeCycleListeners = new HashMap<Integer, List<ResourceListener>>();
private HypervisorType _defaultSystemVMHypervisor;
private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 30; // seconds
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 9dc9dda..ec40411 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -40,6 +40,9 @@ import javax.crypto.spec.SecretKeySpec;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.Logger;
+
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
@@ -438,7 +441,6 @@ import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.framework.config.ConfigDepot;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@@ -450,8 +452,6 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.GetVncPortAnswer;
@@ -468,7 +468,6 @@ import com.cloud.capacity.dao.CapacityDao;
import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
import com.cloud.cluster.ClusterManager;
import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
import com.cloud.consoleproxy.ConsoleProxyManagementState;
import com.cloud.consoleproxy.ConsoleProxyManager;
import com.cloud.dc.AccountVlanMapVO;
@@ -553,7 +552,6 @@ import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.tags.ResourceTagVO;
import com.cloud.tags.dao.ResourceTagDao;
import com.cloud.template.TemplateManager;
@@ -699,38 +697,28 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
private ImageStoreDao _imgStoreDao;
@Inject
- ProjectManager _projectMgr;
- @Inject
- ResourceManager _resourceMgr;
- @Inject
- SnapshotManager _snapshotMgr;
- @Inject
- HighAvailabilityManager _haMgr;
- @Inject
- TemplateManager templateMgr;
- @Inject
- DataStoreManager dataStoreMgr;
+ private ProjectManager _projectMgr;
@Inject
- HostTagsDao _hostTagsDao;
+ private ResourceManager _resourceMgr;
@Inject
- ConfigurationServer _configServer;
+ private HighAvailabilityManager _haMgr;
@Inject
- ConfigDepot _configDepot;
+ private DataStoreManager dataStoreMgr;
@Inject
- UserVmManager _userVmMgr;
+ private HostTagsDao _hostTagsDao;
@Inject
- VolumeDataFactory _volFactory;
+ private ConfigDepot _configDepot;
@Inject
- AccountService _accountService;
+ private UserVmManager _userVmMgr;
@Inject
- ConfigurationManager _configMgr;
+ private AccountService _accountService;
@Inject
- ServiceOfferingDao _offeringDao;
+ private ServiceOfferingDao _offeringDao;
@Inject
- DeploymentPlanningManager _dpMgr;
+ private DeploymentPlanningManager _dpMgr;
- LockMasterListener _lockMasterListener;
+ private LockMasterListener _lockMasterListener;
private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker"));
private final ScheduledExecutorService _alertExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AlertChecker"));
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index d4fa8c1..252d925 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -26,6 +26,8 @@ import java.util.concurrent.ExecutionException;
import javax.inject.Inject;
+import org.apache.log4j.Logger;
+
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
@@ -38,14 +40,10 @@ import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationSer
import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
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.SnapshotService;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
@@ -68,37 +66,27 @@ import org.apache.cloudstack.storage.command.DettachCommand;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.DiskTO;
-import com.cloud.alert.AlertManager;
import com.cloud.api.ApiDBUtils;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.capacity.dao.CapacityDao;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.consoleproxy.ConsoleProxyManager;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
import com.cloud.domain.Domain;
-import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventUtils;
-import com.cloud.event.dao.EventDao;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
@@ -108,29 +96,15 @@ import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorCapabilitiesVO;
-import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
-import com.cloud.network.NetworkModel;
import com.cloud.org.Grouping;
-import com.cloud.resource.ResourceManager;
-import com.cloud.server.ManagementServer;
-import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.SnapshotPolicyDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.StoragePoolWorkDao;
import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeDetailsDao;
-import com.cloud.storage.download.DownloadMonitor;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.storage.snapshot.SnapshotApiService;
import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.storage.snapshot.SnapshotScheduler;
-import com.cloud.tags.dao.ResourceTagDao;
import com.cloud.template.TemplateManager;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
@@ -138,7 +112,6 @@ import com.cloud.user.ResourceLimitService;
import com.cloud.user.User;
import com.cloud.user.VmDiskStatisticsVO;
import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
import com.cloud.user.dao.VmDiskStatisticsDao;
import com.cloud.utils.EnumUtils;
import com.cloud.utils.NumbersUtil;
@@ -155,20 +128,15 @@ import com.cloud.utils.db.UUIDManager;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.NoTransitionException;
import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VmWork;
import com.cloud.vm.VmWorkConstants;
import com.cloud.vm.VmWorkJobHandler;
import com.cloud.vm.VmWorkJobHandlerProxy;
import com.cloud.vm.VmWorkSerializer;
-import com.cloud.vm.dao.ConsoleProxyDao;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.SecondaryStorageVmDao;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.snapshot.VMSnapshotVO;
@@ -180,153 +148,73 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
public static final String VM_WORK_JOB_HANDLER = VolumeApiServiceImpl.class.getSimpleName();
@Inject
- VolumeOrchestrationService _volumeMgr;
+ private VolumeOrchestrationService _volumeMgr;
@Inject
- EntityManager _entityMgr;
- @Inject
- protected UserVmManager _userVmMgr;
- @Inject
- protected AgentManager _agentMgr;
- @Inject
- protected TemplateManager _tmpltMgr;
- @Inject
- protected AsyncJobManager _asyncMgr;
- @Inject
- protected SnapshotManager _snapshotMgr;
- @Inject
- protected SnapshotScheduler _snapshotScheduler;
- @Inject
- protected AccountManager _accountMgr;
- @Inject
- protected ConfigurationManager _configMgr;
+ private EntityManager _entityMgr;
@Inject
- protected ConsoleProxyManager _consoleProxyMgr;
+ private AgentManager _agentMgr;
@Inject
- protected SecondaryStorageVmManager _secStorageMgr;
+ private TemplateManager _tmpltMgr;
@Inject
- protected NetworkModel _networkMgr;
+ private AsyncJobManager _asyncMgr;
@Inject
- protected ServiceOfferingDao _serviceOfferingDao;
+ private SnapshotManager _snapshotMgr;
@Inject
- protected VolumeDao _volsDao;
+ private AccountManager _accountMgr;
@Inject
- protected HostDao _hostDao;
+ private ConfigurationManager _configMgr;
@Inject
- protected ConsoleProxyDao _consoleProxyDao;
+ private VolumeDao _volsDao;
@Inject
- protected SnapshotDao _snapshotDao;
+ private HostDao _hostDao;
@Inject
- protected SnapshotManager _snapMgr;
- @Inject
- protected SnapshotPolicyDao _snapshotPolicyDao;
- @Inject
- protected StoragePoolHostDao _storagePoolHostDao;
+ private SnapshotDao _snapshotDao;
@Inject
StoragePoolDetailsDao storagePoolDetailsDao;
@Inject
- protected AlertManager _alertMgr;
- @Inject
- protected TemplateDataStoreDao _vmTemplateStoreDao = null;
- @Inject
- protected VMTemplatePoolDao _vmTemplatePoolDao = null;
- @Inject
- protected VMTemplateDao _vmTemplateDao = null;
- @Inject
- protected StoragePoolHostDao _poolHostDao = null;
- @Inject
- protected UserVmDao _userVmDao;
+ private UserVmDao _userVmDao;
@Inject
VolumeDataStoreDao _volumeStoreDao;
@Inject
- protected VMInstanceDao _vmInstanceDao;
- @Inject
- protected PrimaryDataStoreDao _storagePoolDao = null;
- @Inject
- protected CapacityDao _capacityDao;
- @Inject
- protected CapacityManager _capacityMgr;
- @Inject
- protected DiskOfferingDao _diskOfferingDao;
+ private VMInstanceDao _vmInstanceDao;
@Inject
- protected AccountDao _accountDao;
+ private final PrimaryDataStoreDao _storagePoolDao = null;
@Inject
- protected EventDao _eventDao = null;
+ private DiskOfferingDao _diskOfferingDao;
@Inject
- protected DataCenterDao _dcDao = null;
+ private AccountDao _accountDao;
@Inject
- protected HostPodDao _podDao = null;
+ private final DataCenterDao _dcDao = null;
@Inject
- protected VMTemplateDao _templateDao;
+ private VMTemplateDao _templateDao;
@Inject
- protected ServiceOfferingDao _offeringDao;
+ private VolumeDao _volumeDao;
@Inject
- protected DomainDao _domainDao;
+ private ResourceLimitService _resourceLimitMgr;
@Inject
- protected UserDao _userDao;
+ private VmDiskStatisticsDao _vmDiskStatsDao;
@Inject
- protected ClusterDao _clusterDao;
+ private VMSnapshotDao _vmSnapshotDao;
+ private List<StoragePoolAllocator> _storagePoolAllocators;
@Inject
- protected VirtualMachineManager _vmMgr;
+ private ConfigurationDao _configDao;
@Inject
- protected DomainRouterDao _domrDao;
+ private DataStoreManager dataStoreMgr;
@Inject
- protected SecondaryStorageVmDao _secStrgDao;
+ private VolumeService volService;
@Inject
- protected StoragePoolWorkDao _storagePoolWorkDao;
+ private VolumeDataFactory volFactory;
@Inject
- protected HypervisorGuruManager _hvGuruMgr;
+ private SnapshotApiService snapshotMgr;
@Inject
- protected VolumeDao _volumeDao;
- @Inject
- protected OCFS2Manager _ocfs2Mgr;
- @Inject
- protected ResourceLimitService _resourceLimitMgr;
- @Inject
- protected SecondaryStorageVmManager _ssvmMgr;
- @Inject
- protected ResourceManager _resourceMgr;
- @Inject
- protected DownloadMonitor _downloadMonitor;
- @Inject
- protected ResourceTagDao _resourceTagDao;
- @Inject
- protected VmDiskStatisticsDao _vmDiskStatsDao;
- @Inject
- protected VMSnapshotDao _vmSnapshotDao;
- protected List<StoragePoolAllocator> _storagePoolAllocators;
- @Inject
- ConfigurationDao _configDao;
- @Inject
- VolumeDetailsDao _volDetailDao;
- @Inject
- ManagementServer _msServer;
- @Inject
- DataStoreManager dataStoreMgr;
- @Inject
- DataStoreProviderManager dataStoreProviderMgr;
- @Inject
- VolumeService volService;
- @Inject
- VolumeDataFactory volFactory;
- @Inject
- TemplateDataFactory tmplFactory;
- @Inject
- SnapshotDataFactory snapshotFactory;
- @Inject
- SnapshotApiService snapshotMgr;
- @Inject
- SnapshotService snapshotSrv;
- @Inject
- UUIDManager _uuidMgr;
+ private UUIDManager _uuidMgr;
@Inject
- protected HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
- @Inject
- StorageManager storageMgr;
+ private HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
@Inject
- protected AsyncJobManager _jobMgr;
+ private AsyncJobManager _jobMgr;
@Inject
protected VmWorkJobDao _workJobDao;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
index 33278af..1b44a12 100755
--- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
@@ -31,10 +31,8 @@ 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.DataStoreManager;
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.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@@ -42,7 +40,6 @@ import org.apache.cloudstack.storage.command.DownloadCommand;
import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
import org.apache.cloudstack.storage.command.DownloadProgressCommand;
import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
@@ -60,7 +57,6 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.Volume;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.storage.template.TemplateConstants;
import com.cloud.storage.upload.UploadListener;
import com.cloud.template.VirtualMachineTemplate;
@@ -74,39 +70,28 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
static final Logger s_logger = Logger.getLogger(DownloadMonitorImpl.class);
@Inject
- TemplateDataStoreDao _vmTemplateStoreDao;
+ private TemplateDataStoreDao _vmTemplateStoreDao;
@Inject
- ImageStoreDao _imageStoreDao;
+ private VolumeDao _volumeDao;
@Inject
- VolumeDao _volumeDao;
+ private VolumeDataStoreDao _volumeStoreDao;
@Inject
- VolumeDataStoreDao _volumeStoreDao;
- @Inject
- VMTemplateDao _templateDao = null;
+ private final VMTemplateDao _templateDao = null;
@Inject
private AgentManager _agentMgr;
@Inject
- SecondaryStorageVmManager _secMgr;
- @Inject
- ConfigurationDao _configDao;
- @Inject
- EndPointSelector _epSelector;
+ private ConfigurationDao _configDao;
@Inject
- TemplateDataFactory tmplFactory;
+ private EndPointSelector _epSelector;
- private Boolean _sslCopy = new Boolean(false);
private String _copyAuthPasswd;
private String _proxy = null;
- Timer _timer;
-
- @Inject
- DataStoreManager storeMgr;
+ private Timer _timer;
@Override
public boolean configure(String name, Map<String, Object> params) {
final Map<String, String> configs = _configDao.getConfiguration("management-server", params);
- _sslCopy = Boolean.parseBoolean(configs.get("secstorage.encrypt.copy"));
_proxy = configs.get(Config.SecStorageProxy.key());
String cert = configs.get("secstorage.ssl.cert.domain");
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
index 4215fa6..43613e7 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
@@ -18,7 +18,6 @@ package com.cloud.storage.secondary;
import org.apache.log4j.Logger;
-import com.cloud.agent.AgentManager;
import com.cloud.agent.Listener;
import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.AgentControlCommand;
@@ -35,11 +34,9 @@ public class SecondaryStorageListener implements Listener {
private final static Logger s_logger = Logger.getLogger(SecondaryStorageListener.class);
SecondaryStorageVmManager _ssVmMgr = null;
- AgentManager _agentMgr = null;
- public SecondaryStorageListener(SecondaryStorageVmManager ssVmMgr, AgentManager agentMgr) {
+ public SecondaryStorageListener(SecondaryStorageVmManager ssVmMgr) {
_ssVmMgr = ssVmMgr;
- _agentMgr = agentMgr;
}
@Override
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
index a5d3d4c..484dfbd 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
@@ -211,8 +211,6 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
UserVmDetailsDao _vmDetailsDao;
@Inject
protected ResourceManager _resourceMgr;
- //@Inject // TODO this is a very strange usage, a singleton class need to inject itself?
- protected SecondaryStorageVmManager _ssvmMgr;
@Inject
NetworkDao _networkDao;
@Inject
@@ -250,7 +248,6 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName());
public SecondaryStorageManagerImpl() {
- _ssvmMgr = this;
}
@Override
@@ -825,7 +822,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
value = agentMgrConfigs.get("port");
_mgmtPort = NumbersUtil.parseInt(value, 8250);
- _listener = new SecondaryStorageListener(this, _agentMgr);
+ _listener = new SecondaryStorageListener(this);
_agentMgr.registerForHostEvents(_listener, true, false, true);
_itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
index a9eae7d..821f43a 100755
--- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -34,7 +34,6 @@ import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd
import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
@@ -54,7 +53,6 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
@@ -64,7 +62,6 @@ import com.cloud.configuration.Config;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.ActionEventUtils;
@@ -94,17 +91,14 @@ import com.cloud.storage.StoragePool;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.SnapshotPolicyDao;
import com.cloud.storage.dao.SnapshotScheduleDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.storage.template.TemplateConstants;
import com.cloud.tags.ResourceTagVO;
import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.template.TemplateManager;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
@@ -138,46 +132,38 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDao;
public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, SnapshotApiService {
private static final Logger s_logger = Logger.getLogger(SnapshotManagerImpl.class);
@Inject
- protected VMTemplateDao _templateDao;
+ private VMTemplateDao _templateDao;
@Inject
- protected UserVmDao _vmDao;
+ private UserVmDao _vmDao;
@Inject
- protected VolumeDao _volsDao;
+ private VolumeDao _volsDao;
@Inject
- protected AccountDao _accountDao;
+ private AccountDao _accountDao;
@Inject
- protected DataCenterDao _dcDao;
+ private SnapshotDao _snapshotDao;
@Inject
- protected DiskOfferingDao _diskOfferingDao;
+ private SnapshotDataStoreDao _snapshotStoreDao;
@Inject
- protected SnapshotDao _snapshotDao;
+ private PrimaryDataStoreDao _storagePoolDao;
@Inject
- protected SnapshotDataStoreDao _snapshotStoreDao;
+ private final SnapshotPolicyDao _snapshotPolicyDao = null;
@Inject
- protected PrimaryDataStoreDao _storagePoolDao;
+ private SnapshotScheduleDao _snapshotScheduleDao;
@Inject
- protected SnapshotPolicyDao _snapshotPolicyDao = null;
+ private DomainDao _domainDao;
@Inject
- protected SnapshotScheduleDao _snapshotScheduleDao;
+ private StorageManager _storageMgr;
@Inject
- protected DomainDao _domainDao;
+ private SnapshotScheduler _snapSchedMgr;
@Inject
- protected StorageManager _storageMgr;
- @Inject
- protected AgentManager _agentMgr;
- @Inject
- protected SnapshotScheduler _snapSchedMgr;
- @Inject
- protected AccountManager _accountMgr;
+ private AccountManager _accountMgr;
@Inject
private AlertManager _alertMgr;
@Inject
- protected ClusterDao _clusterDao;
+ private ClusterDao _clusterDao;
@Inject
private ResourceLimitService _resourceLimitMgr;
@Inject
- private SecondaryStorageVmManager _ssvmMgr;
- @Inject
private DomainManager _domainMgr;
@Inject
private ResourceTagDao _resourceTagDao;
@@ -185,33 +171,23 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
private ConfigurationDao _configDao;
@Inject
private VMSnapshotDao _vmSnapshotDao;
- String _name;
@Inject
- TemplateManager templateMgr;
+ private DataStoreManager dataStoreMgr;
@Inject
- VolumeOrchestrationService volumeMgr;
+ private SnapshotService snapshotSrv;
@Inject
- DataStoreManager dataStoreMgr;
+ private VolumeDataFactory volFactory;
@Inject
- SnapshotService snapshotSrv;
+ private SnapshotDataFactory snapshotFactory;
@Inject
- VolumeDataFactory volFactory;
- @Inject
- SnapshotDataFactory snapshotFactory;
- @Inject
- EndPointSelector _epSelector;
+ private EndPointSelector _epSelector;
@Inject
private ResourceManager _resourceMgr;
@Inject
- StorageStrategyFactory _storageStrategyFactory;
+ private StorageStrategyFactory _storageStrategyFactory;
private int _totalRetries;
private int _pauseInterval;
- private int _backupsnapshotwait;
- Boolean backup;
-
- protected SearchBuilder<SnapshotVO> PolicySnapshotSearch;
- protected SearchBuilder<SnapshotPolicyVO> PoliciesForSnapSearch;
@Override
public Answer sendToPool(Volume vol, Command cmd) {
@@ -970,8 +946,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
String value = _configDao.getValue(Config.BackupSnapshotWait.toString());
- _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue()));
- backup = Boolean.parseBoolean(_configDao.getValue(Config.BackupSnapshotAfterTakingSnapshot.toString()));
Type.HOURLY.setMax(NumbersUtil.parseInt(_configDao.getValue("snapshot.max.hourly"), HOURLYMAX));
Type.DAILY.setMax(NumbersUtil.parseInt(_configDao.getValue("snapshot.max.daily"), DAILYMAX));
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
index 6f1f5e9..8a997b2 100755
--- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
@@ -67,8 +67,6 @@ import com.cloud.storage.UploadVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.UploadDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
@@ -89,35 +87,30 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor {
static final Logger s_logger = Logger.getLogger(UploadMonitorImpl.class);
@Inject
- UploadDao _uploadDao;
+ private UploadDao _uploadDao;
@Inject
- SecondaryStorageVmDao _secStorageVmDao;
+ private SecondaryStorageVmDao _secStorageVmDao;
@Inject
- HostDao _serverDao = null;
- @Inject
- VMTemplateDao _templateDao = null;
+ private final HostDao _serverDao = null;
@Inject
private AgentManager _agentMgr;
@Inject
- ConfigurationDao _configDao;
- @Inject
- ResourceManager _resourceMgr;
+ private ConfigurationDao _configDao;
@Inject
- SecondaryStorageVmManager _ssvmMgr;
+ private ResourceManager _resourceMgr;
@Inject
- EndPointSelector _epSelector;
+ private EndPointSelector _epSelector;
@Inject
- DataStoreManager storeMgr;
+ private DataStoreManager storeMgr;
- private String _name;
private Boolean _sslCopy = new Boolean(false);
private String _ssvmUrlDomain;
private ScheduledExecutorService _executor = null;
- Timer _timer;
- int _cleanupInterval;
- int _urlExpirationInterval;
+ private Timer _timer;
+ private int _cleanupInterval;
+ private int _urlExpirationInterval;
final Map<UploadVO, UploadListener> _listenerMap = new ConcurrentHashMap<UploadVO, UploadListener>();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java
index 93e3c59..70e4a49 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -72,12 +72,10 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.storage.command.AttachCommand;
import org.apache.cloudstack.storage.command.CommandResult;
import org.apache.cloudstack.storage.command.DettachCommand;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
@@ -99,7 +97,6 @@ import com.cloud.configuration.Config;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.domain.Domain;
import com.cloud.domain.dao.DomainDao;
@@ -107,7 +104,6 @@ import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventUtils;
import com.cloud.event.UsageEventVO;
-import com.cloud.event.dao.EventDao;
import com.cloud.event.dao.UsageEventDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
@@ -117,11 +113,8 @@ import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.projects.Project;
import com.cloud.projects.ProjectManager;
-import com.cloud.resource.ResourceManager;
-import com.cloud.server.ConfigurationServer;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.LaunchPermissionVO;
@@ -148,16 +141,10 @@ import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.LaunchPermissionDao;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.UploadDao;
import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateDetailsDao;
-import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.download.DownloadMonitor;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.storage.upload.UploadMonitor;
import com.cloud.template.TemplateAdapter.TemplateAdapterType;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
@@ -166,11 +153,8 @@ import com.cloud.user.AccountVO;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.User;
import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserAccountDao;
-import com.cloud.user.dao.UserDao;
import com.cloud.uservm.UserVm;
import com.cloud.utils.EnumUtils;
-import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.ManagerBase;
@@ -180,12 +164,10 @@ import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallbackNoReturn;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
import com.cloud.vm.dao.VMInstanceDao;
@Local(value = {TemplateManager.class, TemplateApiService.class})
@@ -193,116 +175,78 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class);
@Inject
- VMTemplateDao _tmpltDao;
+ private VMTemplateDao _tmpltDao;
@Inject
- TemplateDataStoreDao _tmplStoreDao;
+ private TemplateDataStoreDao _tmplStoreDao;
@Inject
- VMTemplatePoolDao _tmpltPoolDao;
+ private VMTemplatePoolDao _tmpltPoolDao;
@Inject
- VMTemplateZoneDao _tmpltZoneDao;
+ private VMTemplateZoneDao _tmpltZoneDao;
@Inject
- protected UserVmDetailsDao _vmDetailsDao;
+ private VMInstanceDao _vmInstanceDao;
@Inject
- protected VMTemplateDetailsDao _templateDetailsDao;
+ private PrimaryDataStoreDao _poolDao;
@Inject
- VMInstanceDao _vmInstanceDao;
+ private StoragePoolHostDao _poolHostDao;
@Inject
- PrimaryDataStoreDao _poolDao;
+ private AccountDao _accountDao;
@Inject
- StoragePoolHostDao _poolHostDao;
+ private AgentManager _agentMgr;
@Inject
- EventDao _eventDao;
+ private AccountManager _accountMgr;
@Inject
- DownloadMonitor _downloadMonitor;
+ private HostDao _hostDao;
@Inject
- UploadMonitor _uploadMonitor;
+ private DataCenterDao _dcDao;
@Inject
- UserAccountDao _userAccountDao;
+ private UserVmDao _userVmDao;
@Inject
- AccountDao _accountDao;
+ private VolumeDao _volumeDao;
@Inject
- UserDao _userDao;
+ private SnapshotDao _snapshotDao;
@Inject
- AgentManager _agentMgr;
+ private ConfigurationDao _configDao;
@Inject
- AccountManager _accountMgr;
+ private DomainDao _domainDao;
@Inject
- HostDao _hostDao;
+ private GuestOSDao _guestOSDao;
@Inject
- DataCenterDao _dcDao;
+ private StorageManager _storageMgr;
@Inject
- UserVmDao _userVmDao;
+ private UsageEventDao _usageEventDao;
@Inject
- VolumeDao _volumeDao;
+ private AccountService _accountService;
@Inject
- SnapshotDao _snapshotDao;
+ private ResourceLimitService _resourceLimitMgr;
@Inject
- ConfigurationDao _configDao;
+ private LaunchPermissionDao _launchPermissionDao;
@Inject
- ClusterDao _clusterDao;
+ private ProjectManager _projectMgr;
@Inject
- DomainDao _domainDao;
+ private VolumeDataFactory _volFactory;
@Inject
- UploadDao _uploadDao;
+ private TemplateDataFactory _tmplFactory;
@Inject
- protected GuestOSDao _guestOSDao;
+ private SnapshotDataFactory _snapshotFactory;
@Inject
- StorageManager _storageMgr;
+ private TemplateService _tmpltSvr;
@Inject
- AsyncJobManager _asyncMgr;
+ private DataStoreManager _dataStoreMgr;
@Inject
- UserVmManager _vmMgr;
+ private VolumeOrchestrationService _volumeMgr;
@Inject
- UsageEventDao _usageEventDao;
+ private EndPointSelector _epSelector;
@Inject
- HypervisorGuruManager _hvGuruMgr;
- @Inject
- AccountService _accountService;
- @Inject
- ResourceLimitService _resourceLimitMgr;
- @Inject
- SecondaryStorageVmManager _ssvmMgr;
- @Inject
- LaunchPermissionDao _launchPermissionDao;
- @Inject
- ProjectManager _projectMgr;
- @Inject
- VolumeDataFactory _volFactory;
- @Inject
- TemplateDataFactory _tmplFactory;
- @Inject
- SnapshotDataFactory _snapshotFactory;
- @Inject
- TemplateService _tmpltSvr;
- @Inject
- DataStoreManager _dataStoreMgr;
- @Inject
- protected ResourceManager _resourceMgr;
- @Inject
- VolumeOrchestrationService _volumeMgr;
- @Inject
- ImageStoreDao _imageStoreDao;
- @Inject
- EndPointSelector _epSelector;
- @Inject
- UserVmJoinDao _userVmJoinDao;
- @Inject
- VMTemplateHostDao _vmTemplateHostDao;
-
- @Inject
- ConfigurationServer _configServer;
-
- int _primaryStorageDownloadWait;
- int _storagePoolMaxWaitSeconds = 3600;
- boolean _disableExtraction = false;
- ExecutorService _preloadExecutor;
+ private UserVmJoinDao _userVmJoinDao;
+ private boolean _disableExtraction = false;
+ private ExecutorService _preloadExecutor;
- protected List<TemplateAdapter> _adapters;
+ private List<TemplateAdapter> _adapters;
@Inject
- StorageCacheManager cacheMgr;
+ private StorageCacheManager cacheMgr;
@Inject
- EndPointSelector selector;
+ private EndPointSelector selector;
private TemplateAdapter getAdapter(HypervisorType type) {
TemplateAdapter adapter = null;
@@ -842,13 +786,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
- String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString());
- _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
String disableExtraction = _configDao.getValue(Config.DisableExtraction.toString());
_disableExtraction = (disableExtraction == null) ? false : Boolean.parseBoolean(disableExtraction);
- _storagePoolMaxWaitSeconds = NumbersUtil.parseInt(_configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
_preloadExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("Template-Preloader"));
return true;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
----------------------------------------------------------------------
diff --git a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java b/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
index 58d02fa..22516c0 100644
--- a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
+++ b/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
@@ -106,7 +106,6 @@ import com.cloud.storage.dao.DiskOfferingDaoImpl;
import com.cloud.storage.dao.SnapshotDaoImpl;
import com.cloud.storage.dao.StoragePoolDetailsDaoImpl;
import com.cloud.storage.dao.VolumeDaoImpl;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.tags.dao.ResourceTagsDaoImpl;
import com.cloud.user.AccountDetailsDao;
import com.cloud.user.AccountManager;
@@ -181,11 +180,6 @@ public class ChildTestConfiguration {
}
@Bean
- public SecondaryStorageVmManager ssvmMgr() {
- return Mockito.mock(SecondaryStorageVmManager.class);
- }
-
- @Bean
public VpcManager vpcMgr() {
return Mockito.mock(VpcManager.class);
}
[06/11] Moved the secondary storage service into its own server
directory
Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
new file mode 100755
index 0000000..9782c2e
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -0,0 +1,2430 @@
+// 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.storage.resource;
+
+import static com.cloud.utils.S3Utils.mputFile;
+import static com.cloud.utils.S3Utils.putFile;
+import static com.cloud.utils.StringUtils.join;
+import static java.lang.String.format;
+import static java.util.Arrays.asList;
+import static org.apache.commons.lang.StringUtils.substringAfterLast;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.UnknownHostException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.log4j.Logger;
+
+import com.amazonaws.services.s3.model.S3ObjectSummary;
+
+import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.command.DownloadProgressCommand;
+import org.apache.cloudstack.storage.template.DownloadManager;
+import org.apache.cloudstack.storage.template.DownloadManagerImpl;
+import org.apache.cloudstack.storage.template.DownloadManagerImpl.ZfsPathParser;
+import org.apache.cloudstack.storage.template.UploadManager;
+import org.apache.cloudstack.storage.template.UploadManagerImpl;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+
+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.DeleteSnapshotsDirCommand;
+import com.cloud.agent.api.GetStorageStatsAnswer;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingStorageCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.SecStorageFirewallCfgCommand;
+import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
+import com.cloud.agent.api.SecStorageSetupAnswer;
+import com.cloud.agent.api.SecStorageSetupCommand;
+import com.cloud.agent.api.SecStorageVMSetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupSecondaryStorageCommand;
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.ListTemplateAnswer;
+import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.agent.api.storage.ListVolumeAnswer;
+import com.cloud.agent.api.storage.ListVolumeCommand;
+import com.cloud.agent.api.storage.UploadCommand;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.agent.api.to.SwiftTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.template.OVAProcessor;
+import com.cloud.storage.template.Processor;
+import com.cloud.storage.template.Processor.FormatInfo;
+import com.cloud.storage.template.QCOW2Processor;
+import com.cloud.storage.template.RawImageProcessor;
+import com.cloud.storage.template.TemplateLocation;
+import com.cloud.storage.template.TemplateProp;
+import com.cloud.storage.template.VhdProcessor;
+import com.cloud.storage.template.VmdkProcessor;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.S3Utils;
+import com.cloud.utils.S3Utils.FileNamingStrategy;
+import com.cloud.utils.SwiftUtil;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+import com.cloud.vm.SecondaryStorageVm;
+
+public class NfsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
+
+ private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class);
+
+ private static final String TEMPLATE_ROOT_DIR = "template/tmpl";
+ private static final String VOLUME_ROOT_DIR = "volumes";
+
+ int _timeout;
+
+ public int getTimeout() {
+ return _timeout;
+ }
+
+ public void setTimeout(int timeout) {
+ _timeout = timeout;
+ }
+
+ String _instance;
+ String _dc;
+ String _pod;
+ String _guid;
+ String _role;
+ Map<String, Object> _params;
+ protected StorageLayer _storage;
+ protected boolean _inSystemVM = false;
+ boolean _sslCopy = false;
+
+ protected DownloadManager _dlMgr;
+ protected UploadManager _upldMgr;
+ private String _configSslScr;
+ private String _configAuthScr;
+ private String _configIpFirewallScr;
+ private String _publicIp;
+ private String _hostname;
+ private String _localgw;
+ private String _eth1mask;
+ private String _eth1ip;
+ private String _storageIp;
+ private String _storageNetmask;
+ private String _storageGateway;
+ private final List<String> nfsIps = new ArrayList<String>();
+ protected String _parent = "/mnt/SecStorage";
+ final private String _tmpltpp = "template.properties";
+ protected String createTemplateFromSnapshotXenScript;
+
+ public void setParentPath(String path) {
+ _parent = path;
+ }
+
+ public String getMountingRoot() {
+ return _parent;
+ }
+
+ @Override
+ public void disconnected() {
+ }
+
+ public void setInSystemVM(boolean inSystemVM) {
+ _inSystemVM = inSystemVM;
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ if (cmd instanceof DownloadProgressCommand) {
+ return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
+ } else if (cmd instanceof DownloadCommand) {
+ return execute((DownloadCommand)cmd);
+ } else if (cmd instanceof UploadCommand) {
+ return _upldMgr.handleUploadCommand(this, (UploadCommand)cmd);
+ } else if (cmd instanceof CreateEntityDownloadURLCommand) {
+ return _upldMgr.handleCreateEntityURLCommand((CreateEntityDownloadURLCommand)cmd);
+ } else if (cmd instanceof DeleteEntityDownloadURLCommand) {
+ return _upldMgr.handleDeleteEntityDownloadURLCommand((DeleteEntityDownloadURLCommand)cmd);
+ } else if (cmd instanceof GetStorageStatsCommand) {
+ return execute((GetStorageStatsCommand)cmd);
+ } else if (cmd instanceof CheckHealthCommand) {
+ return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
+ } else if (cmd instanceof ReadyCommand) {
+ return new ReadyAnswer((ReadyCommand)cmd);
+ } else if (cmd instanceof SecStorageFirewallCfgCommand) {
+ return execute((SecStorageFirewallCfgCommand)cmd);
+ } else if (cmd instanceof SecStorageVMSetupCommand) {
+ return execute((SecStorageVMSetupCommand)cmd);
+ } else if (cmd instanceof SecStorageSetupCommand) {
+ return execute((SecStorageSetupCommand)cmd);
+ } else if (cmd instanceof ComputeChecksumCommand) {
+ return execute((ComputeChecksumCommand)cmd);
+ } else if (cmd instanceof ListTemplateCommand) {
+ return execute((ListTemplateCommand)cmd);
+ } else if (cmd instanceof ListVolumeCommand) {
+ return execute((ListVolumeCommand)cmd);
+ } else if (cmd instanceof DeleteSnapshotsDirCommand) {
+ return execute((DeleteSnapshotsDirCommand)cmd);
+ } else if (cmd instanceof CopyCommand) {
+ return execute((CopyCommand)cmd);
+ } else if (cmd instanceof DeleteCommand) {
+ return execute((DeleteCommand)cmd);
+ } else {
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+ }
+
+ protected CopyCmdAnswer postProcessing(File destFile, String downloadPath, String destPath, DataTO srcData, DataTO destData) throws ConfigurationException {
+ if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
+ SnapshotObjectTO snapshot = new SnapshotObjectTO();
+ snapshot.setPath(destPath + File.separator + destFile.getName());
+
+ CopyCmdAnswer answer = new CopyCmdAnswer(snapshot);
+ return answer;
+ }
+ // do post processing to unzip the file if it is compressed
+ String scriptsDir = "scripts/storage/secondary";
+ String createTmpltScr = Script.findScript(scriptsDir, "createtmplt.sh");
+ if (createTmpltScr == null) {
+ throw new ConfigurationException("Unable to find createtmplt.sh");
+ }
+ s_logger.info("createtmplt.sh found in " + createTmpltScr);
+ String createVolScr = Script.findScript(scriptsDir, "createvolume.sh");
+ if (createVolScr == null) {
+ throw new ConfigurationException("Unable to find createvolume.sh");
+ }
+ s_logger.info("createvolume.sh found in " + createVolScr);
+ String script = srcData.getObjectType() == DataObjectType.TEMPLATE ? createTmpltScr : createVolScr;
+
+ int installTimeoutPerGig = 180 * 60 * 1000;
+ long imgSizeGigs = (long)Math.ceil(destFile.length() * 1.0d / (1024 * 1024 * 1024));
+ imgSizeGigs++; // add one just in case
+ long timeout = imgSizeGigs * installTimeoutPerGig;
+
+ String origPath = destFile.getAbsolutePath();
+ String extension = null;
+ if (srcData.getObjectType() == DataObjectType.TEMPLATE) {
+ extension = ((TemplateObjectTO)srcData).getFormat().getFileExtension();
+ } else if (srcData.getObjectType() == DataObjectType.VOLUME) {
+ extension = ((VolumeObjectTO)srcData).getFormat().getFileExtension();
+ }
+
+ String templateName = UUID.randomUUID().toString();
+ String templateFilename = templateName + "." + extension;
+ Script scr = new Script(script, timeout, s_logger);
+ scr.add("-s", Long.toString(imgSizeGigs)); // not used for now
+ scr.add("-n", templateFilename);
+
+ scr.add("-t", downloadPath);
+ scr.add("-f", origPath); // this is the temporary
+ // template file downloaded
+ String result;
+ result = scr.execute();
+
+ if (result != null) {
+ // script execution failure
+ throw new CloudRuntimeException("Failed to run script " + script);
+ }
+
+ String finalFileName = templateFilename;
+ String finalDownloadPath = destPath + File.separator + templateFilename;
+ // compute the size of
+ long size = _storage.getSize(downloadPath + File.separator + templateFilename);
+
+ DataTO newDestTO = null;
+
+ if (destData.getObjectType() == DataObjectType.TEMPLATE) {
+ TemplateObjectTO newTemplTO = new TemplateObjectTO();
+ newTemplTO.setPath(finalDownloadPath);
+ newTemplTO.setName(finalFileName);
+ newTemplTO.setSize(size);
+ newTemplTO.setPhysicalSize(size);
+ newDestTO = newTemplTO;
+ } else {
+ VolumeObjectTO newVolTO = new VolumeObjectTO();
+ newVolTO.setPath(finalDownloadPath);
+ newVolTO.setName(finalFileName);
+ newVolTO.setSize(size);
+ newDestTO = newVolTO;
+ }
+
+ return new CopyCmdAnswer(newDestTO);
+ }
+
+ protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO swiftTO, DataTO destData, NfsTO destImageStore) {
+ final String storagePath = destImageStore.getUrl();
+ final String destPath = destData.getPath();
+ try {
+ String downloadPath = determineStorageTemplatePath(storagePath, destPath);
+ final File downloadDirectory = _storage.getFile(downloadPath);
+ if (!downloadDirectory.mkdirs()) {
+ return new CopyCmdAnswer("Failed to create download directory " + downloadPath);
+ }
+ File destFile = SwiftUtil.getObject(swiftTO, downloadDirectory, srcData.getPath());
+ return postProcessing(destFile, downloadPath, destPath, srcData, destData);
+ } catch (Exception e) {
+ s_logger.debug("Failed to copy swift to nfs", e);
+ return new CopyCmdAnswer(e.toString());
+ }
+ }
+
+ protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) {
+ final String storagePath = destImageStore.getUrl();
+ final String destPath = destData.getPath();
+
+ try {
+
+ String downloadPath = determineStorageTemplatePath(storagePath, destPath);
+ final File downloadDirectory = _storage.getFile(downloadPath);
+
+ if (!downloadDirectory.mkdirs()) {
+ final String errMsg = "Unable to create directory " + downloadPath + " to copy from S3 to cache.";
+ s_logger.error(errMsg);
+ return new CopyCmdAnswer(errMsg);
+ } else {
+ s_logger.debug("Directory " + downloadPath + " already exists");
+ }
+
+ File destFile = S3Utils.getFile(s3, s3.getBucketName(), srcData.getPath(), downloadDirectory, new FileNamingStrategy() {
+ @Override
+ public String determineFileName(final String key) {
+ return substringAfterLast(key, S3Utils.SEPARATOR);
+ }
+ });
+
+ if (destFile == null) {
+ return new CopyCmdAnswer("Can't find template");
+ }
+
+ return postProcessing(destFile, downloadPath, destPath, srcData, destData);
+ } catch (Exception e) {
+
+ final String errMsg = format("Failed to download" + "due to $2%s", e.getMessage());
+ s_logger.error(errMsg, e);
+ return new CopyCmdAnswer(errMsg);
+ }
+ }
+
+ protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData,
+ NfsTO destDataStore) {
+ String srcMountPoint = getRootDir(srcDataStore.getUrl());
+ String snapshotPath = srcData.getPath();
+ int index = snapshotPath.lastIndexOf("/");
+ String snapshotName = snapshotPath.substring(index + 1);
+ if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) {
+ snapshotName = snapshotName + ".vhd";
+ }
+ snapshotPath = snapshotPath.substring(0, index);
+
+ snapshotPath = srcMountPoint + File.separator + snapshotPath;
+ String destMountPoint = getRootDir(destDataStore.getUrl());
+ String destPath = destMountPoint + File.separator + destData.getPath();
+
+ String errMsg = null;
+ try {
+ _storage.mkdir(destPath);
+
+ String templateUuid = UUID.randomUUID().toString();
+ String templateName = templateUuid + ".vhd";
+ Script command = new Script(createTemplateFromSnapshotXenScript, cmd.getWait() * 1000, s_logger);
+ command.add("-p", snapshotPath);
+ command.add("-s", snapshotName);
+ command.add("-n", templateName);
+ command.add("-t", destPath);
+ String result = command.execute();
+
+ if (result != null && !result.equalsIgnoreCase("")) {
+ return new CopyCmdAnswer(result);
+ }
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put(StorageLayer.InstanceConfigKey, _storage);
+ Processor processor = new VhdProcessor();
+
+ processor.configure("Vhd Processor", params);
+ FormatInfo info = processor.process(destPath, null, templateUuid);
+
+ TemplateLocation loc = new TemplateLocation(_storage, destPath);
+ loc.create(1, true, templateUuid);
+ loc.addFormat(info);
+ loc.save();
+ TemplateProp prop = loc.getTemplateInfo();
+ TemplateObjectTO newTemplate = new TemplateObjectTO();
+ newTemplate.setPath(destData.getPath() + File.separator + templateName);
+ newTemplate.setFormat(ImageFormat.VHD);
+ newTemplate.setSize(prop.getSize());
+ newTemplate.setPhysicalSize(prop.getPhysicalSize());
+ newTemplate.setName(templateUuid);
+ return new CopyCmdAnswer(newTemplate);
+ } catch (ConfigurationException e) {
+ s_logger.debug("Failed to create template from snapshot: " + e.toString());
+ errMsg = e.toString();
+ } catch (InternalErrorException e) {
+ s_logger.debug("Failed to create template from snapshot: " + e.toString());
+ errMsg = e.toString();
+ } catch (IOException e) {
+ s_logger.debug("Failed to create template from snapshot: " + e.toString());
+ errMsg = e.toString();
+ }
+
+ return new CopyCmdAnswer(errMsg);
+ }
+
+ protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) {
+
+ if (srcData.getHypervisorType() == HypervisorType.XenServer) {
+ return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore);
+ } else if (srcData.getHypervisorType() == HypervisorType.KVM) {
+ File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl());
+ File destFile = getFile(destData.getPath(), destDataStore.getUrl());
+
+ VolumeObjectTO volumeObjectTO = srcData.getVolume();
+ ImageFormat srcFormat = null;
+ //TODO: the image format should be stored in snapshot table, instead of getting from volume
+ if (volumeObjectTO != null) {
+ srcFormat = volumeObjectTO.getFormat();
+ } else {
+ srcFormat = ImageFormat.QCOW2;
+ }
+
+ // get snapshot file name
+ String templateName = srcFile.getName();
+ // add kvm file extension for copied template name
+ String fileName = templateName + "." + srcFormat.getFileExtension();
+ String destFileFullPath = destFile.getAbsolutePath() + File.separator + fileName;
+ s_logger.debug("copy snapshot " + srcFile.getAbsolutePath() + " to template " + destFileFullPath);
+ Script.runSimpleBashScript("cp " + srcFile.getAbsolutePath() + " " + destFileFullPath);
+ try {
+ // generate template.properties file
+ String metaFileName = destFile.getAbsolutePath() + File.separator + "template.properties";
+ _storage.create(destFile.getAbsolutePath(), "template.properties");
+ File metaFile = new File(metaFileName);
+ FileWriter writer = new FileWriter(metaFile);
+ BufferedWriter bufferWriter = new BufferedWriter(writer);
+ // KVM didn't change template unique name, just used the template name passed from orchestration layer, so no need
+ // to send template name back.
+ bufferWriter.write("uniquename=" + destData.getName());
+ bufferWriter.write("\n");
+ bufferWriter.write("filename=" + fileName);
+ bufferWriter.write("\n");
+ long size = _storage.getSize(destFileFullPath);
+ bufferWriter.write("size=" + size);
+ bufferWriter.close();
+ writer.close();
+
+ /**
+ * Snapshots might be in either QCOW2 or RAW image format
+ *
+ * For example RBD snapshots are in RAW format
+ */
+ Processor processor = null;
+ if (srcFormat == ImageFormat.QCOW2) {
+ processor = new QCOW2Processor();
+ } else if (srcFormat == ImageFormat.RAW) {
+ processor = new RawImageProcessor();
+ } else {
+ throw new ConfigurationException("Unknown image format " + srcFormat.toString());
+ }
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put(StorageLayer.InstanceConfigKey, _storage);
+
+ processor.configure("template processor", params);
+ String destPath = destFile.getAbsolutePath();
+
+ FormatInfo info = processor.process(destPath, null, templateName);
+ TemplateLocation loc = new TemplateLocation(_storage, destPath);
+ loc.create(1, true, destData.getName());
+ loc.addFormat(info);
+ loc.save();
+
+ TemplateProp prop = loc.getTemplateInfo();
+ TemplateObjectTO newTemplate = new TemplateObjectTO();
+ newTemplate.setPath(destData.getPath() + File.separator + fileName);
+ newTemplate.setFormat(srcFormat);
+ newTemplate.setSize(prop.getSize());
+ newTemplate.setPhysicalSize(prop.getPhysicalSize());
+ return new CopyCmdAnswer(newTemplate);
+ } catch (ConfigurationException e) {
+ s_logger.debug("Failed to create template:" + e.toString());
+ return new CopyCmdAnswer(e.toString());
+ } catch (IOException e) {
+ s_logger.debug("Failed to create template:" + e.toString());
+ return new CopyCmdAnswer(e.toString());
+ } catch (InternalErrorException e) {
+ s_logger.debug("Failed to create template:" + e.toString());
+ return new CopyCmdAnswer(e.toString());
+ }
+ }
+
+ return new CopyCmdAnswer("");
+ }
+
+ protected File getFile(String path, String nfsPath) {
+ String filePath = getRootDir(nfsPath) + File.separator + path;
+ File f = new File(filePath);
+ if (!f.exists()) {
+ _storage.mkdirs(filePath);
+ f = new File(filePath);
+ }
+ return f;
+ }
+
+ protected Answer createTemplateFromSnapshot(CopyCommand cmd) {
+ DataTO srcData = cmd.getSrcTO();
+ DataTO destData = cmd.getDestTO();
+ DataStoreTO srcDataStore = srcData.getDataStore();
+ DataStoreTO destDataStore = destData.getDataStore();
+ if (srcDataStore.getRole() == DataStoreRole.Image || srcDataStore.getRole() == DataStoreRole.ImageCache || srcDataStore.getRole() == DataStoreRole.Primary) {
+ if (!(srcDataStore instanceof NfsTO)) {
+ s_logger.debug("only support nfs storage as src, when create template from snapshot");
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+
+ if (destDataStore instanceof NfsTO) {
+ return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, (NfsTO)destDataStore);
+ } else if (destDataStore instanceof SwiftTO) {
+ //create template on the same data store
+ CopyCmdAnswer answer =
+ (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData,
+ (NfsTO)srcDataStore);
+ if (!answer.getResult()) {
+ return answer;
+ }
+ s_logger.debug("starting copy template to swift");
+ DataTO newTemplate = answer.getNewData();
+ File templateFile = getFile(newTemplate.getPath(), ((NfsTO)srcDataStore).getUrl());
+ SwiftTO swift = (SwiftTO)destDataStore;
+ String containterName = SwiftUtil.getContainerName(destData.getObjectType().toString(), destData.getId());
+ String swiftPath = SwiftUtil.putObject(swift, templateFile, containterName, templateFile.getName());
+ //upload template.properties
+ File properties = new File(templateFile.getParent() + File.separator + _tmpltpp);
+ if (properties.exists()) {
+ SwiftUtil.putObject(swift, properties, containterName, _tmpltpp);
+ }
+
+ //clean up template data on staging area
+ try {
+ DeleteCommand deleteCommand = new DeleteCommand(newTemplate);
+ execute(deleteCommand);
+ } catch (Exception e) {
+ s_logger.debug("Failed to clean up staging area:", e);
+ }
+
+ TemplateObjectTO template = new TemplateObjectTO();
+ template.setPath(swiftPath);
+ template.setSize(templateFile.length());
+ template.setPhysicalSize(template.getSize());
+ SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+ template.setFormat(snapshot.getVolume().getFormat());
+ return new CopyCmdAnswer(template);
+ } else if (destDataStore instanceof S3TO) {
+ //create template on the same data store
+ CopyCmdAnswer answer =
+ (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData,
+ (NfsTO)srcDataStore);
+ if (!answer.getResult()) {
+ return answer;
+ }
+ TemplateObjectTO newTemplate = (TemplateObjectTO)answer.getNewData();
+ newTemplate.setDataStore(srcDataStore);
+ CopyCommand newCpyCmd = new CopyCommand(newTemplate, destData, cmd.getWait(), cmd.executeInSequence());
+ Answer result = copyFromNfsToS3(newCpyCmd);
+ //clean up template data on staging area
+ try {
+ DeleteCommand deleteCommand = new DeleteCommand(newTemplate);
+ execute(deleteCommand);
+ } catch (Exception e) {
+ s_logger.debug("Failed to clean up staging area:", e);
+ }
+ return result;
+ }
+ }
+ s_logger.debug("Failed to create templat from snapshot");
+ return new CopyCmdAnswer("Unsupported prototcol");
+ }
+
+ protected Answer copyFromNfsToImage(CopyCommand cmd) {
+ DataTO destData = cmd.getDestTO();
+ DataStoreTO destDataStore = destData.getDataStore();
+
+ if (destDataStore instanceof S3TO) {
+ return copyFromNfsToS3(cmd);
+ } else {
+ return new CopyCmdAnswer("unsupported ");
+ }
+ }
+
+ protected Answer execute(CopyCommand cmd) {
+ DataTO srcData = cmd.getSrcTO();
+ DataTO destData = cmd.getDestTO();
+ DataStoreTO srcDataStore = srcData.getDataStore();
+ DataStoreTO destDataStore = destData.getDataStore();
+
+ if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
+ return createTemplateFromSnapshot(cmd);
+ }
+
+ if (destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache) {
+ NfsTO destImageStore = (NfsTO)destDataStore;
+ if (srcDataStore instanceof S3TO) {
+ S3TO s3 = (S3TO)srcDataStore;
+ return copyFromS3ToNfs(cmd, srcData, s3, destData, destImageStore);
+ } else if (srcDataStore instanceof SwiftTO) {
+ return copyFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, destData, destImageStore);
+ }
+ }
+
+ if (srcDataStore.getRole() == DataStoreRole.ImageCache && destDataStore.getRole() == DataStoreRole.Image) {
+ return copyFromNfsToImage(cmd);
+ }
+
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected String determineS3TemplateDirectory(final Long accountId, final Long templateId, final String templateUniqueName) {
+ return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId, templateUniqueName), S3Utils.SEPARATOR);
+ }
+
+ private String determineS3TemplateNameFromKey(String key) {
+ return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected String determineS3VolumeDirectory(final Long accountId, final Long volId) {
+ return join(asList(VOLUME_ROOT_DIR, accountId, volId), S3Utils.SEPARATOR);
+ }
+
+ protected Long determineS3VolumeIdFromKey(String key) {
+ return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR));
+ }
+
+ private String determineStorageTemplatePath(final String storagePath, String dataPath) {
+ return join(asList(getRootDir(storagePath), dataPath), File.separator);
+ }
+
+ protected File downloadFromUrlToNfs(String url, NfsTO nfs, String path, String name) {
+ HttpClient client = new DefaultHttpClient();
+ HttpGet get = new HttpGet(url);
+ try {
+ HttpResponse response = client.execute(get);
+ HttpEntity entity = response.getEntity();
+ if (entity == null) {
+ s_logger.debug("Faled to get entity");
+ throw new CloudRuntimeException("Failed to get url: " + url);
+ }
+
+ String nfsMountPath = getRootDir(nfs.getUrl());
+
+ String filePath = nfsMountPath + File.separator + path;
+ File directory = new File(filePath);
+ if (!directory.exists()) {
+ _storage.mkdirs(filePath);
+ }
+ File destFile = new File(filePath + File.separator + name);
+ if (!destFile.createNewFile()) {
+ s_logger.warn("Reusing existing file " + destFile.getPath());
+ }
+ FileOutputStream outputStream = new FileOutputStream(destFile);
+ entity.writeTo(outputStream);
+ return new File(destFile.getAbsolutePath());
+ } catch (IOException e) {
+ s_logger.debug("Faild to get url:" + url + ", due to " + e.toString());
+ throw new CloudRuntimeException(e);
+ }
+ }
+
+ protected Answer registerTemplateOnSwift(DownloadCommand cmd) {
+ SwiftTO swiftTO = (SwiftTO)cmd.getDataStore();
+ String path = cmd.getInstallPath();
+ DataStoreTO cacheStore = cmd.getCacheStore();
+ if (cacheStore == null || !(cacheStore instanceof NfsTO)) {
+ return new DownloadAnswer("cache store can't be null", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+ }
+
+ File file = null;
+ try {
+ NfsTO nfsCacheStore = (NfsTO)cacheStore;
+ String fileName = cmd.getName() + "." + cmd.getFormat().getFileExtension();
+ file = downloadFromUrlToNfs(cmd.getUrl(), nfsCacheStore, path, fileName);
+ String container = "T-" + cmd.getId();
+ String swiftPath = SwiftUtil.putObject(swiftTO, file, container, null);
+
+ //put metda file
+ File uniqDir = _storage.createUniqDir();
+ String metaFileName = uniqDir.getAbsolutePath() + File.separator + "template.properties";
+ _storage.create(uniqDir.getAbsolutePath(), "template.properties");
+ File metaFile = new File(metaFileName);
+ FileWriter writer = new FileWriter(metaFile);
+ BufferedWriter bufferWriter = new BufferedWriter(writer);
+ bufferWriter.write("uniquename=" + cmd.getName());
+ bufferWriter.write("\n");
+ bufferWriter.write("filename=" + fileName);
+ bufferWriter.write("\n");
+ bufferWriter.write("size=" + file.length());
+ bufferWriter.close();
+ writer.close();
+
+ SwiftUtil.putObject(swiftTO, metaFile, container, "template.properties");
+ metaFile.delete();
+ uniqDir.delete();
+ String md5sum = null;
+ try {
+ md5sum = DigestUtils.md5Hex(new FileInputStream(file));
+ } catch (IOException e) {
+ s_logger.debug("Failed to get md5sum: " + file.getAbsoluteFile());
+ }
+
+ DownloadAnswer answer =
+ new DownloadAnswer(null, 100, null, VMTemplateStorageResourceAssoc.Status.DOWNLOADED, swiftPath, swiftPath, file.length(), file.length(), md5sum);
+ return answer;
+ } catch (IOException e) {
+ s_logger.debug("Failed to register template into swift", e);
+ return new DownloadAnswer(e.toString(), VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+ } finally {
+ if (file != null) {
+ file.delete();
+ }
+ }
+ }
+
+ private Answer execute(DownloadCommand cmd) {
+ DataStoreTO dstore = cmd.getDataStore();
+ if (dstore instanceof NfsTO || dstore instanceof S3TO) {
+ return _dlMgr.handleDownloadCommand(this, cmd);
+ } else if (dstore instanceof SwiftTO) {
+ return registerTemplateOnSwift(cmd);
+ } else {
+ return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+ }
+
+ }
+
+ private ImageFormat getTemplateFormat(String filePath) {
+ String ext = null;
+ int extensionPos = filePath.lastIndexOf('.');
+ int lastSeparator = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'));
+ int i = lastSeparator > extensionPos ? -1 : extensionPos;
+ if (i > 0) {
+ ext = filePath.substring(i + 1);
+ }
+ if (ext != null) {
+ if (ext.equalsIgnoreCase("vhd")) {
+ return ImageFormat.VHD;
+ } else if (ext.equalsIgnoreCase("vhdx")) {
+ return ImageFormat.VHDX;
+ } else if (ext.equalsIgnoreCase("qcow2")) {
+ return ImageFormat.QCOW2;
+ } else if (ext.equalsIgnoreCase("ova")) {
+ return ImageFormat.OVA;
+ } else if (ext.equalsIgnoreCase("tar")) {
+ return ImageFormat.TAR;
+ } else if (ext.equalsIgnoreCase("img") || ext.equalsIgnoreCase("raw")) {
+ return ImageFormat.RAW;
+ } else if (ext.equalsIgnoreCase("vmdk")) {
+ return ImageFormat.VMDK;
+ } else if (ext.equalsIgnoreCase("vdi")) {
+ return ImageFormat.VDI;
+ }
+ }
+
+ return null;
+
+ }
+
+ protected Long getVirtualSize(File file, ImageFormat format) {
+ Processor processor = null;
+ try {
+ if (format == null) {
+ return file.length();
+ } else if (format == ImageFormat.QCOW2) {
+ processor = new QCOW2Processor();
+ } else if (format == ImageFormat.OVA) {
+ processor = new OVAProcessor();
+ } else if (format == ImageFormat.VHD) {
+ processor = new VhdProcessor();
+ } else if (format == ImageFormat.RAW) {
+ processor = new RawImageProcessor();
+ } else if (format == ImageFormat.VMDK) {
+ processor = new VmdkProcessor();
+ }
+
+ if (processor == null) {
+ return file.length();
+ }
+
+ processor.configure("template processor", new HashMap<String, Object>());
+ return processor.getVirtualSize(file);
+ } catch (Exception e) {
+ s_logger.debug("Failed to get virtual size:", e);
+ }
+ return file.length();
+ }
+
+ protected Answer copyFromNfsToS3(CopyCommand cmd) {
+ final DataTO srcData = cmd.getSrcTO();
+ final DataTO destData = cmd.getDestTO();
+ DataStoreTO srcDataStore = srcData.getDataStore();
+ NfsTO srcStore = (NfsTO)srcDataStore;
+ DataStoreTO destDataStore = destData.getDataStore();
+
+ final S3TO s3 = (S3TO)destDataStore;
+
+ try {
+ final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath());
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + " to upload to S3.");
+ }
+
+ final String bucket = s3.getBucketName();
+ File srcFile = _storage.getFile(templatePath);
+ // guard the case where templatePath does not have file extension, since we are not completely sure
+ // about hypervisor, so we check each extension
+ if (!srcFile.exists()) {
+ srcFile = _storage.getFile(templatePath + ".qcow2");
+ if (!srcFile.exists()) {
+ srcFile = _storage.getFile(templatePath + ".vhd");
+ if (!srcFile.exists()) {
+ srcFile = _storage.getFile(templatePath + ".ova");
+ if (!srcFile.exists()) {
+ srcFile = _storage.getFile(templatePath + ".vmdk");
+ if (!srcFile.exists()) {
+ return new CopyCmdAnswer("Can't find src file:" + templatePath);
+ }
+ }
+ }
+ }
+ }
+
+ long srcSize = srcFile.length();
+ ImageFormat format = getTemplateFormat(srcFile.getName());
+ String key = destData.getPath() + S3Utils.SEPARATOR + srcFile.getName();
+ if (!s3.getSingleUpload(srcSize)) {
+ mputFile(s3, srcFile, bucket, key);
+ } else {
+ putFile(s3, srcFile, bucket, key);
+ }
+
+ DataTO retObj = null;
+ if (destData.getObjectType() == DataObjectType.TEMPLATE) {
+ TemplateObjectTO newTemplate = new TemplateObjectTO();
+ newTemplate.setPath(key);
+ newTemplate.setSize(getVirtualSize(srcFile, format));
+ newTemplate.setPhysicalSize(srcFile.length());
+ newTemplate.setFormat(format);
+ retObj = newTemplate;
+ } else if (destData.getObjectType() == DataObjectType.VOLUME) {
+ VolumeObjectTO newVol = new VolumeObjectTO();
+ newVol.setPath(key);
+ newVol.setSize(srcFile.length());
+ retObj = newVol;
+ } else if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
+ SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+ newSnapshot.setPath(key);
+ retObj = newSnapshot;
+ }
+
+ return new CopyCmdAnswer(retObj);
+ } catch (Exception e) {
+ s_logger.error("failed to upload" + srcData.getPath(), e);
+ return new CopyCmdAnswer("failed to upload" + srcData.getPath() + e.toString());
+ }
+ }
+
+ String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) {
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" +
+ swift.getUserName() + " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath);
+ OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+ String result = command.execute(parser);
+ if (result != null) {
+ String errMsg = "swiftDownload failed err=" + result;
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ if (parser.getLines() != null) {
+ String[] lines = parser.getLines().split("\\n");
+ for (String line : lines) {
+ if (line.contains("Errno") || line.contains("failed")) {
+ String errMsg = "swiftDownload failed , err=" + parser.getLines();
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ }
+ }
+ return null;
+
+ }
+
+ String swiftDownloadContainer(SwiftTO swift, String container, String ldir) {
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" +
+ swift.getUserName() + " -K " + swift.getKey() + " download " + container);
+ OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+ String result = command.execute(parser);
+ if (result != null) {
+ String errMsg = "swiftDownloadContainer failed err=" + result;
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ if (parser.getLines() != null) {
+ String[] lines = parser.getLines().split("\\n");
+ for (String line : lines) {
+ if (line.contains("Errno") || line.contains("failed")) {
+ String errMsg = "swiftDownloadContainer failed , err=" + parser.getLines();
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ }
+ }
+ return null;
+
+ }
+
+ String swiftUpload(SwiftTO swift, String container, String lDir, String lFilename) {
+ long SWIFT_MAX_SIZE = 5L * 1024L * 1024L * 1024L;
+ List<String> files = new ArrayList<String>();
+ if (lFilename.equals("*")) {
+ File dir = new File(lDir);
+ for (String file : dir.list()) {
+ if (file.startsWith(".")) {
+ continue;
+ }
+ files.add(file);
+ }
+ } else {
+ files.add(lFilename);
+ }
+
+ for (String file : files) {
+ File f = new File(lDir + "/" + file);
+ long size = f.length();
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ if (size <= SWIFT_MAX_SIZE) {
+ command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " +
+ swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload " + container + " " + file);
+ } else {
+ command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " +
+ swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file);
+ }
+ OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+ String result = command.execute(parser);
+ if (result != null) {
+ String errMsg = "swiftUpload failed , err=" + result;
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ if (parser.getLines() != null) {
+ String[] lines = parser.getLines().split("\\n");
+ for (String line : lines) {
+ if (line.contains("Errno") || line.contains("failed")) {
+ String errMsg = "swiftUpload failed , err=" + parser.getLines();
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ String[] swiftList(SwiftTO swift, String container, String rFilename) {
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" +
+ swift.getUserName() + " -K " + swift.getKey() + " list " + container + " " + rFilename);
+ OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+ String result = command.execute(parser);
+ if (result == null && parser.getLines() != null) {
+ String[] lines = parser.getLines().split("\\n");
+ return lines;
+ } else {
+ if (result != null) {
+ String errMsg = "swiftList failed , err=" + result;
+ s_logger.warn(errMsg);
+ } else {
+ String errMsg = "swiftList failed, no lines returns";
+ s_logger.warn(errMsg);
+ }
+ }
+ return null;
+ }
+
+ String swiftDelete(SwiftTO swift, String container, String object) {
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" +
+ swift.getUserName() + " -K " + swift.getKey() + " delete " + container + " " + object);
+ OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+ String result = command.execute(parser);
+ if (result != null) {
+ String errMsg = "swiftDelete failed , err=" + result;
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ if (parser.getLines() != null) {
+ String[] lines = parser.getLines().split("\\n");
+ for (String line : lines) {
+ if (line.contains("Errno") || line.contains("failed")) {
+ String errMsg = "swiftDelete failed , err=" + parser.getLines();
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ }
+ }
+ return null;
+ }
+
+ public Answer execute(DeleteSnapshotsDirCommand cmd) {
+ DataStoreTO dstore = cmd.getDataStore();
+ if (dstore instanceof NfsTO) {
+ NfsTO nfs = (NfsTO)dstore;
+ String relativeSnapshotPath = cmd.getDirectory();
+ String parent = getRootDir(nfs.getUrl());
+
+ if (relativeSnapshotPath.startsWith(File.separator)) {
+ relativeSnapshotPath = relativeSnapshotPath.substring(1);
+ }
+
+ if (!parent.endsWith(File.separator)) {
+ parent += File.separator;
+ }
+ String absoluteSnapshotPath = parent + relativeSnapshotPath;
+ File snapshotDir = new File(absoluteSnapshotPath);
+ String details = null;
+ if (!snapshotDir.exists()) {
+ details = "snapshot directory " + snapshotDir.getName() + " doesn't exist";
+ s_logger.debug(details);
+ return new Answer(cmd, true, details);
+ }
+ // delete all files in the directory
+ String lPath = absoluteSnapshotPath + "/*";
+ String result = deleteLocalFile(lPath);
+ if (result != null) {
+ String errMsg = "failed to delete all snapshots " + lPath + " , err=" + result;
+ s_logger.warn(errMsg);
+ return new Answer(cmd, false, errMsg);
+ }
+ // delete the directory
+ if (!snapshotDir.delete()) {
+ details = "Unable to delete directory " + snapshotDir.getName() + " under snapshot path " + relativeSnapshotPath;
+ s_logger.debug(details);
+ return new Answer(cmd, false, details);
+ }
+ return new Answer(cmd, true, null);
+ } else if (dstore instanceof S3TO) {
+ final S3TO s3 = (S3TO)dstore;
+ final String path = cmd.getDirectory();
+ final String bucket = s3.getBucketName();
+ try {
+ S3Utils.deleteDirectory(s3, bucket, path);
+ return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket));
+ } catch (Exception e) {
+ final String errorMessage =
+ String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
+ s_logger.error(errorMessage, e);
+ return new Answer(cmd, false, errorMessage);
+ }
+ } else if (dstore instanceof SwiftTO) {
+ String path = cmd.getDirectory();
+ String volumeId = StringUtils.substringAfterLast(path, "/"); // assuming
+ // that
+ // the
+ // filename
+ // is
+ // the
+ // last
+ // section
+ // in
+ // the
+ // path
+ String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), "");
+ if (result != null) {
+ String errMsg = "failed to delete snapshot for volume " + volumeId + " , err=" + result;
+ s_logger.warn(errMsg);
+ return new Answer(cmd, false, errMsg);
+ }
+ return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
+ } else {
+ return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+ }
+ }
+
+ private Answer execute(ComputeChecksumCommand cmd) {
+
+ String relativeTemplatePath = cmd.getTemplatePath();
+ DataStoreTO store = cmd.getStore();
+ if (!(store instanceof NfsTO)) {
+ return new Answer(cmd, false, "can't handle non nfs data store");
+ }
+ NfsTO nfsStore = (NfsTO)store;
+ String parent = getRootDir(nfsStore.getUrl());
+
+ 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 {
+ if (is != null) {
+ 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 void configCerts(KeystoreManager.Certificates certs) {
+ if (certs == null) {
+ configureSSL();
+ } else {
+ String prvKey = certs.getPrivKey();
+ String pubCert = certs.getPrivCert();
+
+ try {
+ File prvKeyFile = File.createTempFile("prvkey", null);
+ String prvkeyPath = prvKeyFile.getAbsolutePath();
+ BufferedWriter out = new BufferedWriter(new FileWriter(prvKeyFile));
+ out.write(prvKey);
+ out.close();
+
+ File pubCertFile = File.createTempFile("pubcert", null);
+ String pubCertFilePath = pubCertFile.getAbsolutePath();
+
+ out = new BufferedWriter(new FileWriter(pubCertFile));
+ out.write(pubCert);
+ out.close();
+
+ configureSSL(prvkeyPath, pubCertFilePath, null);
+
+ prvKeyFile.delete();
+ pubCertFile.delete();
+
+ } catch (IOException e) {
+ s_logger.debug("Failed to config ssl: " + e.toString());
+ }
+ }
+ }
+
+ private Answer execute(SecStorageSetupCommand cmd) {
+ if (!_inSystemVM) {
+ return new Answer(cmd, true, null);
+ }
+ DataStoreTO dStore = cmd.getDataStore();
+ if (dStore instanceof NfsTO) {
+ String secUrl = cmd.getSecUrl();
+ try {
+ URI uri = new URI(secUrl);
+ String nfsHostIp = getUriHostIp(uri);
+
+ addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
+ String dir = mountUri(uri);
+
+ configCerts(cmd.getCerts());
+
+ nfsIps.add(nfsHostIp);
+ return new SecStorageSetupAnswer(dir);
+ } catch (Exception e) {
+ String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
+ s_logger.error(msg);
+ return new Answer(cmd, false, msg);
+
+ }
+ } else {
+ // TODO: what do we need to setup for S3/Swift, maybe need to mount
+ // to some cache storage
+ return new Answer(cmd, true, null);
+ }
+ }
+
+ protected Answer deleteSnapshot(final DeleteCommand cmd) {
+ DataTO obj = cmd.getData();
+ DataStoreTO dstore = obj.getDataStore();
+ if (dstore instanceof NfsTO) {
+ NfsTO nfs = (NfsTO)dstore;
+ String parent = getRootDir(nfs.getUrl());
+ if (!parent.endsWith(File.separator)) {
+ parent += File.separator;
+ }
+ String snapshotPath = obj.getPath();
+ if (snapshotPath.startsWith(File.separator)) {
+ snapshotPath = snapshotPath.substring(1);
+ }
+ // check if the passed snapshot path is a directory or not. For ImageCache, path is stored as a directory instead of
+ // snapshot file name. If so, since backupSnapshot process has already deleted snapshot in cache, so we just do nothing
+ // and return true.
+ String fullSnapPath = parent + snapshotPath;
+ File snapDir = new File(fullSnapPath);
+ if (snapDir.exists() && snapDir.isDirectory()) {
+ s_logger.debug("snapshot path " + snapshotPath + " is a directory, already deleted during backup snapshot, so no need to delete");
+ return new Answer(cmd, true, null);
+ }
+ // passed snapshot path is a snapshot file path, then get snapshot directory first
+ int index = snapshotPath.lastIndexOf("/");
+ String snapshotName = snapshotPath.substring(index + 1);
+ snapshotPath = snapshotPath.substring(0, index);
+ String absoluteSnapshotPath = parent + snapshotPath;
+ // check if snapshot directory exists
+ File snapshotDir = new File(absoluteSnapshotPath);
+ String details = null;
+ if (!snapshotDir.exists()) {
+ details = "snapshot directory " + snapshotDir.getName() + " doesn't exist";
+ s_logger.debug(details);
+ return new Answer(cmd, false, details);
+ }
+ // delete snapshot in the directory if exists
+ String lPath = absoluteSnapshotPath + "/*" + snapshotName + "*";
+ String result = deleteLocalFile(lPath);
+ if (result != null) {
+ details = "failed to delete snapshot " + lPath + " , err=" + result;
+ s_logger.warn(details);
+ return new Answer(cmd, false, details);
+ }
+ return new Answer(cmd, true, null);
+ } else if (dstore instanceof S3TO) {
+ final S3TO s3 = (S3TO)dstore;
+ final String path = obj.getPath();
+ final String bucket = s3.getBucketName();
+ try {
+ S3Utils.deleteObject(s3, bucket, path);
+ return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket));
+ } catch (Exception e) {
+ final String errorMessage =
+ String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
+ s_logger.error(errorMessage, e);
+ return new Answer(cmd, false, errorMessage);
+ }
+ } else if (dstore instanceof SwiftTO) {
+ SwiftTO swiftTO = (SwiftTO)dstore;
+ String path = obj.getPath();
+ SwiftUtil.deleteObject(swiftTO, path);
+
+ return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
+ } else {
+ return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+ }
+
+ }
+
+ Map<String, TemplateProp> swiftListTemplate(SwiftTO swift) {
+ String[] containers = SwiftUtil.list(swift, "", null);
+ if (containers == null) {
+ return null;
+ }
+ Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
+ for (String container : containers) {
+ if (container.startsWith("T-")) {
+ String[] files = SwiftUtil.list(swift, container, "template.properties");
+ if (files.length != 1) {
+ continue;
+ }
+ try {
+ File tempFile = File.createTempFile("template", ".tmp");
+ File tmpFile = SwiftUtil.getObject(swift, tempFile, container + File.separator + "template.properties");
+ if (tmpFile == null) {
+ continue;
+ }
+ FileReader fr = new FileReader(tmpFile);
+ BufferedReader brf = new BufferedReader(fr);
+ String line = null;
+ String uniqName = null;
+ Long size = null;
+ String name = null;
+ while ((line = brf.readLine()) != null) {
+ if (line.startsWith("uniquename=")) {
+ uniqName = line.split("=")[1];
+ } else if (line.startsWith("size=")) {
+ size = Long.parseLong(line.split("=")[1]);
+ } else if (line.startsWith("filename=")) {
+ name = line.split("=")[1];
+ }
+ }
+ brf.close();
+ tempFile.delete();
+ if (uniqName != null) {
+ TemplateProp prop = new TemplateProp(uniqName, container + File.separator + name, size, size, true, false);
+ tmpltInfos.put(uniqName, prop);
+ }
+
+ } catch (IOException e) {
+ s_logger.debug("Failed to create templ file:" + e.toString());
+ continue;
+ } catch (Exception e) {
+ s_logger.debug("Failed to get properties: " + e.toString());
+ continue;
+ }
+ }
+ }
+ return tmpltInfos;
+
+ }
+
+ Map<String, TemplateProp> s3ListTemplate(S3TO s3) {
+ String bucket = s3.getBucketName();
+ // List the objects in the source directory on S3
+ final List<S3ObjectSummary> objectSummaries = S3Utils.getDirectory(s3, bucket, TEMPLATE_ROOT_DIR);
+ if (objectSummaries == null) {
+ return null;
+ }
+ Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
+ for (S3ObjectSummary objectSummary : objectSummaries) {
+ String key = objectSummary.getKey();
+ // String installPath = StringUtils.substringBeforeLast(key,
+ // S3Utils.SEPARATOR);
+ String uniqueName = determineS3TemplateNameFromKey(key);
+ // TODO: isPublic value, where to get?
+ TemplateProp tInfo = new TemplateProp(uniqueName, key, objectSummary.getSize(), objectSummary.getSize(), true, false);
+ tmpltInfos.put(uniqueName, tInfo);
+ }
+ return tmpltInfos;
+
+ }
+
+ Map<Long, TemplateProp> s3ListVolume(S3TO s3) {
+ String bucket = s3.getBucketName();
+ // List the objects in the source directory on S3
+ final List<S3ObjectSummary> objectSummaries = S3Utils.getDirectory(s3, bucket, VOLUME_ROOT_DIR);
+ if (objectSummaries == null) {
+ return null;
+ }
+ Map<Long, TemplateProp> tmpltInfos = new HashMap<Long, TemplateProp>();
+ for (S3ObjectSummary objectSummary : objectSummaries) {
+ String key = objectSummary.getKey();
+ // String installPath = StringUtils.substringBeforeLast(key,
+ // S3Utils.SEPARATOR);
+ Long id = determineS3VolumeIdFromKey(key);
+ // TODO: how to get volume template name
+ TemplateProp tInfo = new TemplateProp(id.toString(), key, objectSummary.getSize(), objectSummary.getSize(), true, false);
+ tmpltInfos.put(id, tInfo);
+ }
+ return tmpltInfos;
+
+ }
+
+ private Answer execute(ListTemplateCommand cmd) {
+ if (!_inSystemVM) {
+ return new ListTemplateAnswer(null, null);
+ }
+
+ DataStoreTO store = cmd.getDataStore();
+ if (store instanceof NfsTO) {
+ NfsTO nfs = (NfsTO)store;
+ String secUrl = nfs.getUrl();
+ String root = getRootDir(secUrl);
+ Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
+ return new ListTemplateAnswer(secUrl, templateInfos);
+ } else if (store instanceof SwiftTO) {
+ SwiftTO swift = (SwiftTO)store;
+ Map<String, TemplateProp> templateInfos = swiftListTemplate(swift);
+ return new ListTemplateAnswer(swift.toString(), templateInfos);
+ } else if (store instanceof S3TO) {
+ S3TO s3 = (S3TO)store;
+ Map<String, TemplateProp> templateInfos = s3ListTemplate(s3);
+ return new ListTemplateAnswer(s3.getBucketName(), templateInfos);
+ } else {
+ return new Answer(cmd, false, "Unsupported image data store: " + store);
+ }
+ }
+
+ private Answer execute(ListVolumeCommand cmd) {
+ if (!_inSystemVM) {
+ return new ListVolumeAnswer(cmd.getSecUrl(), null);
+ }
+ DataStoreTO store = cmd.getDataStore();
+ if (store instanceof NfsTO) {
+ String root = getRootDir(cmd.getSecUrl());
+ Map<Long, TemplateProp> templateInfos = _dlMgr.gatherVolumeInfo(root);
+ return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
+ } else if (store instanceof S3TO) {
+ S3TO s3 = (S3TO)store;
+ Map<Long, TemplateProp> templateInfos = s3ListVolume(s3);
+ return new ListVolumeAnswer(s3.getBucketName(), templateInfos);
+ } else {
+ return new Answer(cmd, false, "Unsupported image data store: " + store);
+ }
+
+ }
+
+ private Answer execute(SecStorageVMSetupCommand cmd) {
+ if (!_inSystemVM) {
+ return new Answer(cmd, true, null);
+ }
+ boolean success = true;
+ StringBuilder result = new StringBuilder();
+ for (String cidr : cmd.getAllowedInternalSites()) {
+ if (nfsIps.contains(cidr)) {
+ /*
+ * if the internal download ip is the same with secondary
+ * storage ip, adding internal sites will flush ip route to nfs
+ * through storage ip.
+ */
+ continue;
+ }
+ String tmpresult = allowOutgoingOnPrivate(cidr);
+ if (tmpresult != null) {
+ result.append(", ").append(tmpresult);
+ success = false;
+ }
+ }
+ if (success) {
+ if (cmd.getCopyPassword() != null && cmd.getCopyUserName() != null) {
+ String tmpresult = configureAuth(cmd.getCopyUserName(), cmd.getCopyPassword());
+ if (tmpresult != null) {
+ result.append("Failed to configure auth for copy ").append(tmpresult);
+ success = false;
+ }
+ }
+ }
+ return new Answer(cmd, success, result.toString());
+
+ }
+
+ private String deleteLocalFile(String fullPath) {
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("rm -f " + fullPath);
+ String result = command.execute();
+ if (result != null) {
+ String errMsg = "Failed to delete file " + fullPath + ", err=" + result;
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ return null;
+ }
+
+ public String allowOutgoingOnPrivate(String destCidr) {
+ if (!_inSystemVM) {
+ return null;
+ }
+ Script command = new Script("/bin/bash", s_logger);
+ String intf = "eth1";
+ command.add("-c");
+ command.add("iptables -I OUTPUT -o " + intf + " -d " + destCidr + " -p tcp -m state --state NEW -m tcp -j ACCEPT");
+
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in allowing outgoing to " + destCidr + ", err=" + result);
+ return "Error in allowing outgoing to " + destCidr + ", err=" + result;
+ }
+
+ addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, destCidr);
+
+ return null;
+ }
+
+ private Answer execute(SecStorageFirewallCfgCommand cmd) {
+ if (!_inSystemVM) {
+ return new Answer(cmd, true, null);
+ }
+
+ List<String> ipList = new ArrayList<String>();
+
+ for (PortConfig pCfg : cmd.getPortConfigs()) {
+ if (pCfg.isAdd()) {
+ ipList.add(pCfg.getSourceIp());
+ }
+ }
+ boolean success = true;
+ String result;
+ result = configureIpFirewall(ipList, cmd.getIsAppendAIp());
+ if (result != null) {
+ success = false;
+ }
+
+ return new Answer(cmd, success, result);
+ }
+
+ protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
+ DataStoreTO store = cmd.getStore();
+ if (store instanceof S3TO || store instanceof SwiftTO) {
+ long infinity = Integer.MAX_VALUE;
+ return new GetStorageStatsAnswer(cmd, infinity, 0L);
+ }
+
+ String rootDir = getRootDir(((NfsTO)store).getUrl());
+ final long usedSize = getUsedSize(rootDir);
+ final long totalSize = getTotalSize(rootDir);
+ if (usedSize == -1 || totalSize == -1) {
+ return new GetStorageStatsAnswer(cmd, "Unable to get storage stats");
+ } else {
+ return new GetStorageStatsAnswer(cmd, totalSize, usedSize);
+ }
+ }
+
+ protected Answer execute(final DeleteCommand cmd) {
+ DataTO obj = cmd.getData();
+ DataObjectType objType = obj.getObjectType();
+ if (obj.getPath() == null) {
+ // account for those fake entries for NFS migration to object store
+ return new Answer(cmd, true, "Object with null install path does not exist on image store , no need to delete");
+ }
+ switch (objType) {
+ case TEMPLATE:
+ return deleteTemplate(cmd);
+ case VOLUME:
+ return deleteVolume(cmd);
+ case SNAPSHOT:
+ return deleteSnapshot(cmd);
+ }
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+
+ protected Answer deleteTemplate(DeleteCommand cmd) {
+ DataTO obj = cmd.getData();
+ DataStoreTO dstore = obj.getDataStore();
+ if (dstore instanceof NfsTO) {
+ NfsTO nfs = (NfsTO)dstore;
+ String relativeTemplatePath = obj.getPath();
+ String parent = getRootDir(nfs.getUrl());
+
+ if (relativeTemplatePath.startsWith(File.separator)) {
+ relativeTemplatePath = relativeTemplatePath.substring(1);
+ }
+
+ if (!parent.endsWith(File.separator)) {
+ parent += File.separator;
+ }
+ String absoluteTemplatePath = parent + relativeTemplatePath;
+ File tmpltPath = new File(absoluteTemplatePath);
+ File tmpltParent = null;
+ if(tmpltPath.exists() && tmpltPath.isDirectory()) {
+ tmpltParent = tmpltPath;
+ } else {
+ tmpltParent = tmpltPath.getParentFile();
+ }
+
+ String details = null;
+ if (!tmpltParent.exists()) {
+ details = "template parent directory " + tmpltParent.getName() + " doesn't exist";
+ s_logger.debug(details);
+ return new Answer(cmd, true, details);
+ }
+ File[] tmpltFiles = tmpltParent.listFiles();
+ if (tmpltFiles == null || tmpltFiles.length == 0) {
+ details = "No files under template parent directory " + tmpltParent.getName();
+ s_logger.debug(details);
+ } else {
+ boolean found = false;
+ for (File f : tmpltFiles) {
+ if (!found && f.getName().equals("template.properties")) {
+ found = true;
+ }
+
+ // KVM HA monitor makes a mess in the templates with its
+ // heartbeat tests
+ // Don't let this stop us from cleaning up the template
+ if (f.isDirectory() && f.getName().equals("KVMHA")) {
+ s_logger.debug("Deleting KVMHA directory contents from template location");
+ File[] haFiles = f.listFiles();
+ for (File haFile : haFiles) {
+ haFile.delete();
+ }
+ }
+
+ if (!f.delete()) {
+ return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path " + relativeTemplatePath);
+ }
+ }
+
+ if (!found) {
+ details = "Can not find template.properties under " + tmpltParent.getName();
+ s_logger.debug(details);
+ }
+ }
+ if (!tmpltParent.delete()) {
+ details = "Unable to delete directory " + tmpltParent.getName() + " under Template path " + relativeTemplatePath;
+ s_logger.debug(details);
+ return new Answer(cmd, false, details);
+ }
+ return new Answer(cmd, true, null);
+ } else if (dstore instanceof S3TO) {
+ final S3TO s3 = (S3TO)dstore;
+ final String path = obj.getPath();
+ final String bucket = s3.getBucketName();
+ try {
+ S3Utils.deleteDirectory(s3, bucket, path);
+ return new Answer(cmd, true, String.format("Deleted template %1$s from bucket %2$s.", path, bucket));
+ } catch (Exception e) {
+ final String errorMessage =
+ String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
+ s_logger.error(errorMessage, e);
+ return new Answer(cmd, false, errorMessage);
+ }
+ } else if (dstore instanceof SwiftTO) {
+ SwiftTO swift = (SwiftTO)dstore;
+ String container = "T-" + obj.getId();
+ String object = "";
+
+ try {
+ String result = swiftDelete(swift, container, object);
+ if (result != null) {
+ String errMsg = "failed to delete object " + container + "/" + object + " , err=" + result;
+ s_logger.warn(errMsg);
+ return new Answer(cmd, false, errMsg);
+ }
+ return new Answer(cmd, true, "success");
+ } catch (Exception e) {
+ String errMsg = cmd + " Command failed due to " + e.toString();
+ s_logger.warn(errMsg, e);
+ return new Answer(cmd, false, errMsg);
+ }
+ } else {
+ return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+ }
+ }
+
+ protected Answer deleteVolume(final DeleteCommand cmd) {
+ DataTO obj = cmd.getData();
+ DataStoreTO dstore = obj.getDataStore();
+ if (dstore instanceof NfsTO) {
+ NfsTO nfs = (NfsTO)dstore;
+ String relativeVolumePath = obj.getPath();
+ String parent = getRootDir(nfs.getUrl());
+
+ if (relativeVolumePath.startsWith(File.separator)) {
+ relativeVolumePath = relativeVolumePath.substring(1);
+ }
+
+ if (!parent.endsWith(File.separator)) {
+ parent += File.separator;
+ }
+ String absoluteVolumePath = parent + relativeVolumePath;
+ File volPath = new File(absoluteVolumePath);
+ File tmpltParent = null;
+ if (volPath.exists() && volPath.isDirectory()) {
+ // for vmware, absoluteVolumePath represents a directory where volume files are located.
+ tmpltParent = volPath;
+ } else {
+ // for other hypervisors, the volume .vhd or .qcow2 file path is passed
+ tmpltParent = new File(absoluteVolumePath).getParentFile();
+ }
+ String details = null;
+ if (!tmpltParent.exists()) {
+ details = "volume parent directory " + tmpltParent.getName() + " doesn't exist";
+ s_logger.debug(details);
+ return new Answer(cmd, true, details);
+ }
+ File[] tmpltFiles = tmpltParent.listFiles();
+ if (tmpltFiles == null || tmpltFiles.length == 0) {
+ details = "No files under volume parent directory " + tmpltParent.getName();
+ s_logger.debug(details);
+ } else {
+ boolean found = false;
+ for (File f : tmpltFiles) {
+ if (!found && f.getName().equals("volume.properties")) {
+ found = true;
+ }
+
+ // KVM HA monitor makes a mess in the templates with its
+ // heartbeat tests
+ // Don't let this stop us from cleaning up the template
+ if (f.isDirectory() && f.getName().equals("KVMHA")) {
+ s_logger.debug("Deleting KVMHA directory contents from template location");
+ File[] haFiles = f.listFiles();
+ for (File haFile : haFiles) {
+ haFile.delete();
+ }
+ }
+
+ if (!f.delete()) {
+ return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + tmpltParent.getPath());
+ }
+ }
+ if (!found) {
+ details = "Can not find volume.properties under " + tmpltParent.getName();
+ s_logger.debug(details);
+ }
+ }
+ if (!tmpltParent.delete()) {
+ details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " + tmpltParent.getPath();
+ s_logger.debug(details);
+ return new Answer(cmd, false, details);
+ }
+ return new Answer(cmd, true, null);
+ } else if (dstore instanceof S3TO) {
+ final S3TO s3 = (S3TO)dstore;
+ final String path = obj.getPath();
+ final String bucket = s3.getBucketName();
+ try {
+ S3Utils.deleteDirectory(s3, bucket, path);
+ return new Answer(cmd, true, String.format("Deleted volume %1%s from bucket %2$s.", path, bucket));
+ } catch (Exception e) {
+ final String errorMessage = String.format("Failed to delete volume %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
+ s_logger.error(errorMessage, e);
+ return new Answer(cmd, false, errorMessage);
+ }
+ } else if (dstore instanceof SwiftTO) {
+ Long volumeId = obj.getId();
+ String path = obj.getPath();
+ String filename = StringUtils.substringAfterLast(path, "/"); // assuming
+ // that
+ // the
+ // filename
+ // is
+ // the
+ // last
+ // section
+ // in
+ // the
+ // path
+ String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), filename);
+ if (result != null) {
+ String errMsg = "failed to delete volume " + filename + " , err=" + result;
+ s_logger.warn(errMsg);
+ return new Answer(cmd, false, errMsg);
+ }
+ return new Answer(cmd, true, "Deleted volume " + path + " from swift");
+ } else {
+ return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+ }
+
+ }
+
+ @Override
+ synchronized public String getRootDir(String secUrl) {
+ if (!_inSystemVM) {
+ return _parent;
+ }
+ try {
+ URI uri = new URI(secUrl);
+ String dir = mountUri(uri);
+ return _parent + "/" + dir;
+ } catch (Exception e) {
+ String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
+ s_logger.error(msg, e);
+ throw new CloudRuntimeException(msg);
+ }
+ }
+
+ protected long getUsedSize(String rootDir) {
+ return _storage.getUsedSpace(rootDir);
+ }
+
+ protected long getTotalSize(String rootDir) {
+ return _storage.getTotalSpace(rootDir);
+ }
+
+ protected long convertFilesystemSize(final String size) {
+ if (size == null || size.isEmpty()) {
+ return -1;
+ }
+
+ long multiplier = 1;
+ if (size.endsWith("T")) {
+ multiplier = 1024l * 1024l * 1024l * 1024l;
+ } else if (size.endsWith("G")) {
+ multiplier = 1024l * 1024l * 1024l;
+ } else if (size.endsWith("M")) {
+ multiplier = 1024l * 1024l;
+ } else {
+ assert (false) : "Well, I have no idea what this is: " + size;
+ }
+
+ return (long)(Double.parseDouble(size.substring(0, size.length() - 1)) * multiplier);
+ }
+
+ @Override
+ public Type getType() {
+ if (SecondaryStorageVm.Role.templateProcessor.toString().equals(_role)) {
+ return Host.Type.SecondaryStorage;
+ }
+
+ return Host.Type.SecondaryStorageCmdExecutor;
+ }
+
+ @Override
+ public PingCommand getCurrentStatus(final long id) {
+ return new PingStorageCommand(Host.Type.Storage, id, new HashMap<String, Boolean>());
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ _eth1ip = (String)params.get("eth1ip");
+ _eth1mask = (String)params.get("eth1mask");
+ if (_eth1ip != null) { // can only happen inside service vm
+ params.put("private.network.device", "eth1");
+ } else {
+ s_logger.warn("eth1ip parameter has not been configured, assuming that we are not inside a system vm");
+ }
+ String eth2ip = (String)params.get("eth2ip");
+ if (eth2ip != null) {
+ params.put("public.network.device", "eth2");
+ }
+ _publicIp = (String)params.get("eth2ip");
+ _hostname = (String)params.get("name");
+
+ String inSystemVM = (String)params.get("secondary.storage.vm");
+ if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
+ s_logger.debug("conf secondary.storage.vm is true, act as if executing in SSVM");
+ _inSystemVM = true;
+ }
+
+ _storageIp = (String)params.get("storageip");
+ if (_storageIp == null && _inSystemVM) {
+ s_logger.warn("There is no storageip in /proc/cmdline, something wrong!");
+ }
+ _storageNetmask = (String)params.get("storagenetmask");
+ _storageGateway = (String)params.get("storagegateway");
+ super.configure(name, params);
+
+ _params = params;
+ String value = (String)params.get("scripts.timeout");
+ _timeout = NumbersUtil.parseInt(value, 1440) * 1000;
+
+ _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
+ configureStorageLayerClass(params);
+
+ if (_inSystemVM) {
+ _storage.mkdirs(_parent);
+ }
+
+ _configSslScr = Script.findScript(getDefaultScriptsDir(), "config_ssl.sh");
+ if (_configSslScr != null) {
+ s_logger.info("config_ssl.sh found in " + _configSslScr);
+ }
+
+ _configAuthScr = Script.findScript(getDefaultScriptsDir(), "config_auth.sh");
+ if (_configSslScr != null) {
+ s_logger.info("config_auth.sh found in " + _configAuthScr);
+ }
+
+ _configIpFirewallScr = Script.findScript(getDefaultScriptsDir(), "ipfirewall.sh");
+ if (_configIpFirewallScr != null) {
+ s_logger.info("_configIpFirewallScr found in " + _configIpFirewallScr);
+ }
+
+ createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh");
+ if (createTemplateFromSnapshotXenScript == null) {
+ throw new ConfigurationException("create_privatetemplate_from_snapshot_xen.sh not found in " + getDefaultScriptsDir());
+ }
+
+ _role = (String)params.get("role");
+ if (_role == null) {
+ _role = SecondaryStorageVm.Role.templateProcessor.toString();
+ }
+ s_logger.info("Secondary storage runs in role " + _role);
+
+ _guid = (String)params.get("guid");
+ if (_guid == null) {
+ throw new ConfigurationException("Unable to find the guid");
+ }
+
+ _dc = (String)params.get("zone");
+ if (_dc == null) {
+ throw new ConfigurationException("Unable to find the zone");
+ }
+ _pod = (String)params.get("pod");
+
+ _instance = (String)params.get("instance");
+
+ if (!_inSystemVM) {
+ _parent = (String)params.get("mount.path");
+ }
+
+ if (_inSystemVM) {
+ _localgw = (String)params.get("localgw");
+ if (_localgw != null) { // can only happen inside service vm
+ String mgmtHost = (String)params.get("host");
+ addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost);
+
+ String internalDns1 = (String)params.get("internaldns1");
+ if (internalDns1 == null) {
+ s_logger.warn("No DNS entry found during configuration of NfsSecondaryStorage");
+ } else {
+ addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns1);
+ }
+
+ String internalDns2 = (String)params.get("internaldns2");
+ if (internalDns2 != null) {
+ addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns2);
+ }
+
+ }
+
+ startAdditionalServices();
+ _params.put("install.numthreads", "50");
+ _params.put("secondary.storage.vm", "true");
+ }
+
+ try {
+ _params.put(StorageLayer.InstanceConfigKey, _storage);
+ _dlMgr = new DownloadManagerImpl();
+ _dlMgr.configure("DownloadManager", _params);
+ _upldMgr = new UploadManagerImpl();
+ _upldMgr.configure("UploadManager", params);
+ } catch (ConfigurationException e) {
+ s_logger.warn("Caught problem while configuring DownloadManager", e);
+ return false;
+ }
+ return true;
+ }
+
+ protected void configureStorageLayerClass(Map<String, Object> params) throws ConfigurationException {
+ String value;
+ if (_storage == null) {
+ value = (String)params.get(StorageLayer.ClassConfigKey);
+ if (value == null) {
+ value = "com.cloud.storage.JavaStorageLayer";
+ }
+
+ try {
+ Class<?> clazz = Class.forName(value);
+ _storage = (StorageLayer)clazz.newInstance();
+
<TRUNCATED>
[10/11] Moved the controlling logic for secondary storage vm into
place
Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
new file mode 100755
index 0000000..4a59d8f
--- /dev/null
+++ b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
@@ -0,0 +1,1388 @@
+// 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.secondarystorage;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.config.ApiServiceConfiguration;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.SecStorageFirewallCfgCommand;
+import com.cloud.agent.api.SecStorageSetupAnswer;
+import com.cloud.agent.api.SecStorageSetupCommand;
+import com.cloud.agent.api.SecStorageVMSetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupSecondaryStorageCommand;
+import com.cloud.agent.api.check.CheckSshAnswer;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.cluster.ClusterManager;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ZoneConfig;
+import com.cloud.consoleproxy.ConsoleProxyManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.info.RunningHostCountInfo;
+import com.cloud.info.RunningHostInfoAgregator;
+import com.cloud.info.RunningHostInfoAgregator.ZoneHostInfo;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.rules.RulesManager;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.UploadVO;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.UploadDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.secondary.SecStorageVmAlertEventArgs;
+import com.cloud.storage.secondary.SecondaryStorageListener;
+import com.cloud.storage.secondary.SecondaryStorageVmAllocator;
+import com.cloud.storage.secondary.SecondaryStorageVmManager;
+import com.cloud.storage.template.TemplateConstants;
+import com.cloud.template.TemplateManager;
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.events.SubscriptionMgr;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.SecondaryStorageVm;
+import com.cloud.vm.SecondaryStorageVmVO;
+import com.cloud.vm.SystemVmLoadScanHandler;
+import com.cloud.vm.SystemVmLoadScanner;
+import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineGuru;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineName;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.SecondaryStorageVmDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+//
+// Possible secondary storage vm state transition cases
+// Creating -> Destroyed
+// Creating -> Stopped --> Starting -> Running
+// HA -> Stopped -> Starting -> Running
+// Migrating -> Running (if previous state is Running before it enters into Migrating state
+// Migrating -> Stopped (if previous state is not Running before it enters into Migrating state)
+// Running -> HA (if agent lost connection)
+// Stopped -> Destroyed
+//
+// Creating state indicates of record creating and IP address allocation are ready, it is a transient
+// state which will soon be switching towards Running if everything goes well.
+// Stopped state indicates the readiness of being able to start (has storage and IP resources allocated)
+// Starting state can only be entered from Stopped states
+//
+// Starting, HA, Migrating, Creating and Running state are all counted as "Open" for available capacity calculation
+// because sooner or later, it will be driven into Running state
+//
+@Local(value = {SecondaryStorageVmManager.class})
+public class SecondaryStorageManagerImpl extends ManagerBase implements SecondaryStorageVmManager, VirtualMachineGuru, SystemVmLoadScanHandler<Long>,
+ ResourceStateAdapter {
+ private static final Logger s_logger = Logger.getLogger(SecondaryStorageManagerImpl.class);
+
+ private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30
+ // seconds
+ private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC = 180; // 3
+ // minutes
+
+ private static final int STARTUP_DELAY = 60000; // 60 seconds
+
+ private int _mgmtPort = 8250;
+
+ private List<SecondaryStorageVmAllocator> _ssVmAllocators;
+
+ @Inject
+ protected SecondaryStorageVmDao _secStorageVmDao;
+ @Inject
+ private DataCenterDao _dcDao;
+ @Inject
+ private VMTemplateDao _templateDao;
+ @Inject
+ private HostDao _hostDao;
+ @Inject
+ private StoragePoolHostDao _storagePoolHostDao;
+ @Inject
+ private AgentManager _agentMgr;
+ @Inject
+ protected NetworkOrchestrationService _networkMgr;
+ @Inject
+ protected NetworkModel _networkModel;
+ @Inject
+ protected SnapshotDao _snapshotDao;
+ private SecondaryStorageListener _listener;
+
+ private ServiceOfferingVO _serviceOffering;
+
+ @Inject
+ protected ConfigurationDao _configDao;
+ @Inject
+ private ServiceOfferingDao _offeringDao;
+ @Inject
+ private AccountService _accountMgr;
+ @Inject
+ private VirtualMachineManager _itMgr;
+ @Inject
+ protected VMInstanceDao _vmDao;
+ @Inject
+ protected CapacityDao _capacityDao;
+ @Inject
+ UserVmDetailsDao _vmDetailsDao;
+ @Inject
+ protected ResourceManager _resourceMgr;
+ @Inject
+ NetworkDao _networkDao;
+ @Inject
+ NetworkOfferingDao _networkOfferingDao;
+ @Inject
+ protected IPAddressDao _ipAddressDao = null;
+ @Inject
+ protected RulesManager _rulesMgr;
+ @Inject
+ TemplateManager templateMgr;
+ @Inject
+ UploadDao _uploadDao;
+
+ @Inject
+ KeystoreManager _keystoreMgr;
+ @Inject
+ DataStoreManager _dataStoreMgr;
+ @Inject
+ ImageStoreDao _imageStoreDao;
+ @Inject
+ TemplateDataStoreDao _tmplStoreDao;
+ private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL;
+ private int _secStorageVmMtuSize;
+
+ private String _instance;
+ private boolean _useLocalStorage;
+ private boolean _useSSlCopy;
+ private String _httpProxy;
+ private String _allowedInternalSites;
+ protected long _nodeId = ManagementServerNode.getManagementServerId();
+
+ private SystemVmLoadScanner<Long> _loadScanner;
+ private Map<Long, ZoneHostInfo> _zoneHostInfoMap; // map <zone id, info about running host in zone>
+
+ private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName());
+
+ public SecondaryStorageManagerImpl() {
+ }
+
+ @Override
+ public SecondaryStorageVmVO startSecStorageVm(long secStorageVmId) {
+ try {
+ SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
+ _itMgr.advanceStart(secStorageVm.getUuid(), null, null);
+ return _secStorageVmDao.findById(secStorageVm.getId());
+ } catch (StorageUnavailableException e) {
+ s_logger.warn("Exception while trying to start secondary storage vm", e);
+ return null;
+ } catch (InsufficientCapacityException e) {
+ s_logger.warn("Exception while trying to start secondary storage vm", e);
+ return null;
+ } catch (ResourceUnavailableException e) {
+ s_logger.warn("Exception while trying to start secondary storage vm", e);
+ return null;
+ } catch (Exception e) {
+ s_logger.warn("Exception while trying to start secondary storage vm", e);
+ return null;
+ }
+ }
+
+ SecondaryStorageVmVO getSSVMfromHost(HostVO ssAHost) {
+ if (ssAHost.getType() == Host.Type.SecondaryStorageVM) {
+ return _secStorageVmDao.findByInstanceName(ssAHost.getName());
+ }
+ return null;
+ }
+
+ @Override
+ public boolean generateSetupCommand(Long ssHostId) {
+ HostVO cssHost = _hostDao.findById(ssHostId);
+ Long zoneId = cssHost.getDataCenterId();
+ if (cssHost.getType() == Host.Type.SecondaryStorageVM) {
+
+ SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(cssHost.getName());
+ if (secStorageVm == null) {
+ s_logger.warn("secondary storage VM " + cssHost.getName() + " doesn't exist");
+ return false;
+ }
+
+ List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
+ for (DataStore ssStore : ssStores) {
+ if (!(ssStore.getTO() instanceof NfsTO)) {
+ continue; // only do this for Nfs
+ }
+ String secUrl = ssStore.getUri();
+ SecStorageSetupCommand setupCmd = null;
+ if (!_useSSlCopy) {
+ setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, null);
+ } else {
+ KeystoreManager.Certificates certs = _keystoreMgr.getCertificates(ConsoleProxyManager.CERTIFICATE_NAME);
+ setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, certs);
+ }
+
+ Answer answer = _agentMgr.easySend(ssHostId, setupCmd);
+ if (answer != null && answer.getResult()) {
+ SecStorageSetupAnswer an = (SecStorageSetupAnswer)answer;
+ if (an.get_dir() != null) {
+ // update the parent path in image_store table for this image store
+ ImageStoreVO svo = _imageStoreDao.findById(ssStore.getId());
+ svo.setParent(an.get_dir());
+ _imageStoreDao.update(ssStore.getId(), svo);
+ }
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
+ }
+ } else {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
+ }
+ return false;
+ }
+ }
+ }
+ /* After removing SecondaryStorage entries from host table, control should never come here!!
+ else if( cssHost.getType() == Host.Type.SecondaryStorage ) {
+ List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, zoneId, State.Running);
+ String secUrl = cssHost.getStorageUrl();
+ SecStorageSetupCommand setupCmd = new SecStorageSetupCommand(secUrl, null);
+ for ( SecondaryStorageVmVO ssVm : alreadyRunning ) {
+ HostVO host = _resourceMgr.findHostByName(ssVm.getInstanceName());
+ Answer answer = _agentMgr.easySend(host.getId(), setupCmd);
+ if (answer != null && answer.getResult()) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
+ }
+ } else {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
+ }
+ return false;
+ }
+ }
+ }
+ */
+ return true;
+ }
+
+ @Override
+ public boolean generateVMSetupCommand(Long ssAHostId) {
+ HostVO ssAHost = _hostDao.findById(ssAHostId);
+ if (ssAHost.getType() != Host.Type.SecondaryStorageVM) {
+ return false;
+ }
+ SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
+ if (secStorageVm == null) {
+ s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
+ return false;
+ }
+
+ SecStorageVMSetupCommand setupCmd = new SecStorageVMSetupCommand();
+ if (_allowedInternalSites != null) {
+ List<String> allowedCidrs = new ArrayList<String>();
+ String[] cidrs = _allowedInternalSites.split(",");
+ for (String cidr : cidrs) {
+ if (NetUtils.isValidCIDR(cidr) || NetUtils.isValidIp(cidr) || !cidr.startsWith("0.0.0.0")) {
+ allowedCidrs.add(cidr);
+ }
+ }
+ List<? extends Nic> nics = _networkModel.getNicsForTraffic(secStorageVm.getId(), TrafficType.Management);
+ setupCmd.setAllowedInternalSites(allowedCidrs.toArray(new String[allowedCidrs.size()]));
+ }
+ String copyPasswd = _configDao.getValue("secstorage.copy.password");
+ setupCmd.setCopyPassword(copyPasswd);
+ setupCmd.setCopyUserName(TemplateConstants.DEFAULT_HTTP_AUTH_USER);
+ Answer answer = _agentMgr.easySend(ssAHostId, setupCmd);
+ if (answer != null && answer.getResult()) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Successfully programmed http auth into " + secStorageVm.getHostName());
+ }
+ return true;
+ } else {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("failed to program http auth into secondary storage vm : " + secStorageVm.getHostName());
+ }
+ return false;
+ }
+ }
+
+ @Override
+ public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd) {
+ return null;
+ }
+
+ @Override
+ public boolean generateFirewallConfiguration(Long ssAHostId) {
+ if (ssAHostId == null) {
+ return true;
+ }
+ HostVO ssAHost = _hostDao.findById(ssAHostId);
+ SecondaryStorageVmVO thisSecStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
+
+ if (thisSecStorageVm == null) {
+ s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
+ return false;
+ }
+
+ String copyPort = _useSSlCopy ? "443" : Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
+ SecStorageFirewallCfgCommand thiscpc = new SecStorageFirewallCfgCommand(true);
+ thiscpc.addPortConfig(thisSecStorageVm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
+
+ QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+ sc.and(sc.entity().getType(), Op.EQ, Host.Type.SecondaryStorageVM);
+ sc.and(sc.entity().getStatus(), Op.IN, Status.Up, Status.Connecting);
+ List<HostVO> ssvms = sc.list();
+ for (HostVO ssvm : ssvms) {
+ if (ssvm.getId() == ssAHostId) {
+ continue;
+ }
+ Answer answer = _agentMgr.easySend(ssvm.getId(), thiscpc);
+ if (answer != null && answer.getResult()) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Successfully programmed firewall rules into SSVM " + ssvm.getName());
+ }
+ } else {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("failed to program firewall rules into secondary storage vm : " + ssvm.getName());
+ }
+ return false;
+ }
+ }
+
+ SecStorageFirewallCfgCommand allSSVMIpList = new SecStorageFirewallCfgCommand(false);
+ for (HostVO ssvm : ssvms) {
+ if (ssvm.getId() == ssAHostId) {
+ continue;
+ }
+ allSSVMIpList.addPortConfig(ssvm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
+ }
+
+ Answer answer = _agentMgr.easySend(ssAHostId, allSSVMIpList);
+ if (answer != null && answer.getResult()) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Successfully programmed firewall rules into " + thisSecStorageVm.getHostName());
+ }
+ } else {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("failed to program firewall rules into secondary storage vm : " + thisSecStorageVm.getHostName());
+ }
+ return false;
+ }
+
+ return true;
+
+ }
+
+ protected boolean isSecondaryStorageVmRequired(long dcId) {
+ DataCenterVO dc = _dcDao.findById(dcId);
+ _dcDao.loadDetails(dc);
+ String ssvmReq = dc.getDetail(ZoneConfig.EnableSecStorageVm.key());
+ if (ssvmReq != null) {
+ return Boolean.parseBoolean(ssvmReq);
+ }
+ return true;
+ }
+
+ public SecondaryStorageVmVO startNew(long dataCenterId, SecondaryStorageVm.Role role) {
+
+ if (!isSecondaryStorageVmRequired(dataCenterId)) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " acc. to zone config");
+ }
+ return null;
+ }
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Assign secondary storage vm from a newly started instance for request from data center : " + dataCenterId);
+ }
+
+ Map<String, Object> context = createSecStorageVmInstance(dataCenterId, role);
+
+ long secStorageVmId = (Long)context.get("secStorageVmId");
+ if (secStorageVmId == 0) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("Creating secondary storage vm instance failed, data center id : " + dataCenterId);
+ }
+
+ return null;
+ }
+
+ SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
+ // SecondaryStorageVmVO secStorageVm =
+ // allocSecStorageVmStorage(dataCenterId, secStorageVmId);
+ if (secStorageVm != null) {
+ SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
+ new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATED, dataCenterId, secStorageVmId, secStorageVm, null));
+ return secStorageVm;
+ } else {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Unable to allocate secondary storage vm storage, remove the secondary storage vm record from DB, secondary storage vm id: " +
+ secStorageVmId);
+ }
+
+ SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
+ new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATE_FAILURE, dataCenterId, secStorageVmId, null, "Unable to allocate storage"));
+ }
+ return null;
+ }
+
+ protected Map<String, Object> createSecStorageVmInstance(long dataCenterId, SecondaryStorageVm.Role role) {
+ DataStore secStore = _dataStoreMgr.getImageStore(dataCenterId);
+ if (secStore == null) {
+ String msg = "No secondary storage available in zone " + dataCenterId + ", cannot create secondary storage vm";
+ s_logger.warn(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ long id = _secStorageVmDao.getNextInSequence(Long.class, "id");
+ String name = VirtualMachineName.getSystemVmName(id, _instance, "s").intern();
+ Account systemAcct = _accountMgr.getSystemAccount();
+
+ DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
+ DataCenter dc = _dcDao.findById(plan.getDataCenterId());
+
+ NetworkVO defaultNetwork = null;
+ if (dc.getNetworkType() == NetworkType.Advanced && dc.isSecurityGroupEnabled()) {
+ List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dataCenterId);
+ if (networks == null || networks.size() == 0) {
+ throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc);
+ }
+ defaultNetwork = networks.get(0);
+ } else {
+ TrafficType defaultTrafficType = TrafficType.Public;
+
+ if (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()) {
+ defaultTrafficType = TrafficType.Guest;
+ }
+ List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, defaultTrafficType);
+ // api should never allow this situation to happen
+ if (defaultNetworks.size() != 1) {
+ throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
+ }
+ defaultNetwork = defaultNetworks.get(0);
+ }
+
+ List<? extends NetworkOffering> offerings =
+ _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork, NetworkOffering.SystemManagementNetwork,
+ NetworkOffering.SystemStorageNetwork);
+ LinkedHashMap<Network, NicProfile> networks = new LinkedHashMap<Network, NicProfile>(offerings.size() + 1);
+ NicProfile defaultNic = new NicProfile();
+ defaultNic.setDefaultNic(true);
+ defaultNic.setDeviceId(2);
+ try {
+ networks.put(_networkMgr.setupNetwork(systemAcct, _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0),
+ defaultNic);
+ for (NetworkOffering offering : offerings) {
+ networks.put(_networkMgr.setupNetwork(systemAcct, offering, plan, null, null, false).get(0), null);
+ }
+ } catch (ConcurrentOperationException e) {
+ s_logger.info("Unable to setup due to concurrent operation. " + e);
+ return new HashMap<String, Object>();
+ }
+
+ VMTemplateVO template = null;
+ HypervisorType availableHypervisor = _resourceMgr.getAvailableHypervisor(dataCenterId);
+ template = _templateDao.findSystemVMReadyTemplate(dataCenterId, availableHypervisor);
+ if (template == null) {
+ throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId);
+ }
+
+ SecondaryStorageVmVO secStorageVm =
+ new SecondaryStorageVmVO(id, _serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,
+ systemAcct.getDomainId(), systemAcct.getId(), role, _serviceOffering.getOfferHA());
+ secStorageVm.setDynamicallyScalable(template.isDynamicallyScalable());
+ secStorageVm = _secStorageVmDao.persist(secStorageVm);
+ try {
+ _itMgr.allocate(name, template, _serviceOffering, networks, plan, null);
+ secStorageVm = _secStorageVmDao.findById(secStorageVm.getId());
+ } catch (InsufficientCapacityException e) {
+ s_logger.warn("InsufficientCapacity", e);
+ throw new CloudRuntimeException("Insufficient capacity exception", e);
+ }
+
+ Map<String, Object> context = new HashMap<String, Object>();
+ context.put("secStorageVmId", secStorageVm.getId());
+ return context;
+ }
+
+ private SecondaryStorageVmAllocator getCurrentAllocator() {
+
+ // for now, only one adapter is supported
+ if (_ssVmAllocators.size() > 0) {
+ return _ssVmAllocators.get(0);
+ }
+
+ return null;
+ }
+
+ protected String connect(String ipAddress, int port) {
+ return null;
+ }
+
+ public SecondaryStorageVmVO assignSecStorageVmFromRunningPool(long dataCenterId, SecondaryStorageVm.Role role) {
+
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("Assign secondary storage vm from running pool for request from data center : " + dataCenterId);
+ }
+
+ SecondaryStorageVmAllocator allocator = getCurrentAllocator();
+ assert (allocator != null);
+ List<SecondaryStorageVmVO> runningList = _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Running);
+ if (runningList != null && runningList.size() > 0) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("Running secondary storage vm pool size : " + runningList.size());
+ for (SecondaryStorageVmVO secStorageVm : runningList) {
+ s_logger.trace("Running secStorageVm instance : " + secStorageVm.getHostName());
+ }
+ }
+
+ Map<Long, Integer> loadInfo = new HashMap<Long, Integer>();
+
+ return allocator.allocSecondaryStorageVm(runningList, loadInfo, dataCenterId);
+ } else {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("Empty running secStorageVm pool for now in data center : " + dataCenterId);
+ }
+ }
+ return null;
+ }
+
+ public SecondaryStorageVmVO assignSecStorageVmFromStoppedPool(long dataCenterId, SecondaryStorageVm.Role role) {
+ List<SecondaryStorageVmVO> l = _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Starting, State.Stopped, State.Migrating);
+ if (l != null && l.size() > 0) {
+ return l.get(0);
+ }
+
+ return null;
+ }
+
+ private void allocCapacity(long dataCenterId, SecondaryStorageVm.Role role) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("Allocate secondary storage vm standby capacity for data center : " + dataCenterId);
+ }
+
+ if (!isSecondaryStorageVmRequired(dataCenterId)) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " acc. to zone config");
+ }
+ return;
+ }
+
+ boolean secStorageVmFromStoppedPool = false;
+ SecondaryStorageVmVO secStorageVm = assignSecStorageVmFromStoppedPool(dataCenterId, role);
+ if (secStorageVm == null) {
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("No stopped secondary storage vm is available, need to allocate a new secondary storage vm");
+ }
+
+ if (_allocLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
+ try {
+ secStorageVm = startNew(dataCenterId, role);
+ for (UploadVO upload : _uploadDao.listAll()) {
+ _uploadDao.expunge(upload.getId());
+ }
+ } finally {
+ _allocLock.unlock();
+ }
+ } else {
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Unable to acquire synchronization lock to allocate secStorageVm resource for standby capacity, wait for next scan");
+ }
+ return;
+ }
+ } else {
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Found a stopped secondary storage vm, bring it up to running pool. secStorageVm vm id : " + secStorageVm.getId());
+ }
+ secStorageVmFromStoppedPool = true;
+ }
+
+ if (secStorageVm != null) {
+ long secStorageVmId = secStorageVm.getId();
+ GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVmId));
+ try {
+ if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
+ try {
+ secStorageVm = startSecStorageVm(secStorageVmId);
+ } finally {
+ secStorageVmLock.unlock();
+ }
+ } else {
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Unable to acquire synchronization lock to start secStorageVm for standby capacity, secStorageVm vm id : " + secStorageVm.getId());
+ }
+ return;
+ }
+ } finally {
+ secStorageVmLock.releaseRef();
+ }
+
+ if (secStorageVm == null) {
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Unable to start secondary storage vm for standby capacity, secStorageVm vm Id : " + secStorageVmId +
+ ", will recycle it and start a new one");
+ }
+
+ if (secStorageVmFromStoppedPool) {
+ destroySecStorageVm(secStorageVmId);
+ }
+ } else {
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Secondary storage vm " + secStorageVm.getHostName() + " is started");
+ }
+ }
+ }
+ }
+
+ public boolean isZoneReady(Map<Long, ZoneHostInfo> zoneHostInfoMap, long dataCenterId) {
+ ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
+ if (zoneHostInfo != null && (zoneHostInfo.getFlags() & RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK) != 0) {
+ VMTemplateVO template = _templateDao.findSystemVMReadyTemplate(dataCenterId, HypervisorType.Any);
+ if (template == null) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("System vm template is not ready at data center " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
+ }
+ return false;
+ }
+
+ List<DataStore> stores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId));
+ if (stores.size() < 1) {
+ s_logger.debug("No image store added in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
+ return false;
+ }
+
+ DataStore store = templateMgr.getImageStore(dataCenterId, template.getId());
+ if (store == null) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("No secondary storage available in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
+ }
+ return false;
+ }
+
+ List<Pair<Long, Integer>> l = _storagePoolHostDao.getDatacenterStoragePoolHostInfo(dataCenterId, !_useLocalStorage);
+ if (l != null && l.size() > 0 && l.get(0).second().intValue() > 0) {
+ return true;
+ } else {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Primary storage is not ready, wait until it is ready to launch secondary storage vm. dcId: " + dataCenterId +
+ " system.vm.use.local.storage: " + _useLocalStorage +
+ "If you want to use local storage to start ssvm, need to set system.vm.use.local.storage to true");
+ }
+ }
+
+ }
+ return false;
+ }
+
+ private synchronized Map<Long, ZoneHostInfo> getZoneHostInfo() {
+ Date cutTime = DateUtil.currentGMTTime();
+ List<RunningHostCountInfo> l = _hostDao.getRunningHostCounts(new Date(cutTime.getTime() - ClusterManager.HeartbeatThreshold.value()));
+
+ RunningHostInfoAgregator aggregator = new RunningHostInfoAgregator();
+ if (l.size() > 0) {
+ for (RunningHostCountInfo countInfo : l) {
+ aggregator.aggregate(countInfo);
+ }
+ }
+
+ return aggregator.getZoneHostInfoMap();
+ }
+
+ @Override
+ public boolean start() {
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Start secondary storage vm manager");
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ _loadScanner.stop();
+ _allocLock.releaseRef();
+ _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
+ return true;
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Start configuring secondary storage vm manager : " + name);
+ }
+
+ Map<String, String> configs = _configDao.getConfiguration("management-server", params);
+
+ _secStorageVmMtuSize = NumbersUtil.parseInt(configs.get("secstorage.vm.mtu.size"), DEFAULT_SS_VM_MTUSIZE);
+ String useServiceVM = _configDao.getValue("secondary.storage.vm");
+ boolean _useServiceVM = false;
+ if ("true".equalsIgnoreCase(useServiceVM)) {
+ _useServiceVM = true;
+ }
+
+ String sslcopy = _configDao.getValue("secstorage.encrypt.copy");
+ if ("true".equalsIgnoreCase(sslcopy)) {
+ _useSSlCopy = true;
+ }
+
+ _allowedInternalSites = _configDao.getValue("secstorage.allowed.internal.sites");
+
+ String value = configs.get("secstorage.capacityscan.interval");
+ _capacityScanInterval = NumbersUtil.parseLong(value, DEFAULT_CAPACITY_SCAN_INTERVAL);
+
+ _instance = configs.get("instance.name");
+ if (_instance == null) {
+ _instance = "DEFAULT";
+ }
+
+ Map<String, String> agentMgrConfigs = _configDao.getConfiguration("AgentManager", params);
+
+ value = agentMgrConfigs.get("port");
+ _mgmtPort = NumbersUtil.parseInt(value, 8250);
+
+ _listener = new SecondaryStorageListener(this);
+ _agentMgr.registerForHostEvents(_listener, true, false, true);
+
+ _itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this);
+
+ //check if there is a default service offering configured
+ String ssvmSrvcOffIdStr = configs.get(Config.SecondaryStorageServiceOffering.key());
+ if (ssvmSrvcOffIdStr != null) {
+ Long ssvmSrvcOffId = Long.parseLong(ssvmSrvcOffIdStr);
+ _serviceOffering = _offeringDao.findById(ssvmSrvcOffId);
+ if (_serviceOffering == null || !_serviceOffering.getSystemUse()) {
+ String msg = "Can't find system service offering id=" + ssvmSrvcOffId + " for secondary storage vm";
+ s_logger.error(msg);
+ throw new ConfigurationException(msg);
+ }
+ } else {
+ int ramSize = NumbersUtil.parseInt(_configDao.getValue("ssvm.ram.size"), DEFAULT_SS_VM_RAMSIZE);
+ int cpuFreq = NumbersUtil.parseInt(_configDao.getValue("ssvm.cpu.mhz"), DEFAULT_SS_VM_CPUMHZ);
+ _useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key()));
+ _serviceOffering =
+ new ServiceOfferingVO("System Offering For Secondary Storage VM", 1, ramSize, cpuFreq, null, null, false, null, _useLocalStorage, true, null, true,
+ VirtualMachine.Type.SecondaryStorageVm, true);
+ _serviceOffering.setUniqueName(ServiceOffering.ssvmDefaultOffUniqueName);
+ _serviceOffering = _offeringDao.persistSystemServiceOffering(_serviceOffering);
+
+ // this can sometimes happen, if DB is manually or programmatically manipulated
+ if (_serviceOffering == null) {
+ String msg = "Data integrity problem : System Offering For Secondary Storage VM has been removed?";
+ s_logger.error(msg);
+ throw new ConfigurationException(msg);
+ }
+ }
+
+ if (_useServiceVM) {
+ _loadScanner = new SystemVmLoadScanner<Long>(this);
+ _loadScanner.initScan(STARTUP_DELAY, _capacityScanInterval);
+ }
+
+ _httpProxy = configs.get(Config.SecStorageProxy.key());
+ if (_httpProxy != null) {
+ boolean valid = true;
+ String errMsg = null;
+ try {
+ URI uri = new URI(_httpProxy);
+ if (!"http".equalsIgnoreCase(uri.getScheme())) {
+ errMsg = "Only support http proxy";
+ valid = false;
+ } else if (uri.getHost() == null) {
+ errMsg = "host can not be null";
+ valid = false;
+ } else if (uri.getPort() == -1) {
+ _httpProxy = _httpProxy + ":3128";
+ }
+ } catch (URISyntaxException e) {
+ errMsg = e.toString();
+ } finally {
+ if (!valid) {
+ s_logger.debug("ssvm http proxy " + _httpProxy + " is invalid: " + errMsg);
+ throw new ConfigurationException("ssvm http proxy " + _httpProxy + "is invalid: " + errMsg);
+ }
+ }
+ }
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Secondary storage vm Manager is configured.");
+ }
+ _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+ return true;
+ }
+
+ @Override
+ public boolean stopSecStorageVm(long secStorageVmId) {
+ SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
+ if (secStorageVm == null) {
+ String msg = "Stopping secondary storage vm failed: secondary storage vm " + secStorageVmId + " no longer exists";
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug(msg);
+ }
+ return false;
+ }
+ try {
+ if (secStorageVm.getHostId() != null) {
+ GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVm.getId()));
+ try {
+ if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
+ try {
+ _itMgr.stop(secStorageVm.getUuid());
+ return true;
+ } finally {
+ secStorageVmLock.unlock();
+ }
+ } else {
+ String msg = "Unable to acquire secondary storage vm lock : " + secStorageVm.toString();
+ s_logger.debug(msg);
+ return false;
+ }
+ } finally {
+ secStorageVmLock.releaseRef();
+ }
+ }
+
+ // vm was already stopped, return true
+ return true;
+ } catch (ResourceUnavailableException e) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Stopping secondary storage vm " + secStorageVm.getHostName() + " faled : exception " + e.toString());
+ }
+ return false;
+ }
+ }
+
+ @Override
+ public boolean rebootSecStorageVm(long secStorageVmId) {
+ final SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
+
+ if (secStorageVm == null || secStorageVm.getState() == State.Destroyed) {
+ return false;
+ }
+
+ if (secStorageVm.getState() == State.Running && secStorageVm.getHostId() != null) {
+ final RebootCommand cmd = new RebootCommand(secStorageVm.getInstanceName());
+ final Answer answer = _agentMgr.easySend(secStorageVm.getHostId(), cmd);
+
+ if (answer != null && answer.getResult()) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Successfully reboot secondary storage vm " + secStorageVm.getHostName());
+ }
+
+ SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
+ new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_REBOOTED, secStorageVm.getDataCenterId(), secStorageVm.getId(), secStorageVm, null));
+
+ return true;
+ } else {
+ String msg = "Rebooting Secondary Storage VM failed - " + secStorageVm.getHostName();
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug(msg);
+ }
+ return false;
+ }
+ } else {
+ return startSecStorageVm(secStorageVmId) != null;
+ }
+ }
+
+ @Override
+ public boolean destroySecStorageVm(long vmId) {
+ SecondaryStorageVmVO ssvm = _secStorageVmDao.findById(vmId);
+
+ try {
+ _itMgr.expunge(ssvm.getUuid());
+ _secStorageVmDao.remove(ssvm.getId());
+ HostVO host = _hostDao.findByTypeNameAndZoneId(ssvm.getDataCenterId(), ssvm.getHostName(), Host.Type.SecondaryStorageVM);
+ if (host != null) {
+ s_logger.debug("Removing host entry for ssvm id=" + vmId);
+ _hostDao.remove(host.getId());
+ }
+
+ return true;
+ } catch (ResourceUnavailableException e) {
+ s_logger.warn("Unable to expunge " + ssvm, e);
+ return false;
+ }
+ }
+
+ @Override
+ public void onAgentConnect(Long dcId, StartupCommand cmd) {
+ }
+
+ private String getAllocLockName() {
+ // to improve security, it may be better to return a unique mashed
+ // name(for example MD5 hashed)
+ return "secStorageVm.alloc";
+ }
+
+ private String getSecStorageVmLockName(long id) {
+ return "secStorageVm." + id;
+ }
+
+ @Override
+ public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+
+ SecondaryStorageVmVO vm = _secStorageVmDao.findById(profile.getId());
+ Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
+ vm.setDetails(details);
+
+ DataStore secStore = _dataStoreMgr.getImageStore(dest.getDataCenter().getId());
+ assert (secStore != null);
+
+ StringBuilder buf = profile.getBootArgsBuilder();
+ buf.append(" template=domP type=secstorage");
+ buf.append(" host=").append(ApiServiceConfiguration.ManagementHostIPAdr.value());
+ buf.append(" port=").append(_mgmtPort);
+ buf.append(" name=").append(profile.getVirtualMachine().getHostName());
+
+ buf.append(" zone=").append(dest.getDataCenter().getId());
+ buf.append(" pod=").append(dest.getPod().getId());
+
+ buf.append(" guid=").append(profile.getVirtualMachine().getHostName());
+
+ if (_configDao.isPremium()) {
+ s_logger.debug("VmWare hypervisor configured, telling the ssvm to load the PremiumSecondaryStorageResource");
+ buf.append(" resource=com.cloud.storage.resource.PremiumSecondaryStorageResource");
+ } else {
+ buf.append(" resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource");
+ }
+ buf.append(" instance=SecStorage");
+ buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));
+ buf.append(" role=").append(vm.getRole().toString());
+ buf.append(" mtu=").append(_secStorageVmMtuSize);
+
+ boolean externalDhcp = false;
+ String externalDhcpStr = _configDao.getValue("direct.attach.network.externalIpAllocator.enabled");
+ if (externalDhcpStr != null && externalDhcpStr.equalsIgnoreCase("true")) {
+ externalDhcp = true;
+ }
+
+ if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
+ buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
+ }
+
+ for (NicProfile nic : profile.getNics()) {
+ int deviceId = nic.getDeviceId();
+ if (nic.getIp4Address() == null) {
+ buf.append(" eth").append(deviceId).append("mask=").append("0.0.0.0");
+ buf.append(" eth").append(deviceId).append("ip=").append("0.0.0.0");
+ } else {
+ buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address());
+ buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask());
+ }
+
+ if (nic.isDefaultNic()) {
+ buf.append(" gateway=").append(nic.getGateway());
+ }
+ if (nic.getTrafficType() == TrafficType.Management) {
+ String mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key());
+ if (NetUtils.isValidCIDR(mgmt_cidr)) {
+ buf.append(" mgmtcidr=").append(mgmt_cidr);
+ }
+ buf.append(" localgw=").append(dest.getPod().getGateway());
+ buf.append(" private.network.device=").append("eth").append(deviceId);
+ } else if (nic.getTrafficType() == TrafficType.Public) {
+ buf.append(" public.network.device=").append("eth").append(deviceId);
+ } else if (nic.getTrafficType() == TrafficType.Storage) {
+ buf.append(" storageip=").append(nic.getIp4Address());
+ buf.append(" storagenetmask=").append(nic.getNetmask());
+ buf.append(" storagegateway=").append(nic.getGateway());
+ }
+ }
+
+ /* External DHCP mode */
+ if (externalDhcp) {
+ buf.append(" bootproto=dhcp");
+ }
+
+ DataCenterVO dc = _dcDao.findById(profile.getVirtualMachine().getDataCenterId());
+ buf.append(" internaldns1=").append(dc.getInternalDns1());
+ if (dc.getInternalDns2() != null) {
+ buf.append(" internaldns2=").append(dc.getInternalDns2());
+ }
+ buf.append(" dns1=").append(dc.getDns1());
+ if (dc.getDns2() != null) {
+ buf.append(" dns2=").append(dc.getDns2());
+ }
+
+ String bootArgs = buf.toString();
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Boot Args for " + profile + ": " + bootArgs);
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+
+ finalizeCommandsOnStart(cmds, profile);
+
+ SecondaryStorageVmVO secVm = _secStorageVmDao.findById(profile.getId());
+ DataCenter dc = dest.getDataCenter();
+ List<NicProfile> nics = profile.getNics();
+ for (NicProfile nic : nics) {
+ if ((nic.getTrafficType() == TrafficType.Public && dc.getNetworkType() == NetworkType.Advanced) ||
+ (nic.getTrafficType() == TrafficType.Guest && (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()))) {
+ secVm.setPublicIpAddress(nic.getIp4Address());
+ secVm.setPublicNetmask(nic.getNetmask());
+ secVm.setPublicMacAddress(nic.getMacAddress());
+ } else if (nic.getTrafficType() == TrafficType.Management) {
+ secVm.setPrivateIpAddress(nic.getIp4Address());
+ secVm.setPrivateMacAddress(nic.getMacAddress());
+ }
+ }
+ _secStorageVmDao.update(secVm.getId(), secVm);
+ return true;
+ }
+
+ @Override
+ public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
+
+ NicProfile managementNic = null;
+ NicProfile controlNic = null;
+ for (NicProfile nic : profile.getNics()) {
+ if (nic.getTrafficType() == TrafficType.Management) {
+ managementNic = nic;
+ } else if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != null) {
+ controlNic = nic;
+ }
+ }
+
+ if (controlNic == null) {
+ if (managementNic == null) {
+ s_logger.error("Management network doesn't exist for the secondaryStorageVm " + profile.getVirtualMachine());
+ return false;
+ }
+ controlNic = managementNic;
+ }
+
+ // verify ssh access on management nic for system vm running on HyperV
+ if(profile.getHypervisorType() == HypervisorType.Hyperv) {
+ controlNic = managementNic;
+ }
+
+ CheckSshCommand check = new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922);
+ cmds.addCommand("checkSsh", check);
+
+ return true;
+ }
+
+ @Override
+ public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
+ CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
+ if (!answer.getResult()) {
+ s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
+ return false;
+ }
+
+ try {
+ //get system ip and create static nat rule for the vm in case of basic networking with EIP/ELB
+ _rulesMgr.getSystemIpAndEnableStaticNatForVm(profile.getVirtualMachine(), false);
+ IPAddressVO ipaddr = _ipAddressDao.findByAssociatedVmId(profile.getVirtualMachine().getId());
+ if (ipaddr != null && ipaddr.getSystem()) {
+ SecondaryStorageVmVO secVm = _secStorageVmDao.findById(profile.getId());
+ // override SSVM guest IP with EIP, so that download url's with be prepared with EIP
+ secVm.setPublicIpAddress(ipaddr.getAddress().addr());
+ _secStorageVmDao.update(secVm.getId(), secVm);
+ }
+ } catch (Exception ex) {
+ s_logger.warn("Failed to get system ip and enable static nat for the vm " + profile.getVirtualMachine() + " due to exception ", ex);
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
+ //release elastic IP here
+ IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(profile.getId());
+ if (ip != null && ip.getSystem()) {
+ CallContext ctx = CallContext.current();
+ try {
+ _rulesMgr.disableStaticNat(ip.getId(), ctx.getCallingAccount(), ctx.getCallingUserId(), true);
+ } catch (Exception ex) {
+ s_logger.warn("Failed to disable static nat and release system ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ",
+ ex);
+ }
+ }
+ }
+
+ @Override
+ public void finalizeExpunge(VirtualMachine vm) {
+ SecondaryStorageVmVO ssvm = _secStorageVmDao.findByUuid(vm.getUuid());
+
+ ssvm.setPublicIpAddress(null);
+ ssvm.setPublicMacAddress(null);
+ ssvm.setPublicNetmask(null);
+ _secStorageVmDao.update(ssvm.getId(), ssvm);
+ }
+
+ @Override
+ public String getScanHandlerName() {
+ return "secstorage";
+ }
+
+ @Override
+ public boolean canScan() {
+ return true;
+ }
+
+ @Override
+ public void onScanStart() {
+ _zoneHostInfoMap = getZoneHostInfo();
+ }
+
+ @Override
+ public Long[] getScannablePools() {
+ List<DataCenterVO> zones = _dcDao.listEnabledZones();
+
+ Long[] dcIdList = new Long[zones.size()];
+ int i = 0;
+ for (DataCenterVO dc : zones) {
+ dcIdList[i++] = dc.getId();
+ }
+
+ return dcIdList;
+ }
+
+ @Override
+ public boolean isPoolReadyForScan(Long pool) {
+ // pool is at zone basis
+ long dataCenterId = pool.longValue();
+
+ if (!isZoneReady(_zoneHostInfoMap, dataCenterId)) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Zone " + dataCenterId + " is not ready to launch secondary storage VM yet");
+ }
+ return false;
+ }
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Zone " + dataCenterId + " is ready to launch secondary storage VM");
+ }
+ return true;
+ }
+
+ @Override
+ public Pair<AfterScanAction, Object> scanPool(Long pool) {
+ long dataCenterId = pool.longValue();
+
+ List<SecondaryStorageVmVO> ssVms =
+ _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting,
+ State.Stopped, State.Stopping);
+ int vmSize = (ssVms == null) ? 0 : ssVms.size();
+ List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId));
+ int storeSize = (ssStores == null) ? 0 : ssStores.size();
+ if (storeSize > vmSize) {
+ s_logger.info("No secondary storage vms found in datacenter id=" + dataCenterId + ", starting a new one");
+ return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.templateProcessor);
+ }
+
+ return new Pair<AfterScanAction, Object>(AfterScanAction.nop, SecondaryStorageVm.Role.templateProcessor);
+ }
+
+ @Override
+ public void expandPool(Long pool, Object actionArgs) {
+ long dataCenterId = pool.longValue();
+ allocCapacity(dataCenterId, (SecondaryStorageVm.Role)actionArgs);
+ }
+
+ @Override
+ public void shrinkPool(Long pool, Object actionArgs) {
+ }
+
+ @Override
+ public void onScanEnd() {
+ }
+
+ @Override
+ public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
+ /* Called when Secondary Storage VM connected */
+ StartupCommand firstCmd = cmd[0];
+ if (!(firstCmd instanceof StartupSecondaryStorageCommand)) {
+ return null;
+ }
+
+ host.setType(com.cloud.host.Host.Type.SecondaryStorageVM);
+ return host;
+ }
+
+ @Override
+ public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
+ // Used to be Called when add secondary storage on UI through DummySecondaryStorageResource to update that host entry for Secondary Storage.
+ // Now since we move secondary storage from host table, this code is not needed to be invoked anymore.
+ /*
+ StartupCommand firstCmd = startup[0];
+ if (!(firstCmd instanceof StartupStorageCommand)) {
+ return null;
+ }
+
+ com.cloud.host.Host.Type type = null;
+ StartupStorageCommand ssCmd = ((StartupStorageCommand) firstCmd);
+ if (ssCmd.getHostType() == Host.Type.SecondaryStorageCmdExecutor) {
+ type = ssCmd.getHostType();
+ } else {
+ if (ssCmd.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE) {
+ type = Host.Type.SecondaryStorage;
+ if (resource != null && resource instanceof DummySecondaryStorageResource) {
+ host.setResource(null);
+ }
+ } else if (ssCmd.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE) {
+ type = Host.Type.LocalSecondaryStorage;
+ } else {
+ type = Host.Type.Storage;
+ }
+
+ final Map<String, String> hostDetails = ssCmd.getHostDetails();
+ if (hostDetails != null) {
+ if (details != null) {
+ details.putAll(hostDetails);
+ } else {
+ details = hostDetails;
+ }
+ }
+
+ host.setDetails(details);
+ host.setParent(ssCmd.getParent());
+ host.setTotalSize(ssCmd.getTotalSize());
+ host.setHypervisorType(HypervisorType.None);
+ host.setType(type);
+ if (ssCmd.getNfsShare() != null) {
+ host.setStorageUrl(ssCmd.getNfsShare());
+ }
+ }
+ */
+ return null; // no need to handle this event anymore since secondary storage is not in host table anymore.
+ }
+
+ @Override
+ public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+ // Since secondary storage is moved out of host table, this class should not handle delete secondary storage anymore.
+ return null;
+ }
+
+ @Override
+ public List<HostVO> listUpAndConnectingSecondaryStorageVmHost(Long dcId) {
+ QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+ if (dcId != null) {
+ sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+ }
+ sc.and(sc.entity().getState(), Op.IN, Status.Up, Status.Connecting);
+ sc.and(sc.entity().getType(), Op.EQ, Host.Type.SecondaryStorageVM);
+ return sc.list();
+ }
+
+ @Override
+ public HostVO pickSsvmHost(HostVO ssHost) {
+ if (ssHost.getType() == Host.Type.LocalSecondaryStorage) {
+ return ssHost;
+ } else if (ssHost.getType() == Host.Type.SecondaryStorage) {
+ Long dcId = ssHost.getDataCenterId();
+ List<HostVO> ssAHosts = listUpAndConnectingSecondaryStorageVmHost(dcId);
+ if (ssAHosts == null || ssAHosts.isEmpty()) {
+ return null;
+ }
+ Collections.shuffle(ssAHosts);
+ return ssAHosts.get(0);
+ }
+ return null;
+ }
+
+ @Override
+ public void prepareStop(VirtualMachineProfile profile) {
+
+ }
+
+ public List<SecondaryStorageVmAllocator> getSecondaryStorageVmAllocators() {
+ return _ssVmAllocators;
+ }
+
+ @Inject
+ public void setSecondaryStorageVmAllocators(List<SecondaryStorageVmAllocator> ssVmAllocators) {
+ _ssVmAllocators = ssVmAllocators;
+ }
+}
[03/11] Moved the secondary storage service into its own server
directory
Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
deleted file mode 100755
index 9782c2e..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ /dev/null
@@ -1,2430 +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 org.apache.cloudstack.storage.resource;
-
-import static com.cloud.utils.S3Utils.mputFile;
-import static com.cloud.utils.S3Utils.putFile;
-import static com.cloud.utils.StringUtils.join;
-import static java.lang.String.format;
-import static java.util.Arrays.asList;
-import static org.apache.commons.lang.StringUtils.substringAfterLast;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.UnknownHostException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.utils.URLEncodedUtils;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.log4j.Logger;
-
-import com.amazonaws.services.s3.model.S3ObjectSummary;
-
-import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.command.DownloadProgressCommand;
-import org.apache.cloudstack.storage.template.DownloadManager;
-import org.apache.cloudstack.storage.template.DownloadManagerImpl;
-import org.apache.cloudstack.storage.template.DownloadManagerImpl.ZfsPathParser;
-import org.apache.cloudstack.storage.template.UploadManager;
-import org.apache.cloudstack.storage.template.UploadManagerImpl;
-import org.apache.cloudstack.storage.to.SnapshotObjectTO;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-
-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.DeleteSnapshotsDirCommand;
-import com.cloud.agent.api.GetStorageStatsAnswer;
-import com.cloud.agent.api.GetStorageStatsCommand;
-import com.cloud.agent.api.PingCommand;
-import com.cloud.agent.api.PingStorageCommand;
-import com.cloud.agent.api.ReadyAnswer;
-import com.cloud.agent.api.ReadyCommand;
-import com.cloud.agent.api.SecStorageFirewallCfgCommand;
-import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
-import com.cloud.agent.api.SecStorageSetupAnswer;
-import com.cloud.agent.api.SecStorageSetupCommand;
-import com.cloud.agent.api.SecStorageVMSetupCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupSecondaryStorageCommand;
-import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.storage.ListTemplateAnswer;
-import com.cloud.agent.api.storage.ListTemplateCommand;
-import com.cloud.agent.api.storage.ListVolumeAnswer;
-import com.cloud.agent.api.storage.ListVolumeCommand;
-import com.cloud.agent.api.storage.UploadCommand;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.S3TO;
-import com.cloud.agent.api.to.SwiftTO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ServerResourceBase;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.template.OVAProcessor;
-import com.cloud.storage.template.Processor;
-import com.cloud.storage.template.Processor.FormatInfo;
-import com.cloud.storage.template.QCOW2Processor;
-import com.cloud.storage.template.RawImageProcessor;
-import com.cloud.storage.template.TemplateLocation;
-import com.cloud.storage.template.TemplateProp;
-import com.cloud.storage.template.VhdProcessor;
-import com.cloud.storage.template.VmdkProcessor;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.S3Utils;
-import com.cloud.utils.S3Utils.FileNamingStrategy;
-import com.cloud.utils.SwiftUtil;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.script.OutputInterpreter;
-import com.cloud.utils.script.Script;
-import com.cloud.vm.SecondaryStorageVm;
-
-public class NfsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
-
- private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class);
-
- private static final String TEMPLATE_ROOT_DIR = "template/tmpl";
- private static final String VOLUME_ROOT_DIR = "volumes";
-
- int _timeout;
-
- public int getTimeout() {
- return _timeout;
- }
-
- public void setTimeout(int timeout) {
- _timeout = timeout;
- }
-
- String _instance;
- String _dc;
- String _pod;
- String _guid;
- String _role;
- Map<String, Object> _params;
- protected StorageLayer _storage;
- protected boolean _inSystemVM = false;
- boolean _sslCopy = false;
-
- protected DownloadManager _dlMgr;
- protected UploadManager _upldMgr;
- private String _configSslScr;
- private String _configAuthScr;
- private String _configIpFirewallScr;
- private String _publicIp;
- private String _hostname;
- private String _localgw;
- private String _eth1mask;
- private String _eth1ip;
- private String _storageIp;
- private String _storageNetmask;
- private String _storageGateway;
- private final List<String> nfsIps = new ArrayList<String>();
- protected String _parent = "/mnt/SecStorage";
- final private String _tmpltpp = "template.properties";
- protected String createTemplateFromSnapshotXenScript;
-
- public void setParentPath(String path) {
- _parent = path;
- }
-
- public String getMountingRoot() {
- return _parent;
- }
-
- @Override
- public void disconnected() {
- }
-
- public void setInSystemVM(boolean inSystemVM) {
- _inSystemVM = inSystemVM;
- }
-
- @Override
- public Answer executeRequest(Command cmd) {
- if (cmd instanceof DownloadProgressCommand) {
- return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
- } else if (cmd instanceof DownloadCommand) {
- return execute((DownloadCommand)cmd);
- } else if (cmd instanceof UploadCommand) {
- return _upldMgr.handleUploadCommand(this, (UploadCommand)cmd);
- } else if (cmd instanceof CreateEntityDownloadURLCommand) {
- return _upldMgr.handleCreateEntityURLCommand((CreateEntityDownloadURLCommand)cmd);
- } else if (cmd instanceof DeleteEntityDownloadURLCommand) {
- return _upldMgr.handleDeleteEntityDownloadURLCommand((DeleteEntityDownloadURLCommand)cmd);
- } else if (cmd instanceof GetStorageStatsCommand) {
- return execute((GetStorageStatsCommand)cmd);
- } else if (cmd instanceof CheckHealthCommand) {
- return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
- } else if (cmd instanceof ReadyCommand) {
- return new ReadyAnswer((ReadyCommand)cmd);
- } else if (cmd instanceof SecStorageFirewallCfgCommand) {
- return execute((SecStorageFirewallCfgCommand)cmd);
- } else if (cmd instanceof SecStorageVMSetupCommand) {
- return execute((SecStorageVMSetupCommand)cmd);
- } else if (cmd instanceof SecStorageSetupCommand) {
- return execute((SecStorageSetupCommand)cmd);
- } else if (cmd instanceof ComputeChecksumCommand) {
- return execute((ComputeChecksumCommand)cmd);
- } else if (cmd instanceof ListTemplateCommand) {
- return execute((ListTemplateCommand)cmd);
- } else if (cmd instanceof ListVolumeCommand) {
- return execute((ListVolumeCommand)cmd);
- } else if (cmd instanceof DeleteSnapshotsDirCommand) {
- return execute((DeleteSnapshotsDirCommand)cmd);
- } else if (cmd instanceof CopyCommand) {
- return execute((CopyCommand)cmd);
- } else if (cmd instanceof DeleteCommand) {
- return execute((DeleteCommand)cmd);
- } else {
- return Answer.createUnsupportedCommandAnswer(cmd);
- }
- }
-
- protected CopyCmdAnswer postProcessing(File destFile, String downloadPath, String destPath, DataTO srcData, DataTO destData) throws ConfigurationException {
- if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
- SnapshotObjectTO snapshot = new SnapshotObjectTO();
- snapshot.setPath(destPath + File.separator + destFile.getName());
-
- CopyCmdAnswer answer = new CopyCmdAnswer(snapshot);
- return answer;
- }
- // do post processing to unzip the file if it is compressed
- String scriptsDir = "scripts/storage/secondary";
- String createTmpltScr = Script.findScript(scriptsDir, "createtmplt.sh");
- if (createTmpltScr == null) {
- throw new ConfigurationException("Unable to find createtmplt.sh");
- }
- s_logger.info("createtmplt.sh found in " + createTmpltScr);
- String createVolScr = Script.findScript(scriptsDir, "createvolume.sh");
- if (createVolScr == null) {
- throw new ConfigurationException("Unable to find createvolume.sh");
- }
- s_logger.info("createvolume.sh found in " + createVolScr);
- String script = srcData.getObjectType() == DataObjectType.TEMPLATE ? createTmpltScr : createVolScr;
-
- int installTimeoutPerGig = 180 * 60 * 1000;
- long imgSizeGigs = (long)Math.ceil(destFile.length() * 1.0d / (1024 * 1024 * 1024));
- imgSizeGigs++; // add one just in case
- long timeout = imgSizeGigs * installTimeoutPerGig;
-
- String origPath = destFile.getAbsolutePath();
- String extension = null;
- if (srcData.getObjectType() == DataObjectType.TEMPLATE) {
- extension = ((TemplateObjectTO)srcData).getFormat().getFileExtension();
- } else if (srcData.getObjectType() == DataObjectType.VOLUME) {
- extension = ((VolumeObjectTO)srcData).getFormat().getFileExtension();
- }
-
- String templateName = UUID.randomUUID().toString();
- String templateFilename = templateName + "." + extension;
- Script scr = new Script(script, timeout, s_logger);
- scr.add("-s", Long.toString(imgSizeGigs)); // not used for now
- scr.add("-n", templateFilename);
-
- scr.add("-t", downloadPath);
- scr.add("-f", origPath); // this is the temporary
- // template file downloaded
- String result;
- result = scr.execute();
-
- if (result != null) {
- // script execution failure
- throw new CloudRuntimeException("Failed to run script " + script);
- }
-
- String finalFileName = templateFilename;
- String finalDownloadPath = destPath + File.separator + templateFilename;
- // compute the size of
- long size = _storage.getSize(downloadPath + File.separator + templateFilename);
-
- DataTO newDestTO = null;
-
- if (destData.getObjectType() == DataObjectType.TEMPLATE) {
- TemplateObjectTO newTemplTO = new TemplateObjectTO();
- newTemplTO.setPath(finalDownloadPath);
- newTemplTO.setName(finalFileName);
- newTemplTO.setSize(size);
- newTemplTO.setPhysicalSize(size);
- newDestTO = newTemplTO;
- } else {
- VolumeObjectTO newVolTO = new VolumeObjectTO();
- newVolTO.setPath(finalDownloadPath);
- newVolTO.setName(finalFileName);
- newVolTO.setSize(size);
- newDestTO = newVolTO;
- }
-
- return new CopyCmdAnswer(newDestTO);
- }
-
- protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO swiftTO, DataTO destData, NfsTO destImageStore) {
- final String storagePath = destImageStore.getUrl();
- final String destPath = destData.getPath();
- try {
- String downloadPath = determineStorageTemplatePath(storagePath, destPath);
- final File downloadDirectory = _storage.getFile(downloadPath);
- if (!downloadDirectory.mkdirs()) {
- return new CopyCmdAnswer("Failed to create download directory " + downloadPath);
- }
- File destFile = SwiftUtil.getObject(swiftTO, downloadDirectory, srcData.getPath());
- return postProcessing(destFile, downloadPath, destPath, srcData, destData);
- } catch (Exception e) {
- s_logger.debug("Failed to copy swift to nfs", e);
- return new CopyCmdAnswer(e.toString());
- }
- }
-
- protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) {
- final String storagePath = destImageStore.getUrl();
- final String destPath = destData.getPath();
-
- try {
-
- String downloadPath = determineStorageTemplatePath(storagePath, destPath);
- final File downloadDirectory = _storage.getFile(downloadPath);
-
- if (!downloadDirectory.mkdirs()) {
- final String errMsg = "Unable to create directory " + downloadPath + " to copy from S3 to cache.";
- s_logger.error(errMsg);
- return new CopyCmdAnswer(errMsg);
- } else {
- s_logger.debug("Directory " + downloadPath + " already exists");
- }
-
- File destFile = S3Utils.getFile(s3, s3.getBucketName(), srcData.getPath(), downloadDirectory, new FileNamingStrategy() {
- @Override
- public String determineFileName(final String key) {
- return substringAfterLast(key, S3Utils.SEPARATOR);
- }
- });
-
- if (destFile == null) {
- return new CopyCmdAnswer("Can't find template");
- }
-
- return postProcessing(destFile, downloadPath, destPath, srcData, destData);
- } catch (Exception e) {
-
- final String errMsg = format("Failed to download" + "due to $2%s", e.getMessage());
- s_logger.error(errMsg, e);
- return new CopyCmdAnswer(errMsg);
- }
- }
-
- protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData,
- NfsTO destDataStore) {
- String srcMountPoint = getRootDir(srcDataStore.getUrl());
- String snapshotPath = srcData.getPath();
- int index = snapshotPath.lastIndexOf("/");
- String snapshotName = snapshotPath.substring(index + 1);
- if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) {
- snapshotName = snapshotName + ".vhd";
- }
- snapshotPath = snapshotPath.substring(0, index);
-
- snapshotPath = srcMountPoint + File.separator + snapshotPath;
- String destMountPoint = getRootDir(destDataStore.getUrl());
- String destPath = destMountPoint + File.separator + destData.getPath();
-
- String errMsg = null;
- try {
- _storage.mkdir(destPath);
-
- String templateUuid = UUID.randomUUID().toString();
- String templateName = templateUuid + ".vhd";
- Script command = new Script(createTemplateFromSnapshotXenScript, cmd.getWait() * 1000, s_logger);
- command.add("-p", snapshotPath);
- command.add("-s", snapshotName);
- command.add("-n", templateName);
- command.add("-t", destPath);
- String result = command.execute();
-
- if (result != null && !result.equalsIgnoreCase("")) {
- return new CopyCmdAnswer(result);
- }
-
- Map<String, Object> params = new HashMap<String, Object>();
- params.put(StorageLayer.InstanceConfigKey, _storage);
- Processor processor = new VhdProcessor();
-
- processor.configure("Vhd Processor", params);
- FormatInfo info = processor.process(destPath, null, templateUuid);
-
- TemplateLocation loc = new TemplateLocation(_storage, destPath);
- loc.create(1, true, templateUuid);
- loc.addFormat(info);
- loc.save();
- TemplateProp prop = loc.getTemplateInfo();
- TemplateObjectTO newTemplate = new TemplateObjectTO();
- newTemplate.setPath(destData.getPath() + File.separator + templateName);
- newTemplate.setFormat(ImageFormat.VHD);
- newTemplate.setSize(prop.getSize());
- newTemplate.setPhysicalSize(prop.getPhysicalSize());
- newTemplate.setName(templateUuid);
- return new CopyCmdAnswer(newTemplate);
- } catch (ConfigurationException e) {
- s_logger.debug("Failed to create template from snapshot: " + e.toString());
- errMsg = e.toString();
- } catch (InternalErrorException e) {
- s_logger.debug("Failed to create template from snapshot: " + e.toString());
- errMsg = e.toString();
- } catch (IOException e) {
- s_logger.debug("Failed to create template from snapshot: " + e.toString());
- errMsg = e.toString();
- }
-
- return new CopyCmdAnswer(errMsg);
- }
-
- protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) {
-
- if (srcData.getHypervisorType() == HypervisorType.XenServer) {
- return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore);
- } else if (srcData.getHypervisorType() == HypervisorType.KVM) {
- File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl());
- File destFile = getFile(destData.getPath(), destDataStore.getUrl());
-
- VolumeObjectTO volumeObjectTO = srcData.getVolume();
- ImageFormat srcFormat = null;
- //TODO: the image format should be stored in snapshot table, instead of getting from volume
- if (volumeObjectTO != null) {
- srcFormat = volumeObjectTO.getFormat();
- } else {
- srcFormat = ImageFormat.QCOW2;
- }
-
- // get snapshot file name
- String templateName = srcFile.getName();
- // add kvm file extension for copied template name
- String fileName = templateName + "." + srcFormat.getFileExtension();
- String destFileFullPath = destFile.getAbsolutePath() + File.separator + fileName;
- s_logger.debug("copy snapshot " + srcFile.getAbsolutePath() + " to template " + destFileFullPath);
- Script.runSimpleBashScript("cp " + srcFile.getAbsolutePath() + " " + destFileFullPath);
- try {
- // generate template.properties file
- String metaFileName = destFile.getAbsolutePath() + File.separator + "template.properties";
- _storage.create(destFile.getAbsolutePath(), "template.properties");
- File metaFile = new File(metaFileName);
- FileWriter writer = new FileWriter(metaFile);
- BufferedWriter bufferWriter = new BufferedWriter(writer);
- // KVM didn't change template unique name, just used the template name passed from orchestration layer, so no need
- // to send template name back.
- bufferWriter.write("uniquename=" + destData.getName());
- bufferWriter.write("\n");
- bufferWriter.write("filename=" + fileName);
- bufferWriter.write("\n");
- long size = _storage.getSize(destFileFullPath);
- bufferWriter.write("size=" + size);
- bufferWriter.close();
- writer.close();
-
- /**
- * Snapshots might be in either QCOW2 or RAW image format
- *
- * For example RBD snapshots are in RAW format
- */
- Processor processor = null;
- if (srcFormat == ImageFormat.QCOW2) {
- processor = new QCOW2Processor();
- } else if (srcFormat == ImageFormat.RAW) {
- processor = new RawImageProcessor();
- } else {
- throw new ConfigurationException("Unknown image format " + srcFormat.toString());
- }
-
- Map<String, Object> params = new HashMap<String, Object>();
- params.put(StorageLayer.InstanceConfigKey, _storage);
-
- processor.configure("template processor", params);
- String destPath = destFile.getAbsolutePath();
-
- FormatInfo info = processor.process(destPath, null, templateName);
- TemplateLocation loc = new TemplateLocation(_storage, destPath);
- loc.create(1, true, destData.getName());
- loc.addFormat(info);
- loc.save();
-
- TemplateProp prop = loc.getTemplateInfo();
- TemplateObjectTO newTemplate = new TemplateObjectTO();
- newTemplate.setPath(destData.getPath() + File.separator + fileName);
- newTemplate.setFormat(srcFormat);
- newTemplate.setSize(prop.getSize());
- newTemplate.setPhysicalSize(prop.getPhysicalSize());
- return new CopyCmdAnswer(newTemplate);
- } catch (ConfigurationException e) {
- s_logger.debug("Failed to create template:" + e.toString());
- return new CopyCmdAnswer(e.toString());
- } catch (IOException e) {
- s_logger.debug("Failed to create template:" + e.toString());
- return new CopyCmdAnswer(e.toString());
- } catch (InternalErrorException e) {
- s_logger.debug("Failed to create template:" + e.toString());
- return new CopyCmdAnswer(e.toString());
- }
- }
-
- return new CopyCmdAnswer("");
- }
-
- protected File getFile(String path, String nfsPath) {
- String filePath = getRootDir(nfsPath) + File.separator + path;
- File f = new File(filePath);
- if (!f.exists()) {
- _storage.mkdirs(filePath);
- f = new File(filePath);
- }
- return f;
- }
-
- protected Answer createTemplateFromSnapshot(CopyCommand cmd) {
- DataTO srcData = cmd.getSrcTO();
- DataTO destData = cmd.getDestTO();
- DataStoreTO srcDataStore = srcData.getDataStore();
- DataStoreTO destDataStore = destData.getDataStore();
- if (srcDataStore.getRole() == DataStoreRole.Image || srcDataStore.getRole() == DataStoreRole.ImageCache || srcDataStore.getRole() == DataStoreRole.Primary) {
- if (!(srcDataStore instanceof NfsTO)) {
- s_logger.debug("only support nfs storage as src, when create template from snapshot");
- return Answer.createUnsupportedCommandAnswer(cmd);
- }
-
- if (destDataStore instanceof NfsTO) {
- return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, (NfsTO)destDataStore);
- } else if (destDataStore instanceof SwiftTO) {
- //create template on the same data store
- CopyCmdAnswer answer =
- (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData,
- (NfsTO)srcDataStore);
- if (!answer.getResult()) {
- return answer;
- }
- s_logger.debug("starting copy template to swift");
- DataTO newTemplate = answer.getNewData();
- File templateFile = getFile(newTemplate.getPath(), ((NfsTO)srcDataStore).getUrl());
- SwiftTO swift = (SwiftTO)destDataStore;
- String containterName = SwiftUtil.getContainerName(destData.getObjectType().toString(), destData.getId());
- String swiftPath = SwiftUtil.putObject(swift, templateFile, containterName, templateFile.getName());
- //upload template.properties
- File properties = new File(templateFile.getParent() + File.separator + _tmpltpp);
- if (properties.exists()) {
- SwiftUtil.putObject(swift, properties, containterName, _tmpltpp);
- }
-
- //clean up template data on staging area
- try {
- DeleteCommand deleteCommand = new DeleteCommand(newTemplate);
- execute(deleteCommand);
- } catch (Exception e) {
- s_logger.debug("Failed to clean up staging area:", e);
- }
-
- TemplateObjectTO template = new TemplateObjectTO();
- template.setPath(swiftPath);
- template.setSize(templateFile.length());
- template.setPhysicalSize(template.getSize());
- SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
- template.setFormat(snapshot.getVolume().getFormat());
- return new CopyCmdAnswer(template);
- } else if (destDataStore instanceof S3TO) {
- //create template on the same data store
- CopyCmdAnswer answer =
- (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData,
- (NfsTO)srcDataStore);
- if (!answer.getResult()) {
- return answer;
- }
- TemplateObjectTO newTemplate = (TemplateObjectTO)answer.getNewData();
- newTemplate.setDataStore(srcDataStore);
- CopyCommand newCpyCmd = new CopyCommand(newTemplate, destData, cmd.getWait(), cmd.executeInSequence());
- Answer result = copyFromNfsToS3(newCpyCmd);
- //clean up template data on staging area
- try {
- DeleteCommand deleteCommand = new DeleteCommand(newTemplate);
- execute(deleteCommand);
- } catch (Exception e) {
- s_logger.debug("Failed to clean up staging area:", e);
- }
- return result;
- }
- }
- s_logger.debug("Failed to create templat from snapshot");
- return new CopyCmdAnswer("Unsupported prototcol");
- }
-
- protected Answer copyFromNfsToImage(CopyCommand cmd) {
- DataTO destData = cmd.getDestTO();
- DataStoreTO destDataStore = destData.getDataStore();
-
- if (destDataStore instanceof S3TO) {
- return copyFromNfsToS3(cmd);
- } else {
- return new CopyCmdAnswer("unsupported ");
- }
- }
-
- protected Answer execute(CopyCommand cmd) {
- DataTO srcData = cmd.getSrcTO();
- DataTO destData = cmd.getDestTO();
- DataStoreTO srcDataStore = srcData.getDataStore();
- DataStoreTO destDataStore = destData.getDataStore();
-
- if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
- return createTemplateFromSnapshot(cmd);
- }
-
- if (destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache) {
- NfsTO destImageStore = (NfsTO)destDataStore;
- if (srcDataStore instanceof S3TO) {
- S3TO s3 = (S3TO)srcDataStore;
- return copyFromS3ToNfs(cmd, srcData, s3, destData, destImageStore);
- } else if (srcDataStore instanceof SwiftTO) {
- return copyFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, destData, destImageStore);
- }
- }
-
- if (srcDataStore.getRole() == DataStoreRole.ImageCache && destDataStore.getRole() == DataStoreRole.Image) {
- return copyFromNfsToImage(cmd);
- }
-
- return Answer.createUnsupportedCommandAnswer(cmd);
- }
-
- @SuppressWarnings("unchecked")
- protected String determineS3TemplateDirectory(final Long accountId, final Long templateId, final String templateUniqueName) {
- return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId, templateUniqueName), S3Utils.SEPARATOR);
- }
-
- private String determineS3TemplateNameFromKey(String key) {
- return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR);
- }
-
- @SuppressWarnings("unchecked")
- protected String determineS3VolumeDirectory(final Long accountId, final Long volId) {
- return join(asList(VOLUME_ROOT_DIR, accountId, volId), S3Utils.SEPARATOR);
- }
-
- protected Long determineS3VolumeIdFromKey(String key) {
- return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR));
- }
-
- private String determineStorageTemplatePath(final String storagePath, String dataPath) {
- return join(asList(getRootDir(storagePath), dataPath), File.separator);
- }
-
- protected File downloadFromUrlToNfs(String url, NfsTO nfs, String path, String name) {
- HttpClient client = new DefaultHttpClient();
- HttpGet get = new HttpGet(url);
- try {
- HttpResponse response = client.execute(get);
- HttpEntity entity = response.getEntity();
- if (entity == null) {
- s_logger.debug("Faled to get entity");
- throw new CloudRuntimeException("Failed to get url: " + url);
- }
-
- String nfsMountPath = getRootDir(nfs.getUrl());
-
- String filePath = nfsMountPath + File.separator + path;
- File directory = new File(filePath);
- if (!directory.exists()) {
- _storage.mkdirs(filePath);
- }
- File destFile = new File(filePath + File.separator + name);
- if (!destFile.createNewFile()) {
- s_logger.warn("Reusing existing file " + destFile.getPath());
- }
- FileOutputStream outputStream = new FileOutputStream(destFile);
- entity.writeTo(outputStream);
- return new File(destFile.getAbsolutePath());
- } catch (IOException e) {
- s_logger.debug("Faild to get url:" + url + ", due to " + e.toString());
- throw new CloudRuntimeException(e);
- }
- }
-
- protected Answer registerTemplateOnSwift(DownloadCommand cmd) {
- SwiftTO swiftTO = (SwiftTO)cmd.getDataStore();
- String path = cmd.getInstallPath();
- DataStoreTO cacheStore = cmd.getCacheStore();
- if (cacheStore == null || !(cacheStore instanceof NfsTO)) {
- return new DownloadAnswer("cache store can't be null", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
- }
-
- File file = null;
- try {
- NfsTO nfsCacheStore = (NfsTO)cacheStore;
- String fileName = cmd.getName() + "." + cmd.getFormat().getFileExtension();
- file = downloadFromUrlToNfs(cmd.getUrl(), nfsCacheStore, path, fileName);
- String container = "T-" + cmd.getId();
- String swiftPath = SwiftUtil.putObject(swiftTO, file, container, null);
-
- //put metda file
- File uniqDir = _storage.createUniqDir();
- String metaFileName = uniqDir.getAbsolutePath() + File.separator + "template.properties";
- _storage.create(uniqDir.getAbsolutePath(), "template.properties");
- File metaFile = new File(metaFileName);
- FileWriter writer = new FileWriter(metaFile);
- BufferedWriter bufferWriter = new BufferedWriter(writer);
- bufferWriter.write("uniquename=" + cmd.getName());
- bufferWriter.write("\n");
- bufferWriter.write("filename=" + fileName);
- bufferWriter.write("\n");
- bufferWriter.write("size=" + file.length());
- bufferWriter.close();
- writer.close();
-
- SwiftUtil.putObject(swiftTO, metaFile, container, "template.properties");
- metaFile.delete();
- uniqDir.delete();
- String md5sum = null;
- try {
- md5sum = DigestUtils.md5Hex(new FileInputStream(file));
- } catch (IOException e) {
- s_logger.debug("Failed to get md5sum: " + file.getAbsoluteFile());
- }
-
- DownloadAnswer answer =
- new DownloadAnswer(null, 100, null, VMTemplateStorageResourceAssoc.Status.DOWNLOADED, swiftPath, swiftPath, file.length(), file.length(), md5sum);
- return answer;
- } catch (IOException e) {
- s_logger.debug("Failed to register template into swift", e);
- return new DownloadAnswer(e.toString(), VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
- } finally {
- if (file != null) {
- file.delete();
- }
- }
- }
-
- private Answer execute(DownloadCommand cmd) {
- DataStoreTO dstore = cmd.getDataStore();
- if (dstore instanceof NfsTO || dstore instanceof S3TO) {
- return _dlMgr.handleDownloadCommand(this, cmd);
- } else if (dstore instanceof SwiftTO) {
- return registerTemplateOnSwift(cmd);
- } else {
- return new Answer(cmd, false, "Unsupported image data store: " + dstore);
- }
-
- }
-
- private ImageFormat getTemplateFormat(String filePath) {
- String ext = null;
- int extensionPos = filePath.lastIndexOf('.');
- int lastSeparator = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'));
- int i = lastSeparator > extensionPos ? -1 : extensionPos;
- if (i > 0) {
- ext = filePath.substring(i + 1);
- }
- if (ext != null) {
- if (ext.equalsIgnoreCase("vhd")) {
- return ImageFormat.VHD;
- } else if (ext.equalsIgnoreCase("vhdx")) {
- return ImageFormat.VHDX;
- } else if (ext.equalsIgnoreCase("qcow2")) {
- return ImageFormat.QCOW2;
- } else if (ext.equalsIgnoreCase("ova")) {
- return ImageFormat.OVA;
- } else if (ext.equalsIgnoreCase("tar")) {
- return ImageFormat.TAR;
- } else if (ext.equalsIgnoreCase("img") || ext.equalsIgnoreCase("raw")) {
- return ImageFormat.RAW;
- } else if (ext.equalsIgnoreCase("vmdk")) {
- return ImageFormat.VMDK;
- } else if (ext.equalsIgnoreCase("vdi")) {
- return ImageFormat.VDI;
- }
- }
-
- return null;
-
- }
-
- protected Long getVirtualSize(File file, ImageFormat format) {
- Processor processor = null;
- try {
- if (format == null) {
- return file.length();
- } else if (format == ImageFormat.QCOW2) {
- processor = new QCOW2Processor();
- } else if (format == ImageFormat.OVA) {
- processor = new OVAProcessor();
- } else if (format == ImageFormat.VHD) {
- processor = new VhdProcessor();
- } else if (format == ImageFormat.RAW) {
- processor = new RawImageProcessor();
- } else if (format == ImageFormat.VMDK) {
- processor = new VmdkProcessor();
- }
-
- if (processor == null) {
- return file.length();
- }
-
- processor.configure("template processor", new HashMap<String, Object>());
- return processor.getVirtualSize(file);
- } catch (Exception e) {
- s_logger.debug("Failed to get virtual size:", e);
- }
- return file.length();
- }
-
- protected Answer copyFromNfsToS3(CopyCommand cmd) {
- final DataTO srcData = cmd.getSrcTO();
- final DataTO destData = cmd.getDestTO();
- DataStoreTO srcDataStore = srcData.getDataStore();
- NfsTO srcStore = (NfsTO)srcDataStore;
- DataStoreTO destDataStore = destData.getDataStore();
-
- final S3TO s3 = (S3TO)destDataStore;
-
- try {
- final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath());
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + " to upload to S3.");
- }
-
- final String bucket = s3.getBucketName();
- File srcFile = _storage.getFile(templatePath);
- // guard the case where templatePath does not have file extension, since we are not completely sure
- // about hypervisor, so we check each extension
- if (!srcFile.exists()) {
- srcFile = _storage.getFile(templatePath + ".qcow2");
- if (!srcFile.exists()) {
- srcFile = _storage.getFile(templatePath + ".vhd");
- if (!srcFile.exists()) {
- srcFile = _storage.getFile(templatePath + ".ova");
- if (!srcFile.exists()) {
- srcFile = _storage.getFile(templatePath + ".vmdk");
- if (!srcFile.exists()) {
- return new CopyCmdAnswer("Can't find src file:" + templatePath);
- }
- }
- }
- }
- }
-
- long srcSize = srcFile.length();
- ImageFormat format = getTemplateFormat(srcFile.getName());
- String key = destData.getPath() + S3Utils.SEPARATOR + srcFile.getName();
- if (!s3.getSingleUpload(srcSize)) {
- mputFile(s3, srcFile, bucket, key);
- } else {
- putFile(s3, srcFile, bucket, key);
- }
-
- DataTO retObj = null;
- if (destData.getObjectType() == DataObjectType.TEMPLATE) {
- TemplateObjectTO newTemplate = new TemplateObjectTO();
- newTemplate.setPath(key);
- newTemplate.setSize(getVirtualSize(srcFile, format));
- newTemplate.setPhysicalSize(srcFile.length());
- newTemplate.setFormat(format);
- retObj = newTemplate;
- } else if (destData.getObjectType() == DataObjectType.VOLUME) {
- VolumeObjectTO newVol = new VolumeObjectTO();
- newVol.setPath(key);
- newVol.setSize(srcFile.length());
- retObj = newVol;
- } else if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
- SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
- newSnapshot.setPath(key);
- retObj = newSnapshot;
- }
-
- return new CopyCmdAnswer(retObj);
- } catch (Exception e) {
- s_logger.error("failed to upload" + srcData.getPath(), e);
- return new CopyCmdAnswer("failed to upload" + srcData.getPath() + e.toString());
- }
- }
-
- String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) {
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" +
- swift.getUserName() + " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath);
- OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
- String result = command.execute(parser);
- if (result != null) {
- String errMsg = "swiftDownload failed err=" + result;
- s_logger.warn(errMsg);
- return errMsg;
- }
- if (parser.getLines() != null) {
- String[] lines = parser.getLines().split("\\n");
- for (String line : lines) {
- if (line.contains("Errno") || line.contains("failed")) {
- String errMsg = "swiftDownload failed , err=" + parser.getLines();
- s_logger.warn(errMsg);
- return errMsg;
- }
- }
- }
- return null;
-
- }
-
- String swiftDownloadContainer(SwiftTO swift, String container, String ldir) {
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" +
- swift.getUserName() + " -K " + swift.getKey() + " download " + container);
- OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
- String result = command.execute(parser);
- if (result != null) {
- String errMsg = "swiftDownloadContainer failed err=" + result;
- s_logger.warn(errMsg);
- return errMsg;
- }
- if (parser.getLines() != null) {
- String[] lines = parser.getLines().split("\\n");
- for (String line : lines) {
- if (line.contains("Errno") || line.contains("failed")) {
- String errMsg = "swiftDownloadContainer failed , err=" + parser.getLines();
- s_logger.warn(errMsg);
- return errMsg;
- }
- }
- }
- return null;
-
- }
-
- String swiftUpload(SwiftTO swift, String container, String lDir, String lFilename) {
- long SWIFT_MAX_SIZE = 5L * 1024L * 1024L * 1024L;
- List<String> files = new ArrayList<String>();
- if (lFilename.equals("*")) {
- File dir = new File(lDir);
- for (String file : dir.list()) {
- if (file.startsWith(".")) {
- continue;
- }
- files.add(file);
- }
- } else {
- files.add(lFilename);
- }
-
- for (String file : files) {
- File f = new File(lDir + "/" + file);
- long size = f.length();
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- if (size <= SWIFT_MAX_SIZE) {
- command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " +
- swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload " + container + " " + file);
- } else {
- command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " +
- swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file);
- }
- OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
- String result = command.execute(parser);
- if (result != null) {
- String errMsg = "swiftUpload failed , err=" + result;
- s_logger.warn(errMsg);
- return errMsg;
- }
- if (parser.getLines() != null) {
- String[] lines = parser.getLines().split("\\n");
- for (String line : lines) {
- if (line.contains("Errno") || line.contains("failed")) {
- String errMsg = "swiftUpload failed , err=" + parser.getLines();
- s_logger.warn(errMsg);
- return errMsg;
- }
- }
- }
- }
-
- return null;
- }
-
- String[] swiftList(SwiftTO swift, String container, String rFilename) {
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" +
- swift.getUserName() + " -K " + swift.getKey() + " list " + container + " " + rFilename);
- OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
- String result = command.execute(parser);
- if (result == null && parser.getLines() != null) {
- String[] lines = parser.getLines().split("\\n");
- return lines;
- } else {
- if (result != null) {
- String errMsg = "swiftList failed , err=" + result;
- s_logger.warn(errMsg);
- } else {
- String errMsg = "swiftList failed, no lines returns";
- s_logger.warn(errMsg);
- }
- }
- return null;
- }
-
- String swiftDelete(SwiftTO swift, String container, String object) {
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" +
- swift.getUserName() + " -K " + swift.getKey() + " delete " + container + " " + object);
- OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
- String result = command.execute(parser);
- if (result != null) {
- String errMsg = "swiftDelete failed , err=" + result;
- s_logger.warn(errMsg);
- return errMsg;
- }
- if (parser.getLines() != null) {
- String[] lines = parser.getLines().split("\\n");
- for (String line : lines) {
- if (line.contains("Errno") || line.contains("failed")) {
- String errMsg = "swiftDelete failed , err=" + parser.getLines();
- s_logger.warn(errMsg);
- return errMsg;
- }
- }
- }
- return null;
- }
-
- public Answer execute(DeleteSnapshotsDirCommand cmd) {
- DataStoreTO dstore = cmd.getDataStore();
- if (dstore instanceof NfsTO) {
- NfsTO nfs = (NfsTO)dstore;
- String relativeSnapshotPath = cmd.getDirectory();
- String parent = getRootDir(nfs.getUrl());
-
- if (relativeSnapshotPath.startsWith(File.separator)) {
- relativeSnapshotPath = relativeSnapshotPath.substring(1);
- }
-
- if (!parent.endsWith(File.separator)) {
- parent += File.separator;
- }
- String absoluteSnapshotPath = parent + relativeSnapshotPath;
- File snapshotDir = new File(absoluteSnapshotPath);
- String details = null;
- if (!snapshotDir.exists()) {
- details = "snapshot directory " + snapshotDir.getName() + " doesn't exist";
- s_logger.debug(details);
- return new Answer(cmd, true, details);
- }
- // delete all files in the directory
- String lPath = absoluteSnapshotPath + "/*";
- String result = deleteLocalFile(lPath);
- if (result != null) {
- String errMsg = "failed to delete all snapshots " + lPath + " , err=" + result;
- s_logger.warn(errMsg);
- return new Answer(cmd, false, errMsg);
- }
- // delete the directory
- if (!snapshotDir.delete()) {
- details = "Unable to delete directory " + snapshotDir.getName() + " under snapshot path " + relativeSnapshotPath;
- s_logger.debug(details);
- return new Answer(cmd, false, details);
- }
- return new Answer(cmd, true, null);
- } else if (dstore instanceof S3TO) {
- final S3TO s3 = (S3TO)dstore;
- final String path = cmd.getDirectory();
- final String bucket = s3.getBucketName();
- try {
- S3Utils.deleteDirectory(s3, bucket, path);
- return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket));
- } catch (Exception e) {
- final String errorMessage =
- String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
- s_logger.error(errorMessage, e);
- return new Answer(cmd, false, errorMessage);
- }
- } else if (dstore instanceof SwiftTO) {
- String path = cmd.getDirectory();
- String volumeId = StringUtils.substringAfterLast(path, "/"); // assuming
- // that
- // the
- // filename
- // is
- // the
- // last
- // section
- // in
- // the
- // path
- String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), "");
- if (result != null) {
- String errMsg = "failed to delete snapshot for volume " + volumeId + " , err=" + result;
- s_logger.warn(errMsg);
- return new Answer(cmd, false, errMsg);
- }
- return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
- } else {
- return new Answer(cmd, false, "Unsupported image data store: " + dstore);
- }
- }
-
- private Answer execute(ComputeChecksumCommand cmd) {
-
- String relativeTemplatePath = cmd.getTemplatePath();
- DataStoreTO store = cmd.getStore();
- if (!(store instanceof NfsTO)) {
- return new Answer(cmd, false, "can't handle non nfs data store");
- }
- NfsTO nfsStore = (NfsTO)store;
- String parent = getRootDir(nfsStore.getUrl());
-
- 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 {
- if (is != null) {
- 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 void configCerts(KeystoreManager.Certificates certs) {
- if (certs == null) {
- configureSSL();
- } else {
- String prvKey = certs.getPrivKey();
- String pubCert = certs.getPrivCert();
-
- try {
- File prvKeyFile = File.createTempFile("prvkey", null);
- String prvkeyPath = prvKeyFile.getAbsolutePath();
- BufferedWriter out = new BufferedWriter(new FileWriter(prvKeyFile));
- out.write(prvKey);
- out.close();
-
- File pubCertFile = File.createTempFile("pubcert", null);
- String pubCertFilePath = pubCertFile.getAbsolutePath();
-
- out = new BufferedWriter(new FileWriter(pubCertFile));
- out.write(pubCert);
- out.close();
-
- configureSSL(prvkeyPath, pubCertFilePath, null);
-
- prvKeyFile.delete();
- pubCertFile.delete();
-
- } catch (IOException e) {
- s_logger.debug("Failed to config ssl: " + e.toString());
- }
- }
- }
-
- private Answer execute(SecStorageSetupCommand cmd) {
- if (!_inSystemVM) {
- return new Answer(cmd, true, null);
- }
- DataStoreTO dStore = cmd.getDataStore();
- if (dStore instanceof NfsTO) {
- String secUrl = cmd.getSecUrl();
- try {
- URI uri = new URI(secUrl);
- String nfsHostIp = getUriHostIp(uri);
-
- addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
- String dir = mountUri(uri);
-
- configCerts(cmd.getCerts());
-
- nfsIps.add(nfsHostIp);
- return new SecStorageSetupAnswer(dir);
- } catch (Exception e) {
- String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
- s_logger.error(msg);
- return new Answer(cmd, false, msg);
-
- }
- } else {
- // TODO: what do we need to setup for S3/Swift, maybe need to mount
- // to some cache storage
- return new Answer(cmd, true, null);
- }
- }
-
- protected Answer deleteSnapshot(final DeleteCommand cmd) {
- DataTO obj = cmd.getData();
- DataStoreTO dstore = obj.getDataStore();
- if (dstore instanceof NfsTO) {
- NfsTO nfs = (NfsTO)dstore;
- String parent = getRootDir(nfs.getUrl());
- if (!parent.endsWith(File.separator)) {
- parent += File.separator;
- }
- String snapshotPath = obj.getPath();
- if (snapshotPath.startsWith(File.separator)) {
- snapshotPath = snapshotPath.substring(1);
- }
- // check if the passed snapshot path is a directory or not. For ImageCache, path is stored as a directory instead of
- // snapshot file name. If so, since backupSnapshot process has already deleted snapshot in cache, so we just do nothing
- // and return true.
- String fullSnapPath = parent + snapshotPath;
- File snapDir = new File(fullSnapPath);
- if (snapDir.exists() && snapDir.isDirectory()) {
- s_logger.debug("snapshot path " + snapshotPath + " is a directory, already deleted during backup snapshot, so no need to delete");
- return new Answer(cmd, true, null);
- }
- // passed snapshot path is a snapshot file path, then get snapshot directory first
- int index = snapshotPath.lastIndexOf("/");
- String snapshotName = snapshotPath.substring(index + 1);
- snapshotPath = snapshotPath.substring(0, index);
- String absoluteSnapshotPath = parent + snapshotPath;
- // check if snapshot directory exists
- File snapshotDir = new File(absoluteSnapshotPath);
- String details = null;
- if (!snapshotDir.exists()) {
- details = "snapshot directory " + snapshotDir.getName() + " doesn't exist";
- s_logger.debug(details);
- return new Answer(cmd, false, details);
- }
- // delete snapshot in the directory if exists
- String lPath = absoluteSnapshotPath + "/*" + snapshotName + "*";
- String result = deleteLocalFile(lPath);
- if (result != null) {
- details = "failed to delete snapshot " + lPath + " , err=" + result;
- s_logger.warn(details);
- return new Answer(cmd, false, details);
- }
- return new Answer(cmd, true, null);
- } else if (dstore instanceof S3TO) {
- final S3TO s3 = (S3TO)dstore;
- final String path = obj.getPath();
- final String bucket = s3.getBucketName();
- try {
- S3Utils.deleteObject(s3, bucket, path);
- return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket));
- } catch (Exception e) {
- final String errorMessage =
- String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
- s_logger.error(errorMessage, e);
- return new Answer(cmd, false, errorMessage);
- }
- } else if (dstore instanceof SwiftTO) {
- SwiftTO swiftTO = (SwiftTO)dstore;
- String path = obj.getPath();
- SwiftUtil.deleteObject(swiftTO, path);
-
- return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
- } else {
- return new Answer(cmd, false, "Unsupported image data store: " + dstore);
- }
-
- }
-
- Map<String, TemplateProp> swiftListTemplate(SwiftTO swift) {
- String[] containers = SwiftUtil.list(swift, "", null);
- if (containers == null) {
- return null;
- }
- Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
- for (String container : containers) {
- if (container.startsWith("T-")) {
- String[] files = SwiftUtil.list(swift, container, "template.properties");
- if (files.length != 1) {
- continue;
- }
- try {
- File tempFile = File.createTempFile("template", ".tmp");
- File tmpFile = SwiftUtil.getObject(swift, tempFile, container + File.separator + "template.properties");
- if (tmpFile == null) {
- continue;
- }
- FileReader fr = new FileReader(tmpFile);
- BufferedReader brf = new BufferedReader(fr);
- String line = null;
- String uniqName = null;
- Long size = null;
- String name = null;
- while ((line = brf.readLine()) != null) {
- if (line.startsWith("uniquename=")) {
- uniqName = line.split("=")[1];
- } else if (line.startsWith("size=")) {
- size = Long.parseLong(line.split("=")[1]);
- } else if (line.startsWith("filename=")) {
- name = line.split("=")[1];
- }
- }
- brf.close();
- tempFile.delete();
- if (uniqName != null) {
- TemplateProp prop = new TemplateProp(uniqName, container + File.separator + name, size, size, true, false);
- tmpltInfos.put(uniqName, prop);
- }
-
- } catch (IOException e) {
- s_logger.debug("Failed to create templ file:" + e.toString());
- continue;
- } catch (Exception e) {
- s_logger.debug("Failed to get properties: " + e.toString());
- continue;
- }
- }
- }
- return tmpltInfos;
-
- }
-
- Map<String, TemplateProp> s3ListTemplate(S3TO s3) {
- String bucket = s3.getBucketName();
- // List the objects in the source directory on S3
- final List<S3ObjectSummary> objectSummaries = S3Utils.getDirectory(s3, bucket, TEMPLATE_ROOT_DIR);
- if (objectSummaries == null) {
- return null;
- }
- Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
- for (S3ObjectSummary objectSummary : objectSummaries) {
- String key = objectSummary.getKey();
- // String installPath = StringUtils.substringBeforeLast(key,
- // S3Utils.SEPARATOR);
- String uniqueName = determineS3TemplateNameFromKey(key);
- // TODO: isPublic value, where to get?
- TemplateProp tInfo = new TemplateProp(uniqueName, key, objectSummary.getSize(), objectSummary.getSize(), true, false);
- tmpltInfos.put(uniqueName, tInfo);
- }
- return tmpltInfos;
-
- }
-
- Map<Long, TemplateProp> s3ListVolume(S3TO s3) {
- String bucket = s3.getBucketName();
- // List the objects in the source directory on S3
- final List<S3ObjectSummary> objectSummaries = S3Utils.getDirectory(s3, bucket, VOLUME_ROOT_DIR);
- if (objectSummaries == null) {
- return null;
- }
- Map<Long, TemplateProp> tmpltInfos = new HashMap<Long, TemplateProp>();
- for (S3ObjectSummary objectSummary : objectSummaries) {
- String key = objectSummary.getKey();
- // String installPath = StringUtils.substringBeforeLast(key,
- // S3Utils.SEPARATOR);
- Long id = determineS3VolumeIdFromKey(key);
- // TODO: how to get volume template name
- TemplateProp tInfo = new TemplateProp(id.toString(), key, objectSummary.getSize(), objectSummary.getSize(), true, false);
- tmpltInfos.put(id, tInfo);
- }
- return tmpltInfos;
-
- }
-
- private Answer execute(ListTemplateCommand cmd) {
- if (!_inSystemVM) {
- return new ListTemplateAnswer(null, null);
- }
-
- DataStoreTO store = cmd.getDataStore();
- if (store instanceof NfsTO) {
- NfsTO nfs = (NfsTO)store;
- String secUrl = nfs.getUrl();
- String root = getRootDir(secUrl);
- Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
- return new ListTemplateAnswer(secUrl, templateInfos);
- } else if (store instanceof SwiftTO) {
- SwiftTO swift = (SwiftTO)store;
- Map<String, TemplateProp> templateInfos = swiftListTemplate(swift);
- return new ListTemplateAnswer(swift.toString(), templateInfos);
- } else if (store instanceof S3TO) {
- S3TO s3 = (S3TO)store;
- Map<String, TemplateProp> templateInfos = s3ListTemplate(s3);
- return new ListTemplateAnswer(s3.getBucketName(), templateInfos);
- } else {
- return new Answer(cmd, false, "Unsupported image data store: " + store);
- }
- }
-
- private Answer execute(ListVolumeCommand cmd) {
- if (!_inSystemVM) {
- return new ListVolumeAnswer(cmd.getSecUrl(), null);
- }
- DataStoreTO store = cmd.getDataStore();
- if (store instanceof NfsTO) {
- String root = getRootDir(cmd.getSecUrl());
- Map<Long, TemplateProp> templateInfos = _dlMgr.gatherVolumeInfo(root);
- return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
- } else if (store instanceof S3TO) {
- S3TO s3 = (S3TO)store;
- Map<Long, TemplateProp> templateInfos = s3ListVolume(s3);
- return new ListVolumeAnswer(s3.getBucketName(), templateInfos);
- } else {
- return new Answer(cmd, false, "Unsupported image data store: " + store);
- }
-
- }
-
- private Answer execute(SecStorageVMSetupCommand cmd) {
- if (!_inSystemVM) {
- return new Answer(cmd, true, null);
- }
- boolean success = true;
- StringBuilder result = new StringBuilder();
- for (String cidr : cmd.getAllowedInternalSites()) {
- if (nfsIps.contains(cidr)) {
- /*
- * if the internal download ip is the same with secondary
- * storage ip, adding internal sites will flush ip route to nfs
- * through storage ip.
- */
- continue;
- }
- String tmpresult = allowOutgoingOnPrivate(cidr);
- if (tmpresult != null) {
- result.append(", ").append(tmpresult);
- success = false;
- }
- }
- if (success) {
- if (cmd.getCopyPassword() != null && cmd.getCopyUserName() != null) {
- String tmpresult = configureAuth(cmd.getCopyUserName(), cmd.getCopyPassword());
- if (tmpresult != null) {
- result.append("Failed to configure auth for copy ").append(tmpresult);
- success = false;
- }
- }
- }
- return new Answer(cmd, success, result.toString());
-
- }
-
- private String deleteLocalFile(String fullPath) {
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("rm -f " + fullPath);
- String result = command.execute();
- if (result != null) {
- String errMsg = "Failed to delete file " + fullPath + ", err=" + result;
- s_logger.warn(errMsg);
- return errMsg;
- }
- return null;
- }
-
- public String allowOutgoingOnPrivate(String destCidr) {
- if (!_inSystemVM) {
- return null;
- }
- Script command = new Script("/bin/bash", s_logger);
- String intf = "eth1";
- command.add("-c");
- command.add("iptables -I OUTPUT -o " + intf + " -d " + destCidr + " -p tcp -m state --state NEW -m tcp -j ACCEPT");
-
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Error in allowing outgoing to " + destCidr + ", err=" + result);
- return "Error in allowing outgoing to " + destCidr + ", err=" + result;
- }
-
- addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, destCidr);
-
- return null;
- }
-
- private Answer execute(SecStorageFirewallCfgCommand cmd) {
- if (!_inSystemVM) {
- return new Answer(cmd, true, null);
- }
-
- List<String> ipList = new ArrayList<String>();
-
- for (PortConfig pCfg : cmd.getPortConfigs()) {
- if (pCfg.isAdd()) {
- ipList.add(pCfg.getSourceIp());
- }
- }
- boolean success = true;
- String result;
- result = configureIpFirewall(ipList, cmd.getIsAppendAIp());
- if (result != null) {
- success = false;
- }
-
- return new Answer(cmd, success, result);
- }
-
- protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
- DataStoreTO store = cmd.getStore();
- if (store instanceof S3TO || store instanceof SwiftTO) {
- long infinity = Integer.MAX_VALUE;
- return new GetStorageStatsAnswer(cmd, infinity, 0L);
- }
-
- String rootDir = getRootDir(((NfsTO)store).getUrl());
- final long usedSize = getUsedSize(rootDir);
- final long totalSize = getTotalSize(rootDir);
- if (usedSize == -1 || totalSize == -1) {
- return new GetStorageStatsAnswer(cmd, "Unable to get storage stats");
- } else {
- return new GetStorageStatsAnswer(cmd, totalSize, usedSize);
- }
- }
-
- protected Answer execute(final DeleteCommand cmd) {
- DataTO obj = cmd.getData();
- DataObjectType objType = obj.getObjectType();
- if (obj.getPath() == null) {
- // account for those fake entries for NFS migration to object store
- return new Answer(cmd, true, "Object with null install path does not exist on image store , no need to delete");
- }
- switch (objType) {
- case TEMPLATE:
- return deleteTemplate(cmd);
- case VOLUME:
- return deleteVolume(cmd);
- case SNAPSHOT:
- return deleteSnapshot(cmd);
- }
- return Answer.createUnsupportedCommandAnswer(cmd);
- }
-
- protected Answer deleteTemplate(DeleteCommand cmd) {
- DataTO obj = cmd.getData();
- DataStoreTO dstore = obj.getDataStore();
- if (dstore instanceof NfsTO) {
- NfsTO nfs = (NfsTO)dstore;
- String relativeTemplatePath = obj.getPath();
- String parent = getRootDir(nfs.getUrl());
-
- if (relativeTemplatePath.startsWith(File.separator)) {
- relativeTemplatePath = relativeTemplatePath.substring(1);
- }
-
- if (!parent.endsWith(File.separator)) {
- parent += File.separator;
- }
- String absoluteTemplatePath = parent + relativeTemplatePath;
- File tmpltPath = new File(absoluteTemplatePath);
- File tmpltParent = null;
- if(tmpltPath.exists() && tmpltPath.isDirectory()) {
- tmpltParent = tmpltPath;
- } else {
- tmpltParent = tmpltPath.getParentFile();
- }
-
- String details = null;
- if (!tmpltParent.exists()) {
- details = "template parent directory " + tmpltParent.getName() + " doesn't exist";
- s_logger.debug(details);
- return new Answer(cmd, true, details);
- }
- File[] tmpltFiles = tmpltParent.listFiles();
- if (tmpltFiles == null || tmpltFiles.length == 0) {
- details = "No files under template parent directory " + tmpltParent.getName();
- s_logger.debug(details);
- } else {
- boolean found = false;
- for (File f : tmpltFiles) {
- if (!found && f.getName().equals("template.properties")) {
- found = true;
- }
-
- // KVM HA monitor makes a mess in the templates with its
- // heartbeat tests
- // Don't let this stop us from cleaning up the template
- if (f.isDirectory() && f.getName().equals("KVMHA")) {
- s_logger.debug("Deleting KVMHA directory contents from template location");
- File[] haFiles = f.listFiles();
- for (File haFile : haFiles) {
- haFile.delete();
- }
- }
-
- if (!f.delete()) {
- return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path " + relativeTemplatePath);
- }
- }
-
- if (!found) {
- details = "Can not find template.properties under " + tmpltParent.getName();
- s_logger.debug(details);
- }
- }
- if (!tmpltParent.delete()) {
- details = "Unable to delete directory " + tmpltParent.getName() + " under Template path " + relativeTemplatePath;
- s_logger.debug(details);
- return new Answer(cmd, false, details);
- }
- return new Answer(cmd, true, null);
- } else if (dstore instanceof S3TO) {
- final S3TO s3 = (S3TO)dstore;
- final String path = obj.getPath();
- final String bucket = s3.getBucketName();
- try {
- S3Utils.deleteDirectory(s3, bucket, path);
- return new Answer(cmd, true, String.format("Deleted template %1$s from bucket %2$s.", path, bucket));
- } catch (Exception e) {
- final String errorMessage =
- String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
- s_logger.error(errorMessage, e);
- return new Answer(cmd, false, errorMessage);
- }
- } else if (dstore instanceof SwiftTO) {
- SwiftTO swift = (SwiftTO)dstore;
- String container = "T-" + obj.getId();
- String object = "";
-
- try {
- String result = swiftDelete(swift, container, object);
- if (result != null) {
- String errMsg = "failed to delete object " + container + "/" + object + " , err=" + result;
- s_logger.warn(errMsg);
- return new Answer(cmd, false, errMsg);
- }
- return new Answer(cmd, true, "success");
- } catch (Exception e) {
- String errMsg = cmd + " Command failed due to " + e.toString();
- s_logger.warn(errMsg, e);
- return new Answer(cmd, false, errMsg);
- }
- } else {
- return new Answer(cmd, false, "Unsupported image data store: " + dstore);
- }
- }
-
- protected Answer deleteVolume(final DeleteCommand cmd) {
- DataTO obj = cmd.getData();
- DataStoreTO dstore = obj.getDataStore();
- if (dstore instanceof NfsTO) {
- NfsTO nfs = (NfsTO)dstore;
- String relativeVolumePath = obj.getPath();
- String parent = getRootDir(nfs.getUrl());
-
- if (relativeVolumePath.startsWith(File.separator)) {
- relativeVolumePath = relativeVolumePath.substring(1);
- }
-
- if (!parent.endsWith(File.separator)) {
- parent += File.separator;
- }
- String absoluteVolumePath = parent + relativeVolumePath;
- File volPath = new File(absoluteVolumePath);
- File tmpltParent = null;
- if (volPath.exists() && volPath.isDirectory()) {
- // for vmware, absoluteVolumePath represents a directory where volume files are located.
- tmpltParent = volPath;
- } else {
- // for other hypervisors, the volume .vhd or .qcow2 file path is passed
- tmpltParent = new File(absoluteVolumePath).getParentFile();
- }
- String details = null;
- if (!tmpltParent.exists()) {
- details = "volume parent directory " + tmpltParent.getName() + " doesn't exist";
- s_logger.debug(details);
- return new Answer(cmd, true, details);
- }
- File[] tmpltFiles = tmpltParent.listFiles();
- if (tmpltFiles == null || tmpltFiles.length == 0) {
- details = "No files under volume parent directory " + tmpltParent.getName();
- s_logger.debug(details);
- } else {
- boolean found = false;
- for (File f : tmpltFiles) {
- if (!found && f.getName().equals("volume.properties")) {
- found = true;
- }
-
- // KVM HA monitor makes a mess in the templates with its
- // heartbeat tests
- // Don't let this stop us from cleaning up the template
- if (f.isDirectory() && f.getName().equals("KVMHA")) {
- s_logger.debug("Deleting KVMHA directory contents from template location");
- File[] haFiles = f.listFiles();
- for (File haFile : haFiles) {
- haFile.delete();
- }
- }
-
- if (!f.delete()) {
- return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + tmpltParent.getPath());
- }
- }
- if (!found) {
- details = "Can not find volume.properties under " + tmpltParent.getName();
- s_logger.debug(details);
- }
- }
- if (!tmpltParent.delete()) {
- details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " + tmpltParent.getPath();
- s_logger.debug(details);
- return new Answer(cmd, false, details);
- }
- return new Answer(cmd, true, null);
- } else if (dstore instanceof S3TO) {
- final S3TO s3 = (S3TO)dstore;
- final String path = obj.getPath();
- final String bucket = s3.getBucketName();
- try {
- S3Utils.deleteDirectory(s3, bucket, path);
- return new Answer(cmd, true, String.format("Deleted volume %1%s from bucket %2$s.", path, bucket));
- } catch (Exception e) {
- final String errorMessage = String.format("Failed to delete volume %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
- s_logger.error(errorMessage, e);
- return new Answer(cmd, false, errorMessage);
- }
- } else if (dstore instanceof SwiftTO) {
- Long volumeId = obj.getId();
- String path = obj.getPath();
- String filename = StringUtils.substringAfterLast(path, "/"); // assuming
- // that
- // the
- // filename
- // is
- // the
- // last
- // section
- // in
- // the
- // path
- String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), filename);
- if (result != null) {
- String errMsg = "failed to delete volume " + filename + " , err=" + result;
- s_logger.warn(errMsg);
- return new Answer(cmd, false, errMsg);
- }
- return new Answer(cmd, true, "Deleted volume " + path + " from swift");
- } else {
- return new Answer(cmd, false, "Unsupported image data store: " + dstore);
- }
-
- }
-
- @Override
- synchronized public String getRootDir(String secUrl) {
- if (!_inSystemVM) {
- return _parent;
- }
- try {
- URI uri = new URI(secUrl);
- String dir = mountUri(uri);
- return _parent + "/" + dir;
- } catch (Exception e) {
- String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
- s_logger.error(msg, e);
- throw new CloudRuntimeException(msg);
- }
- }
-
- protected long getUsedSize(String rootDir) {
- return _storage.getUsedSpace(rootDir);
- }
-
- protected long getTotalSize(String rootDir) {
- return _storage.getTotalSpace(rootDir);
- }
-
- protected long convertFilesystemSize(final String size) {
- if (size == null || size.isEmpty()) {
- return -1;
- }
-
- long multiplier = 1;
- if (size.endsWith("T")) {
- multiplier = 1024l * 1024l * 1024l * 1024l;
- } else if (size.endsWith("G")) {
- multiplier = 1024l * 1024l * 1024l;
- } else if (size.endsWith("M")) {
- multiplier = 1024l * 1024l;
- } else {
- assert (false) : "Well, I have no idea what this is: " + size;
- }
-
- return (long)(Double.parseDouble(size.substring(0, size.length() - 1)) * multiplier);
- }
-
- @Override
- public Type getType() {
- if (SecondaryStorageVm.Role.templateProcessor.toString().equals(_role)) {
- return Host.Type.SecondaryStorage;
- }
-
- return Host.Type.SecondaryStorageCmdExecutor;
- }
-
- @Override
- public PingCommand getCurrentStatus(final long id) {
- return new PingStorageCommand(Host.Type.Storage, id, new HashMap<String, Boolean>());
- }
-
- @Override
- public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
- _eth1ip = (String)params.get("eth1ip");
- _eth1mask = (String)params.get("eth1mask");
- if (_eth1ip != null) { // can only happen inside service vm
- params.put("private.network.device", "eth1");
- } else {
- s_logger.warn("eth1ip parameter has not been configured, assuming that we are not inside a system vm");
- }
- String eth2ip = (String)params.get("eth2ip");
- if (eth2ip != null) {
- params.put("public.network.device", "eth2");
- }
- _publicIp = (String)params.get("eth2ip");
- _hostname = (String)params.get("name");
-
- String inSystemVM = (String)params.get("secondary.storage.vm");
- if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
- s_logger.debug("conf secondary.storage.vm is true, act as if executing in SSVM");
- _inSystemVM = true;
- }
-
- _storageIp = (String)params.get("storageip");
- if (_storageIp == null && _inSystemVM) {
- s_logger.warn("There is no storageip in /proc/cmdline, something wrong!");
- }
- _storageNetmask = (String)params.get("storagenetmask");
- _storageGateway = (String)params.get("storagegateway");
- super.configure(name, params);
-
- _params = params;
- String value = (String)params.get("scripts.timeout");
- _timeout = NumbersUtil.parseInt(value, 1440) * 1000;
-
- _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
- configureStorageLayerClass(params);
-
- if (_inSystemVM) {
- _storage.mkdirs(_parent);
- }
-
- _configSslScr = Script.findScript(getDefaultScriptsDir(), "config_ssl.sh");
- if (_configSslScr != null) {
- s_logger.info("config_ssl.sh found in " + _configSslScr);
- }
-
- _configAuthScr = Script.findScript(getDefaultScriptsDir(), "config_auth.sh");
- if (_configSslScr != null) {
- s_logger.info("config_auth.sh found in " + _configAuthScr);
- }
-
- _configIpFirewallScr = Script.findScript(getDefaultScriptsDir(), "ipfirewall.sh");
- if (_configIpFirewallScr != null) {
- s_logger.info("_configIpFirewallScr found in " + _configIpFirewallScr);
- }
-
- createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh");
- if (createTemplateFromSnapshotXenScript == null) {
- throw new ConfigurationException("create_privatetemplate_from_snapshot_xen.sh not found in " + getDefaultScriptsDir());
- }
-
- _role = (String)params.get("role");
- if (_role == null) {
- _role = SecondaryStorageVm.Role.templateProcessor.toString();
- }
- s_logger.info("Secondary storage runs in role " + _role);
-
- _guid = (String)params.get("guid");
- if (_guid == null) {
- throw new ConfigurationException("Unable to find the guid");
- }
-
- _dc = (String)params.get("zone");
- if (_dc == null) {
- throw new ConfigurationException("Unable to find the zone");
- }
- _pod = (String)params.get("pod");
-
- _instance = (String)params.get("instance");
-
- if (!_inSystemVM) {
- _parent = (String)params.get("mount.path");
- }
-
- if (_inSystemVM) {
- _localgw = (String)params.get("localgw");
- if (_localgw != null) { // can only happen inside service vm
- String mgmtHost = (String)params.get("host");
- addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost);
-
- String internalDns1 = (String)params.get("internaldns1");
- if (internalDns1 == null) {
- s_logger.warn("No DNS entry found during configuration of NfsSecondaryStorage");
- } else {
- addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns1);
- }
-
- String internalDns2 = (String)params.get("internaldns2");
- if (internalDns2 != null) {
- addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns2);
- }
-
- }
-
- startAdditionalServices();
- _params.put("install.numthreads", "50");
- _params.put("secondary.storage.vm", "true");
- }
-
- try {
- _params.put(StorageLayer.InstanceConfigKey, _storage);
- _dlMgr = new DownloadManagerImpl();
- _dlMgr.configure("DownloadManager", _params);
- _upldMgr = new UploadManagerImpl();
- _upldMgr.configure("UploadManager", params);
- } catch (ConfigurationException e) {
- s_logger.warn("Caught problem while configuring DownloadManager", e);
- return false;
- }
- return true;
- }
-
- protected void configureStorageLayerClass(Map<String, Object> params) throws ConfigurationException {
- String value;
- if (_storage == null) {
- value = (String)params.get(StorageLayer.ClassConfigKey);
- if (value == null) {
- value = "com.cloud.storage.JavaStorageLayer";
- }
-
- try {
- Class<?> clazz = Class.forName(value);
- _storage = (StorageLayer)clazz.newInstance();
- _storage.configure("
<TRUNCATED>
[07/11] git commit: updated refs/heads/master to 54f32a8
Posted by ah...@apache.org.
Moved the secondary storage service into its own server directory
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/4be3b993
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/4be3b993
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/4be3b993
Branch: refs/heads/master
Commit: 4be3b9933760c7713380112dff6f997cbe127def
Parents: aaa2094
Author: Alex Huang <al...@citrix.com>
Authored: Wed Jan 15 17:37:15 2014 -0800
Committer: Alex Huang <al...@citrix.com>
Committed: Wed Feb 5 01:38:24 2014 +0000
----------------------------------------------------------------------
services/secondary-storage/controller/pom.xml | 50 +
services/secondary-storage/pom.xml | 85 +-
.../module.properties | 18 -
...ing-secondary-storage-discoverer-context.xml | 36 -
services/secondary-storage/server/pom.xml | 105 +
.../module.properties | 18 +
...ing-secondary-storage-discoverer-context.xml | 36 +
.../LocalNfsSecondaryStorageResource.java | 95 +
.../resource/LocalSecondaryStorageResource.java | 240 ++
.../resource/NfsSecondaryStorageResource.java | 2430 ++++++++++++++++++
.../resource/SecondaryStorageDiscoverer.java | 312 +++
.../resource/SecondaryStorageResource.java | 29 +
.../SecondaryStorageResourceHandler.java | 24 +
.../storage/template/DownloadManager.java | 108 +
.../storage/template/DownloadManagerImpl.java | 1080 ++++++++
.../storage/template/UploadManager.java | 82 +
.../storage/template/UploadManagerImpl.java | 550 ++++
.../LocalNfsSecondaryStorageResourceTest.java | 143 ++
.../NfsSecondaryStorageResourceTest.java | 110 +
.../LocalNfsSecondaryStorageResource.java | 95 -
.../resource/LocalSecondaryStorageResource.java | 240 --
.../resource/NfsSecondaryStorageResource.java | 2430 ------------------
.../resource/SecondaryStorageDiscoverer.java | 312 ---
.../resource/SecondaryStorageResource.java | 29 -
.../SecondaryStorageResourceHandler.java | 24 -
.../storage/template/DownloadManager.java | 108 -
.../storage/template/DownloadManagerImpl.java | 1080 --------
.../storage/template/UploadManager.java | 82 -
.../storage/template/UploadManagerImpl.java | 550 ----
.../LocalNfsSecondaryStorageResourceTest.java | 143 --
.../NfsSecondaryStorageResourceTest.java | 110 -
31 files changed, 5419 insertions(+), 5335 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/controller/pom.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/controller/pom.xml b/services/secondary-storage/controller/pom.xml
new file mode 100644
index 0000000..47a730d
--- /dev/null
+++ b/services/secondary-storage/controller/pom.xml
@@ -0,0 +1,50 @@
+<!--
+ 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/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>cloud-controller-secondary-storage</artifactId>
+ <name>Apache CloudStack Secondary Storage Controller</name>
+ <parent>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloudstack-service-secondary-storage</artifactId>
+ <version>4.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <dependencies>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-server</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/pom.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml
index 2798584..61077a0 100644
--- a/services/secondary-storage/pom.xml
+++ b/services/secondary-storage/pom.xml
@@ -18,88 +18,17 @@
-->
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <artifactId>cloud-secondary-storage</artifactId>
- <name>Apache CloudStack Secondary Storage Service</name>
+ <artifactId>cloudstack-service-secondary-storage</artifactId>
+ <name>Apache CloudStack Secondary Storage</name>
+ <packaging>pom</packaging>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-services</artifactId>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <properties>
- <skipTests>true</skipTests>
- </properties>
- <dependencies>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- </dependency>
- <!-- required deps for the systemvm -->
- <dependency>
- <groupId>org.apache.cloudstack</groupId>
- <artifactId>cloud-agent</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.cloudstack</groupId>
- <artifactId>cloud-server</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <skipTests>${skipTests}</skipTests>
- <systemPropertyVariables>
- <log4j.configuration>file:${project.build.testSourceDirectory}/../conf/log4j.xml</log4j.configuration>
- </systemPropertyVariables>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <version>1.2.1</version>
- <executions>
- <execution>
- <goals>
- <goal>java</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <mainClass>com.cloud.agent.AgentShell</mainClass>
- <arguments>
- <argument>zone=1</argument>
- <argument>pod=1</argument>
- <argument>host=192.168.56.1</argument>
- <argument>name=192.168.56.10</argument>
- <argument>eth1ip=192.168.56.10</argument>
- <argument>eth2ip=192.168.56.10</argument>
- <argument>guid=SecondaryStorage.1</argument>
- <argument>secondary.storage.vm=false</argument>
- <argument>instance=Secondary</argument>
- </arguments>
- <systemProperties>
- <systemProperty>
- <key>javax.net.ssl.trustStore</key>
- <value>certs/realhostip.keystore</value>
- <key>log.home</key>
- <value>${PWD}/</value>
- </systemProperty>
- </systemProperties>
- </configuration>
- </plugin>
- </plugins>
- </build>
+ <modules>
+ <module>controller</module>
+ <module>server</module>
+ </modules>
</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
----------------------------------------------------------------------
diff --git a/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties b/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
deleted file mode 100644
index 7ff8a3a..0000000
--- a/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
+++ /dev/null
@@ -1,18 +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.
-name=secondary-storage-discoverer
-parent=discoverer
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml b/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
deleted file mode 100644
index 30521aa..0000000
--- a/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
+++ /dev/null
@@ -1,36 +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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- 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 id="SecondaryStorageDiscoverer"
- class="org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer">
- <property name="name" value="SecondaryStorage" />
- </bean>
-
-
-</beans>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/pom.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/pom.xml b/services/secondary-storage/server/pom.xml
new file mode 100644
index 0000000..29fd7c7
--- /dev/null
+++ b/services/secondary-storage/server/pom.xml
@@ -0,0 +1,105 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<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/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>cloud-secondary-storage</artifactId>
+ <name>Apache CloudStack Secondary Storage Service</name>
+ <parent>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloudstack-service-secondary-storage</artifactId>
+ <version>4.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+ <!-- required deps for the systemvm -->
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-agent</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-server</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <skipTests>${skipTests}</skipTests>
+ <systemPropertyVariables>
+ <log4j.configuration>file:${project.build.testSourceDirectory}/../conf/log4j.xml</log4j.configuration>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.2.1</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>java</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <mainClass>com.cloud.agent.AgentShell</mainClass>
+ <arguments>
+ <argument>zone=1</argument>
+ <argument>pod=1</argument>
+ <argument>host=192.168.56.1</argument>
+ <argument>name=192.168.56.10</argument>
+ <argument>eth1ip=192.168.56.10</argument>
+ <argument>eth2ip=192.168.56.10</argument>
+ <argument>guid=SecondaryStorage.1</argument>
+ <argument>secondary.storage.vm=false</argument>
+ <argument>instance=Secondary</argument>
+ </arguments>
+ <systemProperties>
+ <systemProperty>
+ <key>javax.net.ssl.trustStore</key>
+ <value>certs/realhostip.keystore</value>
+ <key>log.home</key>
+ <value>${PWD}/</value>
+ </systemProperty>
+ </systemProperties>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties b/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
new file mode 100644
index 0000000..7ff8a3a
--- /dev/null
+++ b/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+name=secondary-storage-discoverer
+parent=discoverer
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml b/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
new file mode 100644
index 0000000..30521aa
--- /dev/null
+++ b/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
@@ -0,0 +1,36 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ 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 id="SecondaryStorageDiscoverer"
+ class="org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer">
+ <property name="name" value="SecondaryStorage" />
+ </bean>
+
+
+</beans>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
new file mode 100644
index 0000000..9393ee2
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
@@ -0,0 +1,95 @@
+// 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.storage.resource;
+
+import java.net.URI;
+import java.util.concurrent.Executors;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.storage.template.DownloadManagerImpl;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.storage.JavaStorageLayer;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+
+@Component
+public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResource {
+
+ private static final Logger s_logger = Logger.getLogger(LocalNfsSecondaryStorageResource.class);
+
+ public LocalNfsSecondaryStorageResource() {
+ this._dlMgr = new DownloadManagerImpl();
+ ((DownloadManagerImpl)_dlMgr).setThreadPool(Executors.newFixedThreadPool(10));
+ _storage = new JavaStorageLayer();
+ this._inSystemVM = false;
+ }
+
+ @Override
+ public void setParentPath(String path) {
+ this._parent = path;
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ return super.executeRequest(cmd);
+ }
+
+ @Override
+ synchronized public String getRootDir(String secUrl) {
+ try {
+ URI uri = new URI(secUrl);
+ String dir = mountUri(uri);
+ return _parent + "/" + dir;
+ } catch (Exception e) {
+ String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
+ s_logger.error(msg, e);
+ throw new CloudRuntimeException(msg);
+ }
+ }
+
+ @Override
+ protected void mount(String localRootPath, String remoteDevice, URI uri) {
+ ensureLocalRootPathExists(localRootPath, uri);
+
+ if (mountExists(localRootPath, uri)) {
+ return;
+ }
+
+ attemptMount(localRootPath, remoteDevice, uri);
+
+ // Change permissions for the mountpoint - seems to bypass authentication
+ Script script = new Script(true, "chmod", _timeout, s_logger);
+ script.add("777", localRootPath);
+ String result = script.execute();
+ if (result != null) {
+ String errMsg = "Unable to set permissions for " + localRootPath + " due to " + result;
+ s_logger.error(errMsg);
+ throw new CloudRuntimeException(errMsg);
+ }
+ s_logger.debug("Successfully set 777 permission for " + localRootPath);
+
+ // XXX: Adding the check for creation of snapshots dir here. Might have
+ // to move it somewhere more logical later.
+ checkForSnapshotsDir(localRootPath);
+ checkForVolumesDir(localRootPath);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
new file mode 100644
index 0000000..bdfe7e8
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
@@ -0,0 +1,240 @@
+// 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.storage.resource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.command.DownloadProgressCommand;
+import org.apache.cloudstack.storage.template.DownloadManager;
+import org.apache.cloudstack.storage.template.DownloadManagerImpl;
+
+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.PingCommand;
+import com.cloud.agent.api.PingStorageCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.SecStorageSetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.storage.ListTemplateAnswer;
+import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.template.TemplateProp;
+import com.cloud.utils.component.ComponentContext;
+
+public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
+ private static final Logger s_logger = Logger.getLogger(LocalSecondaryStorageResource.class);
+ int _timeout;
+
+ String _instance;
+ String _parent;
+
+ String _dc;
+ String _pod;
+ String _guid;
+
+ StorageLayer _storage;
+
+ DownloadManager _dlMgr;
+
+ @Override
+ public void disconnected() {
+ }
+
+ @Override
+ public String getRootDir(String url) {
+ return getRootDir();
+
+ }
+
+ public String getRootDir() {
+ return _parent;
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ if (cmd instanceof DownloadProgressCommand) {
+ return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
+ } else if (cmd instanceof DownloadCommand) {
+ return _dlMgr.handleDownloadCommand(this, (DownloadCommand)cmd);
+ } else if (cmd instanceof CheckHealthCommand) {
+ return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
+ } else if (cmd instanceof SecStorageSetupCommand) {
+ return new Answer(cmd, true, "success");
+ } else if (cmd instanceof ReadyCommand) {
+ return new ReadyAnswer((ReadyCommand)cmd);
+ } else if (cmd instanceof ListTemplateCommand) {
+ return execute((ListTemplateCommand)cmd);
+ } else if (cmd instanceof ComputeChecksumCommand) {
+ return execute((ComputeChecksumCommand)cmd);
+ } else {
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+ }
+
+ private Answer execute(ComputeChecksumCommand cmd) {
+ return new Answer(cmd, false, null);
+ }
+
+ private Answer execute(ListTemplateCommand cmd) {
+ String root = getRootDir();
+ Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
+ return new ListTemplateAnswer(((NfsTO)cmd.getDataStore()).getUrl(), templateInfos);
+ }
+
+ @Override
+ public Type getType() {
+ return Host.Type.LocalSecondaryStorage;
+ }
+
+ @Override
+ public PingCommand getCurrentStatus(final long id) {
+ return new PingStorageCommand(Host.Type.Storage, id, new HashMap<String, Boolean>());
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ super.configure(name, params);
+
+ _guid = (String)params.get("guid");
+ if (_guid == null) {
+ throw new ConfigurationException("Unable to find the guid");
+ }
+
+ _dc = (String)params.get("zone");
+ if (_dc == null) {
+ throw new ConfigurationException("Unable to find the zone");
+ }
+ _pod = (String)params.get("pod");
+
+ _instance = (String)params.get("instance");
+
+ _parent = (String)params.get("mount.path");
+ if (_parent == null) {
+ throw new ConfigurationException("No directory specified.");
+ }
+
+ _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
+ if (_storage == null) {
+ String value = (String)params.get(StorageLayer.ClassConfigKey);
+ if (value == null) {
+ value = "com.cloud.storage.JavaStorageLayer";
+ }
+
+ try {
+ Class<StorageLayer> clazz = (Class<StorageLayer>)Class.forName(value);
+ _storage = ComponentContext.inject(clazz);
+ } catch (ClassNotFoundException e) {
+ throw new ConfigurationException("Unable to find class " + value);
+ }
+ }
+
+ if (!_storage.mkdirs(_parent)) {
+ s_logger.warn("Unable to create the directory " + _parent);
+ throw new ConfigurationException("Unable to create the directory " + _parent);
+ }
+
+ s_logger.info("Mount point established at " + _parent);
+
+ params.put("template.parent", _parent);
+ params.put(StorageLayer.InstanceConfigKey, _storage);
+
+ _dlMgr = new DownloadManagerImpl();
+ _dlMgr.configure("DownloadManager", params);
+
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public StartupCommand[] initialize() {
+
+ final StartupStorageCommand cmd =
+ new StartupStorageCommand(_parent, StoragePoolType.Filesystem, 1024l * 1024l * 1024l * 1024l, _dlMgr.gatherTemplateInfo(_parent));
+ cmd.setResourceType(Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE);
+ cmd.setIqn("local://");
+ fillNetworkInformation(cmd);
+ cmd.setDataCenter(_dc);
+ cmd.setPod(_pod);
+ cmd.setGuid(_guid);
+ cmd.setName(_guid);
+ cmd.setVersion(LocalSecondaryStorageResource.class.getPackage().getImplementationVersion());
+
+ return new StartupCommand[] {cmd};
+ }
+
+ @Override
+ protected String getDefaultScriptsDir() {
+ return "scripts/storage/secondary";
+ }
+
+ @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 int getRunLevel() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void setRunLevel(int level) {
+ // TODO Auto-generated method stub
+
+ }
+}