You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ch...@apache.org on 2013/04/10 00:16:23 UTC
[01/19] git commit: updated refs/heads/master to bf56403
Updated Branches:
refs/heads/master 4fd3fca84 -> bf56403d8
QuickCloud: start console proxy service from mvn exec:java
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/16790446
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/16790446
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/16790446
Branch: refs/heads/master
Commit: 16790446e51645dc3e2623ebf57f88e0cfe2c89c
Parents: e7983b2
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Mon Mar 25 12:15:14 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:25 2013 -0700
----------------------------------------------------------------------
services/console-proxy/server/conf/log4j-cloud.xml | 2 +-
services/console-proxy/server/pom.xml | 38 +++++++++++++++
2 files changed, 39 insertions(+), 1 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/16790446/services/console-proxy/server/conf/log4j-cloud.xml
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/conf/log4j-cloud.xml b/services/console-proxy/server/conf/log4j-cloud.xml
index 5b31c9d..2d1d361 100644
--- a/services/console-proxy/server/conf/log4j-cloud.xml
+++ b/services/console-proxy/server/conf/log4j-cloud.xml
@@ -27,7 +27,7 @@ under the License.
<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
- <param name="File" value="/var/log/cloud/systemvm.log"/>
+ <param name="File" value="${log.home}systemvm.log"/>
<param name="Append" value="true"/>
<param name="Threshold" value="DEBUG"/>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/16790446/services/console-proxy/server/pom.xml
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml
index f57b4ca..fd7b964 100644
--- a/services/console-proxy/server/pom.xml
+++ b/services/console-proxy/server/pom.xml
@@ -254,6 +254,44 @@
</plugins>
</build>
</profile>
+ <profile>
+ <id>quickcloud</id>
+ <activation>
+ <property>
+ <name>quickcloud</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <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>
+ </arguments>
+ <systemProperties>
+ <systemProperty>
+ <key>javax.net.ssl.trustStore</key>
+ <value>certs/realhostip.keystore</value>
+ </systemProperty>
+ </systemProperties>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
</profiles>
</project>
[18/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: default to enabled if not specified in datacenter config
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/bf56403d
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/bf56403d
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/bf56403d
Branch: refs/heads/master
Commit: bf56403d828aa50c0650cc41cdc51aae79b1c19e
Parents: 2e6c65f
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Tue Apr 9 14:45:12 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:27 2013 -0700
----------------------------------------------------------------------
tools/marvin/marvin/deployDataCenter.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bf56403d/tools/marvin/marvin/deployDataCenter.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py
index d365395..2e270a7 100644
--- a/tools/marvin/marvin/deployDataCenter.py
+++ b/tools/marvin/marvin/deployDataCenter.py
@@ -329,7 +329,7 @@ class deployDataCenters():
self.createSecondaryStorages(zone.secondaryStorages, zoneId)
enabled = getattr(zone, 'enabled', 'True')
- if enabled == 'True' or enabled == 'None':
+ if enabled == 'True' or enabled is None:
self.enableZone(zoneId, "Enabled")
details = getattr(zone, 'details')
if details is not None:
[15/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: also look for consoleproxy.properties using PropertiesUtil.
When executed with mvn exec:java, the path 'conf' is not on the classpath
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/21b46359
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/21b46359
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/21b46359
Branch: refs/heads/master
Commit: 21b4635948152710935ba420cee50b823fd7a2b4
Parents: 3d78019
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Tue Mar 26 10:06:46 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700
----------------------------------------------------------------------
.../src/com/cloud/consoleproxy/ConsoleProxy.java | 16 +++++++++++++-
1 files changed, 14 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21b46359/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java
index b5c2989..2abce56 100644
--- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java
+++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java
@@ -17,6 +17,8 @@
package com.cloud.consoleproxy;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -34,6 +36,7 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.xml.DOMConfigurator;
import com.cloud.consoleproxy.util.Logger;
+import com.cloud.utils.PropertiesUtil;
import com.google.gson.Gson;
import com.sun.net.httpserver.HttpServer;
@@ -282,8 +285,17 @@ public class ConsoleProxy {
InputStream confs = ConsoleProxy.class.getResourceAsStream("/conf/consoleproxy.properties");
Properties props = new Properties();
if (confs == null) {
- s_logger.info("Can't load consoleproxy.properties from classpath, will use default configuration");
- } else {
+ final File file = PropertiesUtil.findConfigFile("consoleproxy.properties");
+ if (file == null)
+ s_logger.info("Can't load consoleproxy.properties from classpath, will use default configuration");
+ else
+ try {
+ confs = new FileInputStream(file);
+ } catch (FileNotFoundException e) {
+ s_logger.info("Ignoring file not found exception and using defaults");
+ }
+ }
+ if (confs != null) {
try {
props.load(confs);
[17/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: we moved the SecondaryStorageDiscoverer from the com.cloud package to the org.apache.cloudstack package
QuickCloud: fix license issue
QuickCloud: use a different activation for deploying quickcloud
Otherwise marvin gets invoked during mvn install -Dquickcloud
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/271d232d
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/271d232d
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/271d232d
Branch: refs/heads/master
Commit: 271d232d620f27c6b8b10bc85f849563c528e3ae
Parents: 778a59f
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Fri Apr 5 11:52:52 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:27 2013 -0700
----------------------------------------------------------------------
client/tomcatconf/applicationContext.xml.in | 2 +-
.../cloud/consoleproxy/ConsoleProxyService.java | 16 +++++++++++++++
tools/devcloud/pom.xml | 4 +-
3 files changed, 19 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/271d232d/client/tomcatconf/applicationContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in
index 3b51a83..67b1286 100644
--- a/client/tomcatconf/applicationContext.xml.in
+++ b/client/tomcatconf/applicationContext.xml.in
@@ -503,7 +503,7 @@
<property name="name" value="XCP Agent"/>
</bean>
- <bean id="SecondaryStorageDiscoverer" class="com.cloud.storage.secondary.SecondaryStorageDiscoverer">
+ <bean id="SecondaryStorageDiscoverer" class="org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer">
<property name="name" value="SecondaryStorage"/>
</bean>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/271d232d/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyService.java b/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
index e43e5c3..fd00f56 100644
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
@@ -1,3 +1,19 @@
+// 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.consoleproxy;
import com.cloud.info.ConsoleProxyInfo;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/271d232d/tools/devcloud/pom.xml
----------------------------------------------------------------------
diff --git a/tools/devcloud/pom.xml b/tools/devcloud/pom.xml
index 93029e1..ba4cc46 100644
--- a/tools/devcloud/pom.xml
+++ b/tools/devcloud/pom.xml
@@ -146,7 +146,7 @@
<id>quickcloud</id>
<activation>
<property>
- <name>quickcloud</name>
+ <name>deployquick</name>
</property>
</activation>
<build>
@@ -157,7 +157,7 @@
<version>1.2.1</version>
<executions>
<execution>
- <phase>package</phase>
+ <phase>integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
[05/19] QuickCloud: Enable secondary storage daemon to run outside
the system vm
Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/template/DownloadManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java
deleted file mode 100755
index 22e78a0..0000000
--- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java
+++ /dev/null
@@ -1,1049 +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.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 com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.storage.DownloadCommand;
-import com.cloud.agent.api.storage.DownloadCommand.Proxy;
-import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
-import com.cloud.agent.api.storage.DownloadProgressCommand;
-import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
-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.resource.SecondaryStorageResource;
-import com.cloud.storage.template.Processor.FormatInfo;
-import com.cloud.storage.template.TemplateDownloader.DownloadCompleteCallback;
-import com.cloud.storage.template.TemplateDownloader.Status;
-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 jobId;
- private final String tmpltName;
- private final boolean hvm;
- private final ImageFormat format;
- private String tmpltPath;
- private final String description;
- private String checksum;
- private final Long accountId;
- 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.jobId = jobId;
- this.tmpltName = tmpltName;
- this.format = format;
- this.hvm = hvm;
- this.accountId = accountId;
- this.description = descr;
- this.checksum = cksum;
- this.installPathPrefix = installPathPrefix;
- this.templatesize = 0;
- this.id = id;
- this.resourceType = resourceType;
- }
-
- public TemplateDownloader getTd() {
- return td;
- }
-
- public String getDescription() {
- return description;
- }
-
- public String getChecksum() {
- return checksum;
- }
-
- public TemplateDownloader getTemplateDownloader() {
- return td;
- }
-
- public String getJobId() {
- return jobId;
- }
-
- public String getTmpltName() {
- return tmpltName;
- }
-
- public ImageFormat getFormat() {
- return format;
- }
-
- public boolean isHvm() {
- return hvm;
- }
-
- public Long getAccountId() {
- return accountId;
- }
-
- 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 List<Processor> processors;
-
- 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;
- private boolean _sslCopy;
-
- /**
- * 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:
- 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()));
- }
- 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 = null;
- ResourceType resourceType = dnld.getResourceType();
-
- // once template path is set, remove the parent dir so that the template is installed with a relative path
- String finalResourcePath = "";
- if (resourceType == ResourceType.TEMPLATE){
- finalResourcePath += _templateDir + File.separator + dnld.getAccountId() + File.separator + dnld.getId() + File.separator;
- resourcePath = dnld.getInstallPathPrefix() + dnld.getAccountId() + File.separator + dnld.getId() + File.separator;// dnld.getTmpltName();
- }else {
- finalResourcePath += _volumeDir + File.separator + dnld.getId() + File.separator;
- resourcePath = dnld.getInstallPathPrefix() + dnld.getId() + File.separator;// dnld.getTmpltName();
- }
-
- _storage.mkdirs(resourcePath);
- dnld.setTmpltPath(finalResourcePath);
-
- 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();
- }
-
- String templateFilename = templateName + "." + extension;
- dnld.setTmpltPath(finalResourcePath + "/" + templateFilename);
- scr.add("-n", templateFilename);
-
- scr.add("-t", resourcePath);
- scr.add("-f", td.getDownloadLocalPath());
- 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 downloadPublicTemplate(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();
- String tmpDir = "";
- if(resourceType == ResourceType.TEMPLATE){
- tmpDir = installPathPrefix + File.separator + accountId + File.separator + id;
- }else {
- tmpDir = installPathPrefix + File.separator + id;
- }
-
- 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")) {
- 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);
- }
- DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType);
- 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);
- }
-
- String installPathPrefix = null;
- if (ResourceType.TEMPLATE == resourceType){
- installPathPrefix = resource.getRootDir(cmd) + File.separator + _templateDir;
- }else {
- installPathPrefix = resource.getRootDir(cmd) + File.separator + _volumeDir;
- }
-
- String user = null;
- String password = null;
- if (cmd.getAuth() != null) {
- user = cmd.getAuth().getUserName();
- password = new String(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 = downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), installPathPrefix, 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", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR.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 String createTempDir(File rootDir, String name) throws IOException {
-
- File f = File.createTempFile(name, "", rootDir);
- f.delete();
- f.mkdir();
- _storage.setWorldReadableAndWriteable(f);
- return f.getAbsolutePath();
-
- }
-
-
- 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, TemplateInfo> gatherTemplateInfo(String rootDir) {
- Map<String, TemplateInfo> result = new HashMap<String, TemplateInfo>();
- 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;
- }
-
- TemplateInfo tInfo = loc.getTemplateInfo();
-
- if ((tInfo.size == tInfo.physicalSize) && (tInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) {
- try {
- Processor processor = _processors.get("VMDK Processor");
- VmdkProcessor vmdkProcessor = (VmdkProcessor)processor;
- long vSize = vmdkProcessor.getTemplateVirtualSize(path, tInfo.installPath.substring(tInfo.installPath.lastIndexOf(File.separator) + 1));
- tInfo.size = vSize;
- loc.updateVirtualSize(vSize);
- loc.save();
- } catch (Exception e) {
- s_logger.error("Unable to get the virtual size of the template: " + tInfo.installPath + " due to " + e.getMessage());
- }
- }
-
- result.put(tInfo.templateName, tInfo);
- s_logger.debug("Added template name: " + tInfo.templateName + ", 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, TemplateInfo> gatherVolumeInfo(String rootDir) {
- Map<Long, TemplateInfo> result = new HashMap<Long, TemplateInfo>();
- 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;
- }
-
- TemplateInfo vInfo = loc.getTemplateInfo();
-
- if ((vInfo.size == vInfo.physicalSize) && (vInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) {
- try {
- Processor processor = _processors.get("VMDK Processor");
- VmdkProcessor vmdkProcessor = (VmdkProcessor)processor;
- long vSize = vmdkProcessor.getTemplateVirtualSize(path, vInfo.installPath.substring(vInfo.installPath.lastIndexOf(File.separator) + 1));
- vInfo.size = vSize;
- loc.updateVirtualSize(vSize);
- loc.save();
- } catch (Exception e) {
- s_logger.error("Unable to get the virtual size of the volume: " + vInfo.installPath + " due to " + e.getMessage());
- }
- }
-
- result.put(vInfo.getId(), vInfo);
- s_logger.debug("Added volume name: " + vInfo.templateName + ", path: " + vol);
- }
- return result;
- }
-
- private int deleteDownloadDirectories(File downloadPath, int deleted) {
- try {
- if (downloadPath.exists()) {
- File[] files = downloadPath.listFiles();
- for (int i = 0; i < files.length; i++) {
- if (files[i].isDirectory()) {
- deleteDownloadDirectories(files[i], deleted);
- files[i].delete();
- deleted++;
- } else {
- files[i].delete();
- deleted++;
- }
- }
- }
- } catch (Exception ex) {
- s_logger.info("Failed to clean up template downloads directory " + ex.toString());
- }
- return deleted;
- }
-
- 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 useSsl = (String)params.get("sslcopy");
- if (useSsl != null) {
- _sslCopy = Boolean.parseBoolean(useSsl);
-
- }
- 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");
- this.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 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/e7983b25/core/src/com/cloud/storage/template/UploadManager.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/UploadManager.java b/core/src/com/cloud/storage/template/UploadManager.java
deleted file mode 100755
index fa40b8c..0000000
--- a/core/src/com/cloud/storage/template/UploadManager.java
+++ /dev/null
@@ -1,85 +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.template;
-
-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.resource.SecondaryStorageResource;
-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);
-
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/template/UploadManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/UploadManagerImpl.java b/core/src/com/cloud/storage/template/UploadManagerImpl.java
deleted file mode 100755
index 2492a1b..0000000
--- a/core/src/com/cloud/storage/template/UploadManagerImpl.java
+++ /dev/null
@@ -1,645 +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.template;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-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.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-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.resource.SecondaryStorageResource;
-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;
- private final String jobId;
- private final String name;
- private final ImageFormat format;
- private String tmpltPath;
- private String description;
- private String checksum;
- private Long accountId;
- private String installPathPrefix;
- private long templatesize;
- private long id;
-
- 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;
- this.jobId = jobId;
- this.name = name;
- this.format = format;
- this.accountId = accountId;
- this.description = descr;
- this.checksum = cksum;
- this.installPathPrefix = installPathPrefix;
- this.templatesize = 0;
- this.id = id;
- }
-
- public TemplateUploader getTd() {
- return tu;
- }
-
- public String getDescription() {
- return description;
- }
-
- public String getChecksum() {
- return checksum;
- }
-
- public UploadJob(TemplateUploader td, String jobId, UploadCommand cmd) {
- this.tu = td;
- this.jobId = jobId;
- this.name = cmd.getName();
- this.format = cmd.getFormat();
- }
-
- public TemplateUploader getTemplateUploader() {
- return tu;
- }
-
- public String getJobId() {
- return jobId;
- }
-
- public String getTmpltName() {
- return name;
- }
-
- public ImageFormat getFormat() {
- return format;
- }
-
- public Long getAccountId() {
- return accountId;
- }
-
- public long getId() {
- return id;
- }
-
- public void setTmpltPath(String tmpltPath) {
- this.tmpltPath = tmpltPath;
- }
-
- public String getTmpltPath() {
- return tmpltPath;
- }
-
- public String getInstallPathPrefix() {
- return installPathPrefix;
- }
-
- public void cleanup() {
- if (tu != null) {
- String upldPath = tu.getUploadLocalPath();
- if (upldPath != null) {
- File f = new File(upldPath);
- f.delete();
- }
- }
- }
-
- public void setTemplatesize(long templatesize) {
- this.templatesize = templatesize;
- }
-
- public long getTemplatesize() {
- return templatesize;
- }
- }
- 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 List<Processor> _processors;
- private String publicTemplateRepo;
- private final String extractMountPoint = "/mnt/SecStorage/extractmnt";
- private StorageLayer _storage;
- private int installTimeoutPerGig;
- private boolean _sslCopy;
- 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();
- if (jobId == null) {
- return new UploadAnswer(null, 0, "Internal Error", com.cloud.storage.UploadVO.Status.UPLOAD_ERROR, "", "", 0);
- }
- 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){
- UploadJob uj = jobs.get(jobId);
- if (uj != null) {
- return uj.getTemplatesize();
- }
- return 0;
- }
-
- @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 useSsl = (String)params.get("sslcopy");
- if (useSsl != null) {
- _sslCopy = Boolean.parseBoolean(useSsl);
-
- }
- 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.timeout.pergig");
- this.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";
- }
-
- // 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/e7983b25/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
index 2d81c2a..a012340 100644
--- a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
@@ -20,6 +20,7 @@ import java.util.Map;
import javax.naming.ConfigurationException;
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
@@ -35,7 +36,6 @@ import com.cloud.agent.manager.SimulatorManager;
import com.cloud.agent.manager.SimulatorManager.AgentType;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
-import com.cloud.storage.resource.SecondaryStorageResource;
import com.cloud.vm.SecondaryStorageVm;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
index 856982a..3966e02 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
@@ -21,6 +21,8 @@ import java.util.Map;
import javax.naming.ConfigurationException;
+import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
+import org.apache.cloudstack.storage.resource.SecondaryStorageResourceHandler;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
index 566e750..ce42f67 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
@@ -18,6 +18,7 @@ package com.cloud.storage.resource;
import java.util.List;
+import org.apache.cloudstack.storage.resource.SecondaryStorageResourceHandler;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/scripts/vm/systemvm/injectkeys.sh
----------------------------------------------------------------------
diff --git a/scripts/vm/systemvm/injectkeys.sh b/scripts/vm/systemvm/injectkeys.sh
index e56eb85..49adfb3 100755
--- a/scripts/vm/systemvm/injectkeys.sh
+++ b/scripts/vm/systemvm/injectkeys.sh
@@ -22,6 +22,7 @@
# $2 = new private key
#set -x
+set -e
TMP=/tmp
MOUNTPATH=${HOME}/systemvm_mnt
@@ -29,7 +30,7 @@ TMPDIR=${TMP}/cloud/systemvm
clean_up() {
- sudo umount $MOUNTPATH
+ $SUDO umount $MOUNTPATH
}
inject_into_iso() {
@@ -39,23 +40,23 @@ inject_into_iso() {
local tmpiso=${TMP}/$1
mkdir -p $MOUNTPATH
[ ! -f $isofile ] && echo "$(basename $0): Could not find systemvm iso patch file $isofile" && return 1
- sudo mount -o loop $isofile $MOUNTPATH
+ $SUDO mount -o loop $isofile $MOUNTPATH
[ $? -ne 0 ] && echo "$(basename $0): Failed to mount original iso $isofile" && clean_up && return 1
diff -q $MOUNTPATH/authorized_keys $newpubkey &> /dev/null && clean_up && return 0
- sudo cp -b $isofile $backup
+ $SUDO cp -b $isofile $backup
[ $? -ne 0 ] && echo "$(basename $0): Failed to backup original iso $isofile" && clean_up && return 1
rm -rf $TMPDIR
mkdir -p $TMPDIR
[ ! -d $TMPDIR ] && echo "$(basename $0): Could not find/create temporary dir $TMPDIR" && clean_up && return 1
- sudo cp -fr $MOUNTPATH/* $TMPDIR/
+ $SUDO cp -fr $MOUNTPATH/* $TMPDIR/
[ $? -ne 0 ] && echo "$(basename $0): Failed to copy from original iso $isofile" && clean_up && return 1
- sudo cp $newpubkey $TMPDIR/authorized_keys
+ $SUDO cp $newpubkey $TMPDIR/authorized_keys
[ $? -ne 0 ] && echo "$(basename $0): Failed to copy key $newpubkey from original iso to new iso " && clean_up && return 1
mkisofs -quiet -r -o $tmpiso $TMPDIR
[ $? -ne 0 ] && echo "$(basename $0): Failed to create new iso $tmpiso from $TMPDIR" && clean_up && return 1
- sudo umount $MOUNTPATH
+ $SUDO umount $MOUNTPATH
[ $? -ne 0 ] && echo "$(basename $0): Failed to unmount old iso from $MOUNTPATH" && return 1
- sudo cp -f $tmpiso $isofile
+ $SUDO cp -f $tmpiso $isofile
[ $? -ne 0 ] && echo "$(basename $0): Failed to overwrite old iso $isofile with $tmpiso" && return 1
rm -rf $TMPDIR
}
@@ -63,12 +64,17 @@ inject_into_iso() {
copy_priv_key() {
local newprivkey=$1
diff -q $newprivkey $(dirname $0)/id_rsa.cloud && return 0
- sudo cp -fb $newprivkey $(dirname $0)/id_rsa.cloud
- sudo chmod 644 $(dirname $0)/id_rsa.cloud
+ $SUDO cp -fb $newprivkey $(dirname $0)/id_rsa.cloud
+ $SUDO chmod 644 $(dirname $0)/id_rsa.cloud
return $?
}
-sudo mkdir -p $MOUNTPATH
+if [[ `whoami` == cloud* ]]
+then
+ SUDO=$SUDO
+fi
+
+$SUDO mkdir -p $MOUNTPATH
[ $# -ne 3 ] && echo "Usage: $(basename $0) <new public key file> <new private key file> <systemvm iso path>" && exit 3
newpubkey=$1
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/server/pom.xml
----------------------------------------------------------------------
diff --git a/server/pom.xml b/server/pom.xml
index a397195..8a6a10c 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -32,6 +32,11 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-secondary-storage</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${cs.servlet.version}</version>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java b/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
index 3ca74a3..6e66e0d 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
@@ -30,6 +30,8 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import org.apache.cloudstack.storage.resource.LocalSecondaryStorageResource;
+import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@@ -47,8 +49,6 @@ import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.resource.DummySecondaryStorageResource;
-import com.cloud.storage.resource.LocalSecondaryStorageResource;
-import com.cloud.storage.resource.NfsSecondaryStorageResource;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.net.NfsUtils;
import com.cloud.utils.script.Script;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/pom.xml
----------------------------------------------------------------------
diff --git a/services/pom.xml b/services/pom.xml
index 35ec2e1..54b22bb 100644
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -32,5 +32,6 @@
</build>
<modules>
<module>console-proxy</module>
+ <module>secondary-storage</module>
</modules>
</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/conf/agent.properties
----------------------------------------------------------------------
diff --git a/services/secondary-storage/conf/agent.properties b/services/secondary-storage/conf/agent.properties
new file mode 100644
index 0000000..4a25cbd
--- /dev/null
+++ b/services/secondary-storage/conf/agent.properties
@@ -0,0 +1,11 @@
+#Storage
+#Sun Mar 24 22:52:35 PDT 2013
+mount.path=/Users/chiradeep/secondary-storage
+eth1ip=192.168.56.1
+name=192.168.56.10
+eth2ip=192.168.56.10
+resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource
+piddir=.
+instance=SecondaryStorage
+developer=true
+secondary.storage.vm=false
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/conf/environment.properties
----------------------------------------------------------------------
diff --git a/services/secondary-storage/conf/environment.properties b/services/secondary-storage/conf/environment.properties
new file mode 100644
index 0000000..269acad
--- /dev/null
+++ b/services/secondary-storage/conf/environment.properties
@@ -0,0 +1,2 @@
+paths.script=../../scripts/storage/secondary/
+paths.pid=.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/conf/log4j-cloud.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/conf/log4j-cloud.xml b/services/secondary-storage/conf/log4j-cloud.xml
new file mode 100644
index 0000000..7d9d22c
--- /dev/null
+++ b/services/secondary-storage/conf/log4j-cloud.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+
+ <!-- ================================= -->
+ <!-- Preserve messages in a local file -->
+ <!-- ================================= -->
+
+ <!-- A time/date based rolling appender -->
+ <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
+ <param name="File" value="${ss.log.home}systemvm.log"/>
+ <param name="Append" value="true"/>
+ <param name="Threshold" value="DEBUG"/>
+
+ <!-- Rollover at midnight each day -->
+ <param name="DatePattern" value="'.'yyyy-MM-dd"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %-5p [%c{3}] (%t:%x) %m%n"/>
+ </layout>
+ </appender>
+
+ <!-- ============================== -->
+ <!-- Append messages to the console -->
+ <!-- ============================== -->
+
+ <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+ <param name="Target" value="System.out"/>
+ <param name="Threshold" value="WARN"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d{ABSOLUTE} %5p %c{1}:%L - %m%n"/>
+ </layout>
+ </appender>
+
+ <!-- ================ -->
+ <!-- Limit categories -->
+ <!-- ================ -->
+
+ <category name="com.cloud.console.ConsoleCanvas">
+ <priority value="WARN"/>
+ </category>
+
+ <category name="com.cloud.consoleproxy.ConsoleProxyAjaxImageHandler">
+ <priority value="WARN"/>
+ </category>
+
+ <category name="com.cloud.consoleproxy.ConsoleProxyViewer">
+ <priority value="WARN"/>
+ </category>
+
+ <category name="com.cloud.consoleproxy">
+ <priority value="INFO"/>
+ </category>
+
+ <category name="com.cloud">
+ <priority value="DEBUG"/>
+ </category>
+
+ <!-- Limit the org.apache category to INFO as its DEBUG is verbose -->
+ <category name="org.apache">
+ <priority value="DEBUG"/>
+ </category>
+
+ <category name="org">
+ <priority value="INFO"/>
+ </category>
+
+ <category name="net">
+ <priority value="INFO"/>
+ </category>
+
+ <!-- ======================= -->
+ <!-- Setup the Root category -->
+ <!-- ======================= -->
+
+ <root>
+ <level value="DEBUG"/>
+ <appender-ref ref="CONSOLE"/>
+ <appender-ref ref="FILE"/>
+ </root>
+
+</log4j:configuration>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/pom.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml
new file mode 100644
index 0000000..d8dbf1d
--- /dev/null
+++ b/services/secondary-storage/pom.xml
@@ -0,0 +1,113 @@
+<!--
+ 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>cloud-services</artifactId>
+ <version>4.2.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <dependencies>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>${cs.log4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>${cs.gson.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>${cs.codec.version}</version>
+ </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-patches</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+ <build>
+ <defaultGoal>install</defaultGoal>
+ <sourceDirectory>src</sourceDirectory>
+ <plugins>
+ <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>
+ </arguments>
+ <systemProperties>
+ <systemProperty>
+ <key>javax.net.ssl.trustStore</key>
+ <value>certs/realhostip.keystore</value>
+ </systemProperty>
+ </systemProperties>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>vmware</id>
+ <activation>
+ <property>
+ <name>nonoss</name>
+ </property>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-plugin-hypervisor-vmware</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-vmware-base</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+
+</project>
[03/19] QuickCloud: Enable secondary storage daemon to run outside
the system vm
Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/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
new file mode 100755
index 0000000..6bcf98e
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -0,0 +1,1882 @@
+// 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.deleteDirectory;
+import static com.cloud.utils.S3Utils.getDirectory;
+import static com.cloud.utils.S3Utils.putDirectory;
+import static com.cloud.utils.StringUtils.join;
+import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock;
+import static java.lang.String.format;
+import static java.util.Arrays.asList;
+import static org.apache.commons.lang.StringUtils.substringAfterLast;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.URI;
+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 java.util.concurrent.Callable;
+
+import javax.naming.ConfigurationException;
+
+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.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckHealthAnswer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CleanupSnapshotBackupCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ComputeChecksumCommand;
+import com.cloud.agent.api.DeleteObjectFromSwiftCommand;
+import com.cloud.agent.api.DeleteSnapshotBackupCommand;
+import com.cloud.agent.api.DeleteSnapshotsDirCommand;
+import com.cloud.agent.api.DeleteTemplateFromS3Command;
+import com.cloud.agent.api.DownloadSnapshotFromS3Command;
+import com.cloud.agent.api.DownloadTemplateFromS3ToSecondaryStorageCommand;
+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.SecStorageSetupCommand.Certificates;
+import com.cloud.agent.api.SecStorageVMSetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupSecondaryStorageCommand;
+import com.cloud.agent.api.UploadTemplateToS3FromSecondaryStorageCommand;
+import com.cloud.agent.api.downloadSnapshotFromSwiftCommand;
+import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand;
+import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand;
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteTemplateCommand;
+import com.cloud.agent.api.storage.DeleteVolumeCommand;
+import com.cloud.agent.api.storage.DownloadCommand;
+import com.cloud.agent.api.storage.DownloadProgressCommand;
+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.storage.ssCommand;
+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.resource.ServerResourceBase;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateLocation;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.S3Utils;
+import com.cloud.utils.S3Utils.FileNamingStrategy;
+import com.cloud.utils.S3Utils.ObjectNamingStrategy;
+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 SNAPSHOT_ROOT_DIR = "snapshots";
+
+ int _timeout;
+
+ String _instance;
+ String _dc;
+ String _pod;
+ String _guid;
+ String _role;
+ Map<String, Object> _params;
+ StorageLayer _storage;
+ protected boolean _inSystemVM = false;
+ boolean _sslCopy = false;
+
+ DownloadManager _dlMgr;
+ 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>();
+ private String _parent = "/mnt/SecStorage";
+ final private String _tmpltDir = "/var/cloudstack/template";
+ final private String _tmpltpp = "template.properties";
+ @Override
+ public void disconnected() {
+ }
+
+ @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 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 DeleteTemplateCommand) {
+ return execute((DeleteTemplateCommand) cmd);
+ } else if (cmd instanceof DeleteVolumeCommand) {
+ return execute((DeleteVolumeCommand) cmd);
+ }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 downloadSnapshotFromSwiftCommand){
+ return execute((downloadSnapshotFromSwiftCommand)cmd);
+ } else if (cmd instanceof DownloadSnapshotFromS3Command) {
+ return execute((DownloadSnapshotFromS3Command) cmd);
+ } else if (cmd instanceof DeleteSnapshotBackupCommand){
+ return execute((DeleteSnapshotBackupCommand)cmd);
+ } else if (cmd instanceof DeleteSnapshotsDirCommand){
+ return execute((DeleteSnapshotsDirCommand)cmd);
+ } else if (cmd instanceof downloadTemplateFromSwiftToSecondaryStorageCommand) {
+ return execute((downloadTemplateFromSwiftToSecondaryStorageCommand) cmd);
+ } else if (cmd instanceof DownloadTemplateFromS3ToSecondaryStorageCommand) {
+ return execute((DownloadTemplateFromS3ToSecondaryStorageCommand) cmd);
+ } else if (cmd instanceof uploadTemplateToSwiftFromSecondaryStorageCommand) {
+ return execute((uploadTemplateToSwiftFromSecondaryStorageCommand) cmd);
+ } else if (cmd instanceof UploadTemplateToS3FromSecondaryStorageCommand) {
+ return execute((UploadTemplateToS3FromSecondaryStorageCommand) cmd);
+ } else if (cmd instanceof DeleteObjectFromSwiftCommand) {
+ return execute((DeleteObjectFromSwiftCommand) cmd);
+ } else if (cmd instanceof DeleteTemplateFromS3Command) {
+ return execute((DeleteTemplateFromS3Command) cmd);
+ } else if (cmd instanceof CleanupSnapshotBackupCommand){
+ return execute((CleanupSnapshotBackupCommand)cmd);
+ } else {
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private String determineS3TemplateDirectory(final Long accountId,
+ final Long templateId) {
+ return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId),
+ S3Utils.SEPARATOR);
+ }
+
+ @SuppressWarnings("unchecked")
+ private String determineStorageTemplatePath(final String storagePath,
+ final Long accountId, final Long templateId) {
+ return join(
+ asList(getRootDir(storagePath), TEMPLATE_ROOT_DIR, accountId,
+ templateId), File.separator);
+ }
+
+ private Answer execute(
+ final DownloadTemplateFromS3ToSecondaryStorageCommand cmd) {
+
+ final S3TO s3 = cmd.getS3();
+ final String storagePath = cmd.getStoragePath();
+ final Long accountId = cmd.getAccountId();
+ final Long templateId = cmd.getTemplateId();
+
+ try {
+
+ final File downloadDirectory = _storage
+ .getFile(determineStorageTemplatePath(storagePath,
+ accountId, templateId));
+ downloadDirectory.mkdirs();
+
+ if (!downloadDirectory.exists()) {
+ final String errMsg = format(
+ "Unable to create directory "
+ + "download directory %1$s for download of template id "
+ + "%2$s from S3.", downloadDirectory.getName(),
+ templateId);
+ s_logger.error(errMsg);
+ return new Answer(cmd, false, errMsg);
+ }
+
+ getDirectory(s3, s3.getBucketName(),
+ determineS3TemplateDirectory(accountId, templateId),
+ downloadDirectory, new FileNamingStrategy() {
+ @Override
+ public String determineFileName(final String key) {
+ return substringAfterLast(key, S3Utils.SEPARATOR);
+ }
+ });
+
+ return new Answer(cmd, true, format("Successfully downloaded "
+ + "template id %1$s from S3 to directory %2$s", templateId,
+ downloadDirectory.getName()));
+
+ } catch (Exception e) {
+
+ final String errMsg = format("Failed to upload template id %1$s "
+ + "due to $2%s", templateId, e.getMessage());
+ s_logger.error(errMsg, e);
+ return new Answer(cmd, false, errMsg);
+
+ }
+
+ }
+
+ private Answer execute(downloadTemplateFromSwiftToSecondaryStorageCommand cmd) {
+ SwiftTO swift = cmd.getSwift();
+ String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+ Long accountId = cmd.getAccountId();
+ Long templateId = cmd.getTemplateId();
+ String path = cmd.getPath();
+ String errMsg;
+ String lDir = null;
+ try {
+ String parent = getRootDir(secondaryStorageUrl);
+ lDir = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString();
+ String result = createLocalDir(lDir);
+ if (result != null) {
+ errMsg = "downloadTemplateFromSwiftToSecondaryStorageCommand failed due to Create local directory failed";
+ s_logger.warn(errMsg);
+ throw new InternalErrorException(errMsg);
+ }
+ String lPath = lDir + "/" + path;
+ result = swiftDownload(swift, "T-" + templateId.toString(), path, lPath);
+ if (result != null) {
+ errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + " , err=" + result;
+ s_logger.warn(errMsg);
+ throw new CloudRuntimeException(errMsg);
+ }
+ path = "template.properties";
+ lPath = lDir + "/" + path;
+ result = swiftDownload(swift, "T-" + templateId.toString(), path, lPath);
+ if (result != null) {
+ errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + " , err=" + result;
+ s_logger.warn(errMsg);
+ throw new CloudRuntimeException(errMsg);
+ }
+ return new Answer(cmd, true, "success");
+ } catch (Exception e) {
+ if (lDir != null) {
+ deleteLocalDir(lDir);
+ }
+ errMsg = cmd + " Command failed due to " + e.toString();
+ s_logger.warn(errMsg, e);
+ return new Answer(cmd, false, errMsg);
+ }
+ }
+
+ private Answer execute(uploadTemplateToSwiftFromSecondaryStorageCommand cmd) {
+ SwiftTO swift = cmd.getSwift();
+ String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+ Long accountId = cmd.getAccountId();
+ Long templateId = cmd.getTemplateId();
+ try {
+ String parent = getRootDir(secondaryStorageUrl);
+ String lPath = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString();
+ if (!_storage.isFile(lPath + "/template.properties")) {
+ String errMsg = cmd + " Command failed due to template doesn't exist ";
+ s_logger.debug(errMsg);
+ return new Answer(cmd, false, errMsg);
+ }
+ String result = swiftUpload(swift, "T-" + templateId.toString(), lPath, "*");
+ if (result != null) {
+ String errMsg = "failed to upload template from secondary storage " + lPath + " to swift , err=" + result;
+ s_logger.debug(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);
+ }
+ }
+
+ private Answer execute(UploadTemplateToS3FromSecondaryStorageCommand cmd) {
+
+ final S3TO s3 = cmd.getS3();
+ final Long accountId = cmd.getAccountId();
+ final Long templateId = cmd.getTemplateId();
+
+ try {
+
+ final String templatePath = determineStorageTemplatePath(
+ cmd.getStoragePath(), accountId, templateId);
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Found template id " + templateId
+ + " account id " + accountId + " from directory "
+ + templatePath + " to upload to S3.");
+ }
+
+ if (!_storage.isDirectory(templatePath)) {
+ final String errMsg = format("S3 Sync Failure: Directory %1$s"
+ + "for template id %2$s does not exist.", templatePath,
+ templateId);
+ s_logger.error(errMsg);
+ return new Answer(cmd, false, errMsg);
+ }
+
+ if (!_storage.isFile(templatePath + "/template.properties")) {
+ final String errMsg = format("S3 Sync Failure: Template id "
+ + "%1$s does not exist on the file system.",
+ templatePath);
+ s_logger.error(errMsg);
+ return new Answer(cmd, false, errMsg);
+ }
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug(format(
+ "Pushing template id %1$s from %2$s to S3...",
+ templateId, templatePath));
+ }
+
+ final String bucket = s3.getBucketName();
+ putDirectory(s3, bucket, _storage.getFile(templatePath),
+ new FilenameFilter() {
+ @Override
+ public boolean accept(final File directory,
+ final String fileName) {
+ File fileToUpload = new File(directory.getAbsolutePath() + "/" + fileName);
+ return !fileName.startsWith(".") && !fileToUpload.isDirectory();
+ }
+ }, new ObjectNamingStrategy() {
+ @Override
+ public String determineKey(final File file) {
+ s_logger.debug(String
+ .format("Determining key using account id %1$s and template id %2$s",
+ accountId, templateId));
+ return join(
+ asList(determineS3TemplateDirectory(
+ accountId, templateId), file
+ .getName()), S3Utils.SEPARATOR);
+ }
+ });
+
+ return new Answer(
+ cmd,
+ true,
+ format("Uploaded the contents of directory %1$s for template id %2$s to S3 bucket %3$s",
+ templatePath, templateId, bucket));
+
+ } catch (Exception e) {
+
+ final String errMsg = format("Failed to upload template id %1$s",
+ templateId);
+ s_logger.error(errMsg, e);
+ return new Answer(cmd, false, errMsg);
+
+ }
+
+ }
+
+ private Answer execute(DeleteObjectFromSwiftCommand cmd) {
+ SwiftTO swift = cmd.getSwift();
+ String container = cmd.getContainer();
+ String object = cmd.getObject();
+ if (object == null) {
+ 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);
+ }
+
+ }
+
+ private Answer execute(final DeleteTemplateFromS3Command cmd) {
+
+ final S3TO s3 = cmd.getS3();
+ final Long accountId = cmd.getAccountId();
+ final Long templateId = cmd.getTemplateId();
+
+ if (accountId == null || (accountId != null && accountId <= 0)) {
+ final String errorMessage = "No account id specified for S3 template deletion.";
+ s_logger.error(errorMessage);
+ return new Answer(cmd, false, errorMessage);
+ }
+
+ if (templateId == null || (templateId != null && templateId <= 0)) {
+ final String errorMessage = "No template id specified for S3 template deletion.";
+ s_logger.error(errorMessage);
+ return new Answer(cmd, false, errorMessage);
+ }
+
+ if (s3 == null) {
+ final String errorMessge = "No S3 client options provided";
+ s_logger.error(errorMessge);
+ return new Answer(cmd, false, errorMessge);
+ }
+
+ final String bucket = s3.getBucketName();
+ try {
+ deleteDirectory(s3, bucket,
+ determineS3TemplateDirectory(templateId, accountId));
+ return new Answer(cmd, true, String.format(
+ "Deleted template %1%s from bucket %2$s.", templateId,
+ bucket));
+ } catch (Exception e) {
+ final String errorMessage = String
+ .format("Failed to delete templaet id %1$s from bucket %2$s due to the following error: %3$s",
+ templateId, bucket, e.getMessage());
+ s_logger.error(errorMessage, e);
+ return new Answer(cmd, false, errorMessage);
+ }
+
+ }
+
+ 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=" + lines.toString();
+ 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=" + lines.toString();
+ 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=" + lines.toString();
+ 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=" + lines.toString();
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ }
+ }
+ return null;
+ }
+
+
+ public Answer execute(DeleteSnapshotsDirCommand cmd){
+ String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+ Long accountId = cmd.getAccountId();
+ Long volumeId = cmd.getVolumeId();
+ try {
+ String parent = getRootDir(secondaryStorageUrl);
+ String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId) + "/*";
+ 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);
+ }
+ 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);
+ }
+ }
+
+ public Answer execute(final DownloadSnapshotFromS3Command cmd) {
+
+ final S3TO s3 = cmd.getS3();
+ final String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+ final Long accountId = cmd.getAccountId();
+ final Long volumeId = cmd.getVolumeId();
+
+ try {
+
+ executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId),
+ new Callable<Void>() {
+
+ @Override
+ public Void call() throws Exception {
+
+ final String directoryName = determineSnapshotLocalDirectory(
+ secondaryStorageUrl, accountId, volumeId);
+
+ String result = createLocalDir(directoryName);
+ if (result != null) {
+ throw new InternalErrorException(
+ format("Failed to create directory %1$s during S3 snapshot download.",
+ directoryName));
+ }
+
+ final String snapshotFileName = determineSnapshotBackupFilename(cmd
+ .getSnapshotUuid());
+ final String key = determineSnapshotS3Key(
+ accountId, volumeId, snapshotFileName);
+ final File targetFile = S3Utils.getFile(s3,
+ s3.getBucketName(), key,
+ _storage.getFile(directoryName),
+ new FileNamingStrategy() {
+
+ @Override
+ public String determineFileName(
+ String key) {
+ return snapshotFileName;
+ }
+
+ });
+
+ if (cmd.getParent() != null) {
+
+ final String parentPath = join(
+ File.pathSeparator, directoryName,
+ determineSnapshotBackupFilename(cmd
+ .getParent()));
+ result = setVhdParent(
+ targetFile.getAbsolutePath(),
+ parentPath);
+ if (result != null) {
+ throw new InternalErrorException(
+ format("Failed to set the parent for backup %1$s to %2$s due to %3$s.",
+ targetFile
+ .getAbsolutePath(),
+ parentPath, result));
+ }
+
+ }
+
+ return null;
+
+ }
+
+ });
+
+ return new Answer(
+ cmd,
+ true,
+ format("Succesfully retrieved volume id %1$s for account id %2$s to %3$s from S3.",
+ volumeId, accountId, secondaryStorageUrl));
+
+ } catch (Exception e) {
+ final String errMsg = format(
+ "Failed to retrieve volume id %1$s for account id %2$s to %3$s from S3 due to exception %4$s",
+ volumeId, accountId, secondaryStorageUrl, e.getMessage());
+ s_logger.error(errMsg);
+ return new Answer(cmd, false, errMsg);
+ }
+
+ }
+
+ private String determineSnapshotS3Directory(final Long accountId,
+ final Long volumeId) {
+ return join(S3Utils.SEPARATOR, SNAPSHOT_ROOT_DIR, accountId, volumeId);
+ }
+
+ private String determineSnapshotS3Key(final Long accountId,
+ final Long volumeId, final String snapshotFileName) {
+
+ final String directoryName = determineSnapshotS3Directory(accountId,
+ volumeId);
+ return join(S3Utils.SEPARATOR, directoryName, snapshotFileName);
+
+ }
+
+ private String determineSnapshotLocalDirectory(
+ final String secondaryStorageUrl, final Long accountId,
+ final Long volumeId) {
+ return join(File.pathSeparator, getRootDir(secondaryStorageUrl),
+ SNAPSHOT_ROOT_DIR, accountId, volumeId);
+ }
+
+ public Answer execute(downloadSnapshotFromSwiftCommand cmd){
+ SwiftTO swift = cmd.getSwift();
+ String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+ Long accountId = cmd.getAccountId();
+ Long volumeId = cmd.getVolumeId();
+ String rFilename = cmd.getSnapshotUuid();
+ String sParent = cmd.getParent();
+ String errMsg = "";
+ try {
+ String parent = getRootDir(secondaryStorageUrl);
+ String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId);
+
+ String result = createLocalDir(lPath);
+ if ( result != null ) {
+ errMsg = "downloadSnapshotFromSwiftCommand failed due to Create local path failed";
+ s_logger.warn(errMsg);
+ throw new InternalErrorException(errMsg);
+ }
+ String lFilename = rFilename;
+ if ( rFilename.startsWith("VHD-") ) {
+ lFilename = rFilename.replace("VHD-", "") + ".vhd";
+ }
+ String lFullPath = lPath + "/" + lFilename;
+ result = swiftDownload(swift, "S-" + volumeId.toString(), rFilename, lFullPath);
+ if (result != null) {
+ return new Answer(cmd, false, result);
+ }
+ if (sParent != null) {
+ if (sParent.startsWith("VHD-") || sParent.endsWith(".vhd")) {
+ String pFilename = sParent;
+ if (sParent.startsWith("VHD-")) {
+ pFilename = pFilename.replace("VHD-", "") + ".vhd";
+ }
+ String pFullPath = lPath + "/" + pFilename;
+ result = setVhdParent(lFullPath, pFullPath);
+ if (result != null) {
+ return new Answer(cmd, false, result);
+ }
+ }
+ }
+
+ return new Answer(cmd, true, "success");
+ } catch (Exception e) {
+ String msg = cmd + " Command failed due to " + e.toString();
+ s_logger.warn(msg, e);
+ throw new CloudRuntimeException(msg);
+ }
+ }
+
+ private Answer execute(ComputeChecksumCommand cmd) {
+
+ String relativeTemplatePath = cmd.getTemplatePath();
+ String parent = getRootDir(cmd);
+
+ 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(Certificates certs) {
+ if (certs == null) {
+ configureSSL();
+ } else {
+ String prvKey = certs.getPrivKey();
+ String pubCert = certs.getPrivCert();
+ String certChain = certs.getCertChain();
+
+ 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);
+ }
+ String secUrl = cmd.getSecUrl();
+ try {
+ URI uri = new URI(secUrl);
+ String nfsHost = uri.getHost();
+
+ InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
+ String nfsHostIp = nfsHostAddr.getHostAddress();
+
+ addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
+ String nfsPath = nfsHostIp + ":" + uri.getPath();
+ String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString();
+ String root = _parent + "/" + dir;
+ mount(root, nfsPath);
+
+ 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);
+
+ }
+ }
+
+ private String deleteSnapshotBackupFromLocalFileSystem(
+ final String secondaryStorageUrl, final Long accountId,
+ final Long volumeId, final String name, final Boolean deleteAllFlag) {
+
+ final String lPath = determineSnapshotLocalDirectory(
+ secondaryStorageUrl, accountId, volumeId)
+ + File.pathSeparator
+ + (deleteAllFlag ? "*" : "*" + name + "*");
+
+ final String result = deleteLocalFile(lPath);
+
+ if (result != null) {
+ return "failed to delete snapshot " + lPath + " , err=" + result;
+ }
+
+ return null;
+
+ }
+
+ private String deleteSnapshotBackupfromS3(final S3TO s3,
+ final String secondaryStorageUrl, final Long accountId,
+ final Long volumeId, final String name, final Boolean deleteAllFlag) {
+
+ try {
+
+ final String bucket = s3.getBucketName();
+
+ final String result = executeWithNoWaitLock(
+ determineSnapshotLockId(accountId, volumeId),
+ new Callable<String>() {
+
+ @Override
+ public String call() throws Exception {
+
+ final String innerResult = deleteSnapshotBackupFromLocalFileSystem(
+ secondaryStorageUrl, accountId, volumeId,
+ name, deleteAllFlag);
+ if (innerResult != null) {
+ return innerResult;
+ }
+
+ if (deleteAllFlag) {
+ S3Utils.deleteDirectory(
+ s3,
+ bucket,
+ determineSnapshotS3Directory(accountId,
+ volumeId));
+ } else {
+ S3Utils.deleteObject(
+ s3,
+ bucket,
+ determineSnapshotS3Key(
+ accountId,
+ volumeId,
+ determineSnapshotBackupFilename(name)));
+ }
+
+ return null;
+
+ }
+
+ });
+
+ return result;
+
+ } catch (Exception e) {
+
+ s_logger.error(
+ String.format(
+ "Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.",
+ accountId, volumeId), e);
+ return e.getMessage();
+
+ }
+
+ }
+
+ private String determineSnapshotBackupFilename(final String snapshotUuid) {
+ return snapshotUuid + ".vhd";
+ }
+
+ private String determineSnapshotLockId(final Long accountId,
+ final Long volumeId) {
+ return join("_", "SNAPSHOT", accountId, volumeId);
+ }
+
+ protected Answer execute(final DeleteSnapshotBackupCommand cmd) {
+ String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+ Long accountId = cmd.getAccountId();
+ Long volumeId = cmd.getVolumeId();
+ String name = cmd.getSnapshotUuid();
+ try {
+ SwiftTO swift = cmd.getSwift();
+ S3TO s3 = cmd.getS3();
+ if (swift == null) {
+ final String result = deleteSnapshotBackupFromLocalFileSystem(
+ secondaryStorageUrl, accountId, volumeId, name,
+ cmd.isAll());
+ if (result != null) {
+ s_logger.warn(result);
+ return new Answer(cmd, false, result);
+ }
+ } else if (s3 != null) {
+ final String result = deleteSnapshotBackupfromS3(s3,
+ secondaryStorageUrl, accountId, volumeId, name,
+ cmd.isAll());
+ if (result != null) {
+ s_logger.warn(result);
+ return new Answer(cmd, false, result);
+ }
+ } else {
+ String filename;
+ if (cmd.isAll()) {
+ filename = "";
+ } else {
+ filename = name;
+ }
+ String result = swiftDelete(swift, "V-" + volumeId.toString(), filename);
+ if (result != null) {
+ String errMsg = "failed to delete snapshot " + filename + " , 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);
+ }
+ }
+
+ Map<String, TemplateInfo> swiftListTemplate(SwiftTO swift) {
+ String[] containers = swiftList(swift, "", "");
+ if (containers == null) {
+ return null;
+ }
+ Map<String, TemplateInfo> tmpltInfos = new HashMap<String, TemplateInfo>();
+ for( String container : containers) {
+ if ( container.startsWith("T-")) {
+ String ldir = _tmpltDir + "/" + UUID.randomUUID().toString();
+ createLocalDir(ldir);
+ String lFullPath = ldir + "/" + _tmpltpp;
+ swiftDownload(swift, container, _tmpltpp, lFullPath);
+ TemplateLocation loc = new TemplateLocation(_storage, ldir);
+ try {
+ if (!loc.load()) {
+ s_logger.warn("Can not parse template.properties file for template " + container);
+ continue;
+ }
+ } catch (IOException e) {
+ s_logger.warn("Unable to load template location " + ldir + " due to " + e.toString(), e);
+ continue;
+ }
+ TemplateInfo tInfo = loc.getTemplateInfo();
+ tInfo.setInstallPath(container);
+ tmpltInfos.put(tInfo.getTemplateName(), tInfo);
+ loc.purge();
+ deleteLocalDir(ldir);
+ }
+ }
+ return tmpltInfos;
+
+ }
+
+ private Answer execute(ListTemplateCommand cmd) {
+
+ if (cmd.getSwift() != null) {
+ Map<String, TemplateInfo> templateInfos = swiftListTemplate(cmd.getSwift());
+ return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos);
+ } else {
+ String root = getRootDir(cmd.getSecUrl());
+ Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
+ return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
+ }
+ }
+
+ private Answer execute(ListVolumeCommand cmd) {
+
+ String root = getRootDir(cmd.getSecUrl());
+ Map<Long, TemplateInfo> templateInfos = _dlMgr.gatherVolumeInfo(root);
+ return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
+
+ }
+
+ 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 setVhdParent(String lFullPath, String pFullPath) {
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("/bin/vhd-util modify -n " + lFullPath + " -p " + pFullPath);
+ String result = command.execute();
+ if (result != null) {
+ String errMsg = "failed to set vhd parent, child " + lFullPath + " parent " + pFullPath + ", err=" + result;
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ return null;
+ }
+
+ private String createLocalDir(String folder) {
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("mkdir -p " + folder);
+ String result = command.execute();
+ if (result != null) {
+ String errMsg = "Create local path " + folder + " failed , err=" + result;
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ return null;
+ }
+
+ private String deleteLocalDir(String folder) {
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("rmdir " + folder);
+ String result = command.execute();
+ if (result != null) {
+ String errMsg = "Delete local path " + folder + " failed , err=" + result;
+ s_logger.warn(errMsg);
+ return errMsg;
+ }
+ return null;
+ }
+
+ 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) {
+ String rootDir = getRootDir(cmd.getSecUrl());
+ 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 DeleteTemplateCommand cmd) {
+ String relativeTemplatePath = cmd.getTemplatePath();
+ String parent = getRootDir(cmd);
+
+ if (relativeTemplatePath.startsWith(File.separator)) {
+ relativeTemplatePath = relativeTemplatePath.substring(1);
+ }
+
+ if (!parent.endsWith(File.separator)) {
+ parent += File.separator;
+ }
+ String absoluteTemplatePath = parent + relativeTemplatePath;
+ File tmpltParent = new File(absoluteTemplatePath).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;
+ }
+ 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);
+ }
+
+ protected Answer execute(final DeleteVolumeCommand cmd) {
+ String relativeVolumePath = cmd.getVolumePath();
+ String parent = getRootDir(cmd);
+
+ if (relativeVolumePath.startsWith(File.separator)) {
+ relativeVolumePath = relativeVolumePath.substring(1);
+ }
+
+ if (!parent.endsWith(File.separator)) {
+ parent += File.separator;
+ }
+ String absoluteVolumePath = parent + relativeVolumePath;
+ File 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;
+ }
+ if (!f.delete()) {
+ return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path "
+ + relativeVolumePath);
+ }
+ }
+ 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 "
+ + relativeVolumePath;
+ s_logger.debug(details);
+ return new Answer(cmd, false, details);
+ }
+ return new Answer(cmd, true, null);
+ }
+
+ Answer execute(CleanupSnapshotBackupCommand cmd) {
+ String parent = getRootDir(cmd.getSecondaryStoragePoolURL());
+ if (!parent.endsWith(File.separator)) {
+ parent += File.separator;
+ }
+ String absoluteSnapsthotDir = parent + File.separator + "snapshots" + File.separator + cmd.getAccountId() + File.separator + cmd.getVolumeId();
+ File ssParent = new File(absoluteSnapsthotDir);
+ if (ssParent.exists() && ssParent.isDirectory()) {
+ File[] files = ssParent.listFiles();
+ for (File file : files) {
+ boolean found = false;
+ String filename = file.getName();
+ for (String uuid : cmd.getValidBackupUUIDs()) {
+ if (filename.startsWith(uuid)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ file.delete();
+ String msg = "snapshot " + filename + " is not recorded in DB, remove it";
+ s_logger.warn(msg);
+ }
+ }
+ }
+ return new Answer(cmd, true, null);
+ }
+
+
+ synchronized public String getRootDir(String secUrl) {
+ if (!_inSystemVM) {
+ return _parent;
+ }
+ try {
+ URI uri = new URI(secUrl);
+ String nfsHost = uri.getHost();
+
+ InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
+ String nfsHostIp = nfsHostAddr.getHostAddress();
+ String nfsPath = nfsHostIp + ":" + uri.getPath();
+ String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString();
+ String root = _parent + "/" + dir;
+ mount(root, nfsPath);
+ return root;
+ } catch (Exception e) {
+ String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
+ s_logger.error(msg, e);
+ throw new CloudRuntimeException(msg);
+ }
+ }
+
+
+ @Override
+ public String getRootDir(ssCommand cmd){
+ return getRootDir(cmd.getSecUrl());
+
+ }
+
+ 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("Wait, what's going on? eth1ip is null!!");
+ }
+ 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)) {
+ _inSystemVM = true;
+ }
+
+ _storageIp = (String) params.get("storageip");
+ if (_storageIp == null) {
+ s_logger.warn("Wait, 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);
+ 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("StorageLayer", params);
+ } catch (ClassNotFoundException e) {
+ throw new ConfigurationException("Unable to find class " + value);
+ } catch (InstantiationException e) {
+ throw new ConfigurationException("Unable to find class " + value);
+ } catch (IllegalAccessException e) {
+ throw new ConfigurationException("Unable to find class " + value);
+ }
+ }
+
+ 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);
+ }
+
+ _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;
+ }
+
+ private void startAdditionalServices() {
+ if (!_inSystemVM) {
+ return;
+ }
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("if [ -f /etc/init.d/ssh ]; then service ssh restart; else service sshd restart; fi ");
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in starting sshd service err=" + result );
+ }
+ command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("iptables -I INPUT -i eth1 -p tcp -m state --state NEW -m tcp --dport 3922 -j ACCEPT");
+ result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in opening up ssh port err=" + result );
+ }
+ }
+
+ private void addRouteToInternalIpOrCidr(String localgw, String eth1ip, String eth1mask, String destIpOrCidr) {
+ if (!_inSystemVM) {
+ return;
+ }
+ s_logger.debug("addRouteToInternalIp: localgw=" + localgw + ", eth1ip=" + eth1ip + ", eth1mask=" + eth1mask + ",destIp=" + destIpOrCidr);
+ if (destIpOrCidr == null) {
+ s_logger.debug("addRouteToInternalIp: destIp is null");
+ return;
+ }
+ if (!NetUtils.isValidIp(destIpOrCidr) && !NetUtils.isValidCIDR(destIpOrCidr)){
+ s_logger.warn(" destIp is not a valid ip address or cidr destIp=" + destIpOrCidr);
+ return;
+ }
+ boolean inSameSubnet = false;
+ if (NetUtils.isValidIp(destIpOrCidr)) {
+ if (eth1ip != null && eth1mask != null) {
+ inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask);
+ } else {
+ s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + ", _eth1mask=" + eth1mask);
+ }
+ } else {
+ inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask));
+ }
+ if (inSameSubnet) {
+ s_logger.debug("addRouteToInternalIp: dest ip " + destIpOrCidr + " is in the same subnet as eth1 ip " + eth1ip);
+ return;
+ }
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("ip route delete " + destIpOrCidr);
+ command.execute();
+ command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("ip route add " + destIpOrCidr + " via " + localgw);
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in configuring route to internal ip err=" + result );
+ } else {
+ s_logger.debug("addRouteToInternalIp: added route to internal ip=" + destIpOrCidr + " via " + localgw);
+ }
+ }
+
+ private void configureSSL() {
+ if (!_inSystemVM) {
+ return;
+ }
+ Script command = new Script(_configSslScr);
+ command.add("-i", _publicIp);
+ command.add("-h", _hostname);
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Unable to configure httpd to use ssl");
+ }
+ }
+
+ private void configureSSL(String prvkeyPath, String prvCertPath, String certChainPath) {
+ if (!_inSystemVM) {
+ return;
+ }
+ Script command = new Script(_configSslScr);
+ command.add("-i", _publicIp);
+ command.add("-h", _hostname);
+ command.add("-k", prvkeyPath);
+ command.add("-p", prvCertPath);
+ if (certChainPath != null) {
+ command.add("-t", certChainPath);
+ }
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Unable to configure httpd to use ssl");
+ }
+ }
+
+ private String configureAuth(String user, String passwd) {
+ Script command = new Script(_configAuthScr);
+ command.add(user);
+ command.add(passwd);
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Unable to configure httpd to use auth");
+ }
+ return result;
+ }
+
+ private String configureIpFirewall(List<String> ipList, boolean isAppend){
+ Script command = new Script(_configIpFirewallScr);
+ command.add(String.valueOf(isAppend));
+ for (String ip : ipList){
+ command.add(ip);
+ }
+
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Unable to configure firewall for command : " +command);
+ }
+ return result;
+ }
+
+ protected String mount(String root, String nfsPath) {
+ File file = new File(root);
+ if (!file.exists()) {
+ if (_storage.mkdir(root)) {
+ s_logger.debug("create mount point: " + root);
+ } else {
+ s_logger.debug("Unable to create mount point: " + root);
+ return null;
+ }
+ }
+
+ Script script = null;
+ String result = null;
+ script = new Script(!_inSystemVM, "mount", _timeout, s_logger);
+ List<String> res = new ArrayList<String>();
+ ZfsPathParser parser = new ZfsPathParser(root);
+ script.execute(parser);
+ res.addAll(parser.getPaths());
+ for( String s : res ) {
+ if ( s.contains(root)) {
+ return root;
+ }
+ }
+
+ Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
+ command.add("-t", "nfs");
+ if (_inSystemVM) {
+ //Fedora Core 12 errors out with any -o option executed from java
+ command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0");
+ }
+ command.add(nfsPath);
+ command.add(root);
+ result = command.execute();
+ if (result != null) {
+ s_logger.warn("Unable to mount " + nfsPath + " due to " + result);
+ file = new File(root);
+ if (file.exists())
+ file.delete();
+ return null;
+ }
+
+ // XXX: Adding the check for creation of snapshots dir here. Might have to move it somewhere more logical later.
+ if (!checkForSnapshotsDir(root)) {
+ return null;
+ }
+
+ // Create the volumes dir
+ if (!checkForVolumesDir(root)) {
+ return null;
+ }
+
+ return root;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public StartupCommand[] initialize() {
+
+ final StartupSecondaryStorageCommand cmd = new StartupSecondaryStorageCommand();
+ fillNetworkInformation(cmd);
+ if(_publicIp != null)
+ cmd.setPublicIpAddress(_publicIp);
+
+ if (_inSystemVM) {
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("ln -sf " + _parent + " /var/www/html/copy");
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in linking err=" + result);
+ return null;
+ }
+ }
+ return new StartupCommand[] {cmd};
+ }
+
+ protected boolean checkForSnapshotsDir(String mountPoint) {
+ String snapshotsDirLocation = mountPoint + File.separator + "snapshots";
+ return createDir("snapshots", snapshotsDirLocation, mountPoint);
+ }
+
+ protected boolean checkForVolumesDir(String mountPoint) {
+ String volumesDirLocation = mountPoint + "/" + "volumes";
+ return createDir("volumes", volumesDirLocation, mountPoint);
+ }
+
+ protected boolean createDir(String dirName, String dirLocation, String mountPoint) {
+ boolean dirExists = false;
+
+ File dir = new File(dirLocation);
+ if (dir.exists()) {
+ if (dir.isDirectory()) {
+ s_logger.debug(dirName + " already exists on secondary storage, and is mounted at " + mountPoint);
+ dirExists = true;
+ } else {
+ if (dir.delete() && _storage.mkdir(dirLocation)) {
+ dirExists = true;
+ }
+ }
+ } else if (_storage.mkdir(dirLocation)) {
+ dirExists = true;
+ }
+
+ if (dirExists) {
+ s_logger.info(dirName + " directory created/exists on Secondary Storage.");
+ } else {
+ s_logger.info(dirName + " directory does not exist on Secondary Storage.");
+ }
+
+ return dirExists;
+ }
+
+ @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
+
+ }
+
+ @Override
+ public void fillNetworkInformation(final StartupCommand cmd) {
+ final String dummyMac = "00:06:0A:0B:0C:0D";
+ final String dummyNetmask = "255.255.255.0";
+ if (!_inSystemVM) {
+ cmd.setPrivateIpAddress(_eth1ip);
+ cmd.setPrivateMacAddress(dummyMac);
+ cmd.setPrivateNetmask(dummyNetmask);
+ cmd.setPublicIpAddress(_publicIp);
+ cmd.setPublicMacAddress(dummyMac);
+ cmd.setPublicNetmask(dummyNetmask);
+ cmd.setName(_hostname);
+ } else {
+ super.fillNetworkInformation(cmd);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/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
new file mode 100755
index 0000000..5c87b0d
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
@@ -0,0 +1,28 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.resource;
+import com.cloud.agent.api.storage.ssCommand;
+import com.cloud.resource.ServerResource;
+/**
+ *
+ * SecondaryStorageServerResource is a generic container to execute commands sent
+ */
+public interface SecondaryStorageResource extends ServerResource {
+
+ public String getRootDir(ssCommand cmd);
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/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
new file mode 100644
index 0000000..d03d983
--- /dev/null
+++ b/services/secondary-storage/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/e7983b25/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
new file mode 100644
index 0000000..3e5072a
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManager.java
@@ -0,0 +1,105 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.template;
+
+import java.util.Map;
+
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.DownloadCommand;
+import com.cloud.agent.api.storage.DownloadCommand.Proxy;
+import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.template.TemplateDownloader;
+import com.cloud.storage.template.TemplateInfo;
+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 userName, String passwd, long maxDownloadSizeInBytes, 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, TemplateInfo> gatherTemplateInfo(String templateDir);
+
+ /**
+ /**
+ * @return list of volume info for installed volumes
+ */
+ public Map<Long, TemplateInfo> gatherVolumeInfo(String volumeDir);
+
+
+}
\ No newline at end of file
[14/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: when using SSVM, pass in the new name of the SS class (com.cloud -> org.apache.cloudstack)
QuickCloud : configuration moved to applicationContext.xml from componentContext.xml
QuickCloud: default to enabled state for devcloud zone
QuickCloud: environment.properties helps customize location of pid file
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/5ff8bcaa
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/5ff8bcaa
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/5ff8bcaa
Branch: refs/heads/master
Commit: 5ff8bcaa2e16035197c6d58bb212ba1696411dce
Parents: 936973a
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Thu Apr 4 17:23:10 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700
----------------------------------------------------------------------
client/pom.xml | 6 +-
.../tomcatconf/quickCloudComponentContext.xml.in | 336 ---------------
.../secondary/SecondaryStorageManagerImpl.java | 8 +-
.../server/conf/environment.properties | 2 +
tools/devcloud/devcloud.cfg | 1 +
5 files changed, 9 insertions(+), 344 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5ff8bcaa/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 4bd1a6f..b3d7acb 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -463,9 +463,9 @@
<target if="${quickcloud}">
<echo>quickcloud</echo>
<replaceregexp
- file="${basedir}/target/generated-webapp/WEB-INF/web.xml"
- match="classpath:componentContext.xml"
- replace="classpath:quickCloudComponentContext.xml" byline="true" />
+ file="${basedir}/target/generated-webapp/WEB-INF/classes/applicationContext.xml"
+ match="com.cloud.consoleproxy.ConsoleProxyManagerImpl"
+ replace="com.cloud.consoleproxy.StaticConsoleProxyManager" byline="true" />
</target>
</configuration>
</execution>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5ff8bcaa/client/tomcatconf/quickCloudComponentContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/quickCloudComponentContext.xml.in b/client/tomcatconf/quickCloudComponentContext.xml.in
deleted file mode 100644
index dbd3117..0000000
--- a/client/tomcatconf/quickCloudComponentContext.xml.in
+++ /dev/null
@@ -1,336 +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:tx="http://www.springframework.org/schema/tx"
- 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/tx
- http://www.springframework.org/schema/tx/spring-tx-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">
-
-
- <!--
- Compose a CloudStack deployment with selected components here
- -->
- <bean id="databaseUpgradeChecker" class="com.cloud.upgrade.DatabaseUpgradeChecker" />
- <bean id="encryptionSecretKeyChecker" class="com.cloud.utils.crypt.EncryptionSecretKeyChecker" />
- <bean id="configurationServerImpl" class="com.cloud.server.ConfigurationServerImpl" />
-
- <bean id="managementServerImpl" class ="com.cloud.server.ManagementServerImpl" >
- <property name="UserAuthenticators">
- <list>
- <ref bean="MD5UserAuthenticator"/>
- <ref bean="LDAPUserAuthenticator"/>
- </list>
- </property>
- </bean>
-
- <bean id ="AccountManagerImpl" class="com.cloud.user.AccountManagerImpl">
- <property name="UserAuthenticators">
- <list>
- <ref bean="MD5UserAuthenticator"/>
- <ref bean="LDAPUserAuthenticator"/>
- </list>
- </property>
- </bean>
-
- <bean id="clusterManagerImpl" class="com.cloud.cluster.ClusterManagerImpl" />
- <bean id="clusteredAgentManagerImpl" class="com.cloud.agent.manager.ClusteredAgentManagerImpl" />
- <bean id="clusteredVirtualMachineManagerImpl" class="com.cloud.vm.ClusteredVirtualMachineManagerImpl" />
- <bean id="highAvailabilityManagerExtImpl" class="com.cloud.ha.HighAvailabilityManagerExtImpl" />
- <bean id="userVmManagerImpl" class="com.cloud.vm.UserVmManagerImpl" />
- <bean id="consoleProxyManagerImpl" class="com.cloud.consoleproxy.StaticConsoleProxyManager" />
- <bean id="securityGroupManagerImpl2" class="com.cloud.network.security.SecurityGroupManagerImpl2" />
- <bean id="premiumSecondaryStorageManagerImpl" class="com.cloud.secstorage.PremiumSecondaryStorageManagerImpl" />
- <bean id="userVmDaoImpl" class="com.cloud.vm.dao.UserVmDaoImpl" />
- <bean id="ipv6AddressManagerImpl" class="com.cloud.network.Ipv6AddressManagerImpl" />
-
- <bean id="apiRateLimitServiceImpl" class="org.apache.cloudstack.ratelimit.ApiRateLimitServiceImpl"/>
- <bean id="BaremetalManager" class="com.cloud.baremetal.manager.BaremetalManagerImpl"/>
- <bean id="BaremetalDhcpManager" class="com.cloud.baremetal.networkservice.BaremetalDhcpManagerImpl"/>
- <bean id="BaremetalKickStartPxeService" class="com.cloud.baremetal.networkservice.BaremetalKickStartServiceImpl"/>
- <bean id="BaremetalPingPxeService" class="com.cloud.baremetal.networkservice.BareMetalPingServiceImpl" />
- <bean id="BaremetalPxeManager" class="com.cloud.baremetal.networkservice.BaremetalPxeManagerImpl" />
- <bean id="UcsManager" class="com.cloud.ucs.manager.UcsManagerImpl" />
- <bean id="UcsBladeDao" class="com.cloud.ucs.database.UcsBladeDaoImpl" />
- <bean id="UcsManagerDao" class="com.cloud.ucs.database.UcsManagerDaoImpl" />
-
-
- <!--
- Network Elements
- -->
- <bean id="Ovs" class="com.cloud.network.element.OvsElement">
- <property name="name" value="Ovs"/>
- </bean>
- <bean id="BareMetalDhcp" class="com.cloud.baremetal.networkservice.BaremetalDhcpElement">
- <property name="name" value="BareMetalDhcp"/>
- </bean>
- <bean id="BareMetalPxe" class="com.cloud.baremetal.networkservice.BaremetalPxeElement">
- <property name="name" value="BareMetalPxe"/>
- </bean>
- <bean id="BareMetalUserdata" class="com.cloud.baremetal.networkservice.BaremetalUserdataElement">
- <property name="name" value="BareMetalUserdata"/>
- </bean>
- <bean id="SecurityGroupProvider" class="com.cloud.network.element.SecurityGroupElement">
- <property name="name" value="SecurityGroupProvider"/>
- </bean>
- <bean id="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement">
- <property name="name" value="VirtualRouter"/>
- </bean>
- <bean id="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement">
- <property name="name" value="VpcVirtualRouter"/>
- </bean>
- <!--
- <bean id="NiciraNvp" class="com.cloud.network.element.NiciraNvpElement">
- <property name="name" value="NiciraNvp"/>
- </bean>
- -->
-
-<!--
- <bean id="BigSwitchVnsElementService" class="com.cloud.network.element.BigSwitchVnsElement">
- <property name="name" value="BigSwitchVnsElementService"/>
- </bean>
--->
-
- <!--
- Adapters
- -->
- <bean id="FirstFitRouting" class="com.cloud.agent.manager.allocator.impl.FirstFitRoutingAllocator">
- <property name="name" value="FirstFitRouting"/>
- </bean>
-
- <bean id="hypervisorTemplateAdapter" class="com.cloud.template.HypervisorTemplateAdapter">
- <property name="name" value="HypervisorAdapter"/>
- </bean>
-
- <!--
- Storage pool allocators
- -->
-
- <bean id="LocalStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.LocalStoragePoolAllocator">
- <property name="name" value="LocalStorage"/>
- </bean>
- <!--
- <bean id="FirstFitStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.FirstFitStoragePoolAllocator">
- <property name="name" value="Storage"/>
- </bean>
- -->
-
- <bean id="UserConcentratedAllocator" class="com.cloud.agent.manager.allocator.impl.UserConcentratedAllocator">
- <property name="name" value="User First"/>
- </bean>
-
- <bean id="ConsoleProxyAllocator" class="com.cloud.consoleproxy.ConsoleProxyBalanceAllocator">
- <property name="name" value="Balance"/>
- </bean>
-
- <bean id="StaticRoleBasedAPIAccessChecker" class="org.apache.cloudstack.acl.StaticRoleBasedAPIAccessChecker"/>
-
- <bean id="ExteralIpAddressAllocator" class="com.cloud.network.ExteralIpAddressAllocator">
- <property name="name" value="Basic"/>
- </bean>
-
- <bean id="HypervisorTemplateAdapter" class="com.cloud.template.HypervisorTemplateAdapter">
- <property name="name" value="HypervisorAdapter"/>
- </bean>
-
- <bean id="BareMetalTemplateAdapter" class="com.cloud.baremetal.manager.BareMetalTemplateAdapter" >
- <property name="name" value="BareMetalTemplateAdapter"/>
- </bean>
-
- <!--
- Authenticators
- -->
- <bean id="MD5UserAuthenticator" class="com.cloud.server.auth.MD5UserAuthenticator">
- <property name="name" value="MD5"/>
- </bean>
-
- <bean id="LDAPUserAuthenticator" class="com.cloud.server.auth.LDAPUserAuthenticator">
- <property name="name" value="LDAP"/>
- </bean>
-
- <!--
- Investigators
- -->
- <bean id="CheckOnAgentInvestigator" class="com.cloud.ha.CheckOnAgentInvestigator">
- <property name="name" value="SimpleInvestigator"/>
- </bean>
-
- <bean id="XenServerInvestigator" class="com.cloud.ha.XenServerInvestigator">
- <property name="name" value="XenServerInvestigator"/>
- </bean>
-
- <bean id="UserVmDomRInvestigator" class="com.cloud.ha.UserVmDomRInvestigator">
- <property name="name" value="PingInvestigator"/>
- </bean>
-
- <bean id="ManagementIPSystemVMInvestigator" class="com.cloud.ha.ManagementIPSystemVMInvestigator">
- <property name="name" value="ManagementIPSysVMInvestigator"/>
- </bean>
-
- <!--
- Fencers
- -->
- <bean id="XenServerFencer" class="com.cloud.ha.XenServerFencer">
- <property name="name" value="XenServerFenceBuilder"/>
- </bean>
- <bean id="KVMFencer" class="com.cloud.ha.KVMFencer">
- <property name="name" value="KVMFenceBuilder"/>
- </bean>
- <bean id="OvmFencer" class="com.cloud.ovm.hypervisor.OvmFencer">
- <property name="name" value="OvmFenceBuilder"/>
- </bean>
-
- <bean id="XcpServerDiscoverer" class="com.cloud.hypervisor.xen.discoverer.XcpServerDiscoverer">
- <property name="name" value="XCP Agent"/>
- </bean>
-
- <!--
- <bean id="SimulatorSecondaryStorageDiscoverer" class="com.cloud.resource.SimulatorSecondaryDiscoverer">
- <property name="name" value="SecondaryStorage"/>
- </bean>
- -->
-
- <bean id="SecondaryStorageDiscoverer" class="org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer">
- <property name="name" value="SecondaryStorage"/>
- </bean>
-
- <bean id="KvmServerDiscoverer" class="com.cloud.hypervisor.kvm.discoverer.KvmServerDiscoverer">
- <property name="name" value="KVM Agent"/>
- </bean>
-
- <bean id="SimulatorDiscoverer" class="com.cloud.resource.SimulatorDiscoverer">
- <property name="name" value="Simulator Agent"/>
- </bean>
-
-
- <bean id="BareMetalDiscoverer" class="com.cloud.baremetal.manager.BareMetalDiscoverer">
- <property name="name" value="Bare Metal Agent"/>
- </bean>
-
- <bean id="HypervServerDiscoverer" class="com.cloud.hypervisor.hyperv.HypervServerDiscoverer">
- <property name="name" value="SCVMMServer"/>
- </bean>
-
- <bean id="OvmDiscoverer" class="com.cloud.ovm.hypervisor.OvmDiscoverer">
- <property name="name" value="Ovm Discover"/>
- </bean>
-
- <bean id="FirstFitPlanner" class="com.cloud.deploy.FirstFitPlanner">
- <property name="name" value="First Fit"/>
- </bean>
-
- <bean id="UserDispersingPlanner" class="com.cloud.deploy.UserDispersingPlanner">
- <property name="name" value="UserDispersing"/>
- </bean>
-
- <bean id="UserConcentratedPodPlanner" class="com.cloud.deploy.UserConcentratedPodPlanner">
- <property name="name" value="UserConcentratedPod"/>
- </bean>
-
- <bean id="BareMetalPlanner" class="com.cloud.baremetal.manager.BareMetalPlanner">
- <property name="name" value="BareMetal Fit"/>
- </bean>
-
- <bean id="BaremetalPlannerSelector" class="com.cloud.baremetal.manager.BaremetalPlannerSelector">
- <property name="name" value="BaremetalPlannerSelector"/>
- </bean>
-
- <bean id="HypervisorPlannerSelector" class="com.cloud.deploy.HypervisorVmPlannerSelector">
- <property name="name" value="HypervisorPlannerSelector"/>
- </bean>
-
-
- <!--
- Network Gurus
- -->
- <bean id="StorageNetworkGuru" class="com.cloud.network.guru.StorageNetworkGuru">
- <property name="name" value="StorageNetworkGuru"/>
- </bean>
- <bean id="ExternalGuestNetworkGuru" class="com.cloud.network.guru.ExternalGuestNetworkGuru">
- <property name="name" value="ExternalGuestNetworkGuru"/>
- </bean>
- <bean id="PublicNetworkGuru" class="com.cloud.network.guru.PublicNetworkGuru">
- <property name="name" value="PublicNetworkGuru"/>
- </bean>
- <bean id="PodBasedNetworkGuru" class="com.cloud.network.guru.PodBasedNetworkGuru">
- <property name="name" value="PodBasedNetworkGuru"/>
- </bean>
- <bean id="ControlNetworkGuru" class="com.cloud.network.guru.ControlNetworkGuru">
- <property name="name" value="ControlNetworkGuru"/>
- </bean>
- <bean id="DirectNetworkGuru" class="com.cloud.network.guru.DirectNetworkGuru">
- <property name="name" value="DirectNetworkGuru"/>
- </bean>
- <bean id="DirectPodBasedNetworkGuru" class="com.cloud.network.guru.DirectPodBasedNetworkGuru">
- <property name="name" value="DirectPodBasedNetworkGuru"/>
- </bean>
- <bean id="OvsGuestNetworkGuru" class="com.cloud.network.guru.OvsGuestNetworkGuru">
- <property name="name" value="OvsGuestNetworkGuru"/>
- </bean>
- <bean id="PrivateNetworkGuru" class="com.cloud.network.guru.PrivateNetworkGuru">
- <property name="name" value="PrivateNetworkGuru"/>
- </bean>
- <bean id="NiciraNvpGuestNetworkGuru" class="com.cloud.network.guru.NiciraNvpGuestNetworkGuru">
- <property name="name" value="NiciraNvpGuestNetworkGuru"/>
- </bean>
-
-<!--
- <bean id="BigSwitchVnsGuestNetworkGuru" class=".BigSwitchVnsGuestNetworkGuru">
- <property name="name" value="com.cloud.network.guru.BigSwitchVnsGuestNetworkGuru"/>
- </bean>
--->
-
- <!--
- Hypervisor Gurus
- -->
- <bean id="XenServerGuru" class="com.cloud.hypervisor.XenServerGuru">
- <property name="name" value="XenServerGuru"/>
- </bean>
-
- <bean id="KVMGuru" class="com.cloud.hypervisor.KVMGuru">
- <property name="name" value="KVMGuru"/>
- </bean>
-
- <bean id="HypervGuru" class="com.cloud.hypervisor.guru.HypervGuru">
- <property name="name" value="HypervGuru"/>
- </bean>
-
- <bean id="OvmGuru" class="com.cloud.ovm.hypervisor.OvmGuru">
- <property name="name" value="OvmGuru"/>
- </bean>
-
- <bean id="SimulatorGuru" class="com.cloud.simulator.SimulatorGuru">
- <property name="name" value="SimulatorGuru"/>
- </bean>
-
- <bean id="BaremetalGuru" class="com.cloud.baremetal.manager.BareMetalGuru">
- <property name="name" value="BaremetalGuru"/>
- </bean>
-
- <bean id="ClassicalPrimaryDataStoreProvider" class="org.apache.cloudstack.storage.datastore.provider.CloudStackPrimaryDataStoreProviderImpl">
- </bean>
-
-</beans>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5ff8bcaa/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 c94224b..d6d6fc0 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
@@ -30,8 +30,6 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
-import org.springframework.context.annotation.Primary;
-import org.springframework.stereotype.Component;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
@@ -98,8 +96,8 @@ import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage;
import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VMTemplateDao;
@@ -1066,10 +1064,10 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
buf.append(" resource=com.cloud.storage.resource.PremiumSecondaryStorageResource");
} else {
s_logger.debug("Telling the ssvm to load the NfsSecondaryStorageResource");
- buf.append(" resource=com.cloud.storage.resource.NfsSecondaryStorageResource");
+ buf.append(" resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource");
}
} else {
- buf.append(" resource=com.cloud.storage.resource.NfsSecondaryStorageResource");
+ buf.append(" resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource");
}
buf.append(" instance=SecStorage");
buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5ff8bcaa/services/console-proxy/server/conf/environment.properties
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/conf/environment.properties b/services/console-proxy/server/conf/environment.properties
new file mode 100644
index 0000000..269acad
--- /dev/null
+++ b/services/console-proxy/server/conf/environment.properties
@@ -0,0 +1,2 @@
+paths.script=../../scripts/storage/secondary/
+paths.pid=.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5ff8bcaa/tools/devcloud/devcloud.cfg
----------------------------------------------------------------------
diff --git a/tools/devcloud/devcloud.cfg b/tools/devcloud/devcloud.cfg
index c41f8bc..e6ab71b 100644
--- a/tools/devcloud/devcloud.cfg
+++ b/tools/devcloud/devcloud.cfg
@@ -20,6 +20,7 @@
"zones": [
{
"name": "DevCloud0",
+ "enabled" : "True",
"physical_networks": [
{
"broadcastdomainrange": "Zone",
[16/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: allow specification of network offering name in datacenter config. The deployDatacenter python script will use this to pick the network offering during creation of the default network in a basic zone
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/a806ce43
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/a806ce43
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/a806ce43
Branch: refs/heads/master
Commit: a806ce43d32e8d5ac064b79dd623c01be4489126
Parents: 1d70b9e
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Tue Mar 26 14:11:36 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700
----------------------------------------------------------------------
tools/devcloud/quickcloud.cfg | 1 +
tools/marvin/marvin/deployDataCenter.py | 3 ++-
2 files changed, 3 insertions(+), 1 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a806ce43/tools/devcloud/quickcloud.cfg
----------------------------------------------------------------------
diff --git a/tools/devcloud/quickcloud.cfg b/tools/devcloud/quickcloud.cfg
index 0e1fb4f..a2613d2 100644
--- a/tools/devcloud/quickcloud.cfg
+++ b/tools/devcloud/quickcloud.cfg
@@ -54,6 +54,7 @@
"securitygroupenabled": "true",
"localstorageenabled": "true",
"networktype": "Basic",
+ "networkofferingname": "QuickCloudNoServices",
"pods": [
{
"endip": "192.168.56.220",
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a806ce43/tools/marvin/marvin/deployDataCenter.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py
index 42bc5f9..d365395 100644
--- a/tools/marvin/marvin/deployDataCenter.py
+++ b/tools/marvin/marvin/deployDataCenter.py
@@ -299,10 +299,11 @@ class deployDataCenters():
if zone.networktype == "Basic":
listnetworkoffering = listNetworkOfferings.listNetworkOfferingsCmd()
-
listnetworkoffering.name = "DefaultSharedNetscalerEIPandELBNetworkOffering" \
if len(filter(lambda x : x.typ == 'Public', zone.physical_networks[0].traffictypes)) > 0 \
else "DefaultSharedNetworkOfferingWithSGService"
+ if zone.networkofferingname is not None:
+ listnetworkoffering.name = zone.networkofferingname
listnetworkofferingresponse = \
self.apiClient.listNetworkOfferings(listnetworkoffering)
[11/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: launch scripts for secondary storage and console proxy outside system vm
QuickCloud: remove stuff added by the daemon
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/936973af
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/936973af
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/936973af
Branch: refs/heads/master
Commit: 936973aff7ba372abe442a7a40e112219fba7570
Parents: c5b11df
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Wed Mar 27 16:49:56 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700
----------------------------------------------------------------------
services/console-proxy/server/scripts/_run.sh | 3 +-
.../console-proxy/server/scripts/consoleproxy.sh | 33 +++++++++++++++
services/secondary-storage/conf/agent.properties | 4 +-
services/secondary-storage/scripts/_run.sh | 3 +-
services/secondary-storage/scripts/secstorage.sh | 33 +++++++++++++++
5 files changed, 71 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/936973af/services/console-proxy/server/scripts/_run.sh
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/scripts/_run.sh b/services/console-proxy/server/scripts/_run.sh
index e408378..bd06346 100755
--- a/services/console-proxy/server/scripts/_run.sh
+++ b/services/console-proxy/server/scripts/_run.sh
@@ -35,6 +35,7 @@ do
CP=${CP}:$file
done
keyvalues=
+LOGHOME=/var/log/cloud/
CMDLINE=$(cat /var/cache/cloud/cmdline)
@@ -60,4 +61,4 @@ then
maxmem=$eightypcnt
fi
-java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@
+java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/936973af/services/console-proxy/server/scripts/consoleproxy.sh
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/scripts/consoleproxy.sh b/services/console-proxy/server/scripts/consoleproxy.sh
new file mode 100755
index 0000000..4a6acde
--- /dev/null
+++ b/services/console-proxy/server/scripts/consoleproxy.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+
+#runs the console proxy as a standalone server
+#i.e., not in the system vm
+
+CP=./:./conf
+for file in *.jar
+do
+ CP=${CP}:$file
+done
+keyvalues=
+#LOGHOME=/var/log/cloud/
+LOGHOME=$PWD
+
+java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -cp $CP com.cloud.agent.AgentShell $keyvalues $@
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/936973af/services/secondary-storage/conf/agent.properties
----------------------------------------------------------------------
diff --git a/services/secondary-storage/conf/agent.properties b/services/secondary-storage/conf/agent.properties
index 4a25cbd..554007f 100644
--- a/services/secondary-storage/conf/agent.properties
+++ b/services/secondary-storage/conf/agent.properties
@@ -1,6 +1,4 @@
-#Storage
-#Sun Mar 24 22:52:35 PDT 2013
-mount.path=/Users/chiradeep/secondary-storage
+#mount.path=~/secondary-storage
eth1ip=192.168.56.1
name=192.168.56.10
eth2ip=192.168.56.10
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/936973af/services/secondary-storage/scripts/_run.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/_run.sh b/services/secondary-storage/scripts/_run.sh
index e408378..cb9624c 100755
--- a/services/secondary-storage/scripts/_run.sh
+++ b/services/secondary-storage/scripts/_run.sh
@@ -36,6 +36,7 @@ do
done
keyvalues=
+LOGHOME=/var/log/cloud/
CMDLINE=$(cat /var/cache/cloud/cmdline)
#CMDLINE="graphical utf8 eth0ip=0.0.0.0 eth0mask=255.255.255.0 eth1ip=192.168.140.40 eth1mask=255.255.255.0 eth2ip=172.24.0.50 eth2mask=255.255.0.0 gateway=172.24.0.1 dns1=72.52.126.11 template=domP dns2=72.52.126.12 host=192.168.1.142 port=8250 mgmtcidr=192.168.1.0/24 localgw=192.168.140.1 zone=5 pod=5"
@@ -60,4 +61,4 @@ then
maxmem=$eightypcnt
fi
-java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@
+java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/936973af/services/secondary-storage/scripts/secstorage.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/secstorage.sh b/services/secondary-storage/scripts/secstorage.sh
new file mode 100755
index 0000000..9afc521
--- /dev/null
+++ b/services/secondary-storage/scripts/secstorage.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+
+#runs the secondary storage service as a standalone server
+#i.e., not in the system vm
+
+CP=./:./conf
+for file in *.jar
+do
+ CP=${CP}:$file
+done
+keyvalues=
+#LOGHOME=/var/log/cloud/
+LOGHOME=$PWD
+
+java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -cp $CP com.cloud.agent.AgentShell $keyvalues $@
[09/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: option to build with componentContext tailored for quickcloud
For now it replaces ConsoleProxyManagerImpl with StaticConsoleProxyManager
Usage: mvn install -Dquickcloud
QuickCloud: rename deploy profile
QuickCloud: remove cyclic dependency introduced in nonoss build by moving SecondaryStorageDiscoverer into services
However with this fix, developers will be unable to run 'PremiumSecondaryStorageResource' (for VMWare installations) using mvn exec:java.
Instead they will have to use the exploded archive from systemvm.zip
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c5b11df6
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c5b11df6
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c5b11df6
Branch: refs/heads/master
Commit: c5b11df6b78dd755acc4141dc2063608e581996d
Parents: a806ce4
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Tue Mar 26 16:40:19 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700
----------------------------------------------------------------------
client/pom.xml | 16 +
.../tomcatconf/quickCloudComponentContext.xml.in | 336 +++++++++++++++
plugins/hypervisors/simulator/pom.xml | 5 +
.../resource/SimulatorSecondaryDiscoverer.java | 3 +-
plugins/hypervisors/vmware/pom.xml | 5 +
server/pom.xml | 5 -
.../secondary/SecondaryStorageDiscoverer.java | 322 --------------
services/console-proxy/server/pom.xml | 10 +-
services/secondary-storage/pom.xml | 28 +-
.../resource/SecondaryStorageDiscoverer.java | 320 ++++++++++++++
tools/devcloud/pom.xml | 4 +-
11 files changed, 695 insertions(+), 359 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 9323d0f..4bd1a6f 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -453,6 +453,22 @@
</target>
</configuration>
</execution>
+ <execution>
+ <id>process-quickcloud-spring-context</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target if="${quickcloud}">
+ <echo>quickcloud</echo>
+ <replaceregexp
+ file="${basedir}/target/generated-webapp/WEB-INF/web.xml"
+ match="classpath:componentContext.xml"
+ replace="classpath:quickCloudComponentContext.xml" byline="true" />
+ </target>
+ </configuration>
+ </execution>
</executions>
</plugin>
<!-- there are the jasypt libs requires by some of the python scripts -->
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/client/tomcatconf/quickCloudComponentContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/quickCloudComponentContext.xml.in b/client/tomcatconf/quickCloudComponentContext.xml.in
new file mode 100644
index 0000000..dbd3117
--- /dev/null
+++ b/client/tomcatconf/quickCloudComponentContext.xml.in
@@ -0,0 +1,336 @@
+<!--
+ 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:tx="http://www.springframework.org/schema/tx"
+ 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/tx
+ http://www.springframework.org/schema/tx/spring-tx-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">
+
+
+ <!--
+ Compose a CloudStack deployment with selected components here
+ -->
+ <bean id="databaseUpgradeChecker" class="com.cloud.upgrade.DatabaseUpgradeChecker" />
+ <bean id="encryptionSecretKeyChecker" class="com.cloud.utils.crypt.EncryptionSecretKeyChecker" />
+ <bean id="configurationServerImpl" class="com.cloud.server.ConfigurationServerImpl" />
+
+ <bean id="managementServerImpl" class ="com.cloud.server.ManagementServerImpl" >
+ <property name="UserAuthenticators">
+ <list>
+ <ref bean="MD5UserAuthenticator"/>
+ <ref bean="LDAPUserAuthenticator"/>
+ </list>
+ </property>
+ </bean>
+
+ <bean id ="AccountManagerImpl" class="com.cloud.user.AccountManagerImpl">
+ <property name="UserAuthenticators">
+ <list>
+ <ref bean="MD5UserAuthenticator"/>
+ <ref bean="LDAPUserAuthenticator"/>
+ </list>
+ </property>
+ </bean>
+
+ <bean id="clusterManagerImpl" class="com.cloud.cluster.ClusterManagerImpl" />
+ <bean id="clusteredAgentManagerImpl" class="com.cloud.agent.manager.ClusteredAgentManagerImpl" />
+ <bean id="clusteredVirtualMachineManagerImpl" class="com.cloud.vm.ClusteredVirtualMachineManagerImpl" />
+ <bean id="highAvailabilityManagerExtImpl" class="com.cloud.ha.HighAvailabilityManagerExtImpl" />
+ <bean id="userVmManagerImpl" class="com.cloud.vm.UserVmManagerImpl" />
+ <bean id="consoleProxyManagerImpl" class="com.cloud.consoleproxy.StaticConsoleProxyManager" />
+ <bean id="securityGroupManagerImpl2" class="com.cloud.network.security.SecurityGroupManagerImpl2" />
+ <bean id="premiumSecondaryStorageManagerImpl" class="com.cloud.secstorage.PremiumSecondaryStorageManagerImpl" />
+ <bean id="userVmDaoImpl" class="com.cloud.vm.dao.UserVmDaoImpl" />
+ <bean id="ipv6AddressManagerImpl" class="com.cloud.network.Ipv6AddressManagerImpl" />
+
+ <bean id="apiRateLimitServiceImpl" class="org.apache.cloudstack.ratelimit.ApiRateLimitServiceImpl"/>
+ <bean id="BaremetalManager" class="com.cloud.baremetal.manager.BaremetalManagerImpl"/>
+ <bean id="BaremetalDhcpManager" class="com.cloud.baremetal.networkservice.BaremetalDhcpManagerImpl"/>
+ <bean id="BaremetalKickStartPxeService" class="com.cloud.baremetal.networkservice.BaremetalKickStartServiceImpl"/>
+ <bean id="BaremetalPingPxeService" class="com.cloud.baremetal.networkservice.BareMetalPingServiceImpl" />
+ <bean id="BaremetalPxeManager" class="com.cloud.baremetal.networkservice.BaremetalPxeManagerImpl" />
+ <bean id="UcsManager" class="com.cloud.ucs.manager.UcsManagerImpl" />
+ <bean id="UcsBladeDao" class="com.cloud.ucs.database.UcsBladeDaoImpl" />
+ <bean id="UcsManagerDao" class="com.cloud.ucs.database.UcsManagerDaoImpl" />
+
+
+ <!--
+ Network Elements
+ -->
+ <bean id="Ovs" class="com.cloud.network.element.OvsElement">
+ <property name="name" value="Ovs"/>
+ </bean>
+ <bean id="BareMetalDhcp" class="com.cloud.baremetal.networkservice.BaremetalDhcpElement">
+ <property name="name" value="BareMetalDhcp"/>
+ </bean>
+ <bean id="BareMetalPxe" class="com.cloud.baremetal.networkservice.BaremetalPxeElement">
+ <property name="name" value="BareMetalPxe"/>
+ </bean>
+ <bean id="BareMetalUserdata" class="com.cloud.baremetal.networkservice.BaremetalUserdataElement">
+ <property name="name" value="BareMetalUserdata"/>
+ </bean>
+ <bean id="SecurityGroupProvider" class="com.cloud.network.element.SecurityGroupElement">
+ <property name="name" value="SecurityGroupProvider"/>
+ </bean>
+ <bean id="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement">
+ <property name="name" value="VirtualRouter"/>
+ </bean>
+ <bean id="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement">
+ <property name="name" value="VpcVirtualRouter"/>
+ </bean>
+ <!--
+ <bean id="NiciraNvp" class="com.cloud.network.element.NiciraNvpElement">
+ <property name="name" value="NiciraNvp"/>
+ </bean>
+ -->
+
+<!--
+ <bean id="BigSwitchVnsElementService" class="com.cloud.network.element.BigSwitchVnsElement">
+ <property name="name" value="BigSwitchVnsElementService"/>
+ </bean>
+-->
+
+ <!--
+ Adapters
+ -->
+ <bean id="FirstFitRouting" class="com.cloud.agent.manager.allocator.impl.FirstFitRoutingAllocator">
+ <property name="name" value="FirstFitRouting"/>
+ </bean>
+
+ <bean id="hypervisorTemplateAdapter" class="com.cloud.template.HypervisorTemplateAdapter">
+ <property name="name" value="HypervisorAdapter"/>
+ </bean>
+
+ <!--
+ Storage pool allocators
+ -->
+
+ <bean id="LocalStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.LocalStoragePoolAllocator">
+ <property name="name" value="LocalStorage"/>
+ </bean>
+ <!--
+ <bean id="FirstFitStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.FirstFitStoragePoolAllocator">
+ <property name="name" value="Storage"/>
+ </bean>
+ -->
+
+ <bean id="UserConcentratedAllocator" class="com.cloud.agent.manager.allocator.impl.UserConcentratedAllocator">
+ <property name="name" value="User First"/>
+ </bean>
+
+ <bean id="ConsoleProxyAllocator" class="com.cloud.consoleproxy.ConsoleProxyBalanceAllocator">
+ <property name="name" value="Balance"/>
+ </bean>
+
+ <bean id="StaticRoleBasedAPIAccessChecker" class="org.apache.cloudstack.acl.StaticRoleBasedAPIAccessChecker"/>
+
+ <bean id="ExteralIpAddressAllocator" class="com.cloud.network.ExteralIpAddressAllocator">
+ <property name="name" value="Basic"/>
+ </bean>
+
+ <bean id="HypervisorTemplateAdapter" class="com.cloud.template.HypervisorTemplateAdapter">
+ <property name="name" value="HypervisorAdapter"/>
+ </bean>
+
+ <bean id="BareMetalTemplateAdapter" class="com.cloud.baremetal.manager.BareMetalTemplateAdapter" >
+ <property name="name" value="BareMetalTemplateAdapter"/>
+ </bean>
+
+ <!--
+ Authenticators
+ -->
+ <bean id="MD5UserAuthenticator" class="com.cloud.server.auth.MD5UserAuthenticator">
+ <property name="name" value="MD5"/>
+ </bean>
+
+ <bean id="LDAPUserAuthenticator" class="com.cloud.server.auth.LDAPUserAuthenticator">
+ <property name="name" value="LDAP"/>
+ </bean>
+
+ <!--
+ Investigators
+ -->
+ <bean id="CheckOnAgentInvestigator" class="com.cloud.ha.CheckOnAgentInvestigator">
+ <property name="name" value="SimpleInvestigator"/>
+ </bean>
+
+ <bean id="XenServerInvestigator" class="com.cloud.ha.XenServerInvestigator">
+ <property name="name" value="XenServerInvestigator"/>
+ </bean>
+
+ <bean id="UserVmDomRInvestigator" class="com.cloud.ha.UserVmDomRInvestigator">
+ <property name="name" value="PingInvestigator"/>
+ </bean>
+
+ <bean id="ManagementIPSystemVMInvestigator" class="com.cloud.ha.ManagementIPSystemVMInvestigator">
+ <property name="name" value="ManagementIPSysVMInvestigator"/>
+ </bean>
+
+ <!--
+ Fencers
+ -->
+ <bean id="XenServerFencer" class="com.cloud.ha.XenServerFencer">
+ <property name="name" value="XenServerFenceBuilder"/>
+ </bean>
+ <bean id="KVMFencer" class="com.cloud.ha.KVMFencer">
+ <property name="name" value="KVMFenceBuilder"/>
+ </bean>
+ <bean id="OvmFencer" class="com.cloud.ovm.hypervisor.OvmFencer">
+ <property name="name" value="OvmFenceBuilder"/>
+ </bean>
+
+ <bean id="XcpServerDiscoverer" class="com.cloud.hypervisor.xen.discoverer.XcpServerDiscoverer">
+ <property name="name" value="XCP Agent"/>
+ </bean>
+
+ <!--
+ <bean id="SimulatorSecondaryStorageDiscoverer" class="com.cloud.resource.SimulatorSecondaryDiscoverer">
+ <property name="name" value="SecondaryStorage"/>
+ </bean>
+ -->
+
+ <bean id="SecondaryStorageDiscoverer" class="org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer">
+ <property name="name" value="SecondaryStorage"/>
+ </bean>
+
+ <bean id="KvmServerDiscoverer" class="com.cloud.hypervisor.kvm.discoverer.KvmServerDiscoverer">
+ <property name="name" value="KVM Agent"/>
+ </bean>
+
+ <bean id="SimulatorDiscoverer" class="com.cloud.resource.SimulatorDiscoverer">
+ <property name="name" value="Simulator Agent"/>
+ </bean>
+
+
+ <bean id="BareMetalDiscoverer" class="com.cloud.baremetal.manager.BareMetalDiscoverer">
+ <property name="name" value="Bare Metal Agent"/>
+ </bean>
+
+ <bean id="HypervServerDiscoverer" class="com.cloud.hypervisor.hyperv.HypervServerDiscoverer">
+ <property name="name" value="SCVMMServer"/>
+ </bean>
+
+ <bean id="OvmDiscoverer" class="com.cloud.ovm.hypervisor.OvmDiscoverer">
+ <property name="name" value="Ovm Discover"/>
+ </bean>
+
+ <bean id="FirstFitPlanner" class="com.cloud.deploy.FirstFitPlanner">
+ <property name="name" value="First Fit"/>
+ </bean>
+
+ <bean id="UserDispersingPlanner" class="com.cloud.deploy.UserDispersingPlanner">
+ <property name="name" value="UserDispersing"/>
+ </bean>
+
+ <bean id="UserConcentratedPodPlanner" class="com.cloud.deploy.UserConcentratedPodPlanner">
+ <property name="name" value="UserConcentratedPod"/>
+ </bean>
+
+ <bean id="BareMetalPlanner" class="com.cloud.baremetal.manager.BareMetalPlanner">
+ <property name="name" value="BareMetal Fit"/>
+ </bean>
+
+ <bean id="BaremetalPlannerSelector" class="com.cloud.baremetal.manager.BaremetalPlannerSelector">
+ <property name="name" value="BaremetalPlannerSelector"/>
+ </bean>
+
+ <bean id="HypervisorPlannerSelector" class="com.cloud.deploy.HypervisorVmPlannerSelector">
+ <property name="name" value="HypervisorPlannerSelector"/>
+ </bean>
+
+
+ <!--
+ Network Gurus
+ -->
+ <bean id="StorageNetworkGuru" class="com.cloud.network.guru.StorageNetworkGuru">
+ <property name="name" value="StorageNetworkGuru"/>
+ </bean>
+ <bean id="ExternalGuestNetworkGuru" class="com.cloud.network.guru.ExternalGuestNetworkGuru">
+ <property name="name" value="ExternalGuestNetworkGuru"/>
+ </bean>
+ <bean id="PublicNetworkGuru" class="com.cloud.network.guru.PublicNetworkGuru">
+ <property name="name" value="PublicNetworkGuru"/>
+ </bean>
+ <bean id="PodBasedNetworkGuru" class="com.cloud.network.guru.PodBasedNetworkGuru">
+ <property name="name" value="PodBasedNetworkGuru"/>
+ </bean>
+ <bean id="ControlNetworkGuru" class="com.cloud.network.guru.ControlNetworkGuru">
+ <property name="name" value="ControlNetworkGuru"/>
+ </bean>
+ <bean id="DirectNetworkGuru" class="com.cloud.network.guru.DirectNetworkGuru">
+ <property name="name" value="DirectNetworkGuru"/>
+ </bean>
+ <bean id="DirectPodBasedNetworkGuru" class="com.cloud.network.guru.DirectPodBasedNetworkGuru">
+ <property name="name" value="DirectPodBasedNetworkGuru"/>
+ </bean>
+ <bean id="OvsGuestNetworkGuru" class="com.cloud.network.guru.OvsGuestNetworkGuru">
+ <property name="name" value="OvsGuestNetworkGuru"/>
+ </bean>
+ <bean id="PrivateNetworkGuru" class="com.cloud.network.guru.PrivateNetworkGuru">
+ <property name="name" value="PrivateNetworkGuru"/>
+ </bean>
+ <bean id="NiciraNvpGuestNetworkGuru" class="com.cloud.network.guru.NiciraNvpGuestNetworkGuru">
+ <property name="name" value="NiciraNvpGuestNetworkGuru"/>
+ </bean>
+
+<!--
+ <bean id="BigSwitchVnsGuestNetworkGuru" class=".BigSwitchVnsGuestNetworkGuru">
+ <property name="name" value="com.cloud.network.guru.BigSwitchVnsGuestNetworkGuru"/>
+ </bean>
+-->
+
+ <!--
+ Hypervisor Gurus
+ -->
+ <bean id="XenServerGuru" class="com.cloud.hypervisor.XenServerGuru">
+ <property name="name" value="XenServerGuru"/>
+ </bean>
+
+ <bean id="KVMGuru" class="com.cloud.hypervisor.KVMGuru">
+ <property name="name" value="KVMGuru"/>
+ </bean>
+
+ <bean id="HypervGuru" class="com.cloud.hypervisor.guru.HypervGuru">
+ <property name="name" value="HypervGuru"/>
+ </bean>
+
+ <bean id="OvmGuru" class="com.cloud.ovm.hypervisor.OvmGuru">
+ <property name="name" value="OvmGuru"/>
+ </bean>
+
+ <bean id="SimulatorGuru" class="com.cloud.simulator.SimulatorGuru">
+ <property name="name" value="SimulatorGuru"/>
+ </bean>
+
+ <bean id="BaremetalGuru" class="com.cloud.baremetal.manager.BareMetalGuru">
+ <property name="name" value="BaremetalGuru"/>
+ </bean>
+
+ <bean id="ClassicalPrimaryDataStoreProvider" class="org.apache.cloudstack.storage.datastore.provider.CloudStackPrimaryDataStoreProviderImpl">
+ </bean>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/plugins/hypervisors/simulator/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/pom.xml b/plugins/hypervisors/simulator/pom.xml
index ff1664a..e4ca927 100644
--- a/plugins/hypervisors/simulator/pom.xml
+++ b/plugins/hypervisors/simulator/pom.xml
@@ -40,5 +40,10 @@
<artifactId>cloud-utils</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-secondary-storage</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
index 3a8cf17..c121fba 100644
--- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
@@ -24,6 +24,7 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@@ -40,9 +41,7 @@ import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.secondary.SecondaryStorageDiscoverer;
import com.cloud.utils.exception.CloudRuntimeException;
-import org.springframework.stereotype.Component;
@Local(value=Discoverer.class)
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/plugins/hypervisors/vmware/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml
index 468e0a5..d65ef64 100644
--- a/plugins/hypervisors/vmware/pom.xml
+++ b/plugins/hypervisors/vmware/pom.xml
@@ -33,6 +33,11 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-secondary-storage</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>com.cloud.com.vmware</groupId>
<artifactId>vmware-vim25</artifactId>
<version>${cs.vmware.api.version}</version>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/server/pom.xml
----------------------------------------------------------------------
diff --git a/server/pom.xml b/server/pom.xml
index 8a6a10c..a397195 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -32,11 +32,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.apache.cloudstack</groupId>
- <artifactId>cloud-secondary-storage</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${cs.servlet.version}</version>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java b/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
deleted file mode 100755
index 6e66e0d..0000000
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
+++ /dev/null
@@ -1,322 +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.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.cloudstack.storage.resource.LocalSecondaryStorageResource;
-import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status.Event;
-import com.cloud.host.dao.HostDao;
-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.VMTemplateHostDao;
-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 HostDao _hostDao = null;
- @Inject
- protected VMTemplateDao _tmpltDao = null;
- @Inject
- protected VMTemplateHostDao _vmTemplateHostDao = null;
- @Inject
- protected VMTemplateZoneDao _vmTemplateZoneDao = null;
- @Inject
- protected VMTemplateDao _vmTemplateDao = null;
- @Inject
- protected ConfigurationDao _configDao = 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("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("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/c5b11df6/services/console-proxy/server/pom.xml
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml
index fd7b964..3d149a5 100644
--- a/services/console-proxy/server/pom.xml
+++ b/services/console-proxy/server/pom.xml
@@ -57,6 +57,11 @@
<version>${project.version}</version>
<type>pom</type>
</dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-secondary-storage</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
@@ -256,11 +261,6 @@
</profile>
<profile>
<id>quickcloud</id>
- <activation>
- <property>
- <name>quickcloud</name>
- </property>
- </activation>
<build>
<plugins>
<plugin>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/services/secondary-storage/pom.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml
index d8dbf1d..0577084 100644
--- a/services/secondary-storage/pom.xml
+++ b/services/secondary-storage/pom.xml
@@ -54,6 +54,11 @@
<version>${project.version}</version>
<type>pom</type>
</dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-server</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
@@ -87,27 +92,4 @@
</plugin>
</plugins>
</build>
- <profiles>
- <profile>
- <id>vmware</id>
- <activation>
- <property>
- <name>nonoss</name>
- </property>
- </activation>
- <dependencies>
- <dependency>
- <groupId>org.apache.cloudstack</groupId>
- <artifactId>cloud-plugin-hypervisor-vmware</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.cloudstack</groupId>
- <artifactId>cloud-vmware-base</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
- </profile>
- </profiles>
-
</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/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
new file mode 100755
index 0000000..d3af792
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
@@ -0,0 +1,320 @@
+// 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.configuration.dao.ConfigurationDao;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status.Event;
+import com.cloud.host.dao.HostDao;
+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.VMTemplateHostDao;
+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 HostDao _hostDao = null;
+ @Inject
+ protected VMTemplateDao _tmpltDao = null;
+ @Inject
+ protected VMTemplateHostDao _vmTemplateHostDao = null;
+ @Inject
+ protected VMTemplateZoneDao _vmTemplateZoneDao = null;
+ @Inject
+ protected VMTemplateDao _vmTemplateDao = null;
+ @Inject
+ protected ConfigurationDao _configDao = 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("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("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/c5b11df6/tools/devcloud/pom.xml
----------------------------------------------------------------------
diff --git a/tools/devcloud/pom.xml b/tools/devcloud/pom.xml
index d32d84b..93029e1 100644
--- a/tools/devcloud/pom.xml
+++ b/tools/devcloud/pom.xml
@@ -143,10 +143,10 @@
</build>
</profile>
<profile>
- <id>quicksvr</id>
+ <id>quickcloud</id>
<activation>
<property>
- <name>quicksvr</name>
+ <name>quickcloud</name>
</property>
</activation>
<build>
[08/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: move devcloud configuration into pom profile for exec:java
Also ignore agent.properties in RAT since
a. they are trivial
b. they are modified by the java code (stripping the license)
QuickCloud: proper path for log.home
QuickCloud: proper path for secstorage.sh
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/778a59fb
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/778a59fb
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/778a59fb
Branch: refs/heads/master
Commit: 778a59fbf6bc8957771718123079bd8a2707affa
Parents: 5ff8bca
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Fri Apr 5 14:25:44 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700
----------------------------------------------------------------------
pom.xml | 4 ++
.../console-proxy/server/conf/agent.properties | 17 --------
services/console-proxy/server/pom.xml | 3 +
.../console-proxy/server/scripts/consoleproxy.sh | 2 +-
.../console-proxy/server/scripts/secstorage.sh | 33 +++++++++++++++
services/secondary-storage/conf/agent.properties | 9 +----
services/secondary-storage/pom.xml | 8 ++++
services/secondary-storage/scripts/secstorage.sh | 33 ---------------
8 files changed, 50 insertions(+), 59 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 6208124..dbc3907 100644
--- a/pom.xml
+++ b/pom.xml
@@ -317,6 +317,10 @@
<exclude>deps/XenServerJava/Makefile</exclude>
<exclude>dist/console-proxy/js/jquery.js</exclude>
<exclude>scripts/vm/systemvm/id_rsa.cloud</exclude>
+ <exclude>services/console-proxy/server/conf/agent.properties</exclude>
+ <exclude>services/console-proxy/server/conf/environment.properties</exclude>
+ <exclude>services/secondary-storage/conf/agent.properties</exclude>
+ <exclude>services/secondary-storage/conf/environment.properties</exclude>
<exclude>tools/devcloud/basebuild/puppet-devcloudinitial/files/network.conf</exclude>
<exclude>tools/appliance/definitions/devcloud/*</exclude>
<exclude>tools/appliance/definitions/systemvmtemplate/*</exclude>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/console-proxy/server/conf/agent.properties
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/conf/agent.properties b/services/console-proxy/server/conf/agent.properties
index 4e217f2..246cb1c 100644
--- a/services/console-proxy/server/conf/agent.properties
+++ b/services/console-proxy/server/conf/agent.properties
@@ -1,19 +1,2 @@
-# 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.
-
instance=ConsoleProxy
resource=com.cloud.agent.resource.consoleproxy.ConsoleProxyResource
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/console-proxy/server/pom.xml
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml
index 3d149a5..3ac5d59 100644
--- a/services/console-proxy/server/pom.xml
+++ b/services/console-proxy/server/pom.xml
@@ -280,11 +280,14 @@
<argument>zone=1</argument>
<argument>pod=1</argument>
<argument>host=192.168.56.1</argument>
+ <argument>guid=ConsoleProxy.1</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>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/console-proxy/server/scripts/consoleproxy.sh
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/scripts/consoleproxy.sh b/services/console-proxy/server/scripts/consoleproxy.sh
index 4a6acde..294d597 100755
--- a/services/console-proxy/server/scripts/consoleproxy.sh
+++ b/services/console-proxy/server/scripts/consoleproxy.sh
@@ -28,6 +28,6 @@ do
done
keyvalues=
#LOGHOME=/var/log/cloud/
-LOGHOME=$PWD
+LOGHOME=$PWD/
java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -cp $CP com.cloud.agent.AgentShell $keyvalues $@
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/console-proxy/server/scripts/secstorage.sh
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/scripts/secstorage.sh b/services/console-proxy/server/scripts/secstorage.sh
new file mode 100755
index 0000000..b45afc2
--- /dev/null
+++ b/services/console-proxy/server/scripts/secstorage.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+
+#runs the secondary storage service as a standalone server
+#i.e., not in the system vm
+
+CP=./:./conf
+for file in *.jar
+do
+ CP=${CP}:$file
+done
+keyvalues=
+#LOGHOME=/var/log/cloud/
+LOGHOME=$PWD/
+
+java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -cp $CP com.cloud.agent.AgentShell $keyvalues $@
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/secondary-storage/conf/agent.properties
----------------------------------------------------------------------
diff --git a/services/secondary-storage/conf/agent.properties b/services/secondary-storage/conf/agent.properties
index 554007f..aab82b6 100644
--- a/services/secondary-storage/conf/agent.properties
+++ b/services/secondary-storage/conf/agent.properties
@@ -1,9 +1,2 @@
-#mount.path=~/secondary-storage
-eth1ip=192.168.56.1
-name=192.168.56.10
-eth2ip=192.168.56.10
+#mount.path=~/secondary-storage/
resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource
-piddir=.
-instance=SecondaryStorage
-developer=true
-secondary.storage.vm=false
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/secondary-storage/pom.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml
index 0577084..2c8a1d0 100644
--- a/services/secondary-storage/pom.xml
+++ b/services/secondary-storage/pom.xml
@@ -81,11 +81,19 @@
<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>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/secondary-storage/scripts/secstorage.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/secstorage.sh b/services/secondary-storage/scripts/secstorage.sh
deleted file mode 100755
index 9afc521..0000000
--- a/services/secondary-storage/scripts/secstorage.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-
-
-#runs the secondary storage service as a standalone server
-#i.e., not in the system vm
-
-CP=./:./conf
-for file in *.jar
-do
- CP=${CP}:$file
-done
-keyvalues=
-#LOGHOME=/var/log/cloud/
-LOGHOME=$PWD
-
-java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -cp $CP com.cloud.agent.AgentShell $keyvalues $@
[06/19] QuickCloud: Enable secondary storage daemon to run outside
the system vm
Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
deleted file mode 100755
index e65cbe1..0000000
--- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
+++ /dev/null
@@ -1,1842 +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.resource;
-
-import static com.cloud.utils.S3Utils.deleteDirectory;
-import static com.cloud.utils.S3Utils.getDirectory;
-import static com.cloud.utils.S3Utils.putDirectory;
-import static com.cloud.utils.StringUtils.join;
-import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock;
-import static java.lang.String.format;
-import static java.util.Arrays.asList;
-import static org.apache.commons.lang.StringUtils.substringAfterLast;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileWriter;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.net.URI;
-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 java.util.concurrent.Callable;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckHealthAnswer;
-import com.cloud.agent.api.CheckHealthCommand;
-import com.cloud.agent.api.CleanupSnapshotBackupCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.ComputeChecksumCommand;
-import com.cloud.agent.api.DeleteObjectFromSwiftCommand;
-import com.cloud.agent.api.DeleteSnapshotBackupCommand;
-import com.cloud.agent.api.DeleteSnapshotsDirCommand;
-import com.cloud.agent.api.DeleteTemplateFromS3Command;
-import com.cloud.agent.api.DownloadSnapshotFromS3Command;
-import com.cloud.agent.api.DownloadTemplateFromS3ToSecondaryStorageCommand;
-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.SecStorageSetupCommand.Certificates;
-import com.cloud.agent.api.SecStorageVMSetupCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupSecondaryStorageCommand;
-import com.cloud.agent.api.UploadTemplateToS3FromSecondaryStorageCommand;
-import com.cloud.agent.api.downloadSnapshotFromSwiftCommand;
-import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand;
-import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand;
-import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DeleteTemplateCommand;
-import com.cloud.agent.api.storage.DeleteVolumeCommand;
-import com.cloud.agent.api.storage.DownloadCommand;
-import com.cloud.agent.api.storage.DownloadProgressCommand;
-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.storage.ssCommand;
-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.resource.ServerResourceBase;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.template.DownloadManager;
-import com.cloud.storage.template.DownloadManagerImpl;
-import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser;
-import com.cloud.storage.template.TemplateInfo;
-import com.cloud.storage.template.TemplateLocation;
-import com.cloud.storage.template.UploadManager;
-import com.cloud.storage.template.UploadManagerImpl;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.S3Utils;
-import com.cloud.utils.S3Utils.FileNamingStrategy;
-import com.cloud.utils.S3Utils.ObjectNamingStrategy;
-import com.cloud.utils.component.ComponentContext;
-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 SNAPSHOT_ROOT_DIR = "snapshots";
-
- int _timeout;
-
- String _instance;
- String _dc;
- String _pod;
- String _guid;
- String _role;
- Map<String, Object> _params;
- StorageLayer _storage;
- boolean _inSystemVM = false;
- boolean _sslCopy = false;
-
- DownloadManager _dlMgr;
- 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>();
- final private String _parent = "/mnt/SecStorage";
- final private String _tmpltDir = "/var/cloudstack/template";
- final private String _tmpltpp = "template.properties";
- @Override
- public void disconnected() {
- }
-
- @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 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 DeleteTemplateCommand) {
- return execute((DeleteTemplateCommand) cmd);
- } else if (cmd instanceof DeleteVolumeCommand) {
- return execute((DeleteVolumeCommand) cmd);
- }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 downloadSnapshotFromSwiftCommand){
- return execute((downloadSnapshotFromSwiftCommand)cmd);
- } else if (cmd instanceof DownloadSnapshotFromS3Command) {
- return execute((DownloadSnapshotFromS3Command) cmd);
- } else if (cmd instanceof DeleteSnapshotBackupCommand){
- return execute((DeleteSnapshotBackupCommand)cmd);
- } else if (cmd instanceof DeleteSnapshotsDirCommand){
- return execute((DeleteSnapshotsDirCommand)cmd);
- } else if (cmd instanceof downloadTemplateFromSwiftToSecondaryStorageCommand) {
- return execute((downloadTemplateFromSwiftToSecondaryStorageCommand) cmd);
- } else if (cmd instanceof DownloadTemplateFromS3ToSecondaryStorageCommand) {
- return execute((DownloadTemplateFromS3ToSecondaryStorageCommand) cmd);
- } else if (cmd instanceof uploadTemplateToSwiftFromSecondaryStorageCommand) {
- return execute((uploadTemplateToSwiftFromSecondaryStorageCommand) cmd);
- } else if (cmd instanceof UploadTemplateToS3FromSecondaryStorageCommand) {
- return execute((UploadTemplateToS3FromSecondaryStorageCommand) cmd);
- } else if (cmd instanceof DeleteObjectFromSwiftCommand) {
- return execute((DeleteObjectFromSwiftCommand) cmd);
- } else if (cmd instanceof DeleteTemplateFromS3Command) {
- return execute((DeleteTemplateFromS3Command) cmd);
- } else if (cmd instanceof CleanupSnapshotBackupCommand){
- return execute((CleanupSnapshotBackupCommand)cmd);
- } else {
- return Answer.createUnsupportedCommandAnswer(cmd);
- }
- }
-
- @SuppressWarnings("unchecked")
- private String determineS3TemplateDirectory(final Long accountId,
- final Long templateId) {
- return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId),
- S3Utils.SEPARATOR);
- }
-
- @SuppressWarnings("unchecked")
- private String determineStorageTemplatePath(final String storagePath,
- final Long accountId, final Long templateId) {
- return join(
- asList(getRootDir(storagePath), TEMPLATE_ROOT_DIR, accountId,
- templateId), File.separator);
- }
-
- private Answer execute(
- final DownloadTemplateFromS3ToSecondaryStorageCommand cmd) {
-
- final S3TO s3 = cmd.getS3();
- final String storagePath = cmd.getStoragePath();
- final Long accountId = cmd.getAccountId();
- final Long templateId = cmd.getTemplateId();
-
- try {
-
- final File downloadDirectory = _storage
- .getFile(determineStorageTemplatePath(storagePath,
- accountId, templateId));
- downloadDirectory.mkdirs();
-
- if (!downloadDirectory.exists()) {
- final String errMsg = format(
- "Unable to create directory "
- + "download directory %1$s for download of template id "
- + "%2$s from S3.", downloadDirectory.getName(),
- templateId);
- s_logger.error(errMsg);
- return new Answer(cmd, false, errMsg);
- }
-
- getDirectory(s3, s3.getBucketName(),
- determineS3TemplateDirectory(accountId, templateId),
- downloadDirectory, new FileNamingStrategy() {
- @Override
- public String determineFileName(final String key) {
- return substringAfterLast(key, S3Utils.SEPARATOR);
- }
- });
-
- return new Answer(cmd, true, format("Successfully downloaded "
- + "template id %1$s from S3 to directory %2$s", templateId,
- downloadDirectory.getName()));
-
- } catch (Exception e) {
-
- final String errMsg = format("Failed to upload template id %1$s "
- + "due to $2%s", templateId, e.getMessage());
- s_logger.error(errMsg, e);
- return new Answer(cmd, false, errMsg);
-
- }
-
- }
-
- private Answer execute(downloadTemplateFromSwiftToSecondaryStorageCommand cmd) {
- SwiftTO swift = cmd.getSwift();
- String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
- Long accountId = cmd.getAccountId();
- Long templateId = cmd.getTemplateId();
- String path = cmd.getPath();
- String errMsg;
- String lDir = null;
- try {
- String parent = getRootDir(secondaryStorageUrl);
- lDir = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString();
- String result = createLocalDir(lDir);
- if (result != null) {
- errMsg = "downloadTemplateFromSwiftToSecondaryStorageCommand failed due to Create local directory failed";
- s_logger.warn(errMsg);
- throw new InternalErrorException(errMsg);
- }
- String lPath = lDir + "/" + path;
- result = swiftDownload(swift, "T-" + templateId.toString(), path, lPath);
- if (result != null) {
- errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + " , err=" + result;
- s_logger.warn(errMsg);
- throw new CloudRuntimeException(errMsg);
- }
- path = "template.properties";
- lPath = lDir + "/" + path;
- result = swiftDownload(swift, "T-" + templateId.toString(), path, lPath);
- if (result != null) {
- errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + " , err=" + result;
- s_logger.warn(errMsg);
- throw new CloudRuntimeException(errMsg);
- }
- return new Answer(cmd, true, "success");
- } catch (Exception e) {
- if (lDir != null) {
- deleteLocalDir(lDir);
- }
- errMsg = cmd + " Command failed due to " + e.toString();
- s_logger.warn(errMsg, e);
- return new Answer(cmd, false, errMsg);
- }
- }
-
- private Answer execute(uploadTemplateToSwiftFromSecondaryStorageCommand cmd) {
- SwiftTO swift = cmd.getSwift();
- String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
- Long accountId = cmd.getAccountId();
- Long templateId = cmd.getTemplateId();
- try {
- String parent = getRootDir(secondaryStorageUrl);
- String lPath = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString();
- if (!_storage.isFile(lPath + "/template.properties")) {
- String errMsg = cmd + " Command failed due to template doesn't exist ";
- s_logger.debug(errMsg);
- return new Answer(cmd, false, errMsg);
- }
- String result = swiftUpload(swift, "T-" + templateId.toString(), lPath, "*");
- if (result != null) {
- String errMsg = "failed to upload template from secondary storage " + lPath + " to swift , err=" + result;
- s_logger.debug(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);
- }
- }
-
- private Answer execute(UploadTemplateToS3FromSecondaryStorageCommand cmd) {
-
- final S3TO s3 = cmd.getS3();
- final Long accountId = cmd.getAccountId();
- final Long templateId = cmd.getTemplateId();
-
- try {
-
- final String templatePath = determineStorageTemplatePath(
- cmd.getStoragePath(), accountId, templateId);
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Found template id " + templateId
- + " account id " + accountId + " from directory "
- + templatePath + " to upload to S3.");
- }
-
- if (!_storage.isDirectory(templatePath)) {
- final String errMsg = format("S3 Sync Failure: Directory %1$s"
- + "for template id %2$s does not exist.", templatePath,
- templateId);
- s_logger.error(errMsg);
- return new Answer(cmd, false, errMsg);
- }
-
- if (!_storage.isFile(templatePath + "/template.properties")) {
- final String errMsg = format("S3 Sync Failure: Template id "
- + "%1$s does not exist on the file system.",
- templatePath);
- s_logger.error(errMsg);
- return new Answer(cmd, false, errMsg);
- }
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug(format(
- "Pushing template id %1$s from %2$s to S3...",
- templateId, templatePath));
- }
-
- final String bucket = s3.getBucketName();
- putDirectory(s3, bucket, _storage.getFile(templatePath),
- new FilenameFilter() {
- @Override
- public boolean accept(final File directory,
- final String fileName) {
- File fileToUpload = new File(directory.getAbsolutePath() + "/" + fileName);
- return !fileName.startsWith(".") && !fileToUpload.isDirectory();
- }
- }, new ObjectNamingStrategy() {
- @Override
- public String determineKey(final File file) {
- s_logger.debug(String
- .format("Determining key using account id %1$s and template id %2$s",
- accountId, templateId));
- return join(
- asList(determineS3TemplateDirectory(
- accountId, templateId), file
- .getName()), S3Utils.SEPARATOR);
- }
- });
-
- return new Answer(
- cmd,
- true,
- format("Uploaded the contents of directory %1$s for template id %2$s to S3 bucket %3$s",
- templatePath, templateId, bucket));
-
- } catch (Exception e) {
-
- final String errMsg = format("Failed to upload template id %1$s",
- templateId);
- s_logger.error(errMsg, e);
- return new Answer(cmd, false, errMsg);
-
- }
-
- }
-
- private Answer execute(DeleteObjectFromSwiftCommand cmd) {
- SwiftTO swift = cmd.getSwift();
- String container = cmd.getContainer();
- String object = cmd.getObject();
- if (object == null) {
- 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);
- }
-
- }
-
- private Answer execute(final DeleteTemplateFromS3Command cmd) {
-
- final S3TO s3 = cmd.getS3();
- final Long accountId = cmd.getAccountId();
- final Long templateId = cmd.getTemplateId();
-
- if (accountId == null || (accountId != null && accountId <= 0)) {
- final String errorMessage = "No account id specified for S3 template deletion.";
- s_logger.error(errorMessage);
- return new Answer(cmd, false, errorMessage);
- }
-
- if (templateId == null || (templateId != null && templateId <= 0)) {
- final String errorMessage = "No template id specified for S3 template deletion.";
- s_logger.error(errorMessage);
- return new Answer(cmd, false, errorMessage);
- }
-
- if (s3 == null) {
- final String errorMessge = "No S3 client options provided";
- s_logger.error(errorMessge);
- return new Answer(cmd, false, errorMessge);
- }
-
- final String bucket = s3.getBucketName();
- try {
- deleteDirectory(s3, bucket,
- determineS3TemplateDirectory(templateId, accountId));
- return new Answer(cmd, true, String.format(
- "Deleted template %1%s from bucket %2$s.", templateId,
- bucket));
- } catch (Exception e) {
- final String errorMessage = String
- .format("Failed to delete templaet id %1$s from bucket %2$s due to the following error: %3$s",
- templateId, bucket, e.getMessage());
- s_logger.error(errorMessage, e);
- return new Answer(cmd, false, errorMessage);
- }
-
- }
-
- 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=" + lines.toString();
- 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=" + lines.toString();
- 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=" + lines.toString();
- 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=" + lines.toString();
- s_logger.warn(errMsg);
- return errMsg;
- }
- }
- }
- return null;
- }
-
-
- public Answer execute(DeleteSnapshotsDirCommand cmd){
- String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
- Long accountId = cmd.getAccountId();
- Long volumeId = cmd.getVolumeId();
- try {
- String parent = getRootDir(secondaryStorageUrl);
- String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId) + "/*";
- 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);
- }
- 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);
- }
- }
-
- public Answer execute(final DownloadSnapshotFromS3Command cmd) {
-
- final S3TO s3 = cmd.getS3();
- final String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
- final Long accountId = cmd.getAccountId();
- final Long volumeId = cmd.getVolumeId();
-
- try {
-
- executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId),
- new Callable<Void>() {
-
- @Override
- public Void call() throws Exception {
-
- final String directoryName = determineSnapshotLocalDirectory(
- secondaryStorageUrl, accountId, volumeId);
-
- String result = createLocalDir(directoryName);
- if (result != null) {
- throw new InternalErrorException(
- format("Failed to create directory %1$s during S3 snapshot download.",
- directoryName));
- }
-
- final String snapshotFileName = determineSnapshotBackupFilename(cmd
- .getSnapshotUuid());
- final String key = determineSnapshotS3Key(
- accountId, volumeId, snapshotFileName);
- final File targetFile = S3Utils.getFile(s3,
- s3.getBucketName(), key,
- _storage.getFile(directoryName),
- new FileNamingStrategy() {
-
- @Override
- public String determineFileName(
- String key) {
- return snapshotFileName;
- }
-
- });
-
- if (cmd.getParent() != null) {
-
- final String parentPath = join(
- File.pathSeparator, directoryName,
- determineSnapshotBackupFilename(cmd
- .getParent()));
- result = setVhdParent(
- targetFile.getAbsolutePath(),
- parentPath);
- if (result != null) {
- throw new InternalErrorException(
- format("Failed to set the parent for backup %1$s to %2$s due to %3$s.",
- targetFile
- .getAbsolutePath(),
- parentPath, result));
- }
-
- }
-
- return null;
-
- }
-
- });
-
- return new Answer(
- cmd,
- true,
- format("Succesfully retrieved volume id %1$s for account id %2$s to %3$s from S3.",
- volumeId, accountId, secondaryStorageUrl));
-
- } catch (Exception e) {
- final String errMsg = format(
- "Failed to retrieve volume id %1$s for account id %2$s to %3$s from S3 due to exception %4$s",
- volumeId, accountId, secondaryStorageUrl, e.getMessage());
- s_logger.error(errMsg);
- return new Answer(cmd, false, errMsg);
- }
-
- }
-
- private String determineSnapshotS3Directory(final Long accountId,
- final Long volumeId) {
- return join(S3Utils.SEPARATOR, SNAPSHOT_ROOT_DIR, accountId, volumeId);
- }
-
- private String determineSnapshotS3Key(final Long accountId,
- final Long volumeId, final String snapshotFileName) {
-
- final String directoryName = determineSnapshotS3Directory(accountId,
- volumeId);
- return join(S3Utils.SEPARATOR, directoryName, snapshotFileName);
-
- }
-
- private String determineSnapshotLocalDirectory(
- final String secondaryStorageUrl, final Long accountId,
- final Long volumeId) {
- return join(File.pathSeparator, getRootDir(secondaryStorageUrl),
- SNAPSHOT_ROOT_DIR, accountId, volumeId);
- }
-
- public Answer execute(downloadSnapshotFromSwiftCommand cmd){
- SwiftTO swift = cmd.getSwift();
- String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
- Long accountId = cmd.getAccountId();
- Long volumeId = cmd.getVolumeId();
- String rFilename = cmd.getSnapshotUuid();
- String sParent = cmd.getParent();
- String errMsg = "";
- try {
- String parent = getRootDir(secondaryStorageUrl);
- String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId);
-
- String result = createLocalDir(lPath);
- if ( result != null ) {
- errMsg = "downloadSnapshotFromSwiftCommand failed due to Create local path failed";
- s_logger.warn(errMsg);
- throw new InternalErrorException(errMsg);
- }
- String lFilename = rFilename;
- if ( rFilename.startsWith("VHD-") ) {
- lFilename = rFilename.replace("VHD-", "") + ".vhd";
- }
- String lFullPath = lPath + "/" + lFilename;
- result = swiftDownload(swift, "S-" + volumeId.toString(), rFilename, lFullPath);
- if (result != null) {
- return new Answer(cmd, false, result);
- }
- if (sParent != null) {
- if (sParent.startsWith("VHD-") || sParent.endsWith(".vhd")) {
- String pFilename = sParent;
- if (sParent.startsWith("VHD-")) {
- pFilename = pFilename.replace("VHD-", "") + ".vhd";
- }
- String pFullPath = lPath + "/" + pFilename;
- result = setVhdParent(lFullPath, pFullPath);
- if (result != null) {
- return new Answer(cmd, false, result);
- }
- }
- }
-
- return new Answer(cmd, true, "success");
- } catch (Exception e) {
- String msg = cmd + " Command failed due to " + e.toString();
- s_logger.warn(msg, e);
- throw new CloudRuntimeException(msg);
- }
- }
-
- private Answer execute(ComputeChecksumCommand cmd) {
-
- String relativeTemplatePath = cmd.getTemplatePath();
- String parent = getRootDir(cmd);
-
- 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(Certificates certs) {
- if (certs == null) {
- configureSSL();
- } else {
- String prvKey = certs.getPrivKey();
- String pubCert = certs.getPrivCert();
- String certChain = certs.getCertChain();
-
- 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);
- }
- String secUrl = cmd.getSecUrl();
- try {
- URI uri = new URI(secUrl);
- String nfsHost = uri.getHost();
-
- InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
- String nfsHostIp = nfsHostAddr.getHostAddress();
-
- addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
- String nfsPath = nfsHostIp + ":" + uri.getPath();
- String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString();
- String root = _parent + "/" + dir;
- mount(root, nfsPath);
-
- 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);
-
- }
- }
-
- private String deleteSnapshotBackupFromLocalFileSystem(
- final String secondaryStorageUrl, final Long accountId,
- final Long volumeId, final String name, final Boolean deleteAllFlag) {
-
- final String lPath = determineSnapshotLocalDirectory(
- secondaryStorageUrl, accountId, volumeId)
- + File.pathSeparator
- + (deleteAllFlag ? "*" : "*" + name + "*");
-
- final String result = deleteLocalFile(lPath);
-
- if (result != null) {
- return "failed to delete snapshot " + lPath + " , err=" + result;
- }
-
- return null;
-
- }
-
- private String deleteSnapshotBackupfromS3(final S3TO s3,
- final String secondaryStorageUrl, final Long accountId,
- final Long volumeId, final String name, final Boolean deleteAllFlag) {
-
- try {
-
- final String bucket = s3.getBucketName();
-
- final String result = executeWithNoWaitLock(
- determineSnapshotLockId(accountId, volumeId),
- new Callable<String>() {
-
- @Override
- public String call() throws Exception {
-
- final String innerResult = deleteSnapshotBackupFromLocalFileSystem(
- secondaryStorageUrl, accountId, volumeId,
- name, deleteAllFlag);
- if (innerResult != null) {
- return innerResult;
- }
-
- if (deleteAllFlag) {
- S3Utils.deleteDirectory(
- s3,
- bucket,
- determineSnapshotS3Directory(accountId,
- volumeId));
- } else {
- S3Utils.deleteObject(
- s3,
- bucket,
- determineSnapshotS3Key(
- accountId,
- volumeId,
- determineSnapshotBackupFilename(name)));
- }
-
- return null;
-
- }
-
- });
-
- return result;
-
- } catch (Exception e) {
-
- s_logger.error(
- String.format(
- "Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.",
- accountId, volumeId), e);
- return e.getMessage();
-
- }
-
- }
-
- private String determineSnapshotBackupFilename(final String snapshotUuid) {
- return snapshotUuid + ".vhd";
- }
-
- private String determineSnapshotLockId(final Long accountId,
- final Long volumeId) {
- return join("_", "SNAPSHOT", accountId, volumeId);
- }
-
- protected Answer execute(final DeleteSnapshotBackupCommand cmd) {
- String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
- Long accountId = cmd.getAccountId();
- Long volumeId = cmd.getVolumeId();
- String name = cmd.getSnapshotUuid();
- try {
- SwiftTO swift = cmd.getSwift();
- S3TO s3 = cmd.getS3();
- if (swift == null) {
- final String result = deleteSnapshotBackupFromLocalFileSystem(
- secondaryStorageUrl, accountId, volumeId, name,
- cmd.isAll());
- if (result != null) {
- s_logger.warn(result);
- return new Answer(cmd, false, result);
- }
- } else if (s3 != null) {
- final String result = deleteSnapshotBackupfromS3(s3,
- secondaryStorageUrl, accountId, volumeId, name,
- cmd.isAll());
- if (result != null) {
- s_logger.warn(result);
- return new Answer(cmd, false, result);
- }
- } else {
- String filename;
- if (cmd.isAll()) {
- filename = "";
- } else {
- filename = name;
- }
- String result = swiftDelete(swift, "V-" + volumeId.toString(), filename);
- if (result != null) {
- String errMsg = "failed to delete snapshot " + filename + " , 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);
- }
- }
-
- Map<String, TemplateInfo> swiftListTemplate(SwiftTO swift) {
- String[] containers = swiftList(swift, "", "");
- if (containers == null) {
- return null;
- }
- Map<String, TemplateInfo> tmpltInfos = new HashMap<String, TemplateInfo>();
- for( String container : containers) {
- if ( container.startsWith("T-")) {
- String ldir = _tmpltDir + "/" + UUID.randomUUID().toString();
- createLocalDir(ldir);
- String lFullPath = ldir + "/" + _tmpltpp;
- swiftDownload(swift, container, _tmpltpp, lFullPath);
- TemplateLocation loc = new TemplateLocation(_storage, ldir);
- try {
- if (!loc.load()) {
- s_logger.warn("Can not parse template.properties file for template " + container);
- continue;
- }
- } catch (IOException e) {
- s_logger.warn("Unable to load template location " + ldir + " due to " + e.toString(), e);
- continue;
- }
- TemplateInfo tInfo = loc.getTemplateInfo();
- tInfo.setInstallPath(container);
- tmpltInfos.put(tInfo.getTemplateName(), tInfo);
- loc.purge();
- deleteLocalDir(ldir);
- }
- }
- return tmpltInfos;
-
- }
-
- private Answer execute(ListTemplateCommand cmd) {
- if (!_inSystemVM){
- return new Answer(cmd, true, null);
- }
- if (cmd.getSwift() != null) {
- Map<String, TemplateInfo> templateInfos = swiftListTemplate(cmd.getSwift());
- return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos);
- } else {
- String root = getRootDir(cmd.getSecUrl());
- Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
- return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
- }
- }
-
- private Answer execute(ListVolumeCommand cmd) {
- if (!_inSystemVM){
- return new Answer(cmd, true, null);
- }
-
- String root = getRootDir(cmd.getSecUrl());
- Map<Long, TemplateInfo> templateInfos = _dlMgr.gatherVolumeInfo(root);
- return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
-
- }
-
- 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 setVhdParent(String lFullPath, String pFullPath) {
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("/bin/vhd-util modify -n " + lFullPath + " -p " + pFullPath);
- String result = command.execute();
- if (result != null) {
- String errMsg = "failed to set vhd parent, child " + lFullPath + " parent " + pFullPath + ", err=" + result;
- s_logger.warn(errMsg);
- return errMsg;
- }
- return null;
- }
-
- private String createLocalDir(String folder) {
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("mkdir -p " + folder);
- String result = command.execute();
- if (result != null) {
- String errMsg = "Create local path " + folder + " failed , err=" + result;
- s_logger.warn(errMsg);
- return errMsg;
- }
- return null;
- }
-
- private String deleteLocalDir(String folder) {
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("rmdir " + folder);
- String result = command.execute();
- if (result != null) {
- String errMsg = "Delete local path " + folder + " failed , err=" + result;
- s_logger.warn(errMsg);
- return errMsg;
- }
- return null;
- }
-
- 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) {
-
- 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) {
- String rootDir = getRootDir(cmd.getSecUrl());
- 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 DeleteTemplateCommand cmd) {
- String relativeTemplatePath = cmd.getTemplatePath();
- String parent = getRootDir(cmd);
-
- if (relativeTemplatePath.startsWith(File.separator)) {
- relativeTemplatePath = relativeTemplatePath.substring(1);
- }
-
- if (!parent.endsWith(File.separator)) {
- parent += File.separator;
- }
- String absoluteTemplatePath = parent + relativeTemplatePath;
- File tmpltParent = new File(absoluteTemplatePath).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;
- }
- 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);
- }
-
- protected Answer execute(final DeleteVolumeCommand cmd) {
- String relativeVolumePath = cmd.getVolumePath();
- String parent = getRootDir(cmd);
-
- if (relativeVolumePath.startsWith(File.separator)) {
- relativeVolumePath = relativeVolumePath.substring(1);
- }
-
- if (!parent.endsWith(File.separator)) {
- parent += File.separator;
- }
- String absoluteVolumePath = parent + relativeVolumePath;
- File 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;
- }
- if (!f.delete()) {
- return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path "
- + relativeVolumePath);
- }
- }
- 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 "
- + relativeVolumePath;
- s_logger.debug(details);
- return new Answer(cmd, false, details);
- }
- return new Answer(cmd, true, null);
- }
-
- Answer execute(CleanupSnapshotBackupCommand cmd) {
- String parent = getRootDir(cmd.getSecondaryStoragePoolURL());
- if (!parent.endsWith(File.separator)) {
- parent += File.separator;
- }
- String absoluteSnapsthotDir = parent + File.separator + "snapshots" + File.separator + cmd.getAccountId() + File.separator + cmd.getVolumeId();
- File ssParent = new File(absoluteSnapsthotDir);
- if (ssParent.exists() && ssParent.isDirectory()) {
- File[] files = ssParent.listFiles();
- for (File file : files) {
- boolean found = false;
- String filename = file.getName();
- for (String uuid : cmd.getValidBackupUUIDs()) {
- if (filename.startsWith(uuid)) {
- found = true;
- break;
- }
- }
- if (!found) {
- file.delete();
- String msg = "snapshot " + filename + " is not recorded in DB, remove it";
- s_logger.warn(msg);
- }
- }
- }
- return new Answer(cmd, true, null);
- }
-
-
- synchronized public String getRootDir(String secUrl) {
- try {
- URI uri = new URI(secUrl);
- String nfsHost = uri.getHost();
-
- InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
- String nfsHostIp = nfsHostAddr.getHostAddress();
- String nfsPath = nfsHostIp + ":" + uri.getPath();
- String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString();
- String root = _parent + "/" + dir;
- mount(root, nfsPath);
- return root;
- } catch (Exception e) {
- String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
- s_logger.error(msg, e);
- throw new CloudRuntimeException(msg);
- }
- }
-
-
- @Override
- public String getRootDir(ssCommand cmd){
- return getRootDir(cmd.getSecUrl());
-
- }
-
- 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("Wait, what's going on? eth1ip is null!!");
- }
- 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");
-
- _storageIp = (String) params.get("storageip");
- if (_storageIp == null) {
- s_logger.warn("Wait, 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);
- 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("StorageLayer", params);
- } catch (ClassNotFoundException e) {
- throw new ConfigurationException("Unable to find class " + value);
- } catch (InstantiationException e) {
- throw new ConfigurationException("Unable to find class " + value);
- } catch (IllegalAccessException e) {
- throw new ConfigurationException("Unable to find class " + value);
- }
- }
- _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);
- }
-
- _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");
-
-
- String inSystemVM = (String)params.get("secondary.storage.vm");
- if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
- _inSystemVM = true;
- _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;
- }
-
- private void startAdditionalServices() {
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("if [ -f /etc/init.d/ssh ]; then service ssh restart; else service sshd restart; fi ");
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Error in starting sshd service err=" + result );
- }
- command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("iptables -I INPUT -i eth1 -p tcp -m state --state NEW -m tcp --dport 3922 -j ACCEPT");
- result = command.execute();
- if (result != null) {
- s_logger.warn("Error in opening up ssh port err=" + result );
- }
- }
-
- private void addRouteToInternalIpOrCidr(String localgw, String eth1ip, String eth1mask, String destIpOrCidr) {
- s_logger.debug("addRouteToInternalIp: localgw=" + localgw + ", eth1ip=" + eth1ip + ", eth1mask=" + eth1mask + ",destIp=" + destIpOrCidr);
- if (destIpOrCidr == null) {
- s_logger.debug("addRouteToInternalIp: destIp is null");
- return;
- }
- if (!NetUtils.isValidIp(destIpOrCidr) && !NetUtils.isValidCIDR(destIpOrCidr)){
- s_logger.warn(" destIp is not a valid ip address or cidr destIp=" + destIpOrCidr);
- return;
- }
- boolean inSameSubnet = false;
- if (NetUtils.isValidIp(destIpOrCidr)) {
- if (eth1ip != null && eth1mask != null) {
- inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask);
- } else {
- s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + ", _eth1mask=" + eth1mask);
- }
- } else {
- inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask));
- }
- if (inSameSubnet) {
- s_logger.debug("addRouteToInternalIp: dest ip " + destIpOrCidr + " is in the same subnet as eth1 ip " + eth1ip);
- return;
- }
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("ip route delete " + destIpOrCidr);
- command.execute();
- command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("ip route add " + destIpOrCidr + " via " + localgw);
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Error in configuring route to internal ip err=" + result );
- } else {
- s_logger.debug("addRouteToInternalIp: added route to internal ip=" + destIpOrCidr + " via " + localgw);
- }
- }
-
- private void configureSSL() {
- Script command = new Script(_configSslScr);
- command.add("-i", _publicIp);
- command.add("-h", _hostname);
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Unable to configure httpd to use ssl");
- }
- }
-
- private void configureSSL(String prvkeyPath, String prvCertPath, String certChainPath) {
- Script command = new Script(_configSslScr);
- command.add("-i", _publicIp);
- command.add("-h", _hostname);
- command.add("-k", prvkeyPath);
- command.add("-p", prvCertPath);
- if (certChainPath != null) {
- command.add("-t", certChainPath);
- }
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Unable to configure httpd to use ssl");
- }
- }
-
- private String configureAuth(String user, String passwd) {
- Script command = new Script(_configAuthScr);
- command.add(user);
- command.add(passwd);
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Unable to configure httpd to use auth");
- }
- return result;
- }
-
- private String configureIpFirewall(List<String> ipList, boolean isAppend){
- Script command = new Script(_configIpFirewallScr);
- command.add(String.valueOf(isAppend));
- for (String ip : ipList){
- command.add(ip);
- }
-
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Unable to configure firewall for command : " +command);
- }
- return result;
- }
-
- protected String mount(String root, String nfsPath) {
- File file = new File(root);
- if (!file.exists()) {
- if (_storage.mkdir(root)) {
- s_logger.debug("create mount point: " + root);
- } else {
- s_logger.debug("Unable to create mount point: " + root);
- return null;
- }
- }
-
- Script script = null;
- String result = null;
- script = new Script(!_inSystemVM, "mount", _timeout, s_logger);
- List<String> res = new ArrayList<String>();
- ZfsPathParser parser = new ZfsPathParser(root);
- script.execute(parser);
- res.addAll(parser.getPaths());
- for( String s : res ) {
- if ( s.contains(root)) {
- return root;
- }
- }
-
- Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
- command.add("-t", "nfs");
- if (_inSystemVM) {
- //Fedora Core 12 errors out with any -o option executed from java
- command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0");
- }
- command.add(nfsPath);
- command.add(root);
- result = command.execute();
- if (result != null) {
- s_logger.warn("Unable to mount " + nfsPath + " due to " + result);
- file = new File(root);
- if (file.exists())
- file.delete();
- return null;
- }
-
- // XXX: Adding the check for creation of snapshots dir here. Might have to move it somewhere more logical later.
- if (!checkForSnapshotsDir(root)) {
- return null;
- }
-
- // Create the volumes dir
- if (!checkForVolumesDir(root)) {
- return null;
- }
-
- return root;
- }
-
- @Override
- public boolean start() {
- return true;
- }
-
- @Override
- public boolean stop() {
- return true;
- }
-
- @Override
- public StartupCommand[] initialize() {
-
- final StartupSecondaryStorageCommand cmd = new StartupSecondaryStorageCommand();
- fillNetworkInformation(cmd);
- if(_publicIp != null)
- cmd.setPublicIpAddress(_publicIp);
-
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("ln -sf " + _parent + " /var/www/html/copy");
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Error in linking err=" + result);
- return null;
- }
- return new StartupCommand[] {cmd};
- }
-
- protected boolean checkForSnapshotsDir(String mountPoint) {
- String snapshotsDirLocation = mountPoint + File.separator + "snapshots";
- return createDir("snapshots", snapshotsDirLocation, mountPoint);
- }
-
- protected boolean checkForVolumesDir(String mountPoint) {
- String volumesDirLocation = mountPoint + "/" + "volumes";
- return createDir("volumes", volumesDirLocation, mountPoint);
- }
-
- protected boolean createDir(String dirName, String dirLocation, String mountPoint) {
- boolean dirExists = false;
-
- File dir = new File(dirLocation);
- if (dir.exists()) {
- if (dir.isDirectory()) {
- s_logger.debug(dirName + " already exists on secondary storage, and is mounted at " + mountPoint);
- dirExists = true;
- } else {
- if (dir.delete() && _storage.mkdir(dirLocation)) {
- dirExists = true;
- }
- }
- } else if (_storage.mkdir(dirLocation)) {
- dirExists = true;
- }
-
- if (dirExists) {
- s_logger.info(dirName + " directory created/exists on Secondary Storage.");
- } else {
- s_logger.info(dirName + " directory does not exist on Secondary Storage.");
- }
-
- return dirExists;
- }
-
- @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
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/resource/SecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/SecondaryStorageResource.java b/core/src/com/cloud/storage/resource/SecondaryStorageResource.java
deleted file mode 100755
index 37c6686..0000000
--- a/core/src/com/cloud/storage/resource/SecondaryStorageResource.java
+++ /dev/null
@@ -1,28 +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.resource;
-import com.cloud.agent.api.storage.ssCommand;
-import com.cloud.resource.ServerResource;
-/**
- *
- * SecondaryStorageServerResource is a generic container to execute commands sent
- */
-public interface SecondaryStorageResource extends ServerResource {
-
- public String getRootDir(ssCommand cmd);
-
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/resource/SecondaryStorageResourceHandler.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/SecondaryStorageResourceHandler.java b/core/src/com/cloud/storage/resource/SecondaryStorageResourceHandler.java
deleted file mode 100644
index 28b96b6..0000000
--- a/core/src/com/cloud/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 com.cloud.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/e7983b25/core/src/com/cloud/storage/template/DownloadManager.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/DownloadManager.java b/core/src/com/cloud/storage/template/DownloadManager.java
deleted file mode 100644
index f4f8a0f..0000000
--- a/core/src/com/cloud/storage/template/DownloadManager.java
+++ /dev/null
@@ -1,103 +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.template;
-
-import java.util.List;
-import java.util.Map;
-
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.storage.DownloadCommand;
-import com.cloud.agent.api.storage.DownloadCommand.Proxy;
-import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.resource.SecondaryStorageResource;
-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 userName, String passwd, long maxDownloadSizeInBytes, 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, TemplateInfo> gatherTemplateInfo(String templateDir);
-
- /**
- /**
- * @return list of volume info for installed volumes
- */
- public Map<Long, TemplateInfo> gatherVolumeInfo(String volumeDir);
-
-
-}
\ No newline at end of file
[13/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: add a network offering without any services
This can be used to avoid starting up a virtual router simply for the purposes of offering dhcp and dns services
With the QuickCloudNoServices offering, no virtual router will be started up and the vm instance will not get a CloudStack-assigned IP address.
Instead, the VM will simply get whatever IP address is offered by an DHCP service that happens to be running in the same network
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/1d70b9ea
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/1d70b9ea
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/1d70b9ea
Branch: refs/heads/master
Commit: 1d70b9ea77fd1e9fce98f7d9cd5fd92cfe444c39
Parents: 21b4635
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Tue Mar 26 13:36:04 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700
----------------------------------------------------------------------
api/src/com/cloud/offering/NetworkOffering.java | 1 +
.../src/com/cloud/network/NetworkManagerImpl.java | 16 +++++++++++++-
2 files changed, 15 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d70b9ea/api/src/com/cloud/offering/NetworkOffering.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java
index 8cb8299..bd14acd 100644
--- a/api/src/com/cloud/offering/NetworkOffering.java
+++ b/api/src/com/cloud/offering/NetworkOffering.java
@@ -46,6 +46,7 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
public final static String SystemPrivateGatewayNetworkOffering = "System-Private-Gateway-Network-Offering";
public final static String DefaultSharedNetworkOfferingWithSGService = "DefaultSharedNetworkOfferingWithSGService";
+ public final static String QuickCloudNoServices = "QuickCloudNoServices";
public final static String DefaultIsolatedNetworkOfferingWithSourceNatService = "DefaultIsolatedNetworkOfferingWithSourceNatService";
public final static String OvsIsolatedNetworkOfferingWithSourceNatService = "OvsIsolatedNetworkOfferingWithSourceNatService";
public final static String DefaultSharedNetworkOffering = "DefaultSharedNetworkOffering";
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d70b9ea/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java
index 6296011..a97f2ce 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -968,9 +968,21 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
// diff between offering #1 and #2 - securityGroup is enabled for the first, and disabled for the third
NetworkOfferingVO offering = null;
+ if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) {
+ offering =
+ _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices,
+ "Offering for QuickCloud with no services", TrafficType.Guest, null, true,
+ Availability.Optional, null, new HashMap<Network.Service, Set<Network.Provider>>(), true,
+ Network.GuestType.Shared, false, null, true, null, true, false);
+ offering.setState(NetworkOffering.State.Enabled);
+ _networkOfferingDao.update(offering.getId(), offering);
+ }
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) {
- offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", TrafficType.Guest, null,
- true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false);
+ offering =
+ _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService,
+ "Offering for Shared Security group enabled networks", TrafficType.Guest, null, true,
+ Availability.Optional, null, defaultSharedNetworkOfferingProviders, true,
+ Network.GuestType.Shared, false, null, true, null, true, false);
offering.setState(NetworkOffering.State.Enabled);
_networkOfferingDao.update(offering.getId(), offering);
}
[12/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: copy authorization code from ConsoleProxyManagerImpl
QuickCloud: refactor to avoid copy paste of authentication and startup code
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/3d78019e
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/3d78019e
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/3d78019e
Branch: refs/heads/master
Commit: 3d78019e571677f1b2ac87acebe6192f2a4fa96c
Parents: 790d2ce
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Tue Mar 26 10:05:06 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700
----------------------------------------------------------------------
.../AgentBasedConsoleProxyManager.java | 184 +-------
.../src/com/cloud/consoleproxy/AgentHookBase.java | 266 +++++++++++
.../consoleproxy/ConsoleProxyManagerImpl.java | 362 ++++++---------
.../consoleproxy/StaticConsoleProxyManager.java | 84 +++-
4 files changed, 489 insertions(+), 407 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3d78019e/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
index 6f8575d..ff6e64e 100755
--- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
+++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
@@ -23,48 +23,28 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer;
-import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
-import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
import com.cloud.agent.api.GetVncPortAnswer;
import com.cloud.agent.api.GetVncPortCommand;
-import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupProxyCommand;
-import com.cloud.agent.api.StopAnswer;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.manager.Commands;
import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.HostVO;
-import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.info.ConsoleProxyInfo;
-import com.cloud.network.Network;
+import com.cloud.keystore.KeystoreManager;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ManagerBase;
import com.cloud.vm.ConsoleProxyVO;
-import com.cloud.vm.ReservationContext;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-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.ConsoleProxyDao;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
@Local(value = { ConsoleProxyManager.class })
-public class AgentBasedConsoleProxyManager extends ManagerBase implements ConsoleProxyManager, VirtualMachineGuru<ConsoleProxyVO>, AgentHook {
+public class AgentBasedConsoleProxyManager extends ManagerBase implements ConsoleProxyManager {
private static final Logger s_logger = Logger.getLogger(AgentBasedConsoleProxyManager.class);
@Inject
@@ -85,9 +65,25 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
VirtualMachineManager _itMgr;
@Inject
protected ConsoleProxyDao _cpDao;
+ @Inject
+ protected KeystoreManager _ksMgr;
@Inject ConfigurationDao _configDao;
+ public class AgentBasedAgentHook extends AgentHookBase {
+
+ public AgentBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao,
+ KeystoreManager ksMgr, AgentManager agentMgr) {
+ super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr);
+ }
+
+ @Override
+ protected HostVO findConsoleProxyHost(StartupProxyCommand cmd) {
+ return _hostDao.findByGuid(cmd.getGuid());
+ }
+
+ }
+
public int getVncPort(VMInstanceVO vm) {
if (vm.getHostId() == null) {
return -1;
@@ -123,11 +119,10 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
_consoleProxyUrlDomain = configs.get("consoleproxy.url.domain");
- _listener = new ConsoleProxyListener(this);
+ _listener =
+ new ConsoleProxyListener(new AgentBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr));
_agentMgr.registerForHostEvents(_listener, true, true, false);
- _itMgr.registerGuru(VirtualMachine.Type.ConsoleProxy, this);
-
if (s_logger.isInfoEnabled()) {
s_logger.info("AgentBasedConsoleProxyManager has been configured. SSL enabled: " + _sslEnabled);
}
@@ -177,64 +172,8 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
return null;
}
- @Override
- public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
- }
-
- @Override
- public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd) {
- long vmId = 0;
-
- if (cmd.getVmId() != null && cmd.getVmId().isEmpty()) {
- if (s_logger.isTraceEnabled()) {
- s_logger.trace("Invalid vm id sent from proxy(happens when proxy session has terminated)");
- }
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
-
- try {
- vmId = Long.parseLong(cmd.getVmId());
- } catch (NumberFormatException e) {
- s_logger.error("Invalid vm id " + cmd.getVmId() + " sent from console access authentication", e);
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
-
- // TODO authentication channel between console proxy VM and management
- // server needs to be secured,
- // the data is now being sent through private network, but this is
- // apparently not enough
- VMInstanceVO vm = _instanceDao.findById(vmId);
- if (vm == null) {
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
-
- if (vm.getHostId() == null) {
- s_logger.warn("VM " + vmId + " lost host info, failed authentication request");
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
-
- HostVO host = _hostDao.findById(vm.getHostId());
- if (host == null) {
- s_logger.warn("VM " + vmId + "'s host does not exist, fail authentication request");
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
- String sid = cmd.getSid();
- if (sid == null || !sid.equals(vm.getVncPassword())) {
- s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
- return new ConsoleAccessAuthenticationAnswer(cmd, true);
- }
-
- @Override
- public void onAgentConnect(HostVO host, StartupCommand cmd) {
- }
-
- @Override
- public void onAgentDisconnect(long agentId, Status state) {
- }
@Override
public ConsoleProxyVO startProxy(long proxyVmId) {
@@ -270,90 +209,7 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
}
@Override
- public void startAgentHttpHandlerInVM(StartupProxyCommand startupCmd) {
- }
-
- @Override
public String getName() {
return _name;
}
-
- @Override
- public Long convertToId(String vmName) {
- if (!VirtualMachineName.isValidConsoleProxyName(vmName, _instance)) {
- return null;
- }
- return VirtualMachineName.getConsoleProxyId(vmName);
- }
-
- @Override
- public ConsoleProxyVO findByName(String name) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public ConsoleProxyVO findById(long id) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public ConsoleProxyVO persist(ConsoleProxyVO vm) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public boolean finalizeVirtualMachineProfile(VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean finalizeStart(VirtualMachineProfile<ConsoleProxyVO> profile, long hostId, Commands cmds, ReservationContext context) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public void finalizeStop(VirtualMachineProfile<ConsoleProxyVO> profile, StopAnswer answer) {
- // TODO Auto-generated method stub
- }
-
- @Override
- public void finalizeExpunge(ConsoleProxyVO proxy) {
- }
-
- @Override
- public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm,
- ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException,
- InsufficientCapacityException {
- //not supported
- throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType());
- }
-
-
- @Override
- public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm,
- ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException {
- //not supported
- throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType());
- }
-
- @Override
- public void prepareStop(VirtualMachineProfile<ConsoleProxyVO> profile) {
- }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3d78019e/server/src/com/cloud/consoleproxy/AgentHookBase.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/AgentHookBase.java b/server/src/com/cloud/consoleproxy/AgentHookBase.java
new file mode 100644
index 0000000..b969f6d
--- /dev/null
+++ b/server/src/com/cloud/consoleproxy/AgentHookBase.java
@@ -0,0 +1,266 @@
+// 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.consoleproxy;
+
+import java.util.Date;
+import java.util.Random;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer;
+import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
+import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
+import com.cloud.agent.api.GetVncPortAnswer;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupProxyCommand;
+import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.keystore.KeystoreManager;
+import com.cloud.servlet.ConsoleProxyServlet;
+import com.cloud.utils.Ternary;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.VMInstanceDao;
+
+/**
+ * Utility class to manage interactions with agent-based console access
+ * Extracted from ConsoleProxyManagerImpl so that other console proxy managers
+ * can reuse
+ */
+public abstract class AgentHookBase implements AgentHook {
+ private static final Logger s_logger = Logger.getLogger(AgentHookBase.class);
+
+ VMInstanceDao _instanceDao;
+ HostDao _hostDao;
+ ConfigurationDao _configDao;
+ AgentManager _agentMgr;
+ KeystoreManager _ksMgr;
+ final Random _random = new Random(System.currentTimeMillis());
+ private String _hashKey;
+
+
+ public AgentHookBase(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr,
+ AgentManager agentMgr) {
+ this._instanceDao = instanceDao;
+ this._hostDao = hostDao;
+ this._agentMgr = agentMgr;
+ this._configDao = cfgDao;
+ this._ksMgr = ksMgr;
+ }
+
+ public String getHashKey() {
+ // although we may have race condition here, database transaction
+ // serialization should give us the same key
+ if (_hashKey == null) {
+ _hashKey =
+ _configDao.getValueAndInitIfNotExist(Config.HashKey.key(), Config.HashKey.getCategory(), UUID
+ .randomUUID().toString());
+ }
+ return _hashKey;
+ }
+
+ public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd) {
+ Long vmId = null;
+
+ String ticketInUrl = cmd.getTicket();
+ if (ticketInUrl == null) {
+ s_logger.error("Access ticket could not be found, you could be running an old version of console proxy. vmId: "
+ + cmd.getVmId());
+ return new ConsoleAccessAuthenticationAnswer(cmd, false);
+ }
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Console authentication. Ticket in url for " + cmd.getHost() + ":" + cmd.getPort() + "-"
+ + cmd.getVmId() + " is " + ticketInUrl);
+ }
+
+ if (!cmd.isReauthenticating()) {
+ String ticket =
+ ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId());
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Console authentication. Ticket in 1 minute boundary for " + cmd.getHost() + ":"
+ + cmd.getPort() + "-" + cmd.getVmId() + " is " + ticket);
+ }
+
+ if (!ticket.equals(ticketInUrl)) {
+ Date now = new Date();
+ // considering of minute round-up
+ String minuteEarlyTicket =
+ ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId(),
+ new Date(now.getTime() - 60 * 1000));
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Console authentication. Ticket in 2-minute boundary for " + cmd.getHost() + ":"
+ + cmd.getPort() + "-" + cmd.getVmId() + " is " + minuteEarlyTicket);
+ }
+
+ if (!minuteEarlyTicket.equals(ticketInUrl)) {
+ s_logger.error("Access ticket expired or has been modified. vmId: " + cmd.getVmId()
+ + "ticket in URL: " + ticketInUrl + ", tickets to check against: " + ticket + ","
+ + minuteEarlyTicket);
+ return new ConsoleAccessAuthenticationAnswer(cmd, false);
+ }
+ }
+ }
+
+ if (cmd.getVmId() != null && cmd.getVmId().isEmpty()) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Invalid vm id sent from proxy(happens when proxy session has terminated)");
+ }
+ return new ConsoleAccessAuthenticationAnswer(cmd, false);
+ }
+
+ VirtualMachine vm = _instanceDao.findByUuid(cmd.getVmId());
+ if (vm == null) {
+ vm = _instanceDao.findById(Long.parseLong(cmd.getVmId()));
+ }
+ if (vm == null) {
+ s_logger.error("Invalid vm id " + cmd.getVmId() + " sent from console access authentication");
+ return new ConsoleAccessAuthenticationAnswer(cmd, false);
+ }
+
+ if (vm.getHostId() == null) {
+ s_logger.warn("VM " + vmId + " lost host info, failed authentication request");
+ return new ConsoleAccessAuthenticationAnswer(cmd, false);
+ }
+
+ HostVO host = _hostDao.findById(vm.getHostId());
+ if (host == null) {
+ s_logger.warn("VM " + vmId + "'s host does not exist, fail authentication request");
+ return new ConsoleAccessAuthenticationAnswer(cmd, false);
+ }
+
+ String sid = cmd.getSid();
+ if (sid == null || !sid.equals(vm.getVncPassword())) {
+ s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
+ return new ConsoleAccessAuthenticationAnswer(cmd, false);
+ }
+
+ if (cmd.isReauthenticating()) {
+ ConsoleAccessAuthenticationAnswer authenticationAnswer = new ConsoleAccessAuthenticationAnswer(cmd, true);
+ authenticationAnswer.setReauthenticating(true);
+
+ s_logger.info("Re-authentication request, ask host " + vm.getHostId() + " for new console info");
+ GetVncPortAnswer answer =
+ (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(),
+ new GetVncPortCommand(vm.getId(), vm.getInstanceName()));
+
+ if (answer != null && answer.getResult()) {
+ Ternary<String, String, String> parsedHostInfo = ConsoleProxyServlet.parseHostInfo(answer.getAddress());
+
+ if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) {
+
+ s_logger.info("Re-authentication result. vm: " + vm.getId() + ", tunnel url: "
+ + parsedHostInfo.second() + ", tunnel session: " + parsedHostInfo.third());
+
+ authenticationAnswer.setTunnelUrl(parsedHostInfo.second());
+ authenticationAnswer.setTunnelSession(parsedHostInfo.third());
+ } else {
+ s_logger.info("Re-authentication result. vm: " + vm.getId() + ", host address: "
+ + parsedHostInfo.first() + ", port: " + answer.getPort());
+
+ authenticationAnswer.setHost(parsedHostInfo.first());
+ authenticationAnswer.setPort(answer.getPort());
+ }
+ } else {
+ s_logger.warn("Re-authentication request failed");
+
+ authenticationAnswer.setSuccess(false);
+ }
+
+ return authenticationAnswer;
+ }
+
+ return new ConsoleAccessAuthenticationAnswer(cmd, true);
+ }
+
+ public void startAgentHttpHandlerInVM(StartupProxyCommand startupCmd) {
+ StartConsoleProxyAgentHttpHandlerCommand cmd = null;
+ if (_configDao.isPremium()) {
+ String storePassword = String.valueOf(_random.nextLong());
+ byte[] ksBits =
+ _ksMgr.getKeystoreBits(ConsoleProxyManager.CERTIFICATE_NAME, ConsoleProxyManager.CERTIFICATE_NAME,
+ storePassword);
+
+ assert (ksBits != null);
+ if (ksBits == null) {
+ s_logger.error("Could not find and construct a valid SSL certificate");
+ }
+ cmd = new StartConsoleProxyAgentHttpHandlerCommand(ksBits, storePassword);
+ cmd.setEncryptorPassword(getHashKey());
+ } else {
+ cmd = new StartConsoleProxyAgentHttpHandlerCommand();
+ cmd.setEncryptorPassword(getHashKey());
+ }
+
+ try {
+
+ HostVO consoleProxyHost = findConsoleProxyHost(startupCmd);
+
+ assert (consoleProxyHost != null);
+
+ Answer answer = _agentMgr.send(consoleProxyHost.getId(), cmd);
+ if (answer == null || !answer.getResult()) {
+ s_logger.error("Console proxy agent reported that it failed to execute http handling startup command");
+ } else {
+ s_logger.info("Successfully sent out command to start HTTP handling in console proxy agent");
+ }
+ } catch (AgentUnavailableException e) {
+ s_logger.error("Unable to send http handling startup command to the console proxy resource for proxy:"
+ + startupCmd.getProxyVmId(), e);
+ } catch (OperationTimedoutException e) {
+ s_logger.error(
+ "Unable to send http handling startup command(time out) to the console proxy resource for proxy:"
+ + startupCmd.getProxyVmId(), e);
+ } catch (OutOfMemoryError e) {
+ s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched");
+ System.exit(1);
+ } catch (Exception e) {
+ s_logger.error(
+ "Unexpected exception when sending http handling startup command(time out) to the console proxy resource for proxy:"
+ + startupCmd.getProxyVmId(), e);
+ }
+ }
+
+ protected abstract HostVO findConsoleProxyHost(StartupProxyCommand cmd);
+
+ @Override
+ public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
+ // no-op since we do not auto-scale
+ }
+
+ @Override
+ public void onAgentConnect(HostVO host, StartupCommand cmd) {
+ // no-op
+ }
+
+ @Override
+ public void onAgentDisconnect(long agentId, Status state) {
+ // no-op since we do not autoscale
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3d78019e/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index fc4fc6e..9740d28 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -23,7 +23,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Random;
import java.util.UUID;
import javax.ejb.Local;
@@ -35,13 +34,8 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer;
-import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
-import com.cloud.agent.api.GetVncPortAnswer;
-import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupProxyCommand;
@@ -49,7 +43,6 @@ import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.check.CheckSshAnswer;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
-import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.manager.Commands;
@@ -66,10 +59,8 @@ import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.deploy.DataCenterDeployment;
import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.host.Host;
@@ -106,7 +97,6 @@ import com.cloud.resource.ServerResource;
import com.cloud.resource.UnableDeleteHostException;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.servlet.ConsoleProxyServlet;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.VMTemplateHostVO;
@@ -123,7 +113,6 @@ import com.cloud.user.UserContext;
import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GlobalLock;
@@ -167,7 +156,7 @@ import com.google.gson.GsonBuilder;
//
@Local(value = { ConsoleProxyManager.class, ConsoleProxyService.class })
public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxyManager,
- AgentHook, VirtualMachineGuru<ConsoleProxyVO>, SystemVmLoadScanHandler<Long>, ResourceStateAdapter {
+ VirtualMachineGuru<ConsoleProxyVO>, SystemVmLoadScanHandler<Long>, ResourceStateAdapter {
private static final Logger s_logger = Logger.getLogger(ConsoleProxyManagerImpl.class);
private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30 seconds
@@ -455,7 +444,131 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
private KeystoreDao _ksDao;
@Inject
private KeystoreManager _ksMgr;
- private final Random _random = new Random(System.currentTimeMillis());
+
+ public class VmBasedAgentHook extends AgentHookBase {
+
+ public VmBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao,
+ KeystoreManager ksMgr, AgentManager agentMgr) {
+ super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr);
+ }
+
+ @Override
+ public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
+ if (cmd.getLoadInfo() == null) {
+ return;
+ }
+
+ ConsoleProxyStatus status = null;
+ try {
+ GsonBuilder gb = new GsonBuilder();
+ gb.setVersion(1.3);
+ Gson gson = gb.create();
+ status = gson.fromJson(cmd.getLoadInfo(), ConsoleProxyStatus.class);
+ } catch (Throwable e) {
+ s_logger.warn("Unable to parse load info from proxy, proxy vm id : " + cmd.getProxyVmId() + ", info : " + cmd.getLoadInfo());
+ }
+
+ if (status != null) {
+ int count = 0;
+ if (status.getConnections() != null) {
+ count = status.getConnections().length;
+ }
+
+ byte[] details = null;
+ if (cmd.getLoadInfo() != null) {
+ details = cmd.getLoadInfo().getBytes(Charset.forName("US-ASCII"));
+ }
+ _consoleProxyDao.update(cmd.getProxyVmId(), count, DateUtil.currentGMTTime(), details);
+ } else {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("Unable to get console proxy load info, id : " + cmd.getProxyVmId());
+ }
+
+ _consoleProxyDao.update(cmd.getProxyVmId(), 0, DateUtil.currentGMTTime(), null);
+ }
+ }
+
+ @Override
+ public void onAgentConnect(HostVO host, StartupCommand cmd) {
+ // no-op
+ }
+
+ @Override
+ public void onAgentDisconnect(long agentId, com.cloud.host.Status state) {
+
+ if (state == com.cloud.host.Status.Alert || state == com.cloud.host.Status.Disconnected) {
+ // be it either in alert or in disconnected state, the agent
+ // process
+ // may be gone in the VM,
+ // we will be reacting to stop the corresponding VM and let the
+ // scan
+ // process to
+ HostVO host = _hostDao.findById(agentId);
+ if (host.getType() == Type.ConsoleProxy) {
+ String name = host.getName();
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Console proxy agent disconnected, proxy: " + name);
+ }
+ if (name != null && name.startsWith("v-")) {
+ String[] tokens = name.split("-");
+ long proxyVmId = 0;
+ try {
+ proxyVmId = Long.parseLong(tokens[1]);
+ } catch (NumberFormatException e) {
+ s_logger.error("Unexpected exception " + e.getMessage(), e);
+ return;
+ }
+
+ final ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
+ if (proxy != null) {
+
+ // Disable this feature for now, as it conflicts
+ // with
+ // the case of allowing user to reboot console proxy
+ // when rebooting happens, we will receive
+ // disconnect
+ // here and we can't enter into stopping process,
+ // as when the rebooted one comes up, it will kick
+ // off a
+ // newly started one and trigger the process
+ // continue on forever
+
+ /*
+ * _capacityScanScheduler.execute(new Runnable() {
+ * public void run() { if(s_logger.isInfoEnabled())
+ * s_logger.info("Stop console proxy " +
+ * proxy.getName() +
+ * " VM because of that the agent running inside it has disconnected"
+ * ); stopProxy(proxy.getId()); } });
+ */
+ } else {
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Console proxy agent disconnected but corresponding console proxy VM no longer exists in DB, proxy: "
+ + name);
+ }
+ }
+ } else {
+ assert (false) : "Invalid console proxy name: " + name;
+ }
+ }
+ }
+
+ }
+
+ @Override
+ protected HostVO findConsoleProxyHost(StartupProxyCommand startupCmd) {
+ long proxyVmId = startupCmd.getProxyVmId();
+ ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(proxyVmId);
+ if (consoleProxy == null) {
+ s_logger.info("Proxy " + proxyVmId + " is no longer in DB, skip sending startup command");
+ return null;
+ }
+
+ assert (consoleProxy != null);
+ return findConsoleProxyHostByName(consoleProxy.getHostName());
+ }
+
+ }
@Override
public ConsoleProxyInfo assignProxy(final long dataCenterId, final long vmId) {
@@ -847,181 +960,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
}
}
- @Override
- public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
- if (cmd.getLoadInfo() == null) {
- return;
- }
-
- ConsoleProxyStatus status = null;
- try {
- GsonBuilder gb = new GsonBuilder();
- gb.setVersion(1.3);
- Gson gson = gb.create();
- status = gson.fromJson(cmd.getLoadInfo(), ConsoleProxyStatus.class);
- } catch (Throwable e) {
- s_logger.warn("Unable to parse load info from proxy, proxy vm id : " + cmd.getProxyVmId() + ", info : " + cmd.getLoadInfo());
- }
-
- if (status != null) {
- int count = 0;
- if (status.getConnections() != null) {
- count = status.getConnections().length;
- }
-
- byte[] details = null;
- if (cmd.getLoadInfo() != null) {
- details = cmd.getLoadInfo().getBytes(Charset.forName("US-ASCII"));
- }
- _consoleProxyDao.update(cmd.getProxyVmId(), count, DateUtil.currentGMTTime(), details);
- } else {
- if (s_logger.isTraceEnabled()) {
- s_logger.trace("Unable to get console proxy load info, id : " + cmd.getProxyVmId());
- }
- _consoleProxyDao.update(cmd.getProxyVmId(), 0, DateUtil.currentGMTTime(), null);
- }
- }
- @Override
- public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd) {
- Long vmId = null;
-
- String ticketInUrl = cmd.getTicket();
- if (ticketInUrl == null) {
- s_logger.error("Access ticket could not be found, you could be running an old version of console proxy. vmId: " + cmd.getVmId());
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Console authentication. Ticket in url for " + cmd.getHost() + ":" + cmd.getPort() + "-" + cmd.getVmId() + " is " + ticketInUrl);
- }
-
- if(!cmd.isReauthenticating()) {
- String ticket = ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId());
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Console authentication. Ticket in 1 minute boundary for " + cmd.getHost() + ":" + cmd.getPort() + "-" + cmd.getVmId() + " is " + ticket);
- }
-
- if (!ticket.equals(ticketInUrl)) {
- Date now = new Date();
- // considering of minute round-up
- String minuteEarlyTicket = ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId(), new Date(now.getTime() - 60 * 1000));
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Console authentication. Ticket in 2-minute boundary for " + cmd.getHost() + ":" + cmd.getPort() + "-" + cmd.getVmId() + " is " + minuteEarlyTicket);
- }
-
- if (!minuteEarlyTicket.equals(ticketInUrl)) {
- s_logger.error("Access ticket expired or has been modified. vmId: " + cmd.getVmId() + "ticket in URL: " + ticketInUrl + ", tickets to check against: " + ticket + ","
- + minuteEarlyTicket);
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
- }
- }
-
- if (cmd.getVmId() != null && cmd.getVmId().isEmpty()) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Invalid vm id sent from proxy(happens when proxy session has terminated)");
- }
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
-
- VirtualMachine vm = _instanceDao.findByUuid(cmd.getVmId());
- if (vm == null) {
- vm = _instanceDao.findById(Long.parseLong(cmd.getVmId()));
- }
- if (vm == null) {
- s_logger.error("Invalid vm id " + cmd.getVmId() + " sent from console access authentication");
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
-
- if (vm.getHostId() == null) {
- s_logger.warn("VM " + vmId + " lost host info, failed authentication request");
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
-
- HostVO host = _hostDao.findById(vm.getHostId());
- if (host == null) {
- s_logger.warn("VM " + vmId + "'s host does not exist, fail authentication request");
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
-
- String sid = cmd.getSid();
- if (sid == null || !sid.equals(vm.getVncPassword())) {
- s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
- return new ConsoleAccessAuthenticationAnswer(cmd, false);
- }
-
- if(cmd.isReauthenticating()) {
- ConsoleAccessAuthenticationAnswer authenticationAnswer = new ConsoleAccessAuthenticationAnswer(cmd, true);
- authenticationAnswer.setReauthenticating(true);
-
- s_logger.info("Re-authentication request, ask host " + vm.getHostId() + " for new console info");
- GetVncPortAnswer answer = (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(), new
- GetVncPortCommand(vm.getId(), vm.getInstanceName()));
-
- if (answer != null && answer.getResult()) {
- Ternary<String, String, String> parsedHostInfo = ConsoleProxyServlet.parseHostInfo(answer.getAddress());
-
- if(parsedHostInfo.second() != null && parsedHostInfo.third() != null) {
-
- s_logger.info("Re-authentication result. vm: " + vm.getId() + ", tunnel url: " + parsedHostInfo.second()
- + ", tunnel session: " + parsedHostInfo.third());
-
- authenticationAnswer.setTunnelUrl(parsedHostInfo.second());
- authenticationAnswer.setTunnelSession(parsedHostInfo.third());
- } else {
- s_logger.info("Re-authentication result. vm: " + vm.getId() + ", host address: " + parsedHostInfo.first()
- + ", port: " + answer.getPort());
-
- authenticationAnswer.setHost(parsedHostInfo.first());
- authenticationAnswer.setPort(answer.getPort());
- }
- } else {
- s_logger.warn("Re-authentication request failed");
-
- authenticationAnswer.setSuccess(false);
- }
-
- return authenticationAnswer;
- }
-
- return new ConsoleAccessAuthenticationAnswer(cmd, true);
- }
-
- @Override
- public void onAgentConnect(HostVO host, StartupCommand cmd) {
- // if (host.getType() == Type.ConsoleProxy) {
- // // TODO we can use this event to mark the proxy is up and
- // // functioning instead of
- // // pinging the console proxy VM command port
- // //
- // // for now, just log a message
- // if (s_logger.isInfoEnabled()) {
- // s_logger.info("Console proxy agent is connected. proxy: " + host.getName());
- // }
- //
- // /* update public/private ip address */
- // if (_IpAllocator != null && _IpAllocator.exteralIpAddressAllocatorEnabled()) {
- // try {
- // ConsoleProxyVO console = findConsoleProxyByHost(host);
- // if (console == null) {
- // s_logger.debug("Can't find console proxy ");
- // return;
- // }
- // console.setPrivateIpAddress(cmd.getPrivateIpAddress());
- // console.setPublicIpAddress(cmd.getPublicIpAddress());
- // console.setPublicNetmask(cmd.getPublicNetmask());
- // _consoleProxyDao.persist(console);
- // } catch (NumberFormatException e) {
- // }
- // }
- // }
- }
-
- @Override
- public void onAgentDisconnect(long agentId, com.cloud.host.Status state) {
+ public void handleAgentDisconnect(long agentId, com.cloud.host.Status state) {
if (state == com.cloud.host.Status.Alert || state == com.cloud.host.Status.Disconnected) {
// be it either in alert or in disconnected state, the agent process
// may be gone in the VM,
@@ -1496,7 +1437,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
value = agentMgrConfigs.get("port");
_mgmt_port = NumbersUtil.parseInt(value, 8250);
- _listener = new ConsoleProxyListener(this);
+ _listener =
+ new ConsoleProxyListener(new VmBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr,
+ _agentMgr));
_agentMgr.registerForHostEvents(_listener, true, true, false);
_itMgr.registerGuru(VirtualMachine.Type.ConsoleProxy, this);
@@ -1719,52 +1662,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
_consoleProxyDao.update(proxy.getId(), proxy);
}
- @Override
- public void startAgentHttpHandlerInVM(StartupProxyCommand startupCmd) {
- StartConsoleProxyAgentHttpHandlerCommand cmd = null;
- if (_configDao.isPremium()) {
- String storePassword = String.valueOf(_random.nextLong());
- byte[] ksBits = _ksMgr.getKeystoreBits(ConsoleProxyManager.CERTIFICATE_NAME, ConsoleProxyManager.CERTIFICATE_NAME, storePassword);
-
- assert (ksBits != null);
- if (ksBits == null) {
- s_logger.error("Could not find and construct a valid SSL certificate");
- }
- cmd = new StartConsoleProxyAgentHttpHandlerCommand(ksBits, storePassword);
- cmd.setEncryptorPassword(getHashKey());
- } else {
- cmd = new StartConsoleProxyAgentHttpHandlerCommand();
- cmd.setEncryptorPassword(getHashKey());
- }
-
- try {
- long proxyVmId = startupCmd.getProxyVmId();
- ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(proxyVmId);
- if (consoleProxy == null) {
- s_logger.info("Proxy " + proxyVmId + " is no longer in DB, skip sending startup command");
- return;
- }
-
- assert (consoleProxy != null);
- HostVO consoleProxyHost = findConsoleProxyHostByName(consoleProxy.getHostName());
- Answer answer = _agentMgr.send(consoleProxyHost.getId(), cmd);
- if (answer == null || !answer.getResult()) {
- s_logger.error("Console proxy agent reported that it failed to execute http handling startup command");
- } else {
- s_logger.info("Successfully sent out command to start HTTP handling in console proxy agent");
- }
- } catch (AgentUnavailableException e) {
- s_logger.error("Unable to send http handling startup command to the console proxy resource for proxy:" + startupCmd.getProxyVmId(), e);
- } catch (OperationTimedoutException e) {
- s_logger.error("Unable to send http handling startup command(time out) to the console proxy resource for proxy:" + startupCmd.getProxyVmId(), e);
- } catch (OutOfMemoryError e) {
- s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched");
- System.exit(1);
- } catch (Exception e) {
- s_logger.error("Unexpected exception when sending http handling startup command(time out) to the console proxy resource for proxy:" + startupCmd.getProxyVmId(), e);
- }
- }
@Override
public ConsoleProxyVO persist(ConsoleProxyVO proxy) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3d78019e/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 3ba98a9..7b59a6b 100755
--- a/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
+++ b/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
@@ -16,29 +16,59 @@
// under the License.
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.springframework.stereotype.Component;
+import org.apache.log4j.Logger;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupProxyCommand;
import com.cloud.configuration.dao.ConfigurationDao;
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.keystore.KeystoreDao;
+import com.cloud.keystore.KeystoreManager;
import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+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 {
- String _ip = null;
- @Inject ConsoleProxyDao _proxyDao;
- @Inject ResourceManager _resourceMgr;
- @Inject ConfigurationDao _configDao;
+public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager implements ConsoleProxyManager,
+ ResourceStateAdapter {
+ private static final Logger s_logger = Logger.getLogger(StaticConsoleProxyManager.class);
+
+ @Inject
+ ConsoleProxyDao _proxyDao;
+ @Inject
+ 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;
+
+
@Override
protected HostVO findHost(VMInstanceVO vm) {
@@ -50,20 +80,52 @@ public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager imp
@Override
public ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId) {
- return new ConsoleProxyInfo(false, _ip, _consoleProxyPort, _consoleProxyUrlPort, _consoleProxyUrlDomain);
+ return new ConsoleProxyInfo(_sslEnabled, _ip, _consoleProxyPort, _consoleProxyUrlPort, _consoleProxyUrlDomain);
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
super.configure(name, params);
-
- Map<String, String> dbParams = _configDao.getConfiguration("ManagementServer", params);
-
- _ip = dbParams.get("public.ip");
+ _ip = _configDao.getValue("consoleproxy.static.publicIp");
if (_ip == null) {
_ip = "127.0.0.1";
}
+
+ String value = (String) params.get("consoleproxy.sslEnabled");
+ if (value != null && value.equalsIgnoreCase("true")) {
+ _sslEnabled = true;
+ }
+ int defaultPort = 8088;
+ if (_sslEnabled)
+ defaultPort = 8443;
+ _consoleProxyUrlPort = NumbersUtil.parseInt(_configDao.getValue("consoleproxy.static.port"), defaultPort);
+
+ _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+
return true;
}
+
+ @Override
+ public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
+ if (!(cmd[0] instanceof StartupProxyCommand)) {
+ return null;
+ }
+
+ host.setType(com.cloud.host.Host.Type.ConsoleProxy);
+ return host;
+ }
+
+ @Override
+ public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource,
+ Map<String, String> details, List<String> hostTags) {
+ return null;
+ }
+
+ @Override
+ public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage)
+ throws UnableDeleteHostException {
+ return null;
+ }
+
}
[07/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: Enable secondary storage daemon to run outside the system vm
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/e7983b25
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e7983b25
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e7983b25
Branch: refs/heads/master
Commit: e7983b25cccc69abe0304a0b8d720c4c85c4561a
Parents: 4fd3fca
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Sun Mar 24 23:50:02 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:25 2013 -0700
----------------------------------------------------------------------
agent/src/com/cloud/agent/AgentShell.java | 3 +-
.../resource/CifsSecondaryStorageResource.java | 755 ------
.../resource/LocalSecondaryStorageResource.java | 246 --
.../resource/NfsSecondaryStorageResource.java | 1842 --------------
.../storage/resource/SecondaryStorageResource.java | 28 -
.../resource/SecondaryStorageResourceHandler.java | 24 -
.../cloud/storage/template/DownloadManager.java | 103 -
.../storage/template/DownloadManagerImpl.java | 1049 --------
.../com/cloud/storage/template/UploadManager.java | 85 -
.../cloud/storage/template/UploadManagerImpl.java | 645 -----
.../com/cloud/resource/AgentStorageResource.java | 2 +-
.../resource/PremiumSecondaryStorageResource.java | 2 +
.../VmwareSecondaryStorageResourceHandler.java | 1 +
scripts/vm/systemvm/injectkeys.sh | 26 +-
server/pom.xml | 5 +
.../secondary/SecondaryStorageDiscoverer.java | 4 +-
services/pom.xml | 1 +
services/secondary-storage/conf/agent.properties | 11 +
.../secondary-storage/conf/environment.properties | 2 +
services/secondary-storage/conf/log4j-cloud.xml | 102 +
services/secondary-storage/pom.xml | 113 +
services/secondary-storage/scripts/_run.sh | 63 +
services/secondary-storage/scripts/config_auth.sh | 69 +
services/secondary-storage/scripts/config_ssl.sh | 174 ++
services/secondary-storage/scripts/ipfirewall.sh | 50 +
services/secondary-storage/scripts/run-proxy.sh | 48 +
services/secondary-storage/scripts/run.bat | 18 +
services/secondary-storage/scripts/run.sh | 45 +
services/secondary-storage/scripts/ssvm-check.sh | 136 ++
.../resource/CifsSecondaryStorageResource.java | 755 ++++++
.../resource/LocalSecondaryStorageResource.java | 246 ++
.../resource/NfsSecondaryStorageResource.java | 1882 +++++++++++++++
.../storage/resource/SecondaryStorageResource.java | 28 +
.../resource/SecondaryStorageResourceHandler.java | 24 +
.../storage/template/DownloadManager.java | 105 +
.../storage/template/DownloadManagerImpl.java | 1074 ++++++++
.../cloudstack/storage/template/UploadManager.java | 87 +
.../storage/template/UploadManagerImpl.java | 648 +++++
tools/devcloud/pom.xml | 33 +
tools/devcloud/quickcloud.cfg | 120 +
tools/marvin/marvin/cloudstackConnection.py | 6 +-
tools/marvin/marvin/deployDataCenter.py | 16 +-
42 files changed, 5880 insertions(+), 4796 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/agent/src/com/cloud/agent/AgentShell.java
----------------------------------------------------------------------
diff --git a/agent/src/com/cloud/agent/AgentShell.java b/agent/src/com/cloud/agent/AgentShell.java
index 2af08e9..73b3950 100644
--- a/agent/src/com/cloud/agent/AgentShell.java
+++ b/agent/src/com/cloud/agent/AgentShell.java
@@ -38,12 +38,10 @@ import java.util.UUID;
import javax.naming.ConfigurationException;
-import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;
-import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.xml.DOMConfigurator;
import com.cloud.agent.Agent.ExitStatus;
@@ -373,6 +371,7 @@ public class AgentShell implements IAgentShell {
throw new ConfigurationException("Unable to find the guid");
}
_guid = UUID.randomUUID().toString();
+ _properties.setProperty("guid", _guid);
}
return true;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java
deleted file mode 100755
index 285005a..0000000
--- a/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java
+++ /dev/null
@@ -1,755 +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.resource;
-
-import java.io.File;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-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.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.SecStorageSetupCommand;
-import com.cloud.agent.api.SecStorageVMSetupCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupStorageCommand;
-import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DeleteTemplateCommand;
-import com.cloud.agent.api.storage.DownloadCommand;
-import com.cloud.agent.api.storage.DownloadProgressCommand;
-import com.cloud.agent.api.storage.UploadCommand;
-import com.cloud.agent.api.storage.ssCommand;
-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.DownloadManager;
-import com.cloud.storage.template.DownloadManagerImpl;
-import com.cloud.storage.template.TemplateInfo;
-import com.cloud.storage.template.UploadManager;
-import com.cloud.storage.template.UploadManagerImpl;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.net.NfsUtils;
-import com.cloud.utils.script.Script;
-
-/**
- * Implementation of Secondary Storage Resource to handle CIFS share
- *
- * TODOD: After mount rest of the functionality should be similar to NfsSecondaryStroage.
- * Move common functionality of NFS and CIFS secondary storage resource class to base class
- **/
-
-public class CifsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
- private static final Logger s_logger = Logger.getLogger(CifsSecondaryStorageResource.class);
- int _timeout;
-
- String _instance;
- String _parent;
-
- String _dc;
- String _pod;
- String _guid;
- String _nfsPath;
- String _mountParent;
- Map<String, Object> _params;
- StorageLayer _storage;
- boolean _inSystemVM = false;
- boolean _sslCopy = false;
-
- Random _rand = new Random(System.currentTimeMillis());
-
- DownloadManager _dlMgr;
- 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;
-
- @Override
- public void disconnected() {
- if (_parent != null && !_inSystemVM) {
- Script script = new Script(!_inSystemVM, "umount", _timeout, s_logger);
- script.add(_parent);
- script.execute();
-
- File file = new File(_parent);
- file.delete();
- }
- }
-
- @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 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 DeleteTemplateCommand) {
- return execute((DeleteTemplateCommand) cmd);
- } 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 new Answer(cmd, true, "success");
- } else {
- return Answer.createUnsupportedCommandAnswer(cmd);
- }
- }
-
- 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()) {
- 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 allowOutgoingOnPrivate(String destCidr) {
-
- 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);
- if (result !=null)
- success = false;
-
- return new Answer(cmd, success, result);
- }
-
- protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
- final long usedSize = getUsedSize();
- final long totalSize = getTotalSize();
- if (usedSize == -1 || totalSize == -1) {
- return new GetStorageStatsAnswer(cmd, "Unable to get storage stats");
- } else {
- return new GetStorageStatsAnswer(cmd, totalSize, usedSize) ;
- }
- }
-
- @Override
- public String getRootDir(ssCommand cmd){
- return null;
- }
-
- protected Answer execute(final DeleteTemplateCommand cmd) {
- String relativeTemplatePath = cmd.getTemplatePath();
- String parent = _parent;
-
- if (relativeTemplatePath.startsWith(File.separator)) {
- relativeTemplatePath = relativeTemplatePath.substring(1);
- }
-
- if (!parent.endsWith(File.separator)) {
- parent += File.separator;
- }
- String absoluteTemplatePath = parent + relativeTemplatePath;
- File tmpltParent = new File(absoluteTemplatePath).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;
- }
- 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);
- }
-
- protected long getUsedSize() {
- return _storage.getUsedSpace(_parent);
- }
-
- protected long getTotalSize() {
- return _storage.getTotalSpace(_parent);
- }
-
- 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() {
- return Host.Type.SecondaryStorage;
- }
-
- @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");
- if (_eth1ip != null) { //can only happen inside service vm
- params.put("private.network.device", "eth1");
- } else {
- s_logger.warn("Wait, what's going on? eth1ip is null!!");
- }
- 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");
-
- 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);
- 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)ComponentContext.inject(clazz);
- _storage.configure("StorageLayer", params);
- } catch (ClassNotFoundException e) {
- throw new ConfigurationException("Unable to find class " + value);
- }
- }
- _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);
- }
-
- _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");
-
- _mountParent = (String)params.get("mount.parent");
- if (_mountParent == null) {
- _mountParent = File.separator + "mnt";
- }
-
- if (_instance != null) {
- _mountParent = _mountParent + File.separator + _instance;
- }
-
- _nfsPath = (String)params.get("mount.path");
- if (_nfsPath == null) {
- throw new ConfigurationException("Unable to find mount.path");
- }
-
-
-
- String inSystemVM = (String)params.get("secondary.storage.vm");
- if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
- _inSystemVM = true;
- _localgw = (String)params.get("localgw");
- if (_localgw != null) { //can only happen inside service vm
- _eth1mask = (String)params.get("eth1mask");
- String internalDns1 = (String)params.get("dns1");
- String internalDns2 = (String)params.get("dns2");
-
- if (internalDns1 == null) {
- s_logger.warn("No DNS entry found during configuration of NfsSecondaryStorage");
- } else {
- addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns1);
- }
-
- String mgmtHost = (String)params.get("host");
- String nfsHost = NfsUtils.getHostPart(_nfsPath);
- if (nfsHost == null) {
- s_logger.error("Invalid or corrupt nfs url " + _nfsPath);
- throw new CloudRuntimeException("Unable to determine host part of nfs path");
- }
- try {
- InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
- nfsHost = nfsHostAddr.getHostAddress();
- } catch (UnknownHostException uhe) {
- s_logger.error("Unable to resolve nfs host " + nfsHost);
- throw new CloudRuntimeException("Unable to resolve nfs host to an ip address " + nfsHost);
- }
- addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, nfsHost);
- addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost);
- if (internalDns2 != null) {
- addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns2);
- }
-
- }
- String useSsl = (String)params.get("sslcopy");
- if (useSsl != null) {
- _sslCopy = Boolean.parseBoolean(useSsl);
- if (_sslCopy) {
- configureSSL();
- }
- }
- startAdditionalServices();
- _params.put("install.numthreads", "50");
- _params.put("secondary.storage.vm", "true");
- }
- _parent = mount(_nfsPath, _mountParent);
- if (_parent == null) {
- throw new ConfigurationException("Unable to create mount point");
- }
-
-
- s_logger.info("Mount point established at " + _parent);
-
- try {
- _params.put("template.parent", _parent);
- _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;
- }
-
- private void startAdditionalServices() {
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("if [ -f /etc/init.d/ssh ]; then service ssh restart; else service sshd restart; fi ");
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Error in starting sshd service err=" + result );
- }
- command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("iptables -I INPUT -i eth1 -p tcp -m state --state NEW -m tcp --dport 3922 -j ACCEPT");
- result = command.execute();
- if (result != null) {
- s_logger.warn("Error in opening up ssh port err=" + result );
- }
- }
-
- private void addRouteToInternalIpOrCidr(String localgw, String eth1ip, String eth1mask, String destIpOrCidr) {
- s_logger.debug("addRouteToInternalIp: localgw=" + localgw + ", eth1ip=" + eth1ip + ", eth1mask=" + eth1mask + ",destIp=" + destIpOrCidr);
- if (destIpOrCidr == null) {
- s_logger.debug("addRouteToInternalIp: destIp is null");
- return;
- }
- if (!NetUtils.isValidIp(destIpOrCidr) && !NetUtils.isValidCIDR(destIpOrCidr)){
- s_logger.warn(" destIp is not a valid ip address or cidr destIp=" + destIpOrCidr);
- return;
- }
- boolean inSameSubnet = false;
- if (NetUtils.isValidIp(destIpOrCidr)) {
- if (eth1ip != null && eth1mask != null) {
- inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask);
- } else {
- s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + ", _eth1mask=" + eth1mask);
- }
- } else {
- inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask));
- }
- if (inSameSubnet) {
- s_logger.debug("addRouteToInternalIp: dest ip " + destIpOrCidr + " is in the same subnet as eth1 ip " + eth1ip);
- return;
- }
- Script command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("ip route delete " + destIpOrCidr);
- command.execute();
- command = new Script("/bin/bash", s_logger);
- command.add("-c");
- command.add("ip route add " + destIpOrCidr + " via " + localgw);
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Error in configuring route to internal ip err=" + result );
- } else {
- s_logger.debug("addRouteToInternalIp: added route to internal ip=" + destIpOrCidr + " via " + localgw);
- }
- }
-
- private void configureSSL() {
- Script command = new Script(_configSslScr);
- command.add(_publicIp);
- command.add(_hostname);
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Unable to configure httpd to use ssl");
- }
- }
-
- private String configureAuth(String user, String passwd) {
- Script command = new Script(_configAuthScr);
- command.add(user);
- command.add(passwd);
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Unable to configure httpd to use auth");
- }
- return result;
- }
-
- private String configureIpFirewall(List<String> ipList){
- Script command = new Script(_configIpFirewallScr);
- for (String ip : ipList){
- command.add(ip);
- }
-
- String result = command.execute();
- if (result != null) {
- s_logger.warn("Unable to configure firewall for command : " +command);
- }
- return result;
- }
-
- protected String mount(String path, String parent) {
- String mountPoint = null;
- for (int i = 0; i < 10; i++) {
- String mntPt = parent + File.separator + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE));
- File file = new File(mntPt);
- if (!file.exists()) {
- if (_storage.mkdir(mntPt)) {
- mountPoint = mntPt;
- break;
- }
- }
- s_logger.debug("Unable to create mount: " + mntPt);
- }
-
- if (mountPoint == null) {
- s_logger.warn("Unable to create a mount point");
- return null;
- }
-
- Script script = null;
- String result = null;
- script = new Script(!_inSystemVM, "umount", _timeout, s_logger);
- script.add(path);
- result = script.execute();
-
- if( _parent != null ) {
- script = new Script("rmdir", _timeout, s_logger);
- script.add(_parent);
- result = script.execute();
- }
-
- Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
- command.add("-t", "cifs");
- if (_inSystemVM) {
- //Fedora Core 12 errors out with any -o option executed from java
- //command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0");
- }
- String tok[] = path.split(":");
- //command.add(path);
- command.add("//"+tok[0]+tok[1]);
- command.add(mountPoint);
- result = command.execute();
- if (result != null) {
- s_logger.warn("Unable to mount " + path + " due to " + result);
- File file = new File(mountPoint);
- if (file.exists())
- file.delete();
- return null;
- }
-
-
-
- // XXX: Adding the check for creation of snapshots dir here. Might have to move it somewhere more logical later.
- if (!checkForSnapshotsDir(mountPoint)) {
- return null;
- }
-
- // Create the volumes dir
- if (!checkForVolumesDir(mountPoint)) {
- return null;
- }
-
- return mountPoint;
- }
-
- @Override
- public boolean start() {
- return true;
- }
-
- @Override
- public boolean stop() {
- return true;
- }
-
- @Override
- public StartupCommand[] initialize() {
- /*disconnected();
-
- _parent = mount(_nfsPath, _mountParent);
-
- if( _parent == null ) {
- s_logger.warn("Unable to mount the nfs server");
- return null;
- }
-
- try {
- _params.put("template.parent", _parent);
- _params.put(StorageLayer.InstanceConfigKey, _storage);
- _dlMgr = new DownloadManagerImpl();
- _dlMgr.configure("DownloadManager", _params);
- } catch (ConfigurationException e) {
- s_logger.warn("Caught problem while configuring folers", e);
- return null;
- }*/
-
- final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.NetworkFilesystem, getTotalSize(), new HashMap<String, TemplateInfo>());
-
- cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE);
- cmd.setIqn(null);
-
- fillNetworkInformation(cmd);
- cmd.setDataCenter(_dc);
- cmd.setPod(_pod);
- cmd.setGuid(_guid);
- cmd.setName(_guid);
- cmd.setVersion(NfsSecondaryStorageResource.class.getPackage().getImplementationVersion());
- cmd.getHostDetails().put("mount.parent", _mountParent);
- cmd.getHostDetails().put("mount.path", _nfsPath);
- String tok[] = _nfsPath.split(":");
- cmd.setNfsShare("nfs://" + tok[0] + tok[1]);
- if (cmd.getHostDetails().get("orig.url") == null) {
- if (tok.length != 2) {
- throw new CloudRuntimeException("Not valid NFS path" + _nfsPath);
- }
- String nfsUrl = "nfs://" + tok[0] + tok[1];
- cmd.getHostDetails().put("orig.url", nfsUrl);
- }
- InetAddress addr;
- try {
- addr = InetAddress.getByName(tok[0]);
- cmd.setPrivateIpAddress(addr.getHostAddress());
- } catch (UnknownHostException e) {
- cmd.setPrivateIpAddress(tok[0]);
- }
- return new StartupCommand [] {cmd};
- }
-
- protected boolean checkForSnapshotsDir(String mountPoint) {
- String snapshotsDirLocation = mountPoint + File.separator + "snapshots";
- return createDir("snapshots", snapshotsDirLocation, mountPoint);
- }
-
- protected boolean checkForVolumesDir(String mountPoint) {
- String volumesDirLocation = mountPoint + "/" + "volumes";
- return createDir("volumes", volumesDirLocation, mountPoint);
- }
-
- protected boolean createDir(String dirName, String dirLocation, String mountPoint) {
- boolean dirExists = false;
-
- File dir = new File(dirLocation);
- if (dir.exists()) {
- if (dir.isDirectory()) {
- s_logger.debug(dirName + " already exists on secondary storage, and is mounted at " + mountPoint);
- dirExists = true;
- } else {
- if (dir.delete() && _storage.mkdir(dirLocation)) {
- dirExists = true;
- }
- }
- } else if (_storage.mkdir(dirLocation)) {
- dirExists = true;
- }
-
- if (dirExists) {
- s_logger.info(dirName + " directory created/exists on Secondary Storage.");
- } else {
- s_logger.info(dirName + " directory does not exist on Secondary Storage.");
- }
-
- return dirExists;
- }
-
- @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
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java
deleted file mode 100644
index c638c5d..0000000
--- a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java
+++ /dev/null
@@ -1,246 +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.resource;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-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.DownloadCommand;
-import com.cloud.agent.api.storage.DownloadProgressCommand;
-import com.cloud.agent.api.storage.ListTemplateAnswer;
-import com.cloud.agent.api.storage.ListTemplateCommand;
-import com.cloud.agent.api.storage.ssCommand;
-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.DownloadManager;
-import com.cloud.storage.template.DownloadManagerImpl;
-import com.cloud.storage.template.TemplateInfo;
-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(ssCommand cmd){
- 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, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
- return new ListTemplateAnswer(cmd.getSecUrl(), 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
-
- }
-}
[10/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: Remove reference to unused code
QuickCloud: remove some dead code in ConsoleProxyManager
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/790d2ce8
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/790d2ce8
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/790d2ce8
Branch: refs/heads/master
Commit: 790d2ce82ef6b1ac910124c8c9ab519e2431e622
Parents: 1679044
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Mon Mar 25 12:13:51 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700
----------------------------------------------------------------------
.../cloud/api/commands/DestroyConsoleProxyCmd.java | 12 +------
.../cloud/consoleproxy/ConsoleProxyService.java | 23 ---------------
api/src/org/apache/cloudstack/api/BaseCmd.java | 2 -
.../cloud/consoleproxy/ConsoleProxyManager.java | 17 +----------
.../consoleproxy/ConsoleProxyManagerImpl.java | 20 ++-----------
.../cloud/consoleproxy/ConsoleProxyService.java | 9 ++++++
6 files changed, 15 insertions(+), 68 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/790d2ce8/api/src/com/cloud/api/commands/DestroyConsoleProxyCmd.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/commands/DestroyConsoleProxyCmd.java b/api/src/com/cloud/api/commands/DestroyConsoleProxyCmd.java
index 829283e..f3210ce 100644
--- a/api/src/com/cloud/api/commands/DestroyConsoleProxyCmd.java
+++ b/api/src/com/cloud/api/commands/DestroyConsoleProxyCmd.java
@@ -17,14 +17,12 @@
package com.cloud.api.commands;
import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
+import com.cloud.exception.UnsupportedServiceException;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
@@ -82,12 +80,6 @@ public class DestroyConsoleProxyCmd extends BaseAsyncCmd {
@Override
public void execute(){
- boolean result = _consoleProxyService.destroyConsoleProxy(this);
- if (result) {
- SuccessResponse response = new SuccessResponse(getCommandName());
- this.setResponseObject(response);
- } else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to destroy console proxy");
- }
+ throw new UnsupportedServiceException("Use destroySystemVm API instead");
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/790d2ce8/api/src/com/cloud/consoleproxy/ConsoleProxyService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/consoleproxy/ConsoleProxyService.java b/api/src/com/cloud/consoleproxy/ConsoleProxyService.java
deleted file mode 100644
index c347e0b..0000000
--- a/api/src/com/cloud/consoleproxy/ConsoleProxyService.java
+++ /dev/null
@@ -1,23 +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.consoleproxy;
-
-import com.cloud.api.commands.DestroyConsoleProxyCmd;
-
-public interface ConsoleProxyService {
- boolean destroyConsoleProxy(DestroyConsoleProxyCmd cmd);
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/790d2ce8/api/src/org/apache/cloudstack/api/BaseCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java
index 78a2af3..8fef422 100644
--- a/api/src/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseCmd.java
@@ -32,7 +32,6 @@ import org.apache.cloudstack.usage.UsageService;
import org.apache.log4j.Logger;
import com.cloud.configuration.ConfigurationService;
-import com.cloud.consoleproxy.ConsoleProxyService;
import com.cloud.dao.EntityManager;
import com.cloud.domain.Domain;
import com.cloud.exception.ConcurrentOperationException;
@@ -109,7 +108,6 @@ public abstract class BaseCmd {
@Inject public TemplateService _templateService;
@Inject public SecurityGroupService _securityGroupService;
@Inject public SnapshotService _snapshotService;
- @Inject public ConsoleProxyService _consoleProxyService;
@Inject public VpcVirtualNetworkApplianceService _routerService;
@Inject public ResponseGenerator _responseGenerator;
@Inject public EntityManager _entityMgr;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/790d2ce8/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
index 6ebf3bc..faec513 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
@@ -16,17 +16,9 @@
// under the License.
package com.cloud.consoleproxy;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
-import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.Host.Type;
-import com.cloud.info.ConsoleProxyInfo;
import com.cloud.utils.component.Manager;
import com.cloud.vm.ConsoleProxyVO;
-public interface ConsoleProxyManager extends Manager {
+public interface ConsoleProxyManager extends Manager, ConsoleProxyService {
public static final int DEFAULT_PROXY_CAPACITY = 50;
public static final int DEFAULT_STANDBY_CAPACITY = 10;
@@ -45,16 +37,9 @@ public interface ConsoleProxyManager extends Manager {
public ConsoleProxyManagementState getManagementState();
public void resumeLastManagementState();
- public ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId);
-
public ConsoleProxyVO startProxy(long proxyVmId);
public boolean stopProxy(long proxyVmId);
public boolean rebootProxy(long proxyVmId);
public boolean destroyProxy(long proxyVmId);
-
- public void onLoadReport(ConsoleProxyLoadReportCommand cmd);
- public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd);
- public void onAgentConnect(HostVO host, StartupCommand cmd);
- public void onAgentDisconnect(long agentId, Status state);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/790d2ce8/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index 1edd869..fc4fc6e 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -30,7 +30,6 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
-import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.log4j.Logger;
@@ -54,7 +53,6 @@ import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.manager.Commands;
-import com.cloud.api.commands.DestroyConsoleProxyCmd;
import com.cloud.certificate.dao.CertificateDao;
import com.cloud.cluster.ClusterManager;
import com.cloud.configuration.Config;
@@ -71,7 +69,6 @@ import com.cloud.deploy.DeployDestination;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
@@ -113,8 +110,8 @@ import com.cloud.servlet.ConsoleProxyServlet;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
@@ -127,7 +124,6 @@ import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.Ternary;
-import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GlobalLock;
@@ -170,7 +166,8 @@ import com.google.gson.GsonBuilder;
// because sooner or later, it will be driven into Running state
//
@Local(value = { ConsoleProxyManager.class, ConsoleProxyService.class })
-public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxyManager, ConsoleProxyService, AgentHook, VirtualMachineGuru<ConsoleProxyVO>, SystemVmLoadScanHandler<Long>, ResourceStateAdapter {
+public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxyManager,
+ AgentHook, VirtualMachineGuru<ConsoleProxyVO>, SystemVmLoadScanHandler<Long>, ResourceStateAdapter {
private static final Logger s_logger = Logger.getLogger(ConsoleProxyManagerImpl.class);
private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30 seconds
@@ -1549,18 +1546,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
return true;
}
- @Override
- public boolean destroyConsoleProxy(DestroyConsoleProxyCmd cmd) throws ServerApiException {
- Long proxyId = cmd.getId();
- // verify parameters
- ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyId);
- if (proxy == null) {
- throw new InvalidParameterValueException("unable to find a console proxy with id " + proxyId);
- }
-
- return destroyProxy(proxyId);
- }
protected ConsoleProxyManagerImpl() {
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/790d2ce8/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyService.java b/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
new file mode 100644
index 0000000..e43e5c3
--- /dev/null
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
@@ -0,0 +1,9 @@
+package com.cloud.consoleproxy;
+
+import com.cloud.info.ConsoleProxyInfo;
+
+public interface ConsoleProxyService {
+
+ public abstract ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId);
+
+}
\ No newline at end of file
[19/19] git commit: updated refs/heads/master to bf56403
Posted by ch...@apache.org.
QuickCloud: sanitize logs for normal running of agents outside systemvm
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/2e6c65fd
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/2e6c65fd
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/2e6c65fd
Branch: refs/heads/master
Commit: 2e6c65fd34dc5f4f885c12a4e5469b505975685d
Parents: 271d232
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Fri Apr 5 14:11:05 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:27 2013 -0700
----------------------------------------------------------------------
.../consoleproxy/ConsoleProxyResource.java | 4 +-
.../src/com/cloud/resource/ServerResourceBase.java | 2 +-
.../AgentBasedConsoleProxyManager.java.orig | 298 +++++++++++++++
.../PremiumSecondaryStorageManagerImpl.java | 6 +-
.../storage/download/DownloadMonitorImpl.java | 11 +-
.../secondary/SecondaryStorageManagerImpl.java | 2 +-
.../resource/NfsSecondaryStorageResource.java | 6 +-
utils/src/com/cloud/utils/nio/NioClient.java | 3 +-
utils/src/com/cloud/utils/nio/NioConnection.java | 2 +-
9 files changed, 320 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
----------------------------------------------------------------------
diff --git a/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java b/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
index 516430b..991764c 100644
--- a/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
+++ b/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
@@ -235,14 +235,14 @@ public class ConsoleProxyResource extends ServerResourceBase implements
if (_eth1ip != null) {
params.put("private.network.device", "eth1");
} else {
- s_logger.warn("WARNING: eth1ip parameter is not found!");
+ s_logger.info("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");
} else {
- s_logger.warn("WARNING: eth2ip parameter is not found!");
+ s_logger.info("eth2ip parameter is not found, assuming that we are not inside a system vm");
}
super.configure(name, params);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/core/src/com/cloud/resource/ServerResourceBase.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/resource/ServerResourceBase.java b/core/src/com/cloud/resource/ServerResourceBase.java
index 9449b05..e381fcb 100755
--- a/core/src/com/cloud/resource/ServerResourceBase.java
+++ b/core/src/com/cloud/resource/ServerResourceBase.java
@@ -80,7 +80,7 @@ public abstract class ServerResourceBase implements ServerResource {
_storageNic2 = getNetworkInterface(storageNic2);
if (_privateNic == null) {
- s_logger.error("Nics are not configured!");
+ s_logger.warn("Nics are not specified in properties file/db, will try to autodiscover");
Enumeration<NetworkInterface> nics = null;
try {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java.orig
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java.orig b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java.orig
new file mode 100755
index 0000000..134d59d
--- /dev/null
+++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java.orig
@@ -0,0 +1,298 @@
+// 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.consoleproxy;
+
+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.AgentManager;
+import com.cloud.agent.api.GetVncPortAnswer;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.StartupProxyCommand;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.info.ConsoleProxyInfo;
+import com.cloud.keystore.KeystoreManager;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.vm.ConsoleProxyVO;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.dao.ConsoleProxyDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Local(value = { ConsoleProxyManager.class })
+public class AgentBasedConsoleProxyManager extends ManagerBase implements ConsoleProxyManager {
+ private static final Logger s_logger = Logger.getLogger(AgentBasedConsoleProxyManager.class);
+
+ @Inject
+ protected HostDao _hostDao;
+ @Inject
+ protected UserVmDao _userVmDao;
+ private String _instance;
+ protected String _consoleProxyUrlDomain;
+ @Inject
+ private VMInstanceDao _instanceDao;
+ private ConsoleProxyListener _listener;
+ protected int _consoleProxyUrlPort = ConsoleProxyManager.DEFAULT_PROXY_URL_PORT;
+ protected int _consoleProxyPort = ConsoleProxyManager.DEFAULT_PROXY_VNC_PORT;
+ protected boolean _sslEnabled = false;
+ @Inject
+ AgentManager _agentMgr;
+ @Inject
+ VirtualMachineManager _itMgr;
+ @Inject
+ protected ConsoleProxyDao _cpDao;
+ @Inject
+ protected KeystoreManager _ksMgr;
+
+ @Inject ConfigurationDao _configDao;
+
+ public class AgentBasedAgentHook extends AgentHookBase {
+
+ public AgentBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao,
+ KeystoreManager ksMgr, AgentManager agentMgr) {
+ super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr);
+ }
+
+ @Override
+ protected HostVO findConsoleProxyHost(StartupProxyCommand cmd) {
+ return _hostDao.findByGuid(cmd.getGuid());
+ }
+
+ }
+
+ public int getVncPort(VMInstanceVO vm) {
+ if (vm.getHostId() == null) {
+ return -1;
+ }
+ GetVncPortAnswer answer = (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(), new GetVncPortCommand(vm.getId(), vm.getHostName()));
+ return (answer == null || !answer.getResult()) ? -1 : answer.getPort();
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Start configuring AgentBasedConsoleProxyManager");
+ }
+
+ Map<String, String> configs = _configDao.getConfiguration("management-server", params);
+ String value = configs.get("consoleproxy.url.port");
+ if (value != null) {
+ _consoleProxyUrlPort = NumbersUtil.parseInt(value, ConsoleProxyManager.DEFAULT_PROXY_URL_PORT);
+ }
+
+ value = configs.get("consoleproxy.port");
+ if (value != null) {
+ _consoleProxyPort = NumbersUtil.parseInt(value, ConsoleProxyManager.DEFAULT_PROXY_VNC_PORT);
+ }
+
+ value = configs.get("consoleproxy.sslEnabled");
+ if (value != null && value.equalsIgnoreCase("true")) {
+ _sslEnabled = true;
+ }
+
+ _instance = configs.get("instance.name");
+
+ _consoleProxyUrlDomain = configs.get("consoleproxy.url.domain");
+
+ _listener =
+ new ConsoleProxyListener(new AgentBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr));
+ _agentMgr.registerForHostEvents(_listener, true, true, false);
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("AgentBasedConsoleProxyManager has been configured. SSL enabled: " + _sslEnabled);
+ }
+ return true;
+ }
+
+ HostVO findHost(VMInstanceVO vm) {
+ return _hostDao.findById(vm.getHostId());
+ }
+
+ @Override
+ public ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId) {
+ UserVmVO userVm = _userVmDao.findById(userVmId);
+ if (userVm == null) {
+ s_logger.warn("User VM " + userVmId + " no longer exists, return a null proxy for user vm:" + userVmId);
+ return null;
+ }
+
+ HostVO host = findHost(userVm);
+ if (host != null) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Assign embedded console proxy running at " + host.getName() + " to user vm " + userVmId + " with public IP "
+ + host.getPublicIpAddress());
+ }
+
+ // only private IP, public IP, host id have meaningful values, rest
+ // of all are place-holder values
+ String publicIp = host.getPublicIpAddress();
+ if (publicIp == null) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Host " + host.getName() + "/" + host.getPrivateIpAddress()
+ + " does not have public interface, we will return its private IP for cosole proxy.");
+ }
+ publicIp = host.getPrivateIpAddress();
+ }
+
+ int urlPort = _consoleProxyUrlPort;
+
+ if (host.getProxyPort() != null && host.getProxyPort().intValue() > 0) {
+ urlPort = host.getProxyPort().intValue();
+ }
+
+ return new ConsoleProxyInfo(_sslEnabled, publicIp, _consoleProxyPort, urlPort, _consoleProxyUrlDomain);
+ } else {
+ s_logger.warn("Host that VM is running is no longer available, console access to VM " + userVmId + " will be temporarily unavailable.");
+ }
+ return null;
+ }
+
+
+
+
+ @Override
+ public ConsoleProxyVO startProxy(long proxyVmId) {
+ return null;
+ }
+
+ @Override
+ public boolean destroyProxy(long proxyVmId) {
+ return false;
+ }
+
+ @Override
+ public boolean rebootProxy(long proxyVmId) {
+ return false;
+ }
+
+ @Override
+ public boolean stopProxy(long proxyVmId) {
+ return false;
+ }
+
+ @Override
+ public void setManagementState(ConsoleProxyManagementState state) {
+ }
+
+ @Override
+ public ConsoleProxyManagementState getManagementState() {
+ return null;
+ }
+
+ @Override
+ public void resumeLastManagementState() {
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+<<<<<<< HEAD
+
+ @Override
+ public Long convertToId(String vmName) {
+ if (!VirtualMachineName.isValidConsoleProxyName(vmName, _instance)) {
+ return null;
+ }
+ return VirtualMachineName.getConsoleProxyId(vmName);
+ }
+
+ @Override
+ public ConsoleProxyVO findByName(String name) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ConsoleProxyVO findById(long id) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ConsoleProxyVO persist(ConsoleProxyVO vm) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean finalizeVirtualMachineProfile(VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean finalizeStart(VirtualMachineProfile<ConsoleProxyVO> profile, long hostId, Commands cmds, ReservationContext context) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public void finalizeStop(VirtualMachineProfile<ConsoleProxyVO> profile, StopAnswer answer) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void finalizeExpunge(ConsoleProxyVO proxy) {
+ }
+
+ @Override
+ public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm,
+ ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException,
+ InsufficientCapacityException {
+ //not supported
+ throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType());
+ }
+
+
+ @Override
+ public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm,
+ ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException {
+ //not supported
+ throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType());
+ }
+
+ @Override
+ public void prepareStop(VirtualMachineProfile<ConsoleProxyVO> profile) {
+ }
+}
+=======
+}
+>>>>>>> QuickCloud: refactor to avoid copy paste of authentication and startup code
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/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
index 73015c1..8658113 100755
--- a/server/src/com/cloud/secstorage/PremiumSecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/secstorage/PremiumSecondaryStorageManagerImpl.java
@@ -25,8 +25,6 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
-import org.springframework.context.annotation.Primary;
-import org.springframework.stereotype.Component;
import com.cloud.agent.api.Command;
import com.cloud.configuration.Config;
@@ -90,6 +88,10 @@ public class PremiumSecondaryStorageManagerImpl extends SecondaryStorageManagerI
@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);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/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 cfb92d5..5d7a210 100755
--- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
@@ -851,7 +851,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
TemplateInfo tmpltInfo = templateInfos.remove(uniqueName);
toBeDownloaded.remove(tmplt);
if (tmpltHost != null) {
- s_logger.info("Template Sync found " + uniqueName + " already in the template host table");
+ s_logger.info("Template Sync found " + tmplt.getName() + " already in the template host table");
if (tmpltHost.getDownloadState() != Status.DOWNLOADED) {
tmpltHost.setErrorString("");
}
@@ -911,10 +911,12 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
continue;
}
if (tmpltHost != null && tmpltHost.getDownloadState() != Status.DOWNLOADED) {
- s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + sserverId + ", will request download to start/resume shortly");
+ s_logger.info("Template Sync did not find " + tmplt.getName() + " ready on server " + sserverId
+ + ", will request download to start/resume shortly");
} else if (tmpltHost == null) {
- s_logger.info("Template Sync did not find " + uniqueName + " on the server " + sserverId + ", will request download shortly");
+ s_logger.info("Template Sync did not find " + tmplt.getName() + " on the server " + sserverId
+ + ", will request download shortly");
VMTemplateHostVO templtHost = new VMTemplateHostVO(sserverId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl());
_vmTemplateHostDao.persist(templtHost);
VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(zoneId, tmplt.getId());
@@ -964,6 +966,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
}
s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + ssHost.getName());
downloadTemplateToStorage(tmplt, ssHost);
+ } else {
+ s_logger.info("Skipping download of template " + tmplt.getName() + " since we don't have any "
+ + tmplt.getHypervisorType() + " hypervisors");
}
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/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 d6d6fc0..3cf9a7e 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
@@ -472,7 +472,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
}
- private boolean isSecondaryStorageVmRequired(long dcId) {
+ protected boolean isSecondaryStorageVmRequired(long dcId) {
DataCenterVO dc = _dcDao.findById(dcId);
_dcDao.loadDetails(dc);
String ssvmReq = dc.getDetail(ZoneConfig.EnableSecStorageVm.key());
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/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
index 6bcf98e..1176d76 100755
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -1464,7 +1464,7 @@ SecondaryStorageResource {
if (_eth1ip != null) { //can only happen inside service vm
params.put("private.network.device", "eth1");
} else {
- s_logger.warn("Wait, what's going on? eth1ip is null!!");
+ 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) {
@@ -1479,8 +1479,8 @@ SecondaryStorageResource {
}
_storageIp = (String) params.get("storageip");
- if (_storageIp == null) {
- s_logger.warn("Wait, there is no storageip in /proc/cmdline, something wrong!");
+ 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");
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/utils/src/com/cloud/utils/nio/NioClient.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/nio/NioClient.java b/utils/src/com/cloud/utils/nio/NioClient.java
index 1e2aa52..8d12f93 100755
--- a/utils/src/com/cloud/utils/nio/NioClient.java
+++ b/utils/src/com/cloud/utils/nio/NioClient.java
@@ -22,8 +22,8 @@ import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
-import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
import org.apache.log4j.Logger;
@@ -78,6 +78,7 @@ public class NioClient extends NioConnection {
Link.doHandshake(sch, sslEngine, true);
s_logger.info("SSL: Handshake done");
+ s_logger.info("Connected to " + _host + ":" + _port);
} catch (Exception e) {
_selector.close();
throw new IOException("SSL: Fail to init SSL! " + e);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/utils/src/com/cloud/utils/nio/NioConnection.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/nio/NioConnection.java b/utils/src/com/cloud/utils/nio/NioConnection.java
index 50e6a88..07c2bea 100755
--- a/utils/src/com/cloud/utils/nio/NioConnection.java
+++ b/utils/src/com/cloud/utils/nio/NioConnection.java
@@ -107,7 +107,7 @@ public abstract class NioConnection implements Runnable {
try {
init();
} catch (ConnectException e) {
- s_logger.error("Unable to connect to remote");
+ s_logger.warn("Unable to connect to remote: is there a server running on port " + _port);
return;
} catch (IOException e) {
s_logger.error("Unable to initialize the threads.", e);
[04/19] QuickCloud: Enable secondary storage daemon to run outside
the system vm
Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/_run.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/_run.sh b/services/secondary-storage/scripts/_run.sh
new file mode 100755
index 0000000..e408378
--- /dev/null
+++ b/services/secondary-storage/scripts/_run.sh
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+
+
+
+#run.sh runs the console proxy.
+
+# make sure we delete the old files from the original template
+rm console-proxy.jar
+rm console-common.jar
+rm conf/cloud.properties
+
+set -x
+
+CP=./:./conf
+for file in *.jar
+do
+ CP=${CP}:$file
+done
+keyvalues=
+
+CMDLINE=$(cat /var/cache/cloud/cmdline)
+
+#CMDLINE="graphical utf8 eth0ip=0.0.0.0 eth0mask=255.255.255.0 eth1ip=192.168.140.40 eth1mask=255.255.255.0 eth2ip=172.24.0.50 eth2mask=255.255.0.0 gateway=172.24.0.1 dns1=72.52.126.11 template=domP dns2=72.52.126.12 host=192.168.1.142 port=8250 mgmtcidr=192.168.1.0/24 localgw=192.168.140.1 zone=5 pod=5"
+for i in $CMDLINE
+ do
+ KEY=$(echo $i | cut -s -d= -f1)
+ VALUE=$(echo $i | cut -s -d= -f2)
+ [ "$KEY" == "" ] && continue
+ case $KEY in
+ *)
+ keyvalues="${keyvalues} $KEY=$VALUE"
+ esac
+ done
+
+tot_mem_k=$(cat /proc/meminfo | grep MemTotal | awk '{print $2}')
+let "tot_mem_m=tot_mem_k>>10"
+let "eightypcnt=$tot_mem_m*8/10"
+let "maxmem=$tot_mem_m-80"
+
+if [ $maxmem -gt $eightypcnt ]
+then
+ maxmem=$eightypcnt
+fi
+
+java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/config_auth.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/config_auth.sh b/services/secondary-storage/scripts/config_auth.sh
new file mode 100755
index 0000000..4b74f8e
--- /dev/null
+++ b/services/secondary-storage/scripts/config_auth.sh
@@ -0,0 +1,69 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+
+
+
+
+BASE_DIR="/var/www/html/copy/template/"
+HTACCESS="$BASE_DIR/.htaccess"
+
+PASSWDFILE="/etc/httpd/.htpasswd"
+if [ -d /etc/apache2 ]
+then
+ PASSWDFILE="/etc/apache2/.htpasswd"
+fi
+
+config_htaccess() {
+ mkdir -p $BASE_DIR
+ result=$?
+ echo "Options -Indexes" > $HTACCESS
+ let "result=$result+$?"
+ echo "AuthType Basic" >> $HTACCESS
+ let "result=$result+$?"
+ echo "AuthName \"Authentication Required\"" >> $HTACCESS
+ let "result=$result+$?"
+ echo "AuthUserFile \"$PASSWDFILE\"" >> $HTACCESS
+ let "result=$result+$?"
+ echo "Require valid-user" >> $HTACCESS
+ let "result=$result+$?"
+ return $result
+}
+
+write_passwd() {
+ local user=$1
+ local passwd=$2
+ htpasswd -bc $PASSWDFILE $user $passwd
+ return $?
+}
+
+if [ $# -ne 2 ] ; then
+ echo $"Usage: `basename $0` username password "
+ exit 0
+fi
+
+write_passwd $1 $2
+if [ $? -ne 0 ]
+then
+ echo "Failed to update password"
+ exit 2
+fi
+
+config_htaccess
+exit $?
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/config_ssl.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/config_ssl.sh b/services/secondary-storage/scripts/config_ssl.sh
new file mode 100755
index 0000000..8d80c47
--- /dev/null
+++ b/services/secondary-storage/scripts/config_ssl.sh
@@ -0,0 +1,174 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+
+
+help() {
+ printf " -c use customized key/cert\n"
+ printf " -k path of private key\n"
+ printf " -p path of certificate of public key\n"
+ printf " -t path of certificate chain\n"
+}
+
+
+config_httpd_conf() {
+ local ip=$1
+ local srvr=$2
+ cp -f /etc/httpd/conf/httpd.conf.orig /etc/httpd/conf/httpd.conf
+ sed -i -e "s/Listen.*:80$/Listen $ip:80/" /etc/httpd/conf/httpd.conf
+ echo "<VirtualHost $ip:443> " >> /etc/httpd/conf/httpd.conf
+ echo " DocumentRoot /var/www/html/" >> /etc/httpd/conf/httpd.conf
+ echo " ServerName $srvr" >> /etc/httpd/conf/httpd.conf
+ echo " SSLEngine on" >> /etc/httpd/conf/httpd.conf
+ echo " SSLCertificateFile /etc/httpd/ssl/certs/realhostip.crt" >> /etc/httpd/conf/httpd.conf
+ echo " SSLCertificateKeyFile /etc/httpd/ssl/keys/realhostip.key" >> /etc/httpd/conf/httpd.conf
+ echo "</VirtualHost>" >> /etc/httpd/conf/httpd.conf
+}
+
+config_apache2_conf() {
+ local ip=$1
+ local srvr=$2
+ cp -f /etc/apache2/sites-available/default.orig /etc/apache2/sites-available/default
+ cp -f /etc/apache2/sites-available/default-ssl.orig /etc/apache2/sites-available/default-ssl
+ sed -i -e "s/<VirtualHost.*>/<VirtualHost $ip:80>/" /etc/apache2/sites-available/default
+ sed -i -e "s/<VirtualHost.*>/<VirtualHost $ip:443>/" /etc/apache2/sites-available/default-ssl
+ sed -i -e "s/Listen .*:80/Listen $ip:80/g" /etc/apache2/ports.conf
+ sed -i -e "s/Listen .*:443/Listen $ip:443/g" /etc/apache2/ports.conf
+ sed -i -e "s/NameVirtualHost .*:80/NameVirtualHost $ip:80/g" /etc/apache2/ports.conf
+ sed -i 's/ssl-cert-snakeoil.key/cert_apache.key/' /etc/apache2/sites-available/default-ssl
+ sed -i 's/ssl-cert-snakeoil.pem/cert_apache.crt/' /etc/apache2/sites-available/default-ssl
+}
+
+copy_certs() {
+ local certdir=$(dirname $0)/certs
+ local mydir=$(dirname $0)
+ if [ -d $certdir ] && [ -f $customPrivKey ] && [ -f $customPrivCert ] ; then
+ mkdir -p /etc/httpd/ssl/keys && mkdir -p /etc/httpd/ssl/certs && cp $customprivKey /etc/httpd/ssl/keys && cp $customPrivCert /etc/httpd/ssl/certs
+ return $?
+ fi
+ if [ ! -z customCertChain ] && [ -f $customCertChain ] ; then
+ cp $customCertChain /etc/httpd/ssl/certs
+ fi
+ return 1
+}
+
+copy_certs_apache2() {
+ local certdir=$(dirname $0)/certs
+ local mydir=$(dirname $0)
+ if [ -f $customPrivKey ] && [ -f $customPrivCert ] ; then
+ cp $customPrivKey /etc/ssl/private/cert_apache.key && cp $customPrivCert /etc/ssl/certs/cert_apache.crt
+ fi
+ if [ ! -z "$customCertChain" ] && [ -f "$customCertChain" ] ; then
+ cp $customCertChain /etc/ssl/certs/cert_apache_chain.crt
+ fi
+ return 0
+}
+
+
+cflag=
+cpkflag=
+cpcflag=
+cccflag=
+customPrivKey=$(dirname $0)/certs/realhostip.key
+customPrivCert=$(dirname $0)/certs/realhostip.crt
+customCertChain=
+publicIp=
+hostName=
+while getopts 'i:h:k:p:t:c' OPTION
+do
+ case $OPTION in
+ c) cflag=1
+ ;;
+ k) cpkflag=1
+ customPrivKey="$OPTARG"
+ ;;
+ p) cpcflag=1
+ customPrivCert="$OPTARG"
+ ;;
+ t) cccflag=1
+ customCertChain="$OPTARG"
+ ;;
+ i) publicIp="$OPTARG"
+ ;;
+ h) hostName="$OPTARG"
+ ;;
+ ?) help
+ ;;
+ esac
+done
+
+
+if [ -z "$publicIp" ] || [ -z "$hostName" ]
+then
+ help
+ exit 1
+fi
+
+if [ "$cflag" == "1" ]
+then
+ if [ "$cpkflag$cpcflag" != "11" ]
+ then
+ help
+ exit 1
+ fi
+ if [ ! -f "$customPrivKey" ]
+ then
+ printf "priviate key file is not exist\n"
+ exit 2
+ fi
+
+ if [ ! -f "$customPrivCert" ]
+ then
+ printf "public certificate is not exist\n"
+ exit 3
+ fi
+
+ if [ "$cccflag" == "1" ]
+ then
+ if [ ! -f "$customCertChain" ]
+ then
+ printf "certificate chain is not exist\n"
+ exit 4
+ fi
+ fi
+fi
+
+if [ -d /etc/apache2 ]
+then
+ copy_certs_apache2
+else
+ copy_certs
+fi
+
+if [ $? -ne 0 ]
+then
+ echo "Failed to copy certificates"
+ exit 2
+fi
+
+if [ -d /etc/apache2 ]
+then
+ config_apache2_conf $publicIp $hostName
+ /etc/init.d/apache2 stop
+ /etc/init.d/apache2 start
+else
+ config_httpd_conf $publicIp $hostName
+fi
+
+
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/ipfirewall.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/ipfirewall.sh b/services/secondary-storage/scripts/ipfirewall.sh
new file mode 100755
index 0000000..4711b8a
--- /dev/null
+++ b/services/secondary-storage/scripts/ipfirewall.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+BASE_DIR="/var/www/html/copy/"
+HTACCESS="$BASE_DIR/.htaccess"
+
+config_htaccess() {
+ mkdir -p $BASE_DIR
+ result=$?
+ echo "Options -Indexes" > $HTACCESS
+ let "result=$result+$?"
+ echo "order deny,allow" >> $HTACCESS
+ let "result=$result+$?"
+ echo "deny from all" >> $HTACCESS
+ let "result=$result+$?"
+ return $result
+}
+
+ips(){
+ echo "allow from $1" >> $HTACCESS
+ result=$?
+ return $result
+}
+
+is_append="$1"
+shift
+if [ $is_append != "true" ]; then
+ config_htaccess
+fi
+for i in $@
+do
+ ips "$i"
+done
+exit $?
+
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/run-proxy.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/run-proxy.sh b/services/secondary-storage/scripts/run-proxy.sh
new file mode 100644
index 0000000..d6ccf7c
--- /dev/null
+++ b/services/secondary-storage/scripts/run-proxy.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+
+
+
+#run.sh runs the console proxy.
+
+# make sure we delete the old files from the original template
+rm console-proxy.jar
+rm console-common.jar
+rm conf/cloud.properties
+
+CP=./:./conf
+for file in *.jar
+do
+ CP=${CP}:$file
+done
+
+#CMDLINE=$(cat /proc/cmdline)
+#for i in $CMDLINE
+# do
+# KEY=$(echo $i | cut -d= -f1)
+# VALUE=$(echo $i | cut -d= -f2)
+# case $KEY in
+# mgmt_host)
+# MGMT_HOST=$VALUE
+# ;;
+# esac
+# done
+
+java -mx700m -cp $CP:./conf com.cloud.consoleproxy.ConsoleProxy $@
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/run.bat
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/run.bat b/services/secondary-storage/scripts/run.bat
new file mode 100644
index 0000000..ce6dc40
--- /dev/null
+++ b/services/secondary-storage/scripts/run.bat
@@ -0,0 +1,18 @@
+rem Licensed to the Apache Software Foundation (ASF) under one
+rem or more contributor license agreements. See the NOTICE file
+rem distributed with this work for additional information
+rem regarding copyright ownership. The ASF licenses this file
+rem to you under the Apache License, Version 2.0 (the
+rem "License"); you may not use this file except in compliance
+rem with the License. You may obtain a copy of the License at
+rem
+rem http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing,
+rem software distributed under the License is distributed on an
+rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem KIND, either express or implied. See the License for the
+rem specific language governing permissions and limitations
+rem under the License.
+
+java -mx700m -cp cloud-console-proxy.jar;;cloud-console-common.jar;log4j-1.2.15.jar;apache-log4j-extras-1.0.jar;gson-1.3.jar;commons-logging-1.1.1.jar;.;.\conf; com.cloud.consoleproxy.ConsoleProxy %*
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/run.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/run.sh b/services/secondary-storage/scripts/run.sh
new file mode 100755
index 0000000..146d96f
--- /dev/null
+++ b/services/secondary-storage/scripts/run.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+
+
+
+#_run.sh runs the agent client.
+
+# set -x
+
+while true
+do
+ ./_run.sh "$@" &
+ wait
+ ex=$?
+ if [ $ex -eq 0 ] || [ $ex -eq 1 ] || [ $ex -eq 66 ] || [ $ex -gt 128 ]; then
+ # permanent errors
+ sleep 5
+ fi
+
+ # user stop agent by service cloud stop
+ grep 'stop' /usr/local/cloud/systemvm/user_request &>/dev/null
+ if [ $? -eq 0 ]; then
+ timestamp=$(date)
+ echo "$timestamp User stops cloud.com service" >> /var/log/cloud.log
+ exit 0
+ fi
+ sleep 5
+done
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/ssvm-check.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/ssvm-check.sh b/services/secondary-storage/scripts/ssvm-check.sh
new file mode 100644
index 0000000..a401164
--- /dev/null
+++ b/services/secondary-storage/scripts/ssvm-check.sh
@@ -0,0 +1,136 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+# Health check script for the Secondary Storage VM
+
+# DNS server is specified.
+
+
+CMDLINE=/var/cache/cloud/cmdline
+for i in `cat $CMDLINE`
+do
+ key=`echo $i | cut -d= -f1`
+ value=`echo $i | cut -d= -f2`
+ case $key in
+ host)
+ MGMTSERVER=$value
+ ;;
+ esac
+done
+
+
+# ping dns server
+echo ================================================
+DNSSERVER=`egrep '^nameserver' /etc/resolv.conf | awk '{print $2}'| head -1`
+echo "First DNS server is " $DNSSERVER
+ping -c 2 $DNSSERVER
+if [ $? -eq 0 ]
+then
+ echo "Good: Can ping DNS server"
+else
+ echo "WARNING: cannot ping DNS server"
+ echo "route follows"
+ route -n
+fi
+
+
+# check dns resolve
+echo ================================================
+nslookup download.cloud.com 1> /tmp/dns 2>&1
+grep 'no servers could' /tmp/dns 1> /dev/null 2>&1
+if [ $? -eq 0 ]
+then
+ echo "ERROR: DNS not resolving download.cloud.com"
+ echo resolv.conf follows
+ cat /etc/resolv.conf
+ exit 2
+else
+ echo "Good: DNS resolves download.cloud.com"
+fi
+
+
+# check to see if we have the NFS volume mounted
+echo ================================================
+mount|grep -v sunrpc|grep nfs 1> /dev/null 2>&1
+if [ $? -eq 0 ]
+then
+ echo "NFS is currently mounted"
+ # check for write access
+ for MOUNTPT in `mount|grep -v sunrpc|grep nfs| awk '{print $3}'`
+ do
+ if [ $MOUNTPT != "/proc/xen" ] # mounted by xen
+ then
+ echo Mount point is $MOUNTPT
+ touch $MOUNTPT/foo
+ if [ $? -eq 0 ]
+ then
+ echo "Good: Can write to mount point"
+ rm $MOUNTPT/foo
+ else
+ echo "ERROR: Cannot write to mount point"
+ echo "You need to export with norootsquash"
+ fi
+ fi
+ done
+else
+ echo "ERROR: NFS is not currently mounted"
+ echo "Try manually mounting from inside the VM"
+ NFSSERVER=`awk '{print $17}' $CMDLINE|awk -F= '{print $2}'|awk -F: '{print $1}'`
+ echo "NFS server is " $NFSSERVER
+ ping -c 2 $NFSSERVER
+ if [ $? -eq 0 ]
+ then
+ echo "Good: Can ping NFS server"
+ else
+ echo "WARNING: cannot ping NFS server"
+ echo routing table follows
+ route -n
+ fi
+fi
+
+
+# check for connectivity to the management server
+echo ================================================
+echo Management server is $MGMTSERVER. Checking connectivity.
+socatout=$(echo | socat - TCP:$MGMTSERVER:8250,connect-timeout=3 2>&1)
+if [ $? -eq 0 ]
+then
+ echo "Good: Can connect to management server port 8250"
+else
+ echo "ERROR: Cannot connect to $MGMTSERVER port 8250"
+ echo $socatout
+ exit 4
+fi
+
+
+# check for the java process running
+echo ================================================
+ps -eaf|grep -v grep|grep java 1> /dev/null 2>&1
+if [ $? -eq 0 ]
+then
+ echo "Good: Java process is running"
+else
+ echo "ERROR: Java process not running. Try restarting the SSVM."
+ exit 3
+fi
+
+echo ================================================
+echo Tests Complete. Look for ERROR or WARNING above.
+
+exit 0
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/src/org/apache/cloudstack/storage/resource/CifsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/CifsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/CifsSecondaryStorageResource.java
new file mode 100755
index 0000000..de4cfe0
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/CifsSecondaryStorageResource.java
@@ -0,0 +1,755 @@
+// 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.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.template.DownloadManager;
+import org.apache.cloudstack.storage.template.DownloadManagerImpl;
+import org.apache.cloudstack.storage.template.UploadManager;
+import org.apache.cloudstack.storage.template.UploadManagerImpl;
+import org.apache.log4j.Logger;
+
+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.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.SecStorageSetupCommand;
+import com.cloud.agent.api.SecStorageVMSetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteTemplateCommand;
+import com.cloud.agent.api.storage.DownloadCommand;
+import com.cloud.agent.api.storage.DownloadProgressCommand;
+import com.cloud.agent.api.storage.UploadCommand;
+import com.cloud.agent.api.storage.ssCommand;
+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.TemplateInfo;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.net.NfsUtils;
+import com.cloud.utils.script.Script;
+
+/**
+ * Implementation of Secondary Storage Resource to handle CIFS share
+ *
+ * TODOD: After mount rest of the functionality should be similar to NfsSecondaryStroage.
+ * Move common functionality of NFS and CIFS secondary storage resource class to base class
+ **/
+
+public class CifsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
+ private static final Logger s_logger = Logger.getLogger(CifsSecondaryStorageResource.class);
+ int _timeout;
+
+ String _instance;
+ String _parent;
+
+ String _dc;
+ String _pod;
+ String _guid;
+ String _nfsPath;
+ String _mountParent;
+ Map<String, Object> _params;
+ StorageLayer _storage;
+ boolean _inSystemVM = false;
+ boolean _sslCopy = false;
+
+ Random _rand = new Random(System.currentTimeMillis());
+
+ DownloadManager _dlMgr;
+ 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;
+
+ @Override
+ public void disconnected() {
+ if (_parent != null && !_inSystemVM) {
+ Script script = new Script(!_inSystemVM, "umount", _timeout, s_logger);
+ script.add(_parent);
+ script.execute();
+
+ File file = new File(_parent);
+ file.delete();
+ }
+ }
+
+ @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 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 DeleteTemplateCommand) {
+ return execute((DeleteTemplateCommand) cmd);
+ } 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 new Answer(cmd, true, "success");
+ } else {
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+ }
+
+ 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()) {
+ 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 allowOutgoingOnPrivate(String destCidr) {
+
+ 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);
+ if (result !=null)
+ success = false;
+
+ return new Answer(cmd, success, result);
+ }
+
+ protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
+ final long usedSize = getUsedSize();
+ final long totalSize = getTotalSize();
+ if (usedSize == -1 || totalSize == -1) {
+ return new GetStorageStatsAnswer(cmd, "Unable to get storage stats");
+ } else {
+ return new GetStorageStatsAnswer(cmd, totalSize, usedSize) ;
+ }
+ }
+
+ @Override
+ public String getRootDir(ssCommand cmd){
+ return null;
+ }
+
+ protected Answer execute(final DeleteTemplateCommand cmd) {
+ String relativeTemplatePath = cmd.getTemplatePath();
+ String parent = _parent;
+
+ if (relativeTemplatePath.startsWith(File.separator)) {
+ relativeTemplatePath = relativeTemplatePath.substring(1);
+ }
+
+ if (!parent.endsWith(File.separator)) {
+ parent += File.separator;
+ }
+ String absoluteTemplatePath = parent + relativeTemplatePath;
+ File tmpltParent = new File(absoluteTemplatePath).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;
+ }
+ 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);
+ }
+
+ protected long getUsedSize() {
+ return _storage.getUsedSpace(_parent);
+ }
+
+ protected long getTotalSize() {
+ return _storage.getTotalSpace(_parent);
+ }
+
+ 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() {
+ return Host.Type.SecondaryStorage;
+ }
+
+ @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");
+ if (_eth1ip != null) { //can only happen inside service vm
+ params.put("private.network.device", "eth1");
+ } else {
+ s_logger.warn("Wait, what's going on? eth1ip is null!!");
+ }
+ 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");
+
+ 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);
+ 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)ComponentContext.inject(clazz);
+ _storage.configure("StorageLayer", params);
+ } catch (ClassNotFoundException e) {
+ throw new ConfigurationException("Unable to find class " + value);
+ }
+ }
+ _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);
+ }
+
+ _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");
+
+ _mountParent = (String)params.get("mount.parent");
+ if (_mountParent == null) {
+ _mountParent = File.separator + "mnt";
+ }
+
+ if (_instance != null) {
+ _mountParent = _mountParent + File.separator + _instance;
+ }
+
+ _nfsPath = (String)params.get("mount.path");
+ if (_nfsPath == null) {
+ throw new ConfigurationException("Unable to find mount.path");
+ }
+
+
+
+ String inSystemVM = (String)params.get("secondary.storage.vm");
+ if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
+ _inSystemVM = true;
+ _localgw = (String)params.get("localgw");
+ if (_localgw != null) { //can only happen inside service vm
+ _eth1mask = (String)params.get("eth1mask");
+ String internalDns1 = (String)params.get("dns1");
+ String internalDns2 = (String)params.get("dns2");
+
+ if (internalDns1 == null) {
+ s_logger.warn("No DNS entry found during configuration of NfsSecondaryStorage");
+ } else {
+ addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns1);
+ }
+
+ String mgmtHost = (String)params.get("host");
+ String nfsHost = NfsUtils.getHostPart(_nfsPath);
+ if (nfsHost == null) {
+ s_logger.error("Invalid or corrupt nfs url " + _nfsPath);
+ throw new CloudRuntimeException("Unable to determine host part of nfs path");
+ }
+ try {
+ InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
+ nfsHost = nfsHostAddr.getHostAddress();
+ } catch (UnknownHostException uhe) {
+ s_logger.error("Unable to resolve nfs host " + nfsHost);
+ throw new CloudRuntimeException("Unable to resolve nfs host to an ip address " + nfsHost);
+ }
+ addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, nfsHost);
+ addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost);
+ if (internalDns2 != null) {
+ addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns2);
+ }
+
+ }
+ String useSsl = (String)params.get("sslcopy");
+ if (useSsl != null) {
+ _sslCopy = Boolean.parseBoolean(useSsl);
+ if (_sslCopy) {
+ configureSSL();
+ }
+ }
+ startAdditionalServices();
+ _params.put("install.numthreads", "50");
+ _params.put("secondary.storage.vm", "true");
+ }
+ _parent = mount(_nfsPath, _mountParent);
+ if (_parent == null) {
+ throw new ConfigurationException("Unable to create mount point");
+ }
+
+
+ s_logger.info("Mount point established at " + _parent);
+
+ try {
+ _params.put("template.parent", _parent);
+ _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;
+ }
+
+ private void startAdditionalServices() {
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("if [ -f /etc/init.d/ssh ]; then service ssh restart; else service sshd restart; fi ");
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in starting sshd service err=" + result );
+ }
+ command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("iptables -I INPUT -i eth1 -p tcp -m state --state NEW -m tcp --dport 3922 -j ACCEPT");
+ result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in opening up ssh port err=" + result );
+ }
+ }
+
+ private void addRouteToInternalIpOrCidr(String localgw, String eth1ip, String eth1mask, String destIpOrCidr) {
+ s_logger.debug("addRouteToInternalIp: localgw=" + localgw + ", eth1ip=" + eth1ip + ", eth1mask=" + eth1mask + ",destIp=" + destIpOrCidr);
+ if (destIpOrCidr == null) {
+ s_logger.debug("addRouteToInternalIp: destIp is null");
+ return;
+ }
+ if (!NetUtils.isValidIp(destIpOrCidr) && !NetUtils.isValidCIDR(destIpOrCidr)){
+ s_logger.warn(" destIp is not a valid ip address or cidr destIp=" + destIpOrCidr);
+ return;
+ }
+ boolean inSameSubnet = false;
+ if (NetUtils.isValidIp(destIpOrCidr)) {
+ if (eth1ip != null && eth1mask != null) {
+ inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask);
+ } else {
+ s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + ", _eth1mask=" + eth1mask);
+ }
+ } else {
+ inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask));
+ }
+ if (inSameSubnet) {
+ s_logger.debug("addRouteToInternalIp: dest ip " + destIpOrCidr + " is in the same subnet as eth1 ip " + eth1ip);
+ return;
+ }
+ Script command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("ip route delete " + destIpOrCidr);
+ command.execute();
+ command = new Script("/bin/bash", s_logger);
+ command.add("-c");
+ command.add("ip route add " + destIpOrCidr + " via " + localgw);
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Error in configuring route to internal ip err=" + result );
+ } else {
+ s_logger.debug("addRouteToInternalIp: added route to internal ip=" + destIpOrCidr + " via " + localgw);
+ }
+ }
+
+ private void configureSSL() {
+ Script command = new Script(_configSslScr);
+ command.add(_publicIp);
+ command.add(_hostname);
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Unable to configure httpd to use ssl");
+ }
+ }
+
+ private String configureAuth(String user, String passwd) {
+ Script command = new Script(_configAuthScr);
+ command.add(user);
+ command.add(passwd);
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Unable to configure httpd to use auth");
+ }
+ return result;
+ }
+
+ private String configureIpFirewall(List<String> ipList){
+ Script command = new Script(_configIpFirewallScr);
+ for (String ip : ipList){
+ command.add(ip);
+ }
+
+ String result = command.execute();
+ if (result != null) {
+ s_logger.warn("Unable to configure firewall for command : " +command);
+ }
+ return result;
+ }
+
+ protected String mount(String path, String parent) {
+ String mountPoint = null;
+ for (int i = 0; i < 10; i++) {
+ String mntPt = parent + File.separator + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE));
+ File file = new File(mntPt);
+ if (!file.exists()) {
+ if (_storage.mkdir(mntPt)) {
+ mountPoint = mntPt;
+ break;
+ }
+ }
+ s_logger.debug("Unable to create mount: " + mntPt);
+ }
+
+ if (mountPoint == null) {
+ s_logger.warn("Unable to create a mount point");
+ return null;
+ }
+
+ Script script = null;
+ String result = null;
+ script = new Script(!_inSystemVM, "umount", _timeout, s_logger);
+ script.add(path);
+ result = script.execute();
+
+ if( _parent != null ) {
+ script = new Script("rmdir", _timeout, s_logger);
+ script.add(_parent);
+ result = script.execute();
+ }
+
+ Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
+ command.add("-t", "cifs");
+ if (_inSystemVM) {
+ //Fedora Core 12 errors out with any -o option executed from java
+ //command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0");
+ }
+ String tok[] = path.split(":");
+ //command.add(path);
+ command.add("//"+tok[0]+tok[1]);
+ command.add(mountPoint);
+ result = command.execute();
+ if (result != null) {
+ s_logger.warn("Unable to mount " + path + " due to " + result);
+ File file = new File(mountPoint);
+ if (file.exists())
+ file.delete();
+ return null;
+ }
+
+
+
+ // XXX: Adding the check for creation of snapshots dir here. Might have to move it somewhere more logical later.
+ if (!checkForSnapshotsDir(mountPoint)) {
+ return null;
+ }
+
+ // Create the volumes dir
+ if (!checkForVolumesDir(mountPoint)) {
+ return null;
+ }
+
+ return mountPoint;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public StartupCommand[] initialize() {
+ /*disconnected();
+
+ _parent = mount(_nfsPath, _mountParent);
+
+ if( _parent == null ) {
+ s_logger.warn("Unable to mount the nfs server");
+ return null;
+ }
+
+ try {
+ _params.put("template.parent", _parent);
+ _params.put(StorageLayer.InstanceConfigKey, _storage);
+ _dlMgr = new DownloadManagerImpl();
+ _dlMgr.configure("DownloadManager", _params);
+ } catch (ConfigurationException e) {
+ s_logger.warn("Caught problem while configuring folers", e);
+ return null;
+ }*/
+
+ final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.NetworkFilesystem, getTotalSize(), new HashMap<String, TemplateInfo>());
+
+ cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE);
+ cmd.setIqn(null);
+
+ fillNetworkInformation(cmd);
+ cmd.setDataCenter(_dc);
+ cmd.setPod(_pod);
+ cmd.setGuid(_guid);
+ cmd.setName(_guid);
+ cmd.setVersion(NfsSecondaryStorageResource.class.getPackage().getImplementationVersion());
+ cmd.getHostDetails().put("mount.parent", _mountParent);
+ cmd.getHostDetails().put("mount.path", _nfsPath);
+ String tok[] = _nfsPath.split(":");
+ cmd.setNfsShare("nfs://" + tok[0] + tok[1]);
+ if (cmd.getHostDetails().get("orig.url") == null) {
+ if (tok.length != 2) {
+ throw new CloudRuntimeException("Not valid NFS path" + _nfsPath);
+ }
+ String nfsUrl = "nfs://" + tok[0] + tok[1];
+ cmd.getHostDetails().put("orig.url", nfsUrl);
+ }
+ InetAddress addr;
+ try {
+ addr = InetAddress.getByName(tok[0]);
+ cmd.setPrivateIpAddress(addr.getHostAddress());
+ } catch (UnknownHostException e) {
+ cmd.setPrivateIpAddress(tok[0]);
+ }
+ return new StartupCommand [] {cmd};
+ }
+
+ protected boolean checkForSnapshotsDir(String mountPoint) {
+ String snapshotsDirLocation = mountPoint + File.separator + "snapshots";
+ return createDir("snapshots", snapshotsDirLocation, mountPoint);
+ }
+
+ protected boolean checkForVolumesDir(String mountPoint) {
+ String volumesDirLocation = mountPoint + "/" + "volumes";
+ return createDir("volumes", volumesDirLocation, mountPoint);
+ }
+
+ protected boolean createDir(String dirName, String dirLocation, String mountPoint) {
+ boolean dirExists = false;
+
+ File dir = new File(dirLocation);
+ if (dir.exists()) {
+ if (dir.isDirectory()) {
+ s_logger.debug(dirName + " already exists on secondary storage, and is mounted at " + mountPoint);
+ dirExists = true;
+ } else {
+ if (dir.delete() && _storage.mkdir(dirLocation)) {
+ dirExists = true;
+ }
+ }
+ } else if (_storage.mkdir(dirLocation)) {
+ dirExists = true;
+ }
+
+ if (dirExists) {
+ s_logger.info(dirName + " directory created/exists on Secondary Storage.");
+ } else {
+ s_logger.info(dirName + " directory does not exist on Secondary Storage.");
+ }
+
+ return dirExists;
+ }
+
+ @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
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/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
new file mode 100644
index 0000000..b904254
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
@@ -0,0 +1,246 @@
+// 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.cloudstack.storage.template.DownloadManager;
+import org.apache.cloudstack.storage.template.DownloadManagerImpl;
+import org.apache.log4j.Logger;
+
+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.DownloadCommand;
+import com.cloud.agent.api.storage.DownloadProgressCommand;
+import com.cloud.agent.api.storage.ListTemplateAnswer;
+import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.agent.api.storage.ssCommand;
+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.TemplateInfo;
+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(ssCommand cmd){
+ 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, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
+ return new ListTemplateAnswer(cmd.getSecUrl(), 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
+
+ }
+}
[02/19] QuickCloud: Enable secondary storage daemon to run outside
the system vm
Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/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
new file mode 100755
index 0000000..a9d23cb
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
@@ -0,0 +1,1074 @@
+// 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.cloudstack.storage.resource.SecondaryStorageResource;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.DownloadCommand;
+import com.cloud.agent.api.storage.DownloadCommand.Proxy;
+import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
+import com.cloud.agent.api.storage.DownloadProgressCommand;
+import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
+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.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.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.TemplateInfo;
+import com.cloud.storage.template.TemplateLocation;
+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 jobId;
+ private final String tmpltName;
+ private final boolean hvm;
+ private final ImageFormat format;
+ private String tmpltPath;
+ private final String description;
+ private String checksum;
+ private final Long accountId;
+ 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.jobId = jobId;
+ this.tmpltName = tmpltName;
+ this.format = format;
+ this.hvm = hvm;
+ this.accountId = accountId;
+ this.description = descr;
+ this.checksum = cksum;
+ this.installPathPrefix = installPathPrefix;
+ this.templatesize = 0;
+ this.id = id;
+ this.resourceType = resourceType;
+ }
+
+ public TemplateDownloader getTd() {
+ return td;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getChecksum() {
+ return checksum;
+ }
+
+ public TemplateDownloader getTemplateDownloader() {
+ return td;
+ }
+
+ public String getJobId() {
+ return jobId;
+ }
+
+ public String getTmpltName() {
+ return tmpltName;
+ }
+
+ public ImageFormat getFormat() {
+ return format;
+ }
+
+ public boolean isHvm() {
+ return hvm;
+ }
+
+ public Long getAccountId() {
+ return accountId;
+ }
+
+ 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 List<Processor> processors;
+
+ 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;
+ private boolean _sslCopy;
+
+ /**
+ * 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:
+ 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()));
+ }
+ 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 = null;
+ ResourceType resourceType = dnld.getResourceType();
+
+ // once template path is set, remove the parent dir so that the template is installed with a relative path
+ String finalResourcePath = "";
+ if (resourceType == ResourceType.TEMPLATE){
+ finalResourcePath += _templateDir + File.separator + dnld.getAccountId() + File.separator + dnld.getId() + File.separator;
+ resourcePath = dnld.getInstallPathPrefix() + dnld.getAccountId() + File.separator + dnld.getId() + File.separator;// dnld.getTmpltName();
+ }else {
+ finalResourcePath += _volumeDir + File.separator + dnld.getId() + File.separator;
+ resourcePath = dnld.getInstallPathPrefix() + dnld.getId() + File.separator;// dnld.getTmpltName();
+ }
+
+ _storage.mkdirs(resourcePath);
+ dnld.setTmpltPath(finalResourcePath);
+
+ 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();
+ }
+
+ String templateFilename = templateName + "." + extension;
+ dnld.setTmpltPath(finalResourcePath + "/" + templateFilename);
+ scr.add("-n", templateFilename);
+
+ scr.add("-t", resourcePath);
+ scr.add("-f", td.getDownloadLocalPath());
+ 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 downloadPublicTemplate(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();
+ String tmpDir = "";
+ if(resourceType == ResourceType.TEMPLATE){
+ tmpDir = installPathPrefix + File.separator + accountId + File.separator + id;
+ }else {
+ tmpDir = installPathPrefix + File.separator + id;
+ }
+
+ 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")) {
+ 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);
+ }
+ DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType);
+ 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);
+ }
+
+ String installPathPrefix = null;
+ if (ResourceType.TEMPLATE == resourceType){
+ installPathPrefix = resource.getRootDir(cmd) + File.separator + _templateDir;
+ }else {
+ installPathPrefix = resource.getRootDir(cmd) + File.separator + _volumeDir;
+ }
+
+ String user = null;
+ String password = null;
+ if (cmd.getAuth() != null) {
+ user = cmd.getAuth().getUserName();
+ password = new String(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 = downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), installPathPrefix, 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", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR.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 String createTempDir(File rootDir, String name) throws IOException {
+
+ File f = File.createTempFile(name, "", rootDir);
+ f.delete();
+ f.mkdir();
+ _storage.setWorldReadableAndWriteable(f);
+ return f.getAbsolutePath();
+
+ }
+
+
+ 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, TemplateInfo> gatherTemplateInfo(String rootDir) {
+ Map<String, TemplateInfo> result = new HashMap<String, TemplateInfo>();
+ 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;
+ }
+
+ TemplateInfo tInfo = loc.getTemplateInfo();
+
+ if ((tInfo.getSize() == tInfo.getPhysicalSize())
+ && (tInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
+ try {
+ Processor processor = _processors.get("VMDK Processor");
+ VmdkProcessor vmdkProcessor = (VmdkProcessor)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, TemplateInfo> gatherVolumeInfo(String rootDir) {
+ Map<Long, TemplateInfo> result = new HashMap<Long, TemplateInfo>();
+ 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;
+ }
+
+ TemplateInfo vInfo = loc.getTemplateInfo();
+
+ if ((vInfo.getSize() == vInfo.getPhysicalSize())
+ && (vInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
+ try {
+ Processor processor = _processors.get("VMDK Processor");
+ VmdkProcessor vmdkProcessor = (VmdkProcessor)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;
+ }
+
+ private int deleteDownloadDirectories(File downloadPath, int deleted) {
+ try {
+ if (downloadPath.exists()) {
+ File[] files = downloadPath.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ if (files[i].isDirectory()) {
+ deleteDownloadDirectories(files[i], deleted);
+ files[i].delete();
+ deleted++;
+ } else {
+ files[i].delete();
+ deleted++;
+ }
+ }
+ }
+ } catch (Exception ex) {
+ s_logger.info("Failed to clean up template downloads directory " + ex.toString());
+ }
+ return deleted;
+ }
+
+ 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 useSsl = (String)params.get("sslcopy");
+ if (useSsl != null) {
+ _sslCopy = Boolean.parseBoolean(useSsl);
+
+ }
+ 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");
+ this.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 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/e7983b25/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
new file mode 100755
index 0000000..14de150
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManager.java
@@ -0,0 +1,87 @@
+// 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);
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/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
new file mode 100755
index 0000000..88623a9
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
@@ -0,0 +1,648 @@
+// 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.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.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+import org.apache.log4j.Logger;
+
+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.Processor;
+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;
+ private final String jobId;
+ private final String name;
+ private final ImageFormat format;
+ private String tmpltPath;
+ private String description;
+ private String checksum;
+ private Long accountId;
+ private String installPathPrefix;
+ private long templatesize;
+ private long id;
+
+ 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;
+ this.jobId = jobId;
+ this.name = name;
+ this.format = format;
+ this.accountId = accountId;
+ this.description = descr;
+ this.checksum = cksum;
+ this.installPathPrefix = installPathPrefix;
+ this.templatesize = 0;
+ this.id = id;
+ }
+
+ public TemplateUploader getTd() {
+ return tu;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getChecksum() {
+ return checksum;
+ }
+
+ public UploadJob(TemplateUploader td, String jobId, UploadCommand cmd) {
+ this.tu = td;
+ this.jobId = jobId;
+ this.name = cmd.getName();
+ this.format = cmd.getFormat();
+ }
+
+ public TemplateUploader getTemplateUploader() {
+ return tu;
+ }
+
+ public String getJobId() {
+ return jobId;
+ }
+
+ public String getTmpltName() {
+ return name;
+ }
+
+ public ImageFormat getFormat() {
+ return format;
+ }
+
+ public Long getAccountId() {
+ return accountId;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setTmpltPath(String tmpltPath) {
+ this.tmpltPath = tmpltPath;
+ }
+
+ public String getTmpltPath() {
+ return tmpltPath;
+ }
+
+ public String getInstallPathPrefix() {
+ return installPathPrefix;
+ }
+
+ public void cleanup() {
+ if (tu != null) {
+ String upldPath = tu.getUploadLocalPath();
+ if (upldPath != null) {
+ File f = new File(upldPath);
+ f.delete();
+ }
+ }
+ }
+
+ public void setTemplatesize(long templatesize) {
+ this.templatesize = templatesize;
+ }
+
+ public long getTemplatesize() {
+ return templatesize;
+ }
+ }
+ 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 List<Processor> _processors;
+ private String publicTemplateRepo;
+ private final String extractMountPoint = "/mnt/SecStorage/extractmnt";
+ private StorageLayer _storage;
+ private int installTimeoutPerGig;
+ private boolean _sslCopy;
+ 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();
+ if (jobId == null) {
+ return new UploadAnswer(null, 0, "Internal Error", com.cloud.storage.UploadVO.Status.UPLOAD_ERROR, "", "", 0);
+ }
+ 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){
+ UploadJob uj = jobs.get(jobId);
+ if (uj != null) {
+ return uj.getTemplatesize();
+ }
+ return 0;
+ }
+
+ @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 useSsl = (String)params.get("sslcopy");
+ if (useSsl != null) {
+ _sslCopy = Boolean.parseBoolean(useSsl);
+
+ }
+ 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.timeout.pergig");
+ this.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";
+ }
+
+ // 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/e7983b25/tools/devcloud/pom.xml
----------------------------------------------------------------------
diff --git a/tools/devcloud/pom.xml b/tools/devcloud/pom.xml
index d7b82c9..d32d84b 100644
--- a/tools/devcloud/pom.xml
+++ b/tools/devcloud/pom.xml
@@ -142,5 +142,38 @@
</plugins>
</build>
</profile>
+ <profile>
+ <id>quicksvr</id>
+ <activation>
+ <property>
+ <name>quicksvr</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.2.1</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <executable>python</executable>
+ <arguments>
+ <argument>../marvin/marvin/deployDataCenter.py</argument>
+ <argument>-i</argument>
+ <argument>quickcloud.cfg</argument>
+ </arguments>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
</profiles>
</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/tools/devcloud/quickcloud.cfg
----------------------------------------------------------------------
diff --git a/tools/devcloud/quickcloud.cfg b/tools/devcloud/quickcloud.cfg
new file mode 100644
index 0000000..0e1fb4f
--- /dev/null
+++ b/tools/devcloud/quickcloud.cfg
@@ -0,0 +1,120 @@
+# 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.
+#
+
+{
+ "zones": [
+ {
+ "name": "QuickCloud00",
+ "enabled" : "True",
+ "details" : [
+ {"key" : "enable.secstorage.vm", "value": "False"},
+ {"key" : "enable.consoleproxy.vm", "value": "False"}
+ ],
+ "physical_networks": [
+ {
+ "broadcastdomainrange": "Zone",
+ "name": "test-network",
+ "traffictypes": [
+ {
+ "typ": "Guest"
+ },
+ {
+ "typ": "Management"
+ }
+ ],
+ "providers": [
+ {
+ "broadcastdomainrange": "ZONE",
+ "name": "VirtualRouter"
+ },
+ {
+ "broadcastdomainrange": "Pod",
+ "name": "SecurityGroupProvider"
+ }
+ ]
+ }
+ ],
+ "dns2": "4.4.4.4",
+ "dns1": "8.8.8.8",
+ "securitygroupenabled": "true",
+ "localstorageenabled": "true",
+ "networktype": "Basic",
+ "pods": [
+ {
+ "endip": "192.168.56.220",
+ "name": "test00",
+ "startip": "192.168.56.200",
+ "guestIpRanges": [
+ {
+ "startip": "192.168.56.100",
+ "endip": "192.168.56.199",
+ "netmask": "255.255.255.0",
+ "gateway": "192.168.56.1"
+ }
+ ],
+ "netmask": "255.255.255.0",
+ "clusters": [
+ {
+ "clustername": "test000",
+ "hypervisor": "XenServer",
+ "hosts": [
+ {
+ "username": "root",
+ "url": "http://192.168.56.10/",
+ "password": "password"
+ }
+ ],
+ "clustertype": "CloudManaged"
+ }
+ ],
+ "gateway": "192.168.56.1"
+ }
+ ],
+ "internaldns1": "192.168.56.1",
+ "secondaryStorages": [
+ {
+ "url": "nfs://192.168.56.10:/opt/storage/secondary"
+ }
+ ]
+ }
+ ],
+ "logger": [
+ {
+ "name": "TestClient",
+ "file": "testclient.log"
+ },
+ {
+ "name": "TestCase",
+ "file": "testcase.log"
+ }
+ ],
+ "mgtSvr": [
+ {
+ "mgtSvrIp": "127.0.0.1",
+ "port": 8096
+ }
+ ],
+ "dbSvr":
+ {
+ "dbSvr": "127.0.0.1",
+ "port": 3306,
+ "user": "cloud",
+ "passwd": "cloud",
+ "db": "cloud"
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/tools/marvin/marvin/cloudstackConnection.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/cloudstackConnection.py b/tools/marvin/marvin/cloudstackConnection.py
index e8b861e..1caeef3 100644
--- a/tools/marvin/marvin/cloudstackConnection.py
+++ b/tools/marvin/marvin/cloudstackConnection.py
@@ -162,9 +162,9 @@ class cloudConnection(object):
else:
requests.pop(param)
i = 0
- for v in value:
- for key, val in v.iteritems():
- requests["%s[%d].%s"%(param,i,key)] = val
+ for val in value:
+ for k,v in val.iteritems():
+ requests["%s[%d].%s"%(param,i,k)] = v
i = i + 1
if self.logging is not None:
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/tools/marvin/marvin/deployDataCenter.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py
index cec920c..42bc5f9 100644
--- a/tools/marvin/marvin/deployDataCenter.py
+++ b/tools/marvin/marvin/deployDataCenter.py
@@ -270,6 +270,12 @@ class deployDataCenters():
zoneCmd.allocationstate = allocation_state
return self.apiClient.updateZone(zoneCmd)
+ def updateZoneDetails(self, zoneid, details):
+ zoneCmd = updateZone.updateZoneCmd()
+ zoneCmd.id = zoneid
+ zoneCmd.details = details
+ return self.apiClient.updateZone(zoneCmd)
+
def createZones(self, zones):
for zone in zones:
createzone = createZone.createZoneCmd()
@@ -320,7 +326,15 @@ class deployDataCenters():
zoneId)
self.createSecondaryStorages(zone.secondaryStorages, zoneId)
- self.enableZone(zoneId, "Enabled")
+
+ enabled = getattr(zone, 'enabled', 'True')
+ if enabled == 'True' or enabled == 'None':
+ self.enableZone(zoneId, "Enabled")
+ details = getattr(zone, 'details')
+ if details is not None:
+ det = [d.__dict__ for d in details]
+ self.updateZoneDetails(zoneId, det)
+
return
def isEipElbZone(self, zone):