This commit is contained in:
Prachi Damle 2012-09-06 11:23:50 -07:00
commit f57f96f7b7
55 changed files with 1704 additions and 1542 deletions

41
LICENSE
View File

@ -375,7 +375,7 @@ Within the deps/awsapi-lib directory
cloud-gson.jar http://code.google.com/p/google-gson/
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
$license.CopyrightNotice
from Json.simple Project http://code.google.com/p/json-simple/
json_simple-1.1.jar http://code.google.com/p/json-simple/source/checkout
@ -2368,7 +2368,8 @@ Within the target/jar directory
cloud-backport-util-concurrent-3.0.jar
licensed under the Apache License, Version 1.1 http://www.apache.org/licenses/LICENSE-1.1 (as follows)
Copyright © 2012 The Apache Software Foundation
/* ====================================================================
* The Apache Software License, Version 1.1
@ -2462,11 +2463,42 @@ Within the target/jar directory
cloud-google-gson-1.7.1.jar http://code.google.com/p/google-gson/
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
$license.CopyrightNotice
from Jetty Committers http://jetty.codehaus.org/jetty/
jetty-6.1.26.jar http://repo1.maven.org/maven2/org/mortbay/jetty/jetty/6.1.26/jetty-6.1.26-sources.jar
jetty-util-6.1.26.jar http://repo1.maven.org/maven2/org/mortbay/jetty/jetty-util/6.1.26/jetty-util-6.1.26-sources.jar
licensed under the BSD (3-clause) http://www.opensource.org/licenses/BSD-3-Clause (as follows)
Copyright © 2009, Caringo, Inc.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
from Caringo, Inc. http://www.caringo.com/
CAStorSDK.jar http://www.castor.org/download.html
licensed under the BSD (3-clause) http://www.opensource.org/licenses/BSD-3-Clause (as follows)
Copyright © 2002-2011 Atsuhiko Yamanaka, JCraft,Inc.
@ -4118,7 +4150,8 @@ Within the ui/lib/jquery-ui directory
Within the ui/lib/qunit directory
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
Copyright © 2012 John Resig, Jörn Zaefferer
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@ -1,370 +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.agent.vmdata;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.File;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.DefaultHandler;
import org.mortbay.jetty.handler.HandlerList;
import org.mortbay.jetty.handler.ResourceHandler;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.thread.QueuedThreadPool;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.network.Networks.TrafficType;
import com.cloud.storage.JavaStorageLayer;
import com.cloud.storage.StorageLayer;
import com.cloud.utils.net.NetUtils;
import com.cloud.utils.script.Script;
/**
* Serves vm data using embedded Jetty server
*
*/
@Local(value = { VmDataServer.class })
public class JettyVmDataServer implements VmDataServer {
private static final Logger s_logger = Logger
.getLogger(JettyVmDataServer.class);
public static final String USER_DATA = "user-data";
public static final String META_DATA = "meta-data";
protected String _vmDataDir;
protected Server _jetty;
protected String _hostIp;
protected Map<String, String> _ipVmMap = new HashMap<String, String>();
protected StorageLayer _fs = new JavaStorageLayer();
public class VmDataServlet extends HttpServlet {
private static final long serialVersionUID = -1640031398971742349L;
JettyVmDataServer _vmDataServer;
String _dataType; // userdata or meta-data
public VmDataServlet(JettyVmDataServer dataServer, String dataType) {
this._vmDataServer = dataServer;
this._dataType = dataType;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
int port = req.getServerPort();
if (port != 80 && port != 8000) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND,
"Request not understood");
return;
}
if (_dataType.equalsIgnoreCase(USER_DATA)) {
handleUserData(req, resp);
} else if (_dataType.equalsIgnoreCase(META_DATA)) {
handleMetaData(req, resp);
}
}
protected void handleUserData(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
String metadataItem = req.getPathInfo();
String requester = req.getRemoteAddr();
resp.setContentType("text/html");
resp.setStatus(HttpServletResponse.SC_OK);
String data = null;
if (metadataItem != null) {
String[] path = metadataItem.split("/");
if (path.length > 1) {
metadataItem = path[1];
}
}
if (metadataItem != null)
data = _vmDataServer.getVmDataItem(requester, metadataItem);
if (data != null) {
resp.getWriter().print(data);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
resp.sendError(HttpServletResponse.SC_NOT_FOUND,
"Request not found");
}
}
protected void handleMetaData(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
String metadataItem = req.getPathInfo();
String requester = req.getRemoteAddr();
resp.setContentType("text/html");
resp.setStatus(HttpServletResponse.SC_OK);
String metaData = _vmDataServer.getVmDataItem(requester,
metadataItem);
if (metaData != null) {
resp.getWriter().print(
_vmDataServer.getVmDataItem(requester, metadataItem));
} else {
resp.sendError(HttpServletResponse.SC_NOT_FOUND,
"Request not found");
}
}
}
@Override
public boolean configure(String name, Map<String, Object> params)
throws ConfigurationException {
boolean success = true;
try {
int vmDataPort = 80;
int fileservingPort = 8000;
_vmDataDir = (String) params.get("vm.data.dir");
String port = (String) params.get("vm.data.port");
if (port != null) {
vmDataPort = Integer.parseInt(port);
}
port = (String) params.get("file.server.port");
if (port != null) {
fileservingPort = Integer.parseInt(port);
}
_hostIp = (String) params.get("host.ip");
if (_vmDataDir == null) {
_vmDataDir = "/var/www/html";
}
success = _fs.mkdirs(_vmDataDir);
success = success && buildIpVmMap();
if (success) {
setupJetty(vmDataPort, fileservingPort);
}
} catch (Exception e) {
s_logger.warn("Failed to configure jetty", e);
throw new ConfigurationException("Failed to configure jetty!!");
}
return success;
}
protected boolean buildIpVmMap() {
String[] dirs = _fs.listFiles(_vmDataDir);
for (String dir : dirs) {
String[] path = dir.split("/");
String vm = path[path.length - 1];
if (vm.startsWith("i-")) {
String[] dataFiles = _fs.listFiles(dir);
for (String dfile : dataFiles) {
String path2[] = dfile.split("/");
String ipv4file = path2[path2.length - 1];
if (ipv4file.equalsIgnoreCase("local-ipv4")) {
try {
BufferedReader input = new BufferedReader(
new FileReader(dfile));
String line = null;
while ((line = input.readLine()) != null) {
if (NetUtils.isValidIp(line)) {
_ipVmMap.put(line, vm);
s_logger.info("Found ip " + line
+ " for vm " + vm);
} else {
s_logger.info("Invalid ip " + line
+ " for vm " + vm);
}
}
} catch (FileNotFoundException e) {
s_logger.warn("Failed to find file " + dfile);
} catch (IOException e) {
s_logger.warn("Failed to get ip address of " + vm);
}
}
}
}
}
return true;
}
public String getVmDataItem(String requester, String dataItem) {
String vmName = _ipVmMap.get(requester);
if (vmName == null) {
return null;
}
String vmDataFile = _vmDataDir + File.separator + vmName
+ File.separator + dataItem;
try {
BufferedReader input = new BufferedReader(
new FileReader(vmDataFile));
StringBuilder result = new StringBuilder();
String line = null;
while ((line = input.readLine()) != null) {
result.append(line);
}
input.close();
return result.toString();
} catch (FileNotFoundException e) {
s_logger.warn("Failed to find requested file " + vmDataFile);
return null;
} catch (IOException e) {
s_logger.warn("Failed to read requested file " + vmDataFile);
return null;
}
}
private void setupJetty(int vmDataPort, int fileservingPort)
throws Exception {
_jetty = new Server();
SelectChannelConnector connector0 = new SelectChannelConnector();
connector0.setHost(_hostIp);
connector0.setPort(fileservingPort);
connector0.setMaxIdleTime(30000);
connector0.setRequestBufferSize(8192);
SelectChannelConnector connector1 = new SelectChannelConnector();
connector1.setHost(_hostIp);
connector1.setPort(vmDataPort);
connector1.setThreadPool(new QueuedThreadPool(5));
connector1.setMaxIdleTime(30000);
connector1.setRequestBufferSize(8192);
_jetty.setConnectors(new Connector[] { connector0, connector1 });
Context root = new Context(_jetty, "/latest", Context.SESSIONS);
root.setResourceBase(_vmDataDir);
root.addServlet(new ServletHolder(new VmDataServlet(this, USER_DATA)),
"/*");
ResourceHandler resource_handler = new ResourceHandler();
resource_handler.setResourceBase("/var/lib/images/");
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { root, resource_handler,
new DefaultHandler() });
_jetty.setHandler(handlers);
_jetty.start();
// _jetty.join();
}
@Override
public boolean start() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean stop() {
return true;
}
@Override
public String getName() {
return "JettyVmDataServer";
}
@Override
public Answer handleVmDataCommand(VmDataCommand cmd) {
String vmDataDir = _vmDataDir + File.separator + cmd.getVmName();
Script.runSimpleBashScript("rm -rf " + vmDataDir);
_fs.mkdirs(vmDataDir);
for (String[] item : cmd.getVmData()) {
try {
_fs.create(vmDataDir, item[1]);
String vmDataFile = vmDataDir + File.separator + item[1];
byte[] data;
if (item[2] != null) {
if (item[1].equals("user-data")) {
data = Base64.decodeBase64(item[2]);
} else {
data = item[2].getBytes();
}
if (data != null && data.length > 0) {
FileOutputStream writer = new FileOutputStream(
vmDataFile);
writer.write(data);
writer.close();
}
}
} catch (IOException e) {
s_logger.warn("Failed to write vm data item " + item[1], e);
return new Answer(cmd, false, "Failed to write vm data item "
+ item[1]);
}
}
return new Answer(cmd);
}
@Override
public void handleVmStarted(VirtualMachineTO vm) {
for (NicTO nic : vm.getNics()) {
if (nic.getType() == TrafficType.Guest) {
if (nic.getIp() != null) {
String ipv4File = _vmDataDir + File.separator
+ vm.getName() + File.separator + "local-ipv4";
try {
_fs.create(_vmDataDir + File.separator + vm.getName(),
"local-ipv4");
BufferedWriter writer = new BufferedWriter(
new FileWriter(ipv4File));
writer.write(nic.getIp());
_ipVmMap.put(nic.getIp(), vm.getName());
writer.close();
} catch (IOException e) {
s_logger.warn(
"Failed to create or write to local-ipv4 file "
+ ipv4File, e);
}
}
}
}
}
@Override
public void handleVmStopped(String vmName) {
String vmDataDir = _vmDataDir + File.separator + vmName;
Script.runSimpleBashScript("rm -rf " + vmDataDir);
}
}

View File

@ -17,6 +17,8 @@
package com.cloud.storage;
public interface GuestOsCategory {
// Used by OS preference, 'None' for no OS preference
public static final String CATEGORY_NONE ="None";
long getId();
String getName();

View File

@ -94,6 +94,11 @@
<artifactId>jasypt</artifactId>
<version>${cs.jasypt.version}</version>
</dependency>
<dependency>
<groupId>com.caringo.client</groupId>
<artifactId>CAStorSDK</artifactId>
<version>1.3.1-CS40</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>

View File

@ -0,0 +1,479 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.bridge.io;
import java.util.Arrays;
import java.util.HashSet;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import org.apache.log4j.Logger;
import com.cloud.bridge.service.core.s3.S3BucketAdapter;
import com.cloud.bridge.service.core.s3.S3MultipartPart;
import com.cloud.bridge.service.exception.ConfigurationException;
import com.cloud.bridge.service.exception.FileNotExistException;
import com.cloud.bridge.service.exception.InternalErrorException;
import com.cloud.bridge.service.exception.OutOfStorageException;
import com.cloud.bridge.service.exception.UnsupportedException;
import com.cloud.bridge.util.StringHelper;
import com.cloud.bridge.util.OrderedPair;
import com.caringo.client.locate.Locator;
import com.caringo.client.locate.StaticLocator;
import com.caringo.client.locate.ZeroconfLocator;
import com.caringo.client.ResettableFileInputStream;
import com.caringo.client.ScspClient;
import com.caringo.client.ScspExecutionException;
import com.caringo.client.ScspHeaders;
import com.caringo.client.ScspQueryArgs;
import com.caringo.client.ScspResponse;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.Header;
/**
* Creates an SCSP client to a CAStor cluster, configured in "storage.root",
* and use CAStor as the back-end storage instead of a file system.
*/
public class S3CAStorBucketAdapter implements S3BucketAdapter {
protected final static Logger s_logger = Logger.getLogger(S3CAStorBucketAdapter.class);
private static final int HTTP_OK = 200;
private static final int HTTP_CREATED = 201;
private static final int HTTP_UNSUCCESSFUL = 300;
private static final int HTTP_PRECONDITION_FAILED = 412;
// For ScspClient
private static final int DEFAULT_SCSP_PORT = 80;
private static final int DEFAULT_MAX_POOL_SIZE = 50;
private static final int DEFAULT_MAX_RETRIES = 5;
private static final int CONNECTION_TIMEOUT = 60 * 1000; // Request activity timeout - 1 minute
private static final int CM_IDLE_TIMEOUT = 60 * 1000; // HttpConnectionManager idle timeout - 1 minute
private static final int LOCATOR_RETRY_TIMEOUT = 0; // StaticLocator pool retry timeout
private ScspClient _scspClient; // talks to CAStor cluster
private Locator _locator; // maintains list of CAStor nodes
private String _domain; // domain where all CloudStack streams will live
private synchronized ScspClient myClient(String mountedRoot) {
if (_scspClient!=null) {
return _scspClient;
}
// The castor cluster is specified either by listing the ip addresses of some nodes, or
// by specifying "zeroconf=" and the cluster's mdns name -- this is "cluster" in castor's node.cfg.
// The "domain" to store streams can be specified. If not specified, streams will be written
// without a "domain" query arg, so they will go into the castor default domain.
// The port is optional and must be at the end of the config string, defaults to 80.
// Examples: "castor 172.16.78.130 172.16.78.131 80", "castor 172.16.78.130 domain=mycluster.example.com",
// "castor zeroconf=mycluster.example.com domain=mycluster.example.com 80"
String[] cfg = mountedRoot.split(" ");
int numIPs = cfg.length-1;
String possiblePort = cfg[cfg.length-1];
int castorPort = DEFAULT_SCSP_PORT;
try {
castorPort = Integer.parseInt(possiblePort);
--numIPs;
} catch (NumberFormatException nfe) {
// okay, it's an ip address, not a port number
}
if (numIPs <= 0) {
throw new ConfigurationException("No CAStor nodes specified in '" + mountedRoot + "'");
}
HashSet<String> ips = new HashSet<String>();
String clusterName = null;
for ( int i = 0; i < numIPs; ++i ) {
String option = cfg[i+1]; // ip address or zeroconf=mycluster.example.com or domain=mydomain.example.com
if (option.toLowerCase().startsWith("zeroconf=")) {
String[] confStr = option.split("=");
if (confStr.length != 2) {
throw new ConfigurationException("Could not parse cluster name from '" + option + "'");
}
clusterName = confStr[1];
} else if (option.toLowerCase().startsWith("domain=")) {
String[] confStr = option.split("=");
if (confStr.length != 2) {
throw new ConfigurationException("Could not parse domain name from '" + option + "'");
}
_domain = confStr[1];
} else {
ips.add(option);
}
}
if (clusterName == null && ips.isEmpty()) {
throw new ConfigurationException("No CAStor nodes specified in '" + mountedRoot + "'");
}
String[] castorNodes = ips.toArray(new String[0]); // list of configured nodes
if (clusterName == null) {
try {
_locator = new StaticLocator(castorNodes, castorPort, LOCATOR_RETRY_TIMEOUT);
_locator.start();
} catch (IOException e) {
throw new ConfigurationException("Could not create CAStor static locator for '" +
Arrays.toString(castorNodes) + "'");
}
} else {
try {
clusterName = clusterName.replace(".", "_"); // workaround needed for CAStorSDK 1.3.1
_locator = new ZeroconfLocator(clusterName);
_locator.start();
} catch (IOException e) {
throw new ConfigurationException("Could not create CAStor zeroconf locator for '" + clusterName + "'");
}
}
try {
s_logger.info("CAStor client starting: " + (_domain==null ? "default domain" : "domain " + _domain) + " " + (clusterName==null ? Arrays.toString(castorNodes) : clusterName) + " :" + castorPort);
_scspClient = new ScspClient(_locator, castorPort, DEFAULT_MAX_POOL_SIZE, DEFAULT_MAX_RETRIES, CONNECTION_TIMEOUT, CM_IDLE_TIMEOUT);
_scspClient.start();
} catch (Exception e) {
s_logger.error("Unable to create CAStor client for '" + mountedRoot + "': " + e.getMessage(), e);
throw new ConfigurationException("Unable to create CAStor client for '" + mountedRoot + "': " + e);
}
return _scspClient;
}
private String castorURL(String mountedRoot, String bucket, String fileName) {
// TODO: Replace this method with access to ScspClient's Locator,
// or add read method that returns the body as an unread
// InputStream for use by loadObject() and loadObjectRange().
myClient(mountedRoot); // make sure castorNodes and castorPort initialized
InetSocketAddress nodeAddr = _locator.locate();
if (nodeAddr == null) {
throw new ConfigurationException("Unable to locate CAStor node with locator " + _locator);
}
InetAddress nodeInetAddr = nodeAddr.getAddress();
if (nodeInetAddr == null) {
_locator.foundDead(nodeAddr);
throw new ConfigurationException("Unable to resolve CAStor node name '" + nodeAddr.getHostName() +
"' to IP address");
}
return "http://" + nodeInetAddr.getHostAddress() + ":" + nodeAddr.getPort() + "/" + bucket + "/" + fileName +
(_domain==null ? "" : "?domain=" + _domain);
}
private ScspQueryArgs domainQueryArg() {
ScspQueryArgs qa = new ScspQueryArgs();
if (this._domain != null)
qa.setValue("domain", this._domain);
return qa;
}
public S3CAStorBucketAdapter() {
// TODO: is there any way to initialize CAStor client here, can it
// get to config?
}
@Override
public void createContainer(String mountedRoot, String bucket) {
try {
ScspResponse bwResponse = myClient(mountedRoot).write(bucket, new ByteArrayInputStream("".getBytes()), 0, domainQueryArg(), new ScspHeaders());
if (bwResponse.getHttpStatusCode() != HTTP_CREATED) {
if (bwResponse.getHttpStatusCode() == HTTP_PRECONDITION_FAILED)
s_logger.error("CAStor unable to create bucket " + bucket + " because domain " +
(this._domain==null ? "(default)" : this._domain) + " does not exist");
else
s_logger.error("CAStor unable to create bucket " + bucket + ": " + bwResponse.getHttpStatusCode());
throw new OutOfStorageException("CAStor unable to create bucket " + bucket + ": " +
bwResponse.getHttpStatusCode());
}
} catch (ScspExecutionException e) {
s_logger.error("CAStor unable to create bucket " + bucket, e);
throw new OutOfStorageException("CAStor unable to create bucket " + bucket + ": " + e.getMessage());
}
}
@Override
public void deleteContainer(String mountedRoot, String bucket) {
try {
ScspResponse bwResponse = myClient(mountedRoot).delete("", bucket, domainQueryArg(), new ScspHeaders());
if (bwResponse.getHttpStatusCode() >= HTTP_UNSUCCESSFUL) {
s_logger.error("CAStor unable to delete bucket " + bucket + ": " + bwResponse.getHttpStatusCode());
throw new OutOfStorageException("CAStor unable to delete bucket " + bucket + ": " +
bwResponse.getHttpStatusCode());
}
} catch (ScspExecutionException e) {
s_logger.error("CAStor unable to delete bucket " + bucket, e);
throw new OutOfStorageException("CAStor unable to delete bucket " + bucket + ": " + e.getMessage());
}
}
@Override
public String saveObject(InputStream is, String mountedRoot, String bucket, String fileName)
{
// TODO: Currently this writes the object to a temporary file,
// so that the MD5 can be computed and so that we have the
// stream length needed by this version of CAStor SDK. Will
// change to calculate MD5 while streaming to CAStor and to
// either pass Content-length to this method or use newer SDK
// that doesn't require it.
FileOutputStream fos = null;
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
s_logger.error("Unexpected exception " + e.getMessage(), e);
throw new InternalErrorException("Unable to get MD5 MessageDigest", e);
}
File spoolFile = null;
try {
spoolFile = File.createTempFile("castor", null);
} catch (IOException e) {
s_logger.error("Unexpected exception creating temporary CAStor spool file: " + e.getMessage(), e);
throw new InternalErrorException("Unable to create temporary CAStor spool file", e);
}
try {
String retVal;
int streamLen = 0;
try {
fos = new FileOutputStream(spoolFile);
byte[] buffer = new byte[4096];
int len = 0;
while( (len = is.read(buffer)) > 0) {
fos.write(buffer, 0, len);
streamLen = streamLen + len;
md5.update(buffer, 0, len);
}
//Convert MD5 digest to (lowercase) hex String
retVal = StringHelper.toHexString(md5.digest());
} catch(IOException e) {
s_logger.error("Unexpected exception " + e.getMessage(), e);
throw new OutOfStorageException(e);
} finally {
try {
if (null != fos)
fos.close();
} catch( Exception e ) {
s_logger.error("Can't close CAStor spool file " +
spoolFile.getAbsolutePath() + ": " + e.getMessage(), e);
throw new OutOfStorageException("Unable to close CAStor spool file: " + e.getMessage(), e);
}
}
try {
ScspResponse bwResponse =
myClient(mountedRoot).write(bucket + "/" + fileName,
new ResettableFileInputStream(spoolFile), streamLen,
domainQueryArg(), new ScspHeaders());
if (bwResponse.getHttpStatusCode() >= HTTP_UNSUCCESSFUL) {
s_logger.error("CAStor write responded with error " + bwResponse.getHttpStatusCode());
throw new OutOfStorageException("Unable to write object to CAStor " +
bucket + "/" + fileName + ": " + bwResponse.getHttpStatusCode());
}
} catch (ScspExecutionException e) {
s_logger.error("Unable to write object to CAStor " + bucket + "/" + fileName, e);
throw new OutOfStorageException("Unable to write object to CAStor " + bucket + "/" + fileName + ": " +
e.getMessage());
} catch (IOException ie) {
s_logger.error("Unable to write object to CAStor " + bucket + "/" + fileName, ie);
throw new OutOfStorageException("Unable to write object to CAStor " + bucket + "/" + fileName + ": " +
ie.getMessage());
}
return retVal;
} finally {
try {
if (!spoolFile.delete()) {
s_logger.error("Failed to delete CAStor spool file " + spoolFile.getAbsolutePath());
}
} catch (SecurityException e) {
s_logger.error("Unable to delete CAStor spool file " + spoolFile.getAbsolutePath(), e);
}
}
}
/**
* From a list of files (each being one part of the multipart upload), concatentate all files into a single
* object that can be accessed by normal S3 calls. This function could take a long time since a multipart is
* allowed to have upto 10,000 parts (each 5 gib long). Amazon defines that while this operation is in progress
* whitespace is sent back to the client inorder to keep the HTTP connection alive.
*
* @param mountedRoot - where both the source and dest buckets are located
* @param destBucket - resulting location of the concatenated objects
* @param fileName - resulting file name of the concatenated objects
* @param sourceBucket - special bucket used to save uploaded file parts
* @param parts - an array of file names in the sourceBucket
* @param client - if not null, then keep the servlet connection alive while this potentially long concatentation takes place
* @return OrderedPair with the first value the MD5 of the final object, and the second value the length of the final object
*/
@Override
public OrderedPair<String,Long> concatentateObjects(String mountedRoot, String destBucket, String fileName, String sourceBucket, S3MultipartPart[] parts, OutputStream client)
{
// TODO
throw new UnsupportedException("Multipart upload support not yet implemented in CAStor plugin");
/*
MessageDigest md5;
long totalLength = 0;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
s_logger.error("Unexpected exception " + e.getMessage(), e);
throw new InternalErrorException("Unable to get MD5 MessageDigest", e);
}
File file = new File(getBucketFolderDir(mountedRoot, destBucket) + File.separatorChar + fileName);
try {
// -> when versioning is off we need to rewrite the file contents
file.delete();
file.createNewFile();
final FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[4096];
// -> get the input stream for the next file part
for( int i=0; i < parts.length; i++ )
{
DataHandler nextPart = loadObject( mountedRoot, sourceBucket, parts[i].getPath());
InputStream is = nextPart.getInputStream();
int len = 0;
while( (len = is.read(buffer)) > 0) {
fos.write(buffer, 0, len);
md5.update(buffer, 0, len);
totalLength += len;
}
is.close();
// -> after each file write tell the client we are still here to keep connection alive
if (null != client) {
client.write( new String(" ").getBytes());
client.flush();
}
}
fos.close();
return new OrderedPair<String, Long>(StringHelper.toHexString(md5.digest()), new Long(totalLength));
//Create an ordered pair whose first element is the MD4 digest as a (lowercase) hex String
}
catch(IOException e) {
s_logger.error("concatentateObjects unexpected exception " + e.getMessage(), e);
throw new OutOfStorageException(e);
}
*/
}
@Override
public DataHandler loadObject(String mountedRoot, String bucket, String fileName) {
try {
return new DataHandler(new URL(castorURL(mountedRoot, bucket, fileName)));
} catch (MalformedURLException e) {
s_logger.error("Failed to loadObject from CAStor", e);
throw new FileNotExistException("Unable to load object from CAStor: " + e.getMessage());
}
}
@Override
public void deleteObject(String mountedRoot, String bucket, String fileName) {
String filePath = bucket + "/" + fileName;
try {
ScspResponse bwResponse = myClient(mountedRoot).delete("", filePath, domainQueryArg(), new ScspHeaders());
if (bwResponse.getHttpStatusCode() != HTTP_OK) {
s_logger.error("CAStor delete object responded with error " + bwResponse.getHttpStatusCode());
throw new OutOfStorageException("CAStor unable to delete object " + filePath + ": " +
bwResponse.getHttpStatusCode());
}
} catch (ScspExecutionException e) {
s_logger.error("CAStor unable to delete object " + filePath, e);
throw new OutOfStorageException("CAStor unable to delete object " + filePath + ": " + e.getMessage());
}
}
public class ScspDataSource implements DataSource {
GetMethod method;
public ScspDataSource(GetMethod m) {
method = m;
}
@Override
public String getContentType() {
Header h = method.getResponseHeader("Content-type");
return h==null ? null : h.getValue();
}
@Override
public InputStream getInputStream() throws IOException {
try {
return method.getResponseBodyAsStream();
} catch (Exception e) {
s_logger.error("CAStor loadObjectRange getInputStream error", e);
return null;
}
}
@Override
public String getName() {
assert(false);
return null;
}
@Override
public OutputStream getOutputStream() throws IOException {
assert(false);
return null;
}
}
@Override
public DataHandler loadObjectRange(String mountedRoot, String bucket, String fileName, long startPos, long endPos) {
try {
HttpClient httpClient = new HttpClient();
// Create a method instance.
GetMethod method = new GetMethod(castorURL(mountedRoot, bucket, fileName));
method.addRequestHeader("Range", "bytes=" + startPos + "-" + endPos);
int statusCode = httpClient.executeMethod(method);
if (statusCode < HTTP_OK || statusCode >= HTTP_UNSUCCESSFUL) {
s_logger.error("CAStor loadObjectRange response: "+ statusCode);
throw new FileNotExistException("CAStor loadObjectRange response: " + statusCode);
}
return new DataHandler(new ScspDataSource(method));
} catch (Exception e) {
s_logger.error("CAStor loadObjectRange failure", e);
throw new FileNotExistException("CAStor loadObjectRange failure: " + e);
}
}
@Override
public String getBucketFolderDir(String mountedRoot, String bucket) {
// This method shouldn't be needed and doesn't need to use
// mountedRoot (which is CAStor config values here), right?
String bucketFolder = getBucketFolderName(bucket);
return bucketFolder;
}
private String getBucketFolderName(String bucket) {
// temporary
String name = bucket.replace(' ', '_');
name = bucket.replace('\\', '-');
name = bucket.replace('/', '-');
return name;
}
}

View File

@ -24,9 +24,11 @@ public interface SHost {
public static final int STORAGE_HOST_TYPE_LOCAL = 0;
public static final int STORAGE_HOST_TYPE_NFS = 1;
public static final int STORAGE_HOST_TYPE_CASTOR = 2;
public static enum StorageHostType {
STORAGE_HOST_TYPE_LOCAL, //0
STORAGE_HOST_TYPE_NFS //1
STORAGE_HOST_TYPE_NFS, //1
STORAGE_HOST_TYPE_CASTOR //2
}
/* private Long id;

View File

@ -243,7 +243,13 @@ public class ServiceProvider {
//PersistContext.flush();
String localStorageRoot = properties.getProperty("storage.root");
if (localStorageRoot != null) setupLocalStorage(localStorageRoot);
if (localStorageRoot != null) {
if (localStorageRoot.toLowerCase().startsWith("castor")) {
setupCAStorStorage(localStorageRoot);
} else {
setupLocalStorage(localStorageRoot);
}
}
multipartDir = properties.getProperty("storage.multipartDir");
@ -318,7 +324,20 @@ public class ServiceProvider {
}
}
public void shutdown() {
private void setupCAStorStorage(String storageRoot) {
SHostVO shost = shostDao.getLocalStorageHost(mhost.getId(), storageRoot);
if(shost == null) {
shost = new SHostVO();
shost.setMhost(mhost);
shost.setMhostid(mhost.getId());
shost.setHostType(SHost.STORAGE_HOST_TYPE_CASTOR);
shost.setHost(NetHelper.getHostName());
shost.setExportRoot(storageRoot);
shostDao.persist(shost);
}
}
public void shutdown() {
timer.cancel();
if(logger.isInfoEnabled())

View File

@ -39,6 +39,7 @@ import org.apache.log4j.Logger;
import org.json.simple.parser.ParseException;
import com.cloud.bridge.io.S3FileSystemBucketAdapter;
import com.cloud.bridge.io.S3CAStorBucketAdapter;
import com.cloud.bridge.model.BucketPolicyVO;
import com.cloud.bridge.model.MHostMountVO;
import com.cloud.bridge.model.MHostVO;
@ -115,6 +116,7 @@ public class S3Engine {
public S3Engine() {
bucketAdapters.put(SHost.STORAGE_HOST_TYPE_LOCAL, new S3FileSystemBucketAdapter());
bucketAdapters.put(SHost.STORAGE_HOST_TYPE_CASTOR, new S3CAStorBucketAdapter());
}
@ -1398,6 +1400,10 @@ public class S3Engine {
return new OrderedPair<SHostVO, String>(shost, shost.getExportRoot());
}
if(shost.getHostType() == SHost.STORAGE_HOST_TYPE_CASTOR ) {
return new OrderedPair<SHostVO, String>(shost, shost.getExportRoot());
}
MHostMountVO mount = mountDao.getHostMount(ServiceProvider.getInstance().getManagementHostId(), shost.getId());
if(mount != null) {
return new OrderedPair<SHostVO, String>(shost, mount.getMountPath());

View File

@ -180,9 +180,9 @@
</path>
<target name="compile-plugins" description="Compile all of the jars corresponding to plugins" depends="compile-utils, compile-api, compile-core, compile-server, compile-hypervisors, compile-deployment-planners, compile-host-allocators, compile-network-elements, compile-user-authenticators, compile-storage-allocators, compile-file-systems "/>
<target name="compile-plugins" description="Compile all of the jars corresponding to plugins" depends="compile-utils, compile-api, compile-core, compile-server, compile-hypervisors, compile-deployment-planners, compile-host-allocators, compile-network-elements, compile-user-authenticators, compile-storage-allocators"/>
<target name="build-plugins" depends="build-hypervisors, build-network-elements, build-deployment-planners, build-host-allocators, build-storage-allocators, build-user-authenticators, build-file-systems" description="Builds all jar's for the plug-in's"/>
<target name="build-plugins" depends="build-hypervisors, build-network-elements, build-deployment-planners, build-host-allocators, build-storage-allocators, build-user-authenticators" description="Builds all jar's for the plug-in's"/>
<target name="clean-plugins" description="Clean all of the generated files by the plugins">
<delete file="${build.log}" />
@ -194,8 +194,8 @@
<!-- ===================== Hypervisors ========================= -->
<target name="compile-hypervisors" depends="compile-kvm, compile-ovm, compile-xen, compile-vmware" description="Compile all hypervisors"/>
<target name="build-hypervisors" depends="build-kvm, build-ovm, build-xen, build-vmware" description="Builds all hypervisors"/>
<target name="compile-hypervisors" depends="compile-ovm, compile-xen" description="Compile all hypervisors"/>
<target name="build-hypervisors" depends="build-ovm, build-xen " description="Builds all hypervisors"/>
<target name="compile-kvm" depends="-init, compile-core, compile-agent" description="Compile KVM">
<ant antfile="${base.dir}/plugins/hypervisors/kvm/build.xml" target="build"/>
@ -280,8 +280,8 @@
<!-- ===================== Network Elements ===================== -->
<target name="compile-network-elements" depends="compile-netscaler, compile-f5, compile-srx, compile-ovs, compile-elb, compile-nicira-nvp" description="Compile all network elements"/>
<target name="build-network-elements" depends="build-netscaler, build-f5, build-srx, build-ovs, build-elb, build-nicira-nvp" description="build all network elements"/>
<target name="compile-network-elements" depends="compile-ovs, compile-elb, compile-nicira-nvp" description="Compile all network elements"/>
<target name="build-network-elements" depends="build-ovs, build-elb, build-nicira-nvp" description="build all network elements"/>
<target name="compile-netscaler" depends="-init, compile-server" description="Compile NetScaler plugin">
<ant antfile="${base.dir}/plugins/network-elements/netscaler/build.xml" target="build"/>

View File

@ -204,7 +204,7 @@
<path refid="deps.classpath" />
<path refid="dist.classpath" />
</path>
<target name="compile-core" depends="-init, compile-utils, compile-api, compile-vmware-base" description="Compile the core business logic.">
<target name="compile-core" depends="-init, compile-utils, compile-api" description="Compile the core business logic.">
<compile-java jar.name="${core.jar}" top.dir="${core.dir}" classpath="core.classpath" />
</target>

View File

@ -73,6 +73,11 @@
<artifactId>cloud-plugin-hypervisor-ovm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-hypervisor-kvm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-storage-allocator-random</artifactId>
@ -99,43 +104,6 @@
<version>5.1.21</version>
<scope>runtime</scope>
</dependency>
<!-- Non-OSS deps -->
<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-plugin-network-srx</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-hypervisor-kvm</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-netapp</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-f5</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-netscaler</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>

View File

@ -114,7 +114,6 @@ under the License.
</adapters>
<adapters key="com.cloud.ha.Investigator">
<adapter name="SimpleInvestigator" class="com.cloud.ha.CheckOnAgentInvestigator"/>
<adapter name="VmwareInvestigator" class="com.cloud.ha.VmwareInvestigator"/>
<adapter name="XenServerInvestigator" class="com.cloud.ha.XenServerInvestigator"/>
<adapter name="PingInvestigator" class="com.cloud.ha.UserVmDomRInvestigator"/>
<adapter name="ManagementIPSysVMInvestigator" class="com.cloud.ha.ManagementIPSystemVMInvestigator"/>
@ -122,7 +121,6 @@ under the License.
<adapters key="com.cloud.ha.FenceBuilder">
<adapter name="XenServerFenceBuilder" class="com.cloud.ha.XenServerFencer"/>
<adapter name="KVMFenceBuilder" class="com.cloud.ha.KVMFencer"/>
<adapter name="VmwareFenceBuilder" class="com.cloud.ha.VmwareFencer"/>
<adapter name="OvmFenceBuilder" class="com.cloud.ovm.hypervisor.OvmFencer"/>
</adapters>
<adapters key="com.cloud.hypervisor.HypervisorGuru">
@ -133,7 +131,6 @@ under the License.
<adapter name="XCP Agent" class="com.cloud.hypervisor.xen.discoverer.XcpServerDiscoverer"/>
<adapter name="SecondaryStorage" class="com.cloud.storage.secondary.SecondaryStorageDiscoverer"/>
<adapter name="KVM Agent" class="com.cloud.hypervisor.kvm.discoverer.KvmServerDiscoverer"/>
<adapter name="VShpereServer" class="com.cloud.hypervisor.vmware.VmwareServerDiscoverer"/>
<adapter name="Bare Metal Agent" class="com.cloud.baremetal.BareMetalDiscoverer"/>
<adapter name="SCVMMServer" class="com.cloud.hypervisor.hyperv.HypervServerDiscoverer"/>
<adapter name="Ovm Discover" class="com.cloud.ovm.hypervisor.OvmDiscoverer" />
@ -153,15 +150,11 @@ under the License.
<adapter name="DomainChecker" class="com.cloud.acl.DomainChecker"/>
</adapters>
<adapters key="com.cloud.network.element.NetworkElement">
<adapter name="JuniperSRX" class="com.cloud.network.element.JuniperSRXExternalFirewallElement"/>
<adapter name="Netscaler" class="com.cloud.network.element.NetscalerElement"/>
<adapter name="F5BigIp" class="com.cloud.network.element.F5ExternalLoadBalancerElement"/>
<adapter name="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement"/>
<adapter name="Ovs" class="com.cloud.network.element.OvsElement"/>
<adapter name="ExternalDhcpServer" class="com.cloud.network.element.ExternalDhcpElement"/>
<adapter name="BareMetal" class="com.cloud.network.element.BareMetalElement"/>
<adapter name="SecurityGroupProvider" class="com.cloud.network.element.SecurityGroupElement"/>
<adapter name="CiscoNexus1000vVSM" class="com.cloud.network.element.CiscoNexusVSMElement"/>
<adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
<adapter name="NiciraNvp" class="com.cloud.network.element.NiciraNvpElement"/>
</adapters>
@ -171,7 +164,6 @@ under the License.
<adapters key="com.cloud.hypervisor.HypervisorGuru">
<adapter name="XenServerGuru" class="com.cloud.hypervisor.XenServerGuru"/>
<adapter name="KVMGuru" class="com.cloud.hypervisor.KVMGuru"/>
<adapter name="VMwareGuru" class="com.cloud.hypervisor.guru.VMwareGuru"/>
<adapter name="BareMetalGuru" class="com.cloud.baremetal.BareMetalGuru"/>
<adapter name="HypervGuru" class="com.cloud.hypervisor.guru.HypervGuru"/>
<adapter name="OvmGuru" class="com.cloud.ovm.hypervisor.OvmGuru" />
@ -179,25 +171,14 @@ under the License.
<adapters key="com.cloud.agent.StartupCommandProcessor">
<adapter name="BasicAgentAuthorizer" class="com.cloud.agent.manager.authn.impl.BasicAgentAuthManager"/>
</adapters>
<manager name="VmwareManager" key="com.cloud.hypervisor.vmware.manager.VmwareManager" class="com.cloud.hypervisor.vmware.manager.VmwareManagerImpl"/>
<manager name="OvsTunnelManager" key="com.cloud.network.ovs.OvsTunnelManager" class="com.cloud.network.ovs.OvsTunnelManagerImpl"/>
<manager name="ElasticLoadBalancerManager" key="com.cloud.network.lb.ElasticLoadBalancerManager" class="com.cloud.network.lb.ElasticLoadBalancerManagerImpl"/>
<pluggableservice name="VirtualRouterElementService" key="com.cloud.network.element.VirtualRouterElementService" class="com.cloud.network.element.VirtualRouterElement"/>
<pluggableservice name="NetscalerExternalLoadBalancerElementService" key="com.cloud.network.element.NetscalerLoadBalancerElementService" class="com.cloud.network.element.NetscalerElement"/>
<pluggableservice name="F5ExternalLoadBalancerElementService" key="com.cloud.network.element.F5ExternalLoadBalancerElementService" class="com.cloud.network.element.F5ExternalLoadBalancerElement"/>
<pluggableservice name="JuniperSRXFirewallElementService" key="com.cloud.network.element.JuniperSRXFirewallElementService" class="com.cloud.network.element.JuniperSRXExternalFirewallElement"/>
<pluggableservice name="CiscoNexusVSMElementService" key="com.cloud.network.element.CiscoNexusVSMElementService" class="com.cloud.network.element.CiscoNexusVSMElement"/>
<pluggableservice name="NiciraNvpElementService" key="com.cloud.network.element.NiciraNvpElementService" class="com.cloud.network.element.NiciraNvpElement"/>
<dao name="NetScalerPodDao" class="com.cloud.network.dao.NetScalerPodDaoImpl" singleton="false"/>
<dao name="CiscoNexusVSMDeviceDao" class="com.cloud.network.dao.CiscoNexusVSMDeviceDaoImpl" singleton="false"/>
<dao name="OvsTunnelInterfaceDao" class="com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl" singleton="false"/>
<dao name="OvsTunnelAccountDao" class="com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl" singleton="false"/>
<dao name="NiciraNvpDao" class="com.cloud.network.dao.NiciraNvpDaoImpl" singleton="false"/>
<dao name="NiciraNvpNicMappingDao" class="com.cloud.network.dao.NiciraNvpNicMappingDaoImpl" singleton="false"/>
<dao name="NetappPool" class="com.cloud.netapp.dao.PoolDaoImpl" singleton="false"/>
<dao name="NetappVolume" class="com.cloud.netapp.dao.VolumeDaoImpl" singleton="false"/>
<dao name="NetappLun" class="com.cloud.netapp.dao.LunDaoImpl" singleton="false"/>
<manager name="NetappManager" key="com.cloud.netapp.NetappManager" class="com.cloud.netapp.NetappManagerImpl"/>
<dao name="ElasticLbVmMapDao" class="com.cloud.network.lb.dao.ElasticLbVmMapDaoImpl" singleton="false"/>
</management-server>
@ -253,4 +234,4 @@ under the License.
<dao name="UserCredentialsDao" class="com.cloud.bridge.persist.dao.UserCredentialsDaoImpl" singleton="false"/>
</awsapi-s3server>
</components.xml>
</components.xml>

View File

@ -164,6 +164,7 @@ Requires: %{name}-utils = %{version}
Requires: apache-commons-dbcp
Requires: apache-commons-collections
Requires: jakarta-commons-httpclient
Requires: jakarta-taglibs-standard
Requires: mysql-connector-java
%endif
@ -432,24 +433,18 @@ fi
%files server
%defattr(0644,root,root,0755)
%{_javadir}/%{name}-server.jar
%{_javadir}/%{name}-vmware-base.jar
%{_javadir}/%{name}-ovm.jar
%{_javadir}/%{name}-dp-user-concentrated-pod.jar
%{_javadir}/%{name}-dp-user-dispersing.jar
%{_javadir}/%{name}-host-allocator-random.jar
%{_javadir}/%{name}-plugin-f5.jar
%{_javadir}/%{name}-plugin-netscaler.jar
%{_javadir}/%{name}-plugin-ovs.jar
%{_javadir}/%{name}-plugin-srx.jar
%{_javadir}/%{name}-storage-allocator-random.jar
%{_javadir}/%{name}-user-authenticator-ldap.jar
%{_javadir}/%{name}-user-authenticator-md5.jar
%{_javadir}/%{name}-user-authenticator-plaintext.jar
%{_javadir}/%{name}-vmware.jar
%{_javadir}/%{name}-xen.jar
%{_javadir}/%{name}-plugin-nicira-nvp.jar
%{_javadir}/%{name}-plugin-elb.jar
%{_javadir}/%{name}-plugin-netapp.jar
%{_javadir}/%{name}-plugin-nicira-nvp.jar
%config(noreplace) %{_sysconfdir}/%{name}/server/*
%files agent-scripts
@ -462,44 +457,35 @@ fi
%files deps
%defattr(0644,root,root,0755)
%{_javadir}/%{name}-commons-codec-1.5.jar
%{_javadir}/%{name}-commons-dbcp-1.4.jar
%{_javadir}/%{name}-commons-pool-1.5.6.jar
%{_javadir}/%{name}-commons-httpclient-3.1.jar
%{_javadir}/%{name}-google-gson-1.7.1.jar
%{_javadir}/%{name}-netscaler.jar
%{_javadir}/%{name}-netscaler-sdx.jar
%{_javadir}/%{name}-log4j-extras.jar
%{_javadir}/%{name}-backport-util-concurrent-3.0.jar
%{_javadir}/%{name}-plugin-hypervisor-kvm.jar
%{_javadir}/%{name}-ehcache.jar
%{_javadir}/%{name}-email.jar
%{_javadir}/%{name}-httpcore-4.0.jar
%{_javadir}/libvirt-0.4.8.jar
%{_javadir}/%{name}-log4j.jar
%{_javadir}/%{name}-trilead-ssh2-build213.jar
%{_javadir}/%{name}-cglib.jar
%{_javadir}/%{name}-xenserver-5.6.100-1.jar
%{_javadir}/%{name}-xmlrpc-common-3.*.jar
%{_javadir}/%{name}-xmlrpc-client-3.*.jar
%{_javadir}/%{name}-jstl-1.2.jar
%{_javadir}/jetty-6.1.26.jar
%{_javadir}/jetty-util-6.1.26.jar
%{_javadir}/%{name}-axis.jar
%{_javadir}/%{name}-commons-discovery.jar
%{_javadir}/%{name}-wsdl4j-1.6.2.jar
%{_javadir}/%{name}-bcprov-jdk16-1.45.jar
%{_javadir}/%{name}-jsch-0.1.42.jar
%{_javadir}/%{name}-iControl.jar
%{_javadir}/%{name}-manageontap.jar
%{_javadir}/vmware*.jar
%{_javadir}/%{name}-jnetpcap.jar
%{_javadir}/%{name}-junit.jar
%{_javadir}/%{name}-jasypt-1.8.jar
%{_javadir}/%{name}-commons-configuration-1.8.jar
%{_javadir}/%{name}-commons-lang-2.6.jar
%{_javadir}/%{name}-ejb-api-3.0.jar
%{_javadir}/%{name}-javax.persistence-2.0.0.jar
%{_javadir}/commons-codec-1.6.jar
%{_javadir}/commons-dbcp-1.4.jar
%{_javadir}/commons-pool-1.6.jar
%{_javadir}/gson-1.7.1.jar
%{_javadir}/backport-util-concurrent-3.1.jar
%{_javadir}/ehcache-1.5.0.jar
%{_javadir}/httpcore-4.0.jar
%{_javadir}/mail-1.4.jar
%{_javadir}/activation-1.1.jar
%{_javadir}/mysql-connector-java-5.1.21.jar
%{_javadir}/hibernate-jpa-2.0-api-1.0.0.Final.jar
%{_javadir}/hibernate-entitymanager-3.5.1-Final.jar
%{_javadir}/hibernate-core-3.5.1-Final.jar
%{_javadir}/hibernate-commons-annotations-3.2.0.Final.jar
%{_javadir}/hibernate-annotations-3.5.1-Final.jar
%{_javadir}/asm-3.1.jar
%{_javadir}/xapi-5.6.100-1-SNAPSHOT.jar
%{_javadir}/log4j-*.jar
%{_javadir}/trilead-ssh2-build213-svnkit-1.3-patch.jar
%{_javadir}/cglib-2.2.jar
%{_javadir}/xmlrpc-common-3.*.jar
%{_javadir}/xmlrpc-client-3.*.jar
%{_javadir}/wsdl4j-1.6.2.jar
%{_javadir}/bcprov-jdk16-1.46.jar
%{_javadir}/jsch-0.1.42.jar
%{_javadir}/jasypt-1.*.jar
%{_javadir}/commons-configuration-1.8.jar
%{_javadir}/commons-lang-2.6.jar
%{_javadir}/ejb-api-3.0.jar
%files core

View File

@ -42,6 +42,32 @@
<artifactId>commons-codec</artifactId>
<version>${cs.codec.version}</version>
</dependency>
<!-- required deps for the systemvm -->
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-agent</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-utils</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-patches</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
@ -54,5 +80,90 @@
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<finalName>systemvm</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>systemvm-descriptor.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-systemvm</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>dist</outputDirectory>
<resources>
<resource>
<directory>target</directory>
<includes>
<include>systemvm.zip</include>
</includes>
</resource>
<resource>
<directory>../patches/target/</directory>
<includes>
<include>cloud-scripts.tar.gz</include>
</includes>
</resource>
<resource>
<directory>../patches/systemvm/debian/config/root/.ssh</directory>
<includes>
<include>authorized_keys</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<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>mkisofs</executable>
<workingDirectory>dist</workingDirectory>
<arguments>
<argument>-quiet</argument>
<argument>-r</argument>
<argument>-o</argument>
<argument>systemvm.iso</argument>
<argument>systemvm.zip</argument>
<argument>cloud-scripts.tar.gz</argument>
<argument>authorized_keys</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,94 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>systemvm</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory></outputDirectory>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>../scripts/storage/secondary/</directory>
<outputDirectory>scripts/storage/secondary</outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
</fileSet>
<fileSet>
<directory>../scripts/storage/secondary/</directory>
<outputDirectory>scripts/storage/secondary</outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
</fileSet>
<fileSet>
<directory>scripts</directory>
<outputDirectory></outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
</fileSet>
<fileSet>
<directory>conf</directory>
<outputDirectory>conf</outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
<includes>
<include>log4j-cloud.xml</include>
<include>consoleproxy.properties</include>
</includes>
</fileSet>
<fileSet>
<directory>../console-proxy/images</directory>
<outputDirectory>images</outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
<includes>
<include>*.jpg</include>
<include>*.gif</include>
<include>*.png</include>
<include>*.cur</include>
</includes>
</fileSet>
<fileSet>
<directory>../console-proxy/js</directory>
<outputDirectory>js</outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
<includes>
<include>*.js</include>
</includes>
</fileSet>
<fileSet>
<directory>../console-proxy/ui</directory>
<outputDirectory>ui</outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
<includes>
<include>*.ftl</include>
</includes>
</fileSet>
<fileSet>
<directory>../console-proxy/css</directory>
<outputDirectory>css</outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
<includes>
<include>*.css</include>
</includes>
</fileSet>
<fileSet>
<directory>../console-proxy/certs</directory>
<outputDirectory>certs</outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
<includes>
<include>*.keystore</include>
<include>*.crt</include>
<include>*.key</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@ -61,14 +61,18 @@ import com.cloud.agent.api.routing.SetFirewallRulesAnswer;
import com.cloud.agent.api.routing.SetFirewallRulesCommand;
import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer;
import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
import com.cloud.agent.api.routing.SetStaticRouteAnswer;
import com.cloud.agent.api.routing.SetStaticRouteCommand;
import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.agent.api.routing.VpnUsersCfgCommand;
import com.cloud.agent.api.to.IpAddressTO;
import com.cloud.agent.api.to.PortForwardingRuleTO;
import com.cloud.agent.api.to.StaticNatRuleTO;
import com.cloud.exception.InternalErrorException;
import com.cloud.network.HAProxyConfigurator;
import com.cloud.network.LoadBalancerConfigurator;
import com.cloud.utils.NumbersUtil;
@ -109,11 +113,15 @@ public class VirtualRoutingResource implements Manager {
public Answer executeRequest(final Command cmd) {
try {
if (cmd instanceof SetPortForwardingRulesCommand ) {
if (cmd instanceof SetPortForwardingRulesVpcCommand ) {
return execute((SetPortForwardingRulesVpcCommand)cmd);
} else if (cmd instanceof SetPortForwardingRulesCommand){
return execute((SetPortForwardingRulesCommand)cmd);
} else if (cmd instanceof SetStaticRouteCommand){
return execute((SetStaticRouteCommand)cmd);
} else if (cmd instanceof SetStaticNatRulesCommand){
return execute((SetStaticNatRulesCommand)cmd);
}else if (cmd instanceof LoadBalancerConfigCommand) {
} else if (cmd instanceof LoadBalancerConfigCommand) {
return execute((LoadBalancerConfigCommand)cmd);
} else if (cmd instanceof IpAssocCommand) {
return execute((IpAssocCommand)cmd);
@ -232,12 +240,11 @@ public class VirtualRoutingResource implements Manager {
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
String[] results = new String[cmd.getRules().length];
int i = 0;
boolean endResult = true;
for (PortForwardingRuleTO rule : cmd.getRules()) {
String result = null;
final Script command = new Script(_firewallPath, _timeout, s_logger);
command.add(routerIp);
command.add(rule.revoked() ? "-D" : "-A");
command.add("-P ", rule.getProtocol().toLowerCase());
@ -674,6 +681,132 @@ public class VirtualRoutingResource implements Manager {
return command.execute();
}
public String assignGuestNetwork(final String dev, final String routerIP,
final String routerGIP, final String gateway, final String cidr,
final String netmask, final String dns, final String domainName){
String args = " -C";
args += " -d " + dev;
args += " -i " + routerGIP;
args += " -g " + gateway;
args += " -m " + cidr;
args += " -n " + netmask;
if ( dns != null && !dns.isEmpty() ) {
args += " -s " + dns;
}
if ( domainName != null && !domainName.isEmpty() ) {
args += " -e " + domainName;
}
return routerProxy("vpc_guestnw.sh", routerIP, args);
}
public String assignNetworkACL(final String routerIP, final String dev,
final String routerGIP, final String netmask, final String rule){
String args = " -d " + dev;
args += " -i " + routerGIP;
args += " -m " + netmask;
args += " -a " + rule;
return routerProxy("vpc_acl.sh", routerIP, args);
}
public String assignSourceNat(final String routerIP, final String pubIP, final String dev) {
String args = " -A ";
args += " -l ";
args += pubIP;
args += " -c ";
args += dev;
return routerProxy("vpc_snat.sh", routerIP, args);
}
private SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) {
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
String[] results = new String[cmd.getRules().length];
int i = 0;
boolean endResult = true;
for (PortForwardingRuleTO rule : cmd.getRules()) {
String args = rule.revoked() ? " -D" : " -A";
args += " -P " + rule.getProtocol().toLowerCase();
args += " -l " + rule.getSrcIp();
args += " -p " + rule.getStringSrcPortRange();
args += " -r " + rule.getDstIp();
args += " -d " + rule.getStringDstPortRange().replace(":", "-");
String result = routerProxy("vpc_portforwarding.sh", routerIp, args);
if (result != null) {
results[i++] = "Failed";
endResult = false;
} else {
results[i++] = null;
}
}
return new SetPortForwardingRulesAnswer(cmd, results, endResult);
}
public void assignVpcIpToRouter(final String routerIP, final boolean add, final String pubIP,
final String nicname, final String gateway, final String netmask, final String subnet) throws Exception {
try {
String args = "";
if (add) {
args += " -A ";
} else {
args += " -D ";
}
args += " -l ";
args += pubIP;
args += " -c ";
args += nicname;
args += " -g ";
args += gateway;
args += " -m ";
args += netmask;
args += " -n ";
args += subnet;
String result = routerProxy("vpc_ipassoc.sh", routerIP, args);
if (result != null) {
throw new InternalErrorException("KVM plugin \"vpc_ipassoc\" failed:"+result);
}
} catch (Exception e) {
String msg = "Unable to assign public IP address due to " + e.toString();
s_logger.warn(msg, e);
throw new Exception(msg);
}
}
private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) {
String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
try {
String[] results = new String[cmd.getStaticRoutes().length];
String [][] rules = cmd.generateSRouteRules();
StringBuilder sb = new StringBuilder();
String[] srRules = rules[0];
for (int i = 0; i < srRules.length; i++) {
sb.append(srRules[i]).append(',');
}
String args = " -a " + sb.toString();
String result = routerProxy("vpc_staticroute.sh", routerIP, args);
if (result != null) {
for (int i=0; i < results.length; i++) {
results[i] = "Failed";
}
return new SetStaticRouteAnswer(cmd, false, results);
}
return new SetStaticRouteAnswer(cmd, true, results);
} catch (Exception e) {
String msg = "SetStaticRoute failed due to " + e.toString();
s_logger.error(msg, e);
return new SetStaticRouteAnswer(cmd, false, null);
}
}
public String assignPublicIpAddress(final String vmName,
final String privateIpAddress, final String publicIpAddress,

View File

@ -4,7 +4,6 @@ mvn install:install-file -Dfile=cloud-iControl.jar -DgroupId=com.cloud.com.
mvn install:install-file -Dfile=cloud-netscaler.jar -DgroupId=com.cloud.com.citrix -DartifactId=netscaler -Dversion=1.0 -Dpackaging=jar
mvn install:install-file -Dfile=cloud-netscaler-sdx.jar -DgroupId=com.cloud.com.citrix -DartifactId=netscaler-sdx -Dversion=1.0 -Dpackaging=jar
mvn install:install-file -Dfile=cloud-manageontap.jar -DgroupId=com.cloud.com.netapp -DartifactId=manageontap -Dversion=1.0 -Dpackaging=jar
mvn install:install-file -Dfile=libvirt-0.4.8.jar -DgroupId=org.libvirt -DartifactId=libvirt -Dversion=0.4.8 -Dpackaging=jar
mvn install:install-file -Dfile=vmware-vim.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim -Dversion=1.0 -Dpackaging=jar
mvn install:install-file -Dfile=vmware-vim25.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim25 -Dversion=1.0 -Dpackaging=jar
mvn install:install-file -Dfile=vmware-apputils.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-apputils -Dversion=1.0 -Dpackaging=jar

35
deps/pom.xml vendored
View File

@ -73,6 +73,11 @@
<artifactId>cloud-plugin-hypervisor-ovm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-hypervisor-kvm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-storage-allocator-random</artifactId>
@ -105,36 +110,6 @@
<scope>runtime</scope>
</dependency>
<!-- Non-OSS deps -->
<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-plugin-network-srx</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-hypervisor-kvm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-netapp</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-f5</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-netscaler</artifactId>
<version>${project.version}</version>
</dependency>
<!-- for awsapi build -->
<dependency>
<groupId>org.apache.axis2</groupId>

View File

@ -40,4 +40,5 @@
<xi:include href="advanced-zone-network-traffic-types.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="advanced-zone-guest-ip-addresses.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="advanced-zone-public-ip-addresses.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="system-reserved-ip-addresses.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</section>

View File

@ -24,5 +24,159 @@
<section id="advanced-zone-configuration">
<title>Advanced Zone Configuration</title>
<para>TODO</para>
<orderedlist>
<listitem><para>After you select Advanced in the Add Zone wizard and click Next, you will be asked to enter the following details. Then click Next.</para>
<itemizedlist>
<listitem><para><emphasis role="bold">Name.</emphasis> A name for the zone.</para></listitem>
<listitem><para><emphasis role="bold">DNS 1 and 2.</emphasis> These are DNS servers for use by guest VMs in the zone. These DNS servers will be accessed via the public network you will add later. The public IP addresses for the zone must have a route to the DNS server named here.</para></listitem>
<listitem><para><emphasis role="bold">Internal DNS 1 and Internal DNS 2.</emphasis> These are DNS servers for use by system VMs in the zone(these are VMs used by &PRODUCT; itself, such as virtual routers, console proxies,and Secondary Storage VMs.) These DNS servers will be accessed via the management traffic network interface of the System VMs. The private IP address you provide for the pods must have a route to the internal DNS server named here.</para></listitem>
<listitem><para><emphasis role="bold">Network Domain.</emphasis> (Optional) If you want to assign a special domain name to the guest VM network, specify the DNS suffix.</para></listitem>
<listitem><para><emphasis role="bold">Guest CIDR.</emphasis> This is the CIDR that describes the IP addresses in use in the guest virtual networks in this zone. For example, 10.1.1.0/24. As a matter of good practice you should set different CIDRs for different zones. This will make it easier to set up VPNs between networks in different zones.</para></listitem>
<listitem><para><emphasis role="bold">Hypervisor.</emphasis> (Introduced in version 3.0.1) Choose the hypervisor for the first cluster in the zone. You can add clusters with different hypervisors later, after you finish adding the zone.</para></listitem>
<listitem><para><emphasis role="bold">Public.</emphasis> A public zone is available to all users. A zone that is not public will be assigned to a particular domain. Only users in that domain will be allowed to create guest VMs in this zone.</para></listitem>
</itemizedlist>
</listitem>
<listitem><para>Choose which traffic types will be carried by the physical network.</para>
<para>The traffic types are management, public, guest, and storage traffic. For more information about the types, roll over the icons to display their tool tips, or see <xref linkend="advanced-zone-network-traffic-types" />. This screen starts out with one network already configured. If you have multiple physical networks, you need to add more. Drag and drop traffic types onto a greyed-out network and it will become active. You can move the traffic icons from one network to another; for example, if the default traffic types shown for Network 1 do not match your actual setup, you can move them down. You can also change the network names if desired.</para>
</listitem>
<listitem><para>(Introduced in version 3.0.1) Assign a network traffic label to each traffic type on each physical network. These labels must match the labels you have already defined on the hypervisor host. To assign each label, click the Edit button under the traffic type icon within each physical network. A popup dialog appears where you can type the label, then click OK.</para>
<para>These traffic labels will be defined only for the hypervisor selected for the first cluster. For all other hypervisors, the labels can be configured after the zone is created.</para>
<para>(VMware only) If you have enabled Nexus dvSwitch in the environment, you must specify the corresponding Ethernet port profile names as network traffic label for each traffic type on the physical network. For more information on Nexus dvSwitch, see Configuring a vSphere Cluster with Nexus 1000v Virtual Switch.</para>
</listitem>
<listitem><para>Click Next.</para>
</listitem>
<listitem><para>Configure the IP range for public Internet traffic. Enter the following details, then click Add. If desired, you can repeat this step to add more public Internet IP ranges. When done, click Next.</para>
<itemizedlist>
<listitem><para><emphasis role="bold">Gateway.</emphasis> The gateway in use for these IP addresses.</para></listitem>
<listitem><para><emphasis role="bold">Netmask.</emphasis> The netmask associated with this IP range.</para></listitem>
<listitem><para><emphasis role="bold">VLAN.</emphasis> The VLAN that will be used for public traffic.</para></listitem>
<listitem><para><emphasis role="bold">Start IP/End IP.</emphasis> A range of IP addresses that are assumed to be accessible from the Internet and will be allocated for access to guest networks.</para></listitem>
</itemizedlist>
</listitem>
<listitem><para>In a new zone, &PRODUCT; adds the first pod for you. You can always add more pods later. For an overview of what a pod is, see <xref linkend="about-pods" />.</para>
<para>To configure the first pod, enter the following, then click Next:</para>
<itemizedlist>
<listitem><para><emphasis role="bold">Pod Name.</emphasis> A name for the pod.</para></listitem>
<listitem><para><emphasis role="bold">Reserved system gateway.</emphasis> The gateway for the hosts in that pod.</para></listitem>
<listitem><para><emphasis role="bold">Reserved system netmask.</emphasis> The network prefix that defines the pod's subnet. Use CIDR notation.</para></listitem>
<listitem><para><emphasis role="bold">Start/End Reserved System IP.</emphasis> The IP range in the management network that &PRODUCT; uses to manage various system VMs, such as Secondary Storage VMs, Console Proxy VMs, and DHCP. For more information, see <xref linkend="system-reserved-ip-addresses" />.</para></listitem>
</itemizedlist>
</listitem>
<listitem><para>Specify a range of VLAN IDs to carry guest traffic for each physical network (see VLAN Allocation Example ), then click Next.</para>
</listitem>
<listitem><para>In a new pod, &PRODUCT; adds the first cluster for you. You can always add more clusters later. For an overview of what a cluster is, see <xref linkend="about-clusters" />.</para>
<para>To configure the first cluster, enter the following, then click Next:</para>
<itemizedlist>
<listitem><para><emphasis role="bold">Hypervisor.</emphasis> (Version 3.0.0 only; in 3.0.1, this field is read only) Choose the type of hypervisor software that all hosts in this cluster will run. If you choose VMware, additional fields appear so you can give information about a vSphere cluster. For vSphere servers, we recommend creating the cluster of hosts in vCenter and then adding the entire cluster to &PRODUCT;. See Add Cluster: vSphere .</para></listitem>
<listitem><para><emphasis role="bold">Cluster name.</emphasis> Enter a name for the cluster. This can be text of your choosing and is not used by &PRODUCT;.</para></listitem>
</itemizedlist>
</listitem>
<listitem><para>In a new cluster, &PRODUCT; adds the first host for you. You can always add more hosts later. For an overview of what a host is, see <xref linkend="about-hosts" />.</para>
<note><para>When you deploy &PRODUCT;, the hypervisor host must not have any VMs already running.</para></note>
<para>Before you can configure the host, you need to install the hypervisor software on the host. You will need to know which version of the hypervisor software version is supported by &PRODUCT; and what additional configuration is required to ensure the host will work with &PRODUCT;. To find these installation details, see:</para>
<itemizedlist>
<listitem><para>Citrix XenServer Installation for &PRODUCT;</para></listitem>
<listitem><para>VMware vSphere Installation and Configuration</para></listitem>
<listitem><para>KVM Installation and Configuration</para></listitem>
<listitem><para>Oracle VM (OVM) Installation and Configuration</para></listitem>
</itemizedlist>
<para>To configure the first host, enter the following, then click Next:</para>
<itemizedlist>
<listitem><para><emphasis role="bold">Host Name.</emphasis> The DNS name or IP address of the host.</para></listitem>
<listitem><para><emphasis role="bold">Username.</emphasis> Usually root.</para></listitem>
<listitem><para><emphasis role="bold">Password.</emphasis> This is the password for the user named above (from your XenServer or KVM install).</para></listitem>
<listitem><para><emphasis role="bold">Host Tags.</emphasis> (Optional) Any labels that you use to categorize hosts for ease of maintenance. For example, you can set to the cloud's HA tag (set in the ha.tag global configuration parameter) if you want this host to be used only for VMs with the "high availability" feature enabled. For more information, see HA-Enabled Virtual Machines as well as HA for Hosts, both in the Administration Guide.</para></listitem>
</itemizedlist>
</listitem>
<listitem><para>In a new cluster, &PRODUCT; adds the first primary storage server for you. You can always add more servers later. For an overview of what primary storage is, see <xref linkend="about-primary-storage" />.</para>
<para>To configure the first primary storage server, enter the following, then click Next:</para>
<itemizedlist>
<listitem><para><emphasis role="bold">Name.</emphasis> The name of the storage device.</para></listitem>
<listitem><para><emphasis role="bold">Protocol.</emphasis> For XenServer, choose either NFS, iSCSI, or PreSetup. For KVM, choose NFS or SharedMountPoint. For vSphere choose either VMFS (iSCSI or FiberChannel) or NFS. The remaining fields in the screen vary depending on what you choose here.</para>
<informaltable frame="all">
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<colspec colname="c1" />
<colspec colname="c2" />
<tbody>
<row>
<entry><para>NFS</para></entry>
<entry>
<itemizedlist>
<listitem><para><emphasis role="bold">Server.</emphasis> The IP address or DNS name of the storage device.</para></listitem>
<listitem><para><emphasis role="bold">Path.</emphasis> The exported path from the server.</para></listitem>
<listitem>
<para><emphasis role="bold">Tags (optional).</emphasis> The comma-separated list of tags for this storage device. It should be an equivalent set or superset of the tags on your disk offerings.</para>
<para>The tag sets on primary storage across clusters in a Zone must be identical. For example, if cluster A provides primary storage that has tags T1 and T2, all other clusters in the Zone must also provide primary storage that has tags T1 and T2.</para>
</listitem>
</itemizedlist>
</entry>
</row>
<row>
<entry><para>iSCSI</para></entry>
<entry>
<itemizedlist>
<listitem><para><emphasis role="bold">Server.</emphasis> The IP address or DNS name of the storage device.</para></listitem>
<listitem><para><emphasis role="bold">Target IQN.</emphasis> The IQN of the target. For example, iqn.1986-03.com.sun:02:01ec9bb549-1271378984.</para></listitem>
<listitem><para><emphasis role="bold">Lun.</emphasis> The LUN number. For example, 3.</para></listitem>
<listitem>
<para><emphasis role="bold">Tags (optional).</emphasis> The comma-separated list of tags for this storage device. It should be an equivalent set or superset of the tags on your disk offerings.</para>
<para>The tag sets on primary storage across clusters in a Zone must be identical. For example, if cluster A provides primary storage that has tags T1 and T2, all other clusters in the Zone must also provide primary storage that has tags T1 and T2.</para>
</listitem>
</itemizedlist>
</entry>
</row>
<row>
<entry><para>preSetup</para></entry>
<entry>
<itemizedlist>
<listitem><para><emphasis role="bold">Server.</emphasis> The IP address or DNS name of the storage device.</para></listitem>
<listitem><para><emphasis role="bold">SR Name-Label.</emphasis> Enter the name-label of the SR that has been set up outside &PRODUCT;.</para></listitem>
<listitem>
<para><emphasis role="bold">Tags (optional).</emphasis> The comma-separated list of tags for this storage device. It should be an equivalent set or superset of the tags on your disk offerings.</para>
<para>The tag sets on primary storage across clusters in a Zone must be identical. For example, if cluster A provides primary storage that has tags T1 and T2, all other clusters in the Zone must also provide primary storage that has tags T1 and T2.</para>
</listitem>
</itemizedlist>
</entry>
</row>
<row>
<entry><para>SharedMountPoint</para></entry>
<entry>
<itemizedlist>
<listitem><para><emphasis role="bold">Path.</emphasis> The path on each host that is where this primary storage is mounted. For example, "/mnt/primary".</para></listitem>
<listitem>
<para><emphasis role="bold">Tags (optional).</emphasis> The comma-separated list of tags for this storage device. It should be an equivalent set or superset of the tags on your disk offerings.</para>
<para>The tag sets on primary storage across clusters in a Zone must be identical. For example, if cluster A provides primary storage that has tags T1 and T2, all other clusters in the Zone must also provide primary storage that has tags T1 and T2.</para>
</listitem>
</itemizedlist>
</entry>
</row>
<row>
<entry><para>VMFS</para></entry>
<entry>
<itemizedlist>
<listitem><para><emphasis role="bold">Server.</emphasis> The IP address or DNS name of the vCenter server.</para></listitem>
<listitem><para><emphasis role="bold">Path.</emphasis> A combination of the datacenter name and the datastore name. The format is "/" datacenter name "/" datastore name. For example, "/cloud.dc.VM/cluster1datastore".</para></listitem>
<listitem>
<para><emphasis role="bold">Tags (optional).</emphasis> The comma-separated list of tags for this storage device. It should be an equivalent set or superset of the tags on your disk offerings.</para>
<para>The tag sets on primary storage across clusters in a Zone must be identical. For example, if cluster A provides primary storage that has tags T1 and T2, all other clusters in the Zone must also provide primary storage that has tags T1 and T2.</para>
</listitem>
</itemizedlist>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</listitem>
</itemizedlist>
</listitem>
<listitem><para>In a new zone, &PRODUCT; adds the first secondary storage server for you. For an overview of what secondary storage is, see <xref linkend="about-secondary-storage" />.</para>
<para>Before you can fill out this screen, you need to prepare the secondary storage by setting up NFS shares and installing the latest &PRODUCT; System VM template. See Adding Secondary Storage :</para>
<itemizedlist>
<listitem><para><emphasis role="bold">NFS Server.</emphasis> The IP address of the server.</para></listitem>
<listitem><para><emphasis role="bold">Path.</emphasis> The exported path from the server.</para></listitem>
</itemizedlist>
</listitem>
<listitem><para>Click Launch.</para>
</listitem>
</orderedlist>
</section>

View File

@ -30,4 +30,5 @@
<xi:include href="about-hosts.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="about-primary-storage.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="about-secondary-storage.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="about-physical-networks.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</section>

View File

@ -24,5 +24,30 @@
<section id="initialize-and-test">
<title>Initialize and Test</title>
<para>TODO</para>
<para>After everything is configured, &PRODUCT; will perform its initialization. This can take 30 minutes or more, depending on the speed of your network. When the initialization has completed successfully, the administrator's Dashboard should be displayed in the &PRODUCT; UI.</para>
<orderedlist>
<listitem><para>Verify that the system is ready. In the left navigation bar, select Templates. Click on the CentOS 5.5 (64bit) no Gui (KVM) template. Check to be sure that the status is "Download Complete." Do not proceed to the next step until this status is displayed.</para></listitem>
<listitem><para>Go to the Instances tab, and filter by My Instances.</para></listitem>
<listitem><para>Click Add Instance and follow the steps in the wizard.</para>
<orderedlist numeration="loweralpha">
<listitem><para>Choose the zone you just added.</para></listitem>
<listitem><para>In the template selection, choose the template to use in the VM. If this is a fresh installation, likely only the provided CentOS template is available.</para></listitem>
<listitem><para>Select a service offering. Be sure that the hardware you have allows starting the selected service offering.</para></listitem>
<listitem><para>In data disk offering, if desired, add another data disk. This is a second volume that will be available to but not mounted in the guest. For example, in Linux on XenServer you will see /dev/xvdb in the guest after rebooting the VM. A reboot is not required if you have a PV-enabled OS kernel in use.</para></listitem>
<listitem><para>In default network, choose the primary network for the guest. In a trial installation, you would have only one option here.</para></listitem>
<listitem><para>Optionally give your VM a name and a group. Use any descriptive text you would like.</para></listitem>
<listitem><para>Click Launch VM. Your VM will be created and started. It might take some time to download the template and complete the VM startup. You can watch the VMs progress in the Instances screen.</para></listitem>
</orderedlist>
</listitem>
<listitem>
<para>To use the VM, click the View Console button.
<inlinemediaobject>
<imageobject><imagedata fileref="./images/console-icon.png" /></imageobject>
<textobject><phrase>ConsoleButton.png: button to launch a console</phrase></textobject>
</inlinemediaobject>
</para>
</listitem>
</orderedlist>
<para>Congratulations! You have successfully completed a &PRODUCT; Installation.</para>
<para>If you decide to grow your deployment, you can add more hosts, primary storage, zones, pods, and clusters.</para>
</section>

View File

@ -0,0 +1,43 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>cloud-scripts</id>
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>../patches/systemvm/debian/config/</directory>
<outputDirectory></outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
</fileSet>
<fileSet>
<directory>../patches/systemvm/debian/vpn/</directory>
<outputDirectory></outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
</fileSet>
<fileSet>
<directory>../patches/systemvm/debian/xe/</directory>
<outputDirectory></outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
<excludes>
<exclude>**/xe-*</exclude>
<exclude>**/xen-*</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>../patches/systemvm/debian/xe/</directory>
<outputDirectory>usr/sbin</outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
<includes>
<include>**/xe-*</include>
<include>**/xen-*</include>
</includes>
</fileSet>
</fileSets>
</assembly>

92
patches/pom.xml Normal file
View File

@ -0,0 +1,92 @@
<!--
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-patches</artifactId>
<name>Apache CloudStack SystemVM Patches</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack</artifactId>
<version>4.0.0-SNAPSHOT</version>
</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-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-agent</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-utils</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<finalName>cloud-scripts</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>cloudpatch-descriptor.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-cloud-scripts</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -542,10 +542,10 @@ echo "*************CONFIGURING VPN********************"
vpn_config
echo "*************FIX DHCP ISSUE********************"
dhcp_fix
#dhcp_fix
echo "*************INSTALL XS TOOLS********************"
install_xs_tool
#install_xs_tool
echo "*************CLEANING UP********************"
cleanup

View File

@ -58,19 +58,31 @@ create_acl_chain() {
setup_apache2() {
logger_it "Setting up apache web server for $dev"
logger -t cloud "Setting up apache web server for $dev"
cp /etc/apache2/vhostexample.conf /etc/apache2/conf.d/vhost$dev.conf
sed -i -e "s/<VirtualHost.*:80>/<VirtualHost $ip:80>/" /etc/apache2/conf.d/vhost$dev.conf
sed -i -e "s/<VirtualHost.*:443>/<VirtualHost $ip:443>/" /etc/apache2/conf.d/vhost$dev.conf
sed -i -e "s/\tServerName.*/\tServerName vhost$dev.cloudinternal.com/" /etc/apache2/conf.d/vhost$dev.conf
sed -i -e "s/Listen .*:80/Listen $ip:80/g" /etc/apache2/conf.d/vhost$dev.conf
sed -i -e "s/Listen .*:443/Listen $ip:443/g" /etc/apache2/conf.d/vhost$dev.conf
if [ -e "/etc/apache2/sites-enabled/000-default" ]
then
sed -i -e "s/^#*/#/g" /etc/apache2/sites-enabled/000-default
fi
if [ -e "/etc/apache2/sites-enabled/default-ssl" ]
then
sed -i -e "s/^#*/#/g" /etc/apache2/sites-enabled/default-ssl
fi
if [ -e "/etc/apache2/ports.conf" ]
then
sed -i -e "s/^#*/#/g" /etc/apache2/ports.conf
fi
service apache2 restart
sudo iptables -A INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 80 -j ACCEPT
}
desetup_apache2() {
logger_it "Desetting up apache web server for $dev"
logger -t cloud "Desetting up apache web server for $dev"
rm -f /etc/apache2/conf.d/vhost$dev.conf
service apache2 restart
sudo iptables -D INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 80 -j ACCEPT

View File

@ -27,6 +27,12 @@
<version>4.0.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<repositories>
<repository>
<id>libvirt-org</id>
<url>http://libvirt.org/maven2</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.cloudstack</groupId>

View File

@ -1,641 +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.hypervisor.kvm.resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
import com.cloud.agent.api.AttachVolumeCommand;
import com.cloud.agent.api.CheckHealthAnswer;
import com.cloud.agent.api.CheckHealthCommand;
import com.cloud.agent.api.CheckStateAnswer;
import com.cloud.agent.api.CheckStateCommand;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.CleanupNetworkRulesCmd;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.GetHostStatsAnswer;
import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.GetStorageStatsAnswer;
import com.cloud.agent.api.GetStorageStatsCommand;
import com.cloud.agent.api.GetVmStatsAnswer;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.ModifySshKeysCommand;
import com.cloud.agent.api.ModifyStoragePoolAnswer;
import com.cloud.agent.api.ModifyStoragePoolCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.PingRoutingCommand;
import com.cloud.agent.api.PingTestCommand;
import com.cloud.agent.api.ReadyAnswer;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.RebootAnswer;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.SecurityGroupRuleAnswer;
import com.cloud.agent.api.SecurityGroupRulesCmd;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.agent.api.StartupRoutingCommand.VmState;
import com.cloud.agent.api.StartupStorageCommand;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.StoragePoolInfo;
import com.cloud.agent.api.routing.SavePasswordCommand;
import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.agent.api.storage.CreateAnswer;
import com.cloud.agent.api.storage.CreateCommand;
import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.agent.dhcp.DhcpSnooper;
import com.cloud.agent.dhcp.FakeDhcpSnooper;
import com.cloud.agent.mockvm.MockVm;
import com.cloud.agent.mockvm.MockVmMgr;
import com.cloud.agent.mockvm.VmMgr;
import com.cloud.agent.vmdata.JettyVmDataServer;
import com.cloud.agent.vmdata.VmDataServer;
import com.cloud.host.Host.Type;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.Networks.RouterPrivateIpStrategy;
import com.cloud.network.Networks.TrafficType;
import com.cloud.resource.ServerResource;
import com.cloud.resource.ServerResourceBase;
import com.cloud.storage.Storage;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.Volume;
import com.cloud.storage.template.TemplateInfo;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
import com.cloud.vm.VirtualMachine.State;
/**
* Pretends to be a computing resource
*
*/
@Local(value = { ServerResource.class })
public class FakeComputingResource extends ServerResourceBase implements
ServerResource {
private static final Logger s_logger = Logger
.getLogger(FakeComputingResource.class);
private Map<String, Object> _params;
private VmMgr _vmManager = new MockVmMgr();
protected HashMap<String, State> _vms = new HashMap<String, State>(20);
protected DhcpSnooper _dhcpSnooper = new FakeDhcpSnooper();
protected VmDataServer _vmDataServer = new JettyVmDataServer();
@Override
public Type getType() {
return Type.Routing;
}
@Override
public StartupCommand[] initialize() {
Map<String, VmState> changes = null;
final List<Object> info = getHostInfo();
final StartupRoutingCommand cmd = new StartupRoutingCommand(
(Integer) info.get(0), (Long) info.get(1), (Long) info.get(2),
(Long) info.get(4), (String) info.get(3), HypervisorType.KVM,
RouterPrivateIpStrategy.HostLocal, changes);
fillNetworkInformation(cmd);
cmd.getHostDetails().putAll(getVersionStrings());
cmd.setCluster(getConfiguredProperty("cluster", "1"));
StoragePoolInfo pi = initializeLocalStorage();
StartupStorageCommand sscmd = new StartupStorageCommand();
sscmd.setPoolInfo(pi);
sscmd.setGuid(pi.getUuid());
sscmd.setDataCenter((String) _params.get("zone"));
sscmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL);
return new StartupCommand[] { cmd, sscmd };
}
private Map<String, String> getVersionStrings() {
Map<String, String> result = new HashMap<String, String>();
String hostOs = (String) _params.get("Host.OS");
String hostOsVer = (String) _params.get("Host.OS.Version");
String hostOsKernVer = (String) _params.get("Host.OS.Kernel.Version");
result.put("Host.OS", hostOs == null ? "Fedora" : hostOs);
result.put("Host.OS.Version", hostOsVer == null ? "14" : hostOsVer);
result.put("Host.OS.Kernel.Version",
hostOsKernVer == null ? "2.6.35.6-45.fc14.x86_64"
: hostOsKernVer);
return result;
}
protected void fillNetworkInformation(final StartupCommand cmd) {
cmd.setPrivateIpAddress((String) _params.get("private.ip.address"));
cmd.setPrivateMacAddress((String) _params.get("private.mac.address"));
cmd.setPrivateNetmask((String) _params.get("private.ip.netmask"));
cmd.setStorageIpAddress((String) _params.get("private.ip.address"));
cmd.setStorageMacAddress((String) _params.get("private.mac.address"));
cmd.setStorageNetmask((String) _params.get("private.ip.netmask"));
cmd.setGatewayIpAddress((String) _params.get("gateway.ip.address"));
}
protected StoragePoolInfo initializeLocalStorage() {
String hostIp = (String) _params.get("private.ip.address");
String localStoragePath = (String) _params.get("local.storage.path");
String lh = hostIp + localStoragePath;
String uuid = UUID.nameUUIDFromBytes(lh.getBytes()).toString();
String capacity = (String) _params.get("local.storage.capacity");
String available = (String) _params.get("local.storage.avail");
return new StoragePoolInfo(uuid, hostIp, localStoragePath,
localStoragePath, StoragePoolType.Filesystem,
Long.parseLong(capacity), Long.parseLong(available));
}
@Override
public PingCommand getCurrentStatus(long id) {
final HashMap<String, State> newStates = new HashMap<String, State>();
_dhcpSnooper.syncIpAddr();
return new PingRoutingCommand(com.cloud.host.Host.Type.Routing, id,
newStates);
}
@Override
public Answer executeRequest(Command cmd) {
try {
if (cmd instanceof ReadyCommand) {
return execute((ReadyCommand) cmd);
} else if (cmd instanceof ModifySshKeysCommand) {
return execute((ModifySshKeysCommand) cmd);// TODO: remove
} else if (cmd instanceof GetHostStatsCommand) {
return execute((GetHostStatsCommand) cmd);
} else if (cmd instanceof PrimaryStorageDownloadCommand) {
return execute((PrimaryStorageDownloadCommand) cmd);
} else if (cmd instanceof StopCommand) {
return execute((StopCommand) cmd);
} else if (cmd instanceof GetVmStatsCommand) {
return execute((GetVmStatsCommand) cmd);
} else if (cmd instanceof RebootCommand) {
return execute((RebootCommand) cmd);
} else if (cmd instanceof CheckStateCommand) {
return executeRequest(cmd);
} else if (cmd instanceof CheckHealthCommand) {
return execute((CheckHealthCommand) cmd);
} else if (cmd instanceof PingTestCommand) {
return execute((PingTestCommand) cmd);
} else if (cmd instanceof CheckVirtualMachineCommand) {
return execute((CheckVirtualMachineCommand) cmd);
} else if (cmd instanceof ReadyCommand) {
return execute((ReadyCommand) cmd);
} else if (cmd instanceof StopCommand) {
return execute((StopCommand) cmd);
} else if (cmd instanceof CreateCommand) {
return execute((CreateCommand) cmd);
} else if (cmd instanceof DestroyCommand) {
return execute((DestroyCommand) cmd);
} else if (cmd instanceof PrimaryStorageDownloadCommand) {
return execute((PrimaryStorageDownloadCommand) cmd);
} else if (cmd instanceof GetStorageStatsCommand) {
return execute((GetStorageStatsCommand) cmd);
} else if (cmd instanceof ModifyStoragePoolCommand) {
return execute((ModifyStoragePoolCommand) cmd);
} else if (cmd instanceof SecurityGroupRulesCmd) {
return execute((SecurityGroupRulesCmd) cmd);
} else if (cmd instanceof StartCommand) {
return execute((StartCommand) cmd);
} else if (cmd instanceof CleanupNetworkRulesCmd) {
return execute((CleanupNetworkRulesCmd) cmd);
} else if (cmd instanceof SavePasswordCommand) {
return execute((SavePasswordCommand) cmd);
} else if (cmd instanceof VmDataCommand) {
return execute((VmDataCommand) cmd);
} else {
s_logger.warn("Unsupported command ");
return Answer.createUnsupportedCommandAnswer(cmd);
}
} catch (final IllegalArgumentException e) {
return new Answer(cmd, false, e.getMessage());
}
}
private Answer execute(CleanupNetworkRulesCmd cmd) {
return new Answer(cmd);
}
private Answer execute(SecurityGroupRulesCmd cmd) {
s_logger.info("Programmed network rules for vm " + cmd.getVmName()
+ " guestIp=" + cmd.getGuestIp() + ",ingress numrules="
+ cmd.getIngressRuleSet().length + ",egress numrules="
+ cmd.getEgressRuleSet().length);
return new SecurityGroupRuleAnswer(cmd);
}
private Answer execute(ModifyStoragePoolCommand cmd) {
long capacity = getConfiguredProperty("local.storage.capacity",
10000000000L);
long used = 10000000L;
long available = capacity - used;
if (cmd.getAdd()) {
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd,
capacity, used, new HashMap<String, TemplateInfo>());
if (s_logger.isInfoEnabled())
s_logger.info("Sending ModifyStoragePoolCommand answer with capacity: "
+ capacity
+ ", used: "
+ used
+ ", available: "
+ available);
return answer;
} else {
if (s_logger.isInfoEnabled())
s_logger.info("ModifyNetfsStoragePoolCmd is not add command, cmd: "
+ cmd.toString());
return new Answer(cmd);
}
}
private Answer execute(GetStorageStatsCommand cmd) {
return new GetStorageStatsAnswer(cmd, getConfiguredProperty(
"local.storage.capacity", 100000000000L), 0L);
}
protected synchronized ReadyAnswer execute(ReadyCommand cmd) {
return new ReadyAnswer(cmd);
}
private Answer execute(PrimaryStorageDownloadCommand cmd) {
return new PrimaryStorageDownloadAnswer(cmd.getLocalPath(), 16000000L);
}
private Answer execute(ModifySshKeysCommand cmd) {
return new Answer(cmd, true, null);
}
@Override
protected String getDefaultScriptsDir() {
return null;
}
protected String getConfiguredProperty(String key, String defaultValue) {
String val = (String) _params.get(key);
return val == null ? defaultValue : val;
}
protected Long getConfiguredProperty(String key, Long defaultValue) {
String val = (String) _params.get(key);
if (val != null) {
Long result = Long.parseLong(val);
return result;
}
return defaultValue;
}
protected List<Object> getHostInfo() {
final ArrayList<Object> info = new ArrayList<Object>();
long speed = getConfiguredProperty("cpuspeed", 4000L);
long cpus = getConfiguredProperty("cpus", 4L);
long ram = getConfiguredProperty("memory", 16000L * 1024L * 1024L);
long dom0ram = Math.min(ram / 10, 768 * 1024 * 1024L);
String cap = getConfiguredProperty("capabilities", "hvm");
info.add((int) cpus);
info.add(speed);
info.add(ram);
info.add(cap);
info.add(dom0ram);
return info;
}
private Map<String, Object> getSimulatorProperties()
throws ConfigurationException {
final File file = PropertiesUtil.findConfigFile("simulator.properties");
if (file == null) {
throw new ConfigurationException(
"Unable to find simulator.properties.");
}
s_logger.info("simulator.properties found at " + file.getAbsolutePath());
Properties properties = new Properties();
try {
properties.load(new FileInputStream(file));
final Map<String, Object> params = PropertiesUtil.toMap(properties);
return params;
} catch (final FileNotFoundException ex) {
throw new CloudRuntimeException("Cannot find the file: "
+ file.getAbsolutePath(), ex);
} catch (final IOException ex) {
throw new CloudRuntimeException("IOException in reading "
+ file.getAbsolutePath(), ex);
}
}
@Override
public boolean configure(String name, Map<String, Object> params)
throws ConfigurationException {
Map<String, Object> simProps = getSimulatorProperties();
params.putAll(simProps);
setParams(params);
_vmManager.configure(params);
_dhcpSnooper.configure(name, params);
_vmDataServer.configure(name, params);
return true;
}
public void setParams(Map<String, Object> _params) {
this._params = _params;
}
public Map<String, Object> getParams() {
return _params;
}
protected synchronized StartAnswer execute(StartCommand cmd) {
VmMgr vmMgr = getVmManager();
VirtualMachineTO vmSpec = cmd.getVirtualMachine();
String vmName = vmSpec.getName();
State state = State.Stopped;
try {
if (!_vms.containsKey(vmName)) {
synchronized (_vms) {
_vms.put(vmName, State.Starting);
}
MockVm vm = vmMgr.createVmFromSpec(vmSpec);
vmMgr.createVbd(vmSpec, vmName, vm);
vmMgr.createVif(vmSpec, vmName, vm);
state = State.Running;
for (NicTO nic : cmd.getVirtualMachine().getNics()) {
if (nic.getType() == TrafficType.Guest) {
InetAddress addr = _dhcpSnooper.getIPAddr(nic.getMac(),
vmName);
nic.setIp(addr.getHostAddress());
}
}
_vmDataServer.handleVmStarted(cmd.getVirtualMachine());
return new StartAnswer(cmd);
} else {
String msg = "There is already a VM having the same name "
+ vmName;
s_logger.warn(msg);
return new StartAnswer(cmd, msg);
}
} catch (Exception ex) {
} finally {
synchronized (_vms) {
_vms.put(vmName, state);
}
}
return new StartAnswer(cmd);
}
protected synchronized StopAnswer execute(StopCommand cmd) {
VmMgr vmMgr = getVmManager();
StopAnswer answer = null;
String vmName = cmd.getVmName();
Integer port = vmMgr.getVncPort(vmName);
State state = null;
synchronized (_vms) {
state = _vms.get(vmName);
_vms.put(vmName, State.Stopping);
}
try {
String result = vmMgr.stopVM(vmName, false);
if (result != null) {
s_logger.info("Trying destroy on " + vmName);
if (result == Script.ERR_TIMEOUT) {
result = vmMgr.stopVM(vmName, true);
}
s_logger.warn("Couldn't stop " + vmName);
if (result != null) {
return new StopAnswer(cmd, result, false);
}
}
answer = new StopAnswer(cmd, null, port, true);
String result2 = vmMgr.cleanupVnet(cmd.getVnet());
if (result2 != null) {
result = result2 + (result != null ? ("\n" + result) : "");
answer = new StopAnswer(cmd, result, port, true);
}
_dhcpSnooper.cleanup(vmName, null);
return answer;
} finally {
if (answer == null || !answer.getResult()) {
synchronized (_vms) {
_vms.put(vmName, state);
}
}
}
}
protected Answer execute(final VmDataCommand cmd) {
return _vmDataServer.handleVmDataCommand(cmd);
}
protected Answer execute(final SavePasswordCommand cmd) {
return new Answer(cmd);
}
protected Answer execute(RebootCommand cmd) {
VmMgr vmMgr = getVmManager();
vmMgr.rebootVM(cmd.getVmName());
return new RebootAnswer(cmd, "success", true);
}
private Answer execute(PingTestCommand cmd) {
return new Answer(cmd);
}
protected GetVmStatsAnswer execute(GetVmStatsCommand cmd) {
return null;
}
private VmMgr getVmManager() {
return _vmManager;
}
protected Answer execute(GetHostStatsCommand cmd) {
VmMgr vmMgr = getVmManager();
return new GetHostStatsAnswer(cmd, vmMgr.getHostCpuUtilization(),
vmMgr.getHostFreeMemory(), vmMgr.getHostTotalMemory(), 0, 0,
"SimulatedHost");
}
protected CheckStateAnswer execute(CheckStateCommand cmd) {
State state = getVmManager().checkVmState(cmd.getVmName());
return new CheckStateAnswer(cmd, state);
}
protected CheckHealthAnswer execute(CheckHealthCommand cmd) {
return new CheckHealthAnswer(cmd, true);
}
protected CheckVirtualMachineAnswer execute(
final CheckVirtualMachineCommand cmd) {
VmMgr vmMgr = getVmManager();
final String vmName = cmd.getVmName();
final State state = vmMgr.checkVmState(vmName);
Integer vncPort = null;
if (state == State.Running) {
vncPort = vmMgr.getVncPort(vmName);
synchronized (_vms) {
_vms.put(vmName, State.Running);
}
}
return new CheckVirtualMachineAnswer(cmd, state, vncPort);
}
protected Answer execute(final AttachVolumeCommand cmd) {
return new Answer(cmd);
}
protected Answer execute(final AttachIsoCommand cmd) {
return new Answer(cmd);
}
protected CreateAnswer execute(final CreateCommand cmd) {
try {
VolumeTO vol = new VolumeTO(cmd.getVolumeId(), Volume.Type.ROOT,
com.cloud.storage.Storage.StoragePoolType.LVM, cmd
.getPool().getUuid(), "dummy", "/mountpoint",
"dummyPath", 1000L, null);
return new CreateAnswer(cmd, vol);
} catch (Throwable th) {
return new CreateAnswer(cmd, new Exception("Unexpected exception"));
}
}
protected HashMap<String, State> sync() {
Map<String, State> newStates;
Map<String, State> oldStates = null;
HashMap<String, State> changes = new HashMap<String, State>();
synchronized (_vms) {
newStates = getVmManager().getVmStates();
oldStates = new HashMap<String, State>(_vms.size());
oldStates.putAll(_vms);
for (Map.Entry<String, State> entry : newStates.entrySet()) {
String vm = entry.getKey();
State newState = entry.getValue();
State oldState = oldStates.remove(vm);
if (s_logger.isTraceEnabled()) {
s_logger.trace("VM " + vm + ": xen has state " + newState
+ " and we have state "
+ (oldState != null ? oldState.toString() : "null"));
}
if (oldState == null) {
_vms.put(vm, newState);
changes.put(vm, newState);
} else if (oldState == State.Starting) {
if (newState == State.Running) {
_vms.put(vm, newState);
} else if (newState == State.Stopped) {
s_logger.debug("Ignoring vm " + vm
+ " because of a lag in starting the vm.");
}
} else if (oldState == State.Stopping) {
if (newState == State.Stopped) {
_vms.put(vm, newState);
} else if (newState == State.Running) {
s_logger.debug("Ignoring vm " + vm
+ " because of a lag in stopping the vm. ");
}
} else if (oldState != newState) {
_vms.put(vm, newState);
changes.put(vm, newState);
}
}
for (Map.Entry<String, State> entry : oldStates.entrySet()) {
String vm = entry.getKey();
State oldState = entry.getValue();
if (s_logger.isTraceEnabled()) {
s_logger.trace("VM " + vm
+ " is now missing from xen so reporting stopped");
}
if (oldState == State.Stopping) {
s_logger.debug("Ignoring VM " + vm
+ " in transition state stopping.");
_vms.remove(vm);
} else if (oldState == State.Starting) {
s_logger.debug("Ignoring VM " + vm
+ " in transition state starting.");
} else if (oldState == State.Stopped) {
_vms.remove(vm);
} else {
changes.put(entry.getKey(), State.Stopped);
}
}
}
return changes;
}
protected Answer execute(DestroyCommand cmd) {
return new Answer(cmd, true, null);
}
}

View File

@ -105,6 +105,7 @@ public class KVMGuestOsMapper {
s_mapper.put("Ubuntu 8.04 (64-bit)", "Other Linux");
s_mapper.put("Debian GNU/Linux 5(32-bit)", "Debian GNU/Linux 5");
s_mapper.put("Debian GNU/Linux 5(64-bit)", "Debian GNU/Linux 5");
s_mapper.put("Debian GNU/Linux 5.0(32-bit)", "Debian GNU/Linux 5");
s_mapper.put("Debian GNU/Linux 4(32-bit)", "Debian GNU/Linux 4");
s_mapper.put("Debian GNU/Linux 4(64-bit)", "Debian GNU/Linux 4");
s_mapper.put("Debian GNU/Linux 6(64-bit)", "Debian GNU/Linux 6");

View File

@ -126,6 +126,8 @@ import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.RebootRouterCommand;
import com.cloud.agent.api.SecurityGroupRuleAnswer;
import com.cloud.agent.api.SecurityGroupRulesCmd;
import com.cloud.agent.api.SetupGuestNetworkAnswer;
import com.cloud.agent.api.SetupGuestNetworkCommand;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.StartupCommand;
@ -144,7 +146,12 @@ import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
import com.cloud.agent.api.routing.IpAssocAnswer;
import com.cloud.agent.api.routing.IpAssocCommand;
import com.cloud.agent.api.routing.IpAssocVpcCommand;
import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.routing.SetNetworkACLAnswer;
import com.cloud.agent.api.routing.SetNetworkACLCommand;
import com.cloud.agent.api.routing.SetSourceNatAnswer;
import com.cloud.agent.api.routing.SetSourceNatCommand;
import com.cloud.agent.api.storage.CopyVolumeAnswer;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.CreateAnswer;
@ -1028,6 +1035,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements
return execute((PlugNicCommand) cmd);
} else if (cmd instanceof UnPlugNicCommand) {
return execute((UnPlugNicCommand) cmd);
} else if (cmd instanceof SetupGuestNetworkCommand) {
return execute((SetupGuestNetworkCommand) cmd);
} else if (cmd instanceof SetNetworkACLCommand) {
return execute((SetNetworkACLCommand) cmd);
} else if (cmd instanceof SetSourceNatCommand) {
return execute((SetSourceNatCommand) cmd);
} else if (cmd instanceof IpAssocVpcCommand) {
return execute((IpAssocVpcCommand) cmd);
} else if (cmd instanceof IpAssocCommand) {
return execute((IpAssocCommand) cmd);
} else if (cmd instanceof NetworkElementCommand) {
@ -1239,7 +1254,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements
}
Domain vm = getDomain(conn, vmName);
vm.attachDevice(_vifDriver.plug(nicTO, "Other PV").toString());
vm.attachDevice(_vifDriver.plug(nicTO, "Other PV (32-bit)").toString());
}
private PlugNicAnswer execute(PlugNicCommand cmd) {
@ -1249,7 +1264,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements
try {
conn = LibvirtConnection.getConnection();
Domain vm = getDomain(conn, vmName);
vm.attachDevice(_vifDriver.plug(nic, "Other PV").toString());
List<InterfaceDef> pluggedNics = getInterfaces(conn, vmName);
Integer nicnum = 0;
for (InterfaceDef pluggedNic : pluggedNics) {
if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) {
s_logger.debug("found existing nic for mac "+ pluggedNic.getMacAddress() + " at index "+nicnum);
return new PlugNicAnswer(cmd, true, "success");
}
nicnum++;
}
vm.attachDevice(_vifDriver.plug(nic, "Other PV (32-bit)").toString());
return new PlugNicAnswer(cmd, true, "success");
} catch (Exception e) {
String msg = " Plug Nic failed due to " + e.toString();
@ -1277,7 +1301,195 @@ public class LibvirtComputingResource extends ServerResourceBase implements
String msg = " Unplug Nic failed due to " + e.toString();
s_logger.warn(msg, e);
return new UnPlugNicAnswer(cmd, false, msg);
}
}
}
private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) {
Connect conn;
NicTO nic = cmd.getNic();
String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
String routerGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP);
String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
String gateway = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY);
String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask()));;
String domainName = cmd.getNetworkDomain();
String dns = cmd.getDefaultDns1();
if (dns == null || dns.isEmpty()) {
dns = cmd.getDefaultDns2();
} else {
String dns2= cmd.getDefaultDns2();
if ( dns2 != null && !dns2.isEmpty()) {
dns += "," + dns2;
}
}
try {
conn = LibvirtConnection.getConnection();
Domain vm = getDomain(conn, routerName);
List<InterfaceDef> pluggedNics = getInterfaces(conn, routerName);
InterfaceDef routerNic = null;
for (InterfaceDef pluggedNic : pluggedNics) {
if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) {
routerNic = pluggedNic;
break;
}
}
if ( routerNic == null ) {
return new SetupGuestNetworkAnswer(cmd, false, "Can not find nic with mac " + nic.getMac() + " for VM " + routerName);
}
String args = "vpc_guestnw.sh " + routerIP + " -C";
String dev = "eth" + nic.getDeviceId();
String netmask = NetUtils.getSubNet(routerGIP, nic.getNetmask());
String result = _virtRouterResource.assignGuestNetwork(dev, routerIP,
routerGIP, gateway, cidr, netmask, dns, domainName );
if (result != null) {
return new SetupGuestNetworkAnswer(cmd, false, "Creating guest network failed due to " + result);
}
return new SetupGuestNetworkAnswer(cmd, true, "success");
} catch (Exception e) {
String msg = "Creating guest network failed due to " + e.toString();
s_logger.warn(msg, e);
return new SetupGuestNetworkAnswer(cmd, false, msg);
}
}
private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) {
String[] results = new String[cmd.getRules().length];
String callResult;
Connect conn;
String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
try {
conn = LibvirtConnection.getConnection();
Domain vm = getDomain(conn, routerName);
String [][] rules = cmd.generateFwRules();
String[] aclRules = rules[0];
NicTO nic = cmd.getNic();
String dev = "eth" + nic.getDeviceId();
String netmask = Long.toString(NetUtils.getCidrSize(nic.getNetmask()));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < aclRules.length; i++) {
sb.append(aclRules[i]).append(',');
}
String rule = sb.toString();
String result = _virtRouterResource.assignNetworkACL(routerIp,
dev, nic.getIp(), netmask, rule);
if (result != null) {
for (int i=0; i < results.length; i++) {
results[i] = "Failed";
}
return new SetNetworkACLAnswer(cmd, false, results);
}
return new SetNetworkACLAnswer(cmd, true, results);
} catch (Exception e) {
String msg = "SetNetworkACL failed due to " + e.toString();
s_logger.error(msg, e);
return new SetNetworkACLAnswer(cmd, false, results);
}
}
protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) {
Connect conn;
String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
IpAddressTO pubIP = cmd.getIpAddress();
try {
conn = LibvirtConnection.getConnection();
Domain vm = getDomain(conn, routerName);
Integer devNum = 0;
String pubVlan = pubIP.getVlanId();
List<InterfaceDef> pluggedNics = getInterfaces(conn, routerName);
for (InterfaceDef pluggedNic : pluggedNics) {
String pluggedVlanBr = pluggedNic.getBrName();
String pluggedVlanId = getVlanIdFromBridge(pluggedVlanBr);
if (pubVlan.equalsIgnoreCase(Vlan.UNTAGGED)
&& pluggedVlanBr.equalsIgnoreCase(_publicBridgeName)) {
break;
} else if (pluggedVlanBr.equalsIgnoreCase(_linkLocalBridgeName)){
/*skip over, no physical bridge device exists*/
} else if (pluggedVlanId == null) {
/*this should only be true in the case of link local bridge*/
return new SetSourceNatAnswer(cmd, false, "unable to find the vlan id for bridge "+pluggedVlanBr+
" when attempting to set up" + pubVlan + " on router " + routerName);
} else if (pluggedVlanId.equals(pubVlan)) {
break;
}
devNum++;
}
String dev = "eth" + devNum;
String result = _virtRouterResource.assignSourceNat(routerIP, pubIP.getPublicIp(), dev);
if (result != null) {
return new SetSourceNatAnswer(cmd, false, "KVM plugin \"vpc_snat\" failed:"+result);
}
return new SetSourceNatAnswer(cmd, true, "success");
} catch (Exception e) {
String msg = "Ip SNAT failure due to " + e.toString();
s_logger.error(msg, e);
return new SetSourceNatAnswer(cmd, false, msg);
}
}
protected IpAssocAnswer execute(IpAssocVpcCommand cmd) {
Connect conn;
String[] results = new String[cmd.getIpAddresses().length];
int i = 0;
String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
try {
conn = LibvirtConnection.getConnection();
IpAddressTO[] ips = cmd.getIpAddresses();
Domain vm = getDomain(conn, routerName);
Integer devNum = 0;
Map<String, Integer> vlanToNicNum = new HashMap<String, Integer>();
List<InterfaceDef> pluggedNics = getInterfaces(conn, routerName);
for (InterfaceDef pluggedNic : pluggedNics) {
String pluggedVlan = pluggedNic.getBrName();
if (pluggedVlan.equalsIgnoreCase(_linkLocalBridgeName)) {
vlanToNicNum.put("LinkLocal",devNum);
}
else if (pluggedVlan.equalsIgnoreCase(_publicBridgeName)
|| pluggedVlan.equalsIgnoreCase(_privBridgeName)
|| pluggedVlan.equalsIgnoreCase(_guestBridgeName)) {
vlanToNicNum.put(Vlan.UNTAGGED,devNum);
}
else {
vlanToNicNum.put(getVlanIdFromBridge(pluggedVlan),devNum);
}
devNum++;
}
for (IpAddressTO ip : ips) {
String ipVlan = ip.getVlanId();
String nicName = "eth" + vlanToNicNum.get(ip.getVlanId());
String netmask = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask()));
String subnet = NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask());
_virtRouterResource.assignVpcIpToRouter(routerIP, ip.isAdd(), ip.getPublicIp(),
nicName, ip.getVlanGateway(), netmask, subnet);
results[i++] = ip.getPublicIp() + " - success";
}
} catch (Exception e) {
s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e);
results[i++] = IpAssocAnswer.errorResult;
}
return new IpAssocAnswer(cmd, results);
}
public Answer execute(IpAssocCommand cmd) {
@ -1295,12 +1507,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements
if (nic.getBrName().equalsIgnoreCase(_linkLocalBridgeName)) {
vlanAllocatedToVM.put("LinkLocal", nicPos);
} else {
if (nic.getBrName().equalsIgnoreCase(_publicBridgeName) || nic.getBrName().equalsIgnoreCase(_privBridgeName) || nic.getBrName().equalsIgnoreCase(_guestBridgeName)) {
vlanAllocatedToVM.put(Vlan.UNTAGGED, nicPos);
} else {
String vlanId = getVlanIdFromBridge(nic.getBrName());
vlanAllocatedToVM.put(vlanId, nicPos);
}
if (nic.getBrName().equalsIgnoreCase(_publicBridgeName)
|| nic.getBrName().equalsIgnoreCase(_privBridgeName)
|| nic.getBrName().equalsIgnoreCase(_guestBridgeName)) {
vlanAllocatedToVM.put(Vlan.UNTAGGED, nicPos);
} else {
String vlanId = getVlanIdFromBridge(nic.getBrName());
vlanAllocatedToVM.put(vlanId, nicPos);
}
}
nicPos++;
}

View File

@ -7378,7 +7378,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
return new SetupGuestNetworkAnswer(cmd, true, "success");
} catch (Exception e) {
String msg = " UnPlug Nic failed due to " + e.toString();
String msg = "Creating guest network failed due to " + e.toString();
s_logger.warn(msg, e);
return new SetupGuestNetworkAnswer(cmd, false, msg);
}

View File

@ -37,6 +37,7 @@
<module>host-allocators/random</module>
<module>hypervisors/ovm</module>
<module>hypervisors/xen</module>
<module>hypervisors/kvm</module>
<module>network-elements/elastic-loadbalancer</module>
<module>network-elements/ovs</module>
<module>network-elements/nicira-nvp</module>

View File

@ -154,9 +154,9 @@
<module>usage</module>
<module>utils</module>
<module>deps/XenServerJava</module>
<module>vmware-base</module>
<module>plugins</module>
<module>awsapi</module>
<module>patches</module>
</modules>
<dependencies>

View File

@ -118,7 +118,7 @@ public class ApiResponseSerializer {
private static String toXMLSerializedString(ResponseObject result) {
StringBuilder sb = new StringBuilder();
sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
sb.append("<" + result.getResponseName() + " cloud-stack-version=\"" + ApiDBUtils.getVersion() + "\">");
if (result instanceof ListResponse) {

View File

@ -187,7 +187,7 @@ public interface NetworkManager extends NetworkService {
Nic getDefaultNic(long vmId);
List<? extends UserDataServiceProvider> getPasswordResetElements();
UserDataServiceProvider getPasswordResetProvider(Network network);
boolean networkIsConfiguredForExternalNetworking(long zoneId, long networkId);

View File

@ -4298,15 +4298,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
@Override
public List<? extends UserDataServiceProvider> getPasswordResetElements() {
List<UserDataServiceProvider> elements = new ArrayList<UserDataServiceProvider>();
for (NetworkElement element : _networkElements) {
if (element instanceof UserDataServiceProvider) {
UserDataServiceProvider e = (UserDataServiceProvider) element;
elements.add(e);
}
public UserDataServiceProvider getPasswordResetProvider(Network network) {
String passwordProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.UserData);
if (passwordProvider == null) {
s_logger.debug("Network " + network + " doesn't support service " + Service.UserData.getName());
return null;
}
return elements;
return (UserDataServiceProvider)getElementImplementingProvider(passwordProvider);
}
@Override

View File

@ -444,37 +444,21 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
}
@Override
public boolean savePasswordToRouter(Network network, NicProfile nic, VirtualMachineProfile<UserVm> profile, List<? extends VirtualRouter> routers) throws ResourceUnavailableException {
if (routers == null || routers.isEmpty()) {
s_logger.warn("Unable save password, router doesn't exist in network " + network.getId());
throw new CloudRuntimeException("Unable to save password to router");
}
public boolean savePasswordToRouter(Network network, final NicProfile nic, VirtualMachineProfile<UserVm> profile, List<? extends VirtualRouter> routers) throws ResourceUnavailableException {
_userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine());
UserVm userVm = profile.getVirtualMachine();
String password = (String) profile.getParameter(Param.VmPassword);
String encodedPassword = PasswordGenerator.rot13(password);
DataCenter dc = _dcDao.findById(userVm.getDataCenterIdToDeployIn());
final VirtualMachineProfile<UserVm> updatedProfile = profile;
boolean result = true;
for (VirtualRouter router : routers) {
boolean sendPassword = true;
if (dc.getNetworkType() == NetworkType.Basic && userVm.getPodIdToDeployIn().longValue() != router.getPodIdToDeployIn().longValue()) {
sendPassword = false;
return applyRules(network, routers, "save password entry", false, null, false, new RuleApplier() {
@Override
public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException {
// for basic zone, send vm data/password information only to the router in the same pod
Commands cmds = new Commands(OnError.Stop);
NicVO nicVo = _nicDao.findById(nic.getId());
createPasswordCommand(router, updatedProfile, nicVo, cmds);
return sendCommandsToRouter(router, cmds);
}
if (sendPassword) {
Commands cmds = new Commands(OnError.Continue);
SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), userVm.getHostName());
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId()));
cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn());
cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
cmds.addCommand("password", cmd);
result = result && sendCommandsToRouter(router, cmds);
}
}
return result;
});
}
@Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_STOP, eventDescription = "stopping router Vm", async = true)

View File

@ -1211,7 +1211,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId);
Map<String, String> hostDetails = _hostDetailsDao.findDetails(hostId);
if (guestOSCategory != null) {
if (guestOSCategory != null && !GuestOSCategoryVO.CATEGORY_NONE.equalsIgnoreCase(guestOSCategory.getName())) {
// Save a new entry for guest.os.category.id
hostDetails.put("guest.os.category.id", String.valueOf(guestOSCategory.getId()));
} else {

View File

@ -421,6 +421,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
userVm.setDetail("Encrypted.Password", encryptedPasswd);
_vmDao.saveDetails(userVm);
}
} else {
throw new CloudRuntimeException("Failed to reset password for the virtual machine ");
}
return userVm;
@ -448,15 +450,14 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
VirtualMachineProfile<VMInstanceVO> vmProfile = new VirtualMachineProfileImpl<VMInstanceVO>(vmInstance);
vmProfile.setParameter(VirtualMachineProfile.Param.VmPassword, password);
List<? extends UserDataServiceProvider> elements = _networkMgr.getPasswordResetElements();
boolean result = true;
for (UserDataServiceProvider element : elements) {
if (!element.savePassword(defaultNetwork, defaultNicProfile, vmProfile)) {
result = false;
}
UserDataServiceProvider element = _networkMgr.getPasswordResetProvider(defaultNetwork);
if (element == null) {
throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() +
" provider needed for password reset");
}
boolean result = element.savePassword(defaultNetwork, defaultNicProfile, vmProfile);
// Need to reboot the virtual machine so that the password gets redownloaded from the DomR, and reset on the VM
if (!result) {
s_logger.debug("Failed to reset password for the virutal machine; no need to reboot the vm");

View File

@ -610,7 +610,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS
}
@Override
public List<? extends UserDataServiceProvider> getPasswordResetElements() {
public UserDataServiceProvider getPasswordResetProvider(Network network) {
// TODO Auto-generated method stub
return null;
}

View File

@ -805,7 +805,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager{
* @see com.cloud.network.NetworkManager#getPasswordResetElements()
*/
@Override
public List<? extends UserDataServiceProvider> getPasswordResetElements() {
public UserDataServiceProvider getPasswordResetProvider(Network network) {
// TODO Auto-generated method stub
return null;
}

View File

@ -69,7 +69,7 @@ class DBDeployer(object):
dbDotProperties = {}
dbDotPropertiesIndex = 0
encryptionKeyFile = '@MSCONF@/key'
encryptionJarPath = '@JAVADIR@/cloud-jasypt-1.8.jar'
encryptionJarPath = '@JAVADIR@/jasypt-1.9.0.jar'
success = False
magicString = 'This_is_a_magic_string_i_think_no_one_will_duplicate'
tmpMysqlFile = os.path.join(os.path.expanduser('~/'), 'cloudstackmysql.tmp.sql')

View File

@ -466,3 +466,5 @@ UPDATE `cloud`.`configuration` SET description='Comma separated list of cidrs in
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'site2site.vpn.vpngateway.connection.limit', '4', 'The maximum number of VPN connection per VPN gateway');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'site2site.vpn.customergateway.subnets.limit', '10', 'The maximum number of subnets per customer gateway');
INSERT IGNORE INTO `cloud`.`guest_os_category` VALUES ('11','None',NULL);

View File

@ -48,7 +48,7 @@ INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (7, 'Other');
INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (8, 'Novel');
INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (9, 'Unix');
INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (10, 'Ubuntu');
INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (11, 'None');
INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (1, 1, 'CentOS 4.5 (32-bit)');
INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (2, 1, 'CentOS 4.6 (32-bit)');

View File

@ -1,300 +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.
from optparse import OptionParser
import sys
import os, os.path
import fnmatch
import time
class CopyRightDetecter(object):
def isCopyRightLine(self, txt):
return False
class KeyWordCopyRightDetecter(CopyRightDetecter):
keywords = ['Cloud.com', 'Copyright', '(C)', '2011', 'Citrix', 'Systems', 'Inc', 'All', 'rights', 'reserved', 'This', 'software', 'is', 'licensed', 'under', 'the',
'GNU', 'General', 'Public', 'License', 'v3', 'or', 'later', 'It', 'is', 'free', 'software:', 'you', 'can', 'redistribute', 'it', 'and/or', 'modify', 'it',
'under', 'the', 'terms', 'of', 'the', 'GNU', 'General', 'Public', 'License', 'as', 'published', 'by', 'the', 'Free', 'Software', 'Foundation', 'either',
'version', '3', 'of', 'the', 'License', 'or', 'any', 'later', 'version', 'This', 'program', 'is', 'distributed', 'in', 'the', 'hope', 'that', 'it', 'will',
'be', 'useful', 'but', 'WITHOUT', 'ANY', 'WARRANTY;', 'without', 'even', 'the', 'implied', 'warranty', 'of', 'MERCHANTABILITY', 'or', 'FITNESS', 'FOR', 'A',
'PARTICULAR', 'PURPOSE', 'See', 'the', 'GNU', 'General', 'Public', 'License', 'for', 'more', 'details', 'You', 'should', 'have', 'received', 'a', 'copy', 'of',
'the', 'GNU', 'General', 'Public', 'License', 'along', 'with', 'this', 'program', 'If', 'not', 'see', '<http://www.gnu.org/licenses/>', 'Version', '2', 'only',
'("GPL")', 'Common', 'Development', 'and', 'Distribution', 'License("CDDL")', '(collectively', 'License").', 'language', 'governing', 'permissions', 'limitations',
'License.', '-', 'When', 'distributing', 'include', 'Header', 'Notice', 'each', 'file', 'at', 'glassfish/bootstrap/legal/LICENSE.txt.', 'Sun', 'designates',
'particular', 'subject', 'to', 'Classpath', 'exception', 'provided', 'GPL', 'section', 'accompanied', 'code.', 'applicable', 'add', 'following', 'below',
'fields', 'enclosed', 'brackets', 'replaced', 'your', 'own', 'identifying', 'information', 'Portions', 'Copyrighted', 'year', 'name', 'copyright', 'owner]',
'Contributor(s)', 'indicate', 'decision', 'adding', '[Contributor', 'elects', 'distribution', 'CDDL', 'license.', "don't", 'single', 'choice', 'license',
'recipient', 'has', 'option', 'distribute', 'extend', 'its', 'licensees', 'above.', 'However', 'if', 'code', 'therefore', 'elected', 'then', 'applies', 'new',
'made', 'such', 'holder.']
def isCopyRightLine(self, txt):
words = [ c.strip().strip('.').strip('\n').strip(',').strip() for c in txt.split(" ") ]
total = len(words)
if total == 0: return False
numKeyWord = 0
for w in words:
if w == "": continue
if w in self.keywords: numKeyWord+=1
if float(numKeyWord)/float(total) >= float(1)/float(2): return True
return False
copyRightDetectingFactory = {"KeyWord":KeyWordCopyRightDetecter.__name__}
logfd = open("/tmp/addcopyright.log", 'w')
class Logger(object):
@staticmethod
def info(msg):
sys.stdout.write("INFO: %s"%msg)
sys.stdout.write("\n")
sys.stdout.flush()
@staticmethod
def debug(msg):
logfd.write("DEBUG: %s"%msg)
logfd.write("\n")
@staticmethod
def warn(msg):
sys.stdout.write("WARNNING: %s"%msg)
sys.stdout.write("\n")
sys.stdout.flush()
@staticmethod
def error(msg):
sys.stderr.write("ERROR: %s"%msg)
sys.stderr.write("\n")
sys.stderr.flush()
class Adder(object):
defaultTxt = '''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.
'''
copyRightTxt = None
targetFile = None
fileBody = None
decter = None
signature = 'Automatically generated by addcopyright.py at %s' % time.strftime("%m/%d/%Y", time.localtime())
COMMENT_NOTATION = ""
def __init__(self):
self.decter = eval(copyRightDetectingFactory["KeyWord"])()
def setTargetFile(self, fpath):
self.targetFile = fpath
if not os.path.exists(self.targetFile):
raise Exception("Cannot find %s"%self.targetFile)
def setCopyRightTxt(self, txt):
self.copyRightTxt = txt.split("\n")
def checkParams(self):
assert self.targetFile != None, "Target file not set"
if self.copyRightTxt == None:
self.copyRightTxt = self.defaultTxt.split("\n")
def pasteCopyRight(self):
self.fileBody = self.copyRightTxt + self.fileBody
file(self.targetFile, 'w').write("".join(self.fileBody))
Logger.info("Added copyright header to %s"%self.targetFile)
def composeCopyRight(self):
l = self.copyRightTxt
l.append(self.signature)
l = [ self.COMMENT_NOTATION + " " + line + "\n" for line in l ]
self.copyRightTxt = l
def getFileBody(self):
self.fileBody = file(self.targetFile).readlines()
def isCommentLine(self, line):
if line.strip().startswith(self.COMMENT_NOTATION):
return True
return False
def removeOldCopyRight(self):
newBody = []
removed = False
for line in self.fileBody[0:50]:
if self.isCommentLine(line) and self.decter.isCopyRightLine(line):
removed = True
Logger.debug("remove old copyright: %s" % line)
continue
newBody.append(line)
self.fileBody = newBody + self.fileBody[50:]
if removed:
Logger.info("Removed old copyright header of %s"%self.targetFile)
def cleanBlankComment(self):
newBody = []
for l in self.fileBody[0:50]:
if self.isCommentLine(l) and l.strip().strip(self.COMMENT_NOTATION).strip().strip('\n') == "":
Logger.debug("Blank Comment: %s" % l)
continue
newBody.append(l)
self.fileBody = newBody + self.fileBody[50:]
def doWork(self):
self.checkParams()
self.getFileBody()
self.removeOldCopyRight()
self.composeCopyRight()
self.cleanBlankComment()
self.pasteCopyRight()
class SqlAdder(Adder):
def __init__(self):
super(SqlAdder, self).__init__()
self.COMMENT_NOTATION = "#"
class InterpreterAdder(Adder):
def __init__(self):
super(InterpreterAdder, self).__init__()
self.COMMENT_NOTATION = "#"
def pasteCopyRight(self):
if len(self.fileBody) > 0 and self.isCommentLine(self.fileBody[0]):
# Don't cover the first line of interpreter comment
self.fileBody = [self.fileBody[0]] + self.copyRightTxt + self.fileBody[1:]
else:
self.fileBody = self.copyRightTxt + self.fileBody
file(self.targetFile, 'w').write("".join(self.fileBody))
Logger.info("Added copyright header to %s"%self.targetFile)
class JavaAdder(Adder):
commentOn = False
def __init__(self):
super(JavaAdder, self).__init__()
self.COMMENT_NOTATION = '//'
def isCommentLine(self, line):
if line.strip().startswith('//'):
return True
elif line.strip().startswith('/*'):
self.commentOn = True
return True
elif self.commentOn == True and line.find('*/') != -1:
self.commentOn = False
return True
elif self.commentOn:
return True
else:
return False
def cleanBlankComment(self):
#TODO
pass
copyRightAdderFactory = {".sql":SqlAdder.__name__, ".sh":InterpreterAdder.__name__, ".py":InterpreterAdder.__name__}
class CopyRightAdder(object):
parser = None
options = None
args = None
targetFiles = None
excludeFiles = None
copyRightFileTxt = None
rootDir = None
def errAndExit(self, msg):
Logger.error(msg)
Logger.info("addcopyright -h for help")
sys.exit(1)
def __init__(self):
usage = '''Usage: addcopyright [file_name_pattern] [--exculdes=file_name_pattern] [--file=copyright_file] [--root=root_dir_of_files_to_add_header] [--replace]
Examples:
addcopyright
addcopyright *.sql
addcopyright *.sql --excludes="*.sql~"
addcopyright *.sql --file=/root/Citrix.copyright
addcopyright *.sql --file=/root/Citrix.copyright --root=~/cloudstack-oss
'''
self.parser = OptionParser(usage=usage)
self.parser.add_option("", "--excludes", action="store", type="string", dest="excludes", default="",
help="Exclude these files when adding copyright header")
self.parser.add_option("", "--file", action="store", type="string", dest="copyRightFile", default="",
help="Path to copyright header file. Default to Citrix copyright header")
self.parser.add_option("", "--root", action="store", type="string", dest="rootDir", default="",
help="Root folder where files being added copyright header locate. Default to current directory")
(self.options, self.args) = self.parser.parse_args()
if len(self.args) > 1:
self.errAndExit("Invalid arguments:%s" % self.args)
if len(self.args) == 1:
self.targetFiles = self.args[0]
if self.options.excludes != "":
self.excludeFiles = self.options.excludes
if self.options.copyRightFile != "":
self.copyRightFileTxt = file(self.options.copyRightFile).read()
if self.options.rootDir != "":
self.rootDir = os.path.expanduser(self.options.rootDir)
if not os.path.isdir(self.rootDir): raise Exception("Cannot find directory %s"%self.rootDir)
else:
self.rootDir = os.getcwd()
def createConcreteAdder(self, filename):
(x, ext) = os.path.splitext(filename)
if not copyRightAdderFactory.has_key(ext): return None
return eval(copyRightAdderFactory[ext])()
def run(self):
for root, dirs, files in os.walk(self.rootDir):
for f in files:
fpath = os.path.join(root, f)
if self.excludeFiles != None and fnmatch.fnmatch(f, self.excludeFiles):
Logger.info("Skipping excluded file %s" % fpath)
continue
if self.targetFiles != None and not fnmatch.fnmatch(f, self.targetFiles):
Logger.info("Skipping %s not matching our file name pattern" % fpath)
continue
adder = self.createConcreteAdder(f)
if adder == None:
Logger.warn("Cannot find a proper copyright Adder for %s, skip it" % fpath)
continue
adder.setTargetFile(fpath)
if self.copyRightFileTxt != None:
adder.setCopyRightTxt(self.copyRightFileTxt)
adder.doWork()
if __name__ == '__main__':
task = CopyRightAdder()
task.run()

105
tools/build/build_asf.sh Executable file
View File

@ -0,0 +1,105 @@
#!/bin/sh
# 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.
version='TESTBUILD'
sourcedir=~/incubator-cloudstack/
outputdir=~/cs-asf-build/
branch='master'
tag='no'
certid='X'
usage(){
echo "usage: $0 -v version [-b branch] [-s source dir] [-o output dir] [-t [-u]] [-h]"
echo " -v sets the version"
echo " -b sets the branch (defaults to 'master')"
echo " -s sets the source directory (defaults to $sourcedir)"
echo " -o sets the output directory (defaults to $outputdir)"
echo " -t tags the git repo with the version"
echo " -u sets the certificate ID to sign the tag with (if not provided, the default key is attempted)"
echo " -h"
}
while getopts v:s:o:b:tu:h opt
do
case "$opt" in
v) version="$OPTARG";;
s) sourcedir="$OPTARG";;
o) outputdir="$OPTARG";;
b) branch="$OPTARG";;
t) tag='yes';;
u) certid="$OPTARG";;
h) usage
exit 0;;
\?) # unknown flag
usage
exit 1;;
esac
done
shift `expr $OPTIND - 1`
if [ $version == 'TESTBUILD' ]; then
echo >&2 "A version must be specified with the -v option: build_asf.sh -v 4.0.0RC1"
exit 1
fi
echo "Using version: $version"
echo "Using source directory: $sourcedir"
echo "Using output directory: $outputdir"
echo "Using branch: $branch"
if [ $tag == 'yes' ]; then
if [ $certid == 'X' ]; then
echo "Tagging the branch with the version number, and signing the branch with your default certificate."
else
echo "Tagging the branch with the version number, and signing the branch with certificate ID $certid."
fi
else
echo "The branch will not be tagged. You should consider doing this."
fi
if [ -d "$outputdir" ]; then
rm $outputdir/*
else
mkdir $outputdir
fi
cp $sourcedir/KEYS $outputdir/KEYS
cd $sourcedir
git archive --format=tar.gz --prefix=$version/ $branch > $outputdir/cloudstack-source-$version.tar.gz
git archive --format=zip --prefix=$version/ $branch > $outputdir/cloudstack-source-$version.zip
cd $outputdir
gpg -v --armor --output cloudstack-source-$version.tar.gz.asc --detach-sig cloudstack-source-$version.tar.gz
gpg -v --armor --output cloudstack-source-$version.zip.asc --detach-sig cloudstack-source-$version.zip
gpg -v --print-md MD5 cloudstack-source-$version.tar.gz > cloudstack-source-$version.tar.gz.md5
gpg -v --print-md MD5 cloudstack-source-$version.zip > cloudstack-source-$version.zip.md5
gpg -v --print-md SHA512 cloudstack-source-$version.tar.gz > cloudstack-source-$version.tar.gz.sha
gpg -v --print-md SHA512 cloudstack-source-$version.zip > cloudstack-source-$version.zip.sha
gpg -v --verify cloudstack-source-$version.tar.gz.asc cloudstack-source-$version.tar.gz
gpg -v --verify cloudstack-source-$version.zip.asc cloudstack-source-$version.zip
if [ $tag == 'yes' ]; then
cd $sourcedir
if [ $certid == 'X' ]; then
git tag -s $version -m "Tagging release $version on branch $branch."
else
git tag -u $certid -s $version -m "Tagging release $version on branch $branch."
fi
fi

View File

@ -2400,6 +2400,10 @@ this distribution.
id='citrix.com'
name='Citrix Systems, Inc'
url='http://www.citrix.com/' />
<organisation
id='caringo.com'
name='Caringo, Inc.'
url='http://www.caringo.com/' />
</organisations>
<primary-license id='ApacheLicenseVersion2'>
<copyright-notice>Copyright (c) 2012 The Apache Software Foundation</copyright-notice>
@ -2516,6 +2520,7 @@ Updated November 2009 with contributions from: btburnett3, Anthony Aragues and X
</by-organisation>
</with-license>
<with-license id='MIT'>
<copyright-notice />
<by-organisation id='person:ole.laursen'>
<resource name="jquery.colorhelpers.js" notice='jquery.colorhelpers.notice' />
</by-organisation>
@ -2523,6 +2528,7 @@ Updated November 2009 with contributions from: btburnett3, Anthony Aragues and X
</within>
<within dir='ui/lib/jquery-ui'>
<with-license id='MIT'>
<copyright-notice />
<by-organisation id='jqueryui.com'>
<resource name="css/jquery-ui.css" />
<resource name="js/jquery-ui.js" />
@ -2531,10 +2537,10 @@ Updated November 2009 with contributions from: btburnett3, Anthony Aragues and X
</with-license>
</within>
<within dir='ui/lib/qunit'>
<copyright-notice>
Copyright © 2012 John Resig, Jörn Zaefferer
</copyright-notice>
<with-license id='MIT'>
<copyright-notice>
Copyright © 2012 John Resig, Jörn Zaefferer
</copyright-notice>
<by-organisation id='person:jorn.zaefferer'>
<resource name="qunit.css" source='http://docs.jquery.com/QUnit' />
<resource name="qunit.js" source='http://docs.jquery.com/QUnit' />
@ -2585,6 +2591,9 @@ Copyright © 2012 The Apache Software Foundation
</by-organisation>
</with-license>
<with-license id="ApacheLicenseVersion1.1">
<copyright-notice>
Copyright © 2012 The Apache Software Foundation
</copyright-notice>
<by-organisation id="apache.org">
<resource name="cloud-commons-discovery.jar" source="http://commons.apache.org/discovery/" />
</by-organisation>
@ -2640,6 +2649,14 @@ Copyright © 2012 The Eclipse Foundation.
</with-license>
<with-license id='BSD3ClauseGeneric'>
<copyright-notice>
Copyright © 2009, Caringo, Inc.
</copyright-notice>
<by-organisation id='caringo.com'>
<resource name='CAStorSDK.jar' source='http://www.castor.org/download.html' />
</by-organisation>
</with-license>
<with-license id='BSD3ClauseGeneric'>
<copyright-notice>
Copyright © 2002-2011 Atsuhiko Yamanaka, JCraft,Inc.
</copyright-notice>
<by-organisation id='jcraft.com'>
@ -2656,11 +2673,13 @@ Copyright © IBM Corp 2006
</by-organisation>
</with-license>
<with-license id='xstream.bsd'>
<copyright-notice />
<by-organisation id='xstream.codehaus.com'>
<resource name='cloud-xstream-1.3.1.jar' source='http://xstream.codehaus.org/repository.html' />
</by-organisation>
</with-license>
<with-license id='bouncy.mit'>
<copyright-notice />
<by-organisation id='bouncy.castle'>
<resource name='cloud-bcprov-jdk16-1.45.jar' source='http://repo1.maven.org/maven2/org/bouncycastle/bcprov-jdk16/1.45/bcprov-jdk16-1.45-sources.jar' />
</by-organisation>
@ -2675,12 +2694,14 @@ All rights reserved.
</by-organisation>
</with-license>
<with-license id='ApacheLicenseVersion2'>
<copyright-notice />
<by-organisation id='jetty.codehaus.com'>
<resource name='jetty-6.1.26.jar' source='http://repo1.maven.org/maven2/org/mortbay/jetty/jetty/6.1.26/jetty-6.1.26-sources.jar' />
<resource name='jetty-util-6.1.26.jar' source='http://repo1.maven.org/maven2/org/mortbay/jetty/jetty-util/6.1.26/jetty-util-6.1.26-sources.jar' />
</by-organisation>
</with-license>
<with-license id='CPL1'>
<copyright-notice />
<by-organisation id='junit.org'>
<resource name='cloud-junit.jar' source='http://kentbeck.github.com/junit/' />
</by-organisation>
@ -2731,6 +2752,7 @@ Copyright © 2004-2008 The Apache Software Foundation
</by-organisation>
</with-license>
<with-license id='antlr2'>
<copyright-notice />
<by-organisation id='antlr2.org'>
<resource name='antlr-2.7.6.jar' source='http://repo1.maven.org/maven2/antlr/antlr/2.7.6/antlr-2.7.6-sources.jar' />
</by-organisation>
@ -2788,6 +2810,7 @@ Copyright © 2009 Google Inc.
</by-organisation>
</with-license>
<with-license id='dom4j.license'>
<copyright-notice />
<by-organisation id='dom4j.sourceforge.net'>
<!-- TODO: Need to have a review of this license! -->
<resource name='dom4j-1.6.1.jar' source='http://dom4j.sourceforge.net/source-repository.html' />
@ -2820,6 +2843,7 @@ Copyright © 2002-2011 Atsuhiko Yamanaka, JCraft,Inc.
</by-organisation>
</with-license>
<with-license id='ApacheLicenseVersion2'>
<copyright-notice />
<by-organisation id='json-simple'>
<resource name='json_simple-1.1.jar' source='http://code.google.com/p/json-simple/source/checkout' />
</by-organisation>
@ -2833,11 +2857,13 @@ Copyright © 1997-2010 Oracle and/or its affiliates. All rights reserved.
</by-organisation>
</with-license>
<with-license id='CPL1'>
<copyright-notice />
<by-organisation id='junit.org'>
<resource name='junit-4.8.1.jar' source='http://kentbeck.github.com/junit/' />
</by-organisation>
</with-license>
<with-license id='MPL1'>
<copyright-notice />
<license-parameters>
<parameter><name>PROJECT</name><value>Javassist</value></parameter>
<parameter><name>INITIAL_DEVELOPER</name><value>Shigeru Chiba</value></parameter>

View File

@ -7635,7 +7635,7 @@
var array1 = [];
array1.push("&hosttags=" + todb(args.data.hosttags));
if (args.data.oscategoryid != null && args.data.oscategoryid != 'None')
if (args.data.oscategoryid != null)
array1.push("&osCategoryId=" + args.data.oscategoryid);
$.ajax({
@ -7852,11 +7852,12 @@
async: true,
success: function(json) {
var oscategoryObjs = json.listoscategoriesresponse.oscategory;
var items = [
{ id: null, description: _l('label.none') }
];
var items = [];
$(oscategoryObjs).each(function() {
items.push({id: this.id, description: this.name});
if(this.name == 'None')
items.unshift({ id: this.id, description: _l('label.none') });
else
items.push({id: this.id, description: this.name});
});
args.response.success({data: items});
}

View File

@ -20,7 +20,6 @@ under the License.
This is the version information for the manifests in the JAR files.
Implementation_Version: @Implementation_Version@
Ant arguments: @ant_args@
This file exists solely to trigger ant recompilation if it is needed.
Otherwise, JAR files and all the dependent files are brought from cache.

View File

@ -636,6 +636,7 @@ def rpm(context):
shutil.move(tarball,_join(sourcedir,tarball))
specfile = "%s.spec"%APPNAME
Utils.exec_command("mvn install -P deps")
checkdeps = lambda: c(["rpmbuild","--define","_topdir %s"%outputdir,"--nobuild",specfile]+packagever+releasever)
dorpm = lambda: c(["rpmbuild","--define","_topdir %s"%outputdir,"-bb",specfile]+buildnumber+prerelease+packagever+releasever)
try: checkdeps()

View File

@ -161,10 +161,10 @@ def build_dependences ():
"cloud-commons-collections-3.2.1.jar", "cloud-wsdl4j.jar"]
start_path = bld.path.find_dir ("deps")
bld.install_files('${JAVADIR}',start_path.ant_glob("*.jar", excl = excludes), cwd=start_path)
if buildpremium:
start_path = bld.path.find_dir ("cloudstack-proprietary/premium/deps")
bld.install_files('${JAVADIR}',start_path.ant_glob("*.jar", excl = excludes), cwd=start_path)
bld.install_files('${JAVADIR}',start_path.ant_glob(["commons-codec-1.6.jar", "ejb-api-3.0.jar", "xmlrpc-client-3.1.3.jar", "commons-dbcp-1.4.jar", "commons-pool-1.6.jar", "gson-1.7.1.jar",
"netscaler-1.0.jar", "netscaler-sdx-1.0.jar", "backport-util-concurrent-3.1.jar", "ehcache-1.5.0.jar", "httpcore-4.0.jar", "log4j-1.2.16.jar", "trilead-ssh2-build213-svnkit-1.3-patch.jar", "cglib-2.2.jar", "xmlrpc-common-3.*.jar",
"xmlrpc-client-3.*.jar", "axis-1.4.jar", "wsdl4j-1.6.2.jar", "bcprov-jdk16-1.46.jar", "jsch-0.1.42.jar", "jasypt-1.9.0.jar", "commons-configuration-1.8.jar", "commons-lang-2.6.jar", "mail-1.4.jar", "activation-1.1.jar", "mysql-connector-java-5.1.21.jar", "hibernate-jpa-2.0-api-1.0.0.Final.jar", "hibernate-entitymanager-3.5.1-Final.jar", "hibernate-core-3.5.1-Final.jar", "hibernate-commons-annotations-3.2.0.Final.jar", "hibernate-annotations-3.5.1-Final.jar", "asm-3.1.jar", "xapi-5.6.100-1-SNAPSHOT.jar"], excl = excludes), cwd=start_path)
#def build_console_proxy ():
# binary unsubstitutable files:

View File

@ -61,12 +61,23 @@ systemjars = {
"tomcat6-servlet-2.5-api.jar",
"tomcat6-el-2.1-api-6.0.24.jar",
"tomcat6-jsp-2.1-api-6.0.24.jar",
"jakarta-taglibs-core-1.1.1.jar",
"jakarta-taglibs-standard-1.1.1.jar",
"tomcat6/jasper.jar",
"tomcat6/jasper-el.jar",
"tomcat6/jasper-jdt.jar",
),
'CentOS':
(
"tomcat6-servlet-2.5-api.jar",
"tomcat6-jsp-2.1-api-6.0.24.jar",
"tomcat6-el-2.1-api-6.0.24.jar",
"jakarta-taglibs-core-1.1.1.jar",
"jakarta-taglibs-standard-1.1.1.jar",
"tomcat6/jasper.jar",
"tomcat6/jasper-el.jar",
"tomcat6/jasper-jdt.jar",
#"tomcat6/catalina.jar", # all supported distros put the file there
),
'Ubuntu':