diff --git a/INSTALL.md b/INSTALL.md index 00c724b11b4..a2137fdf69d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -51,19 +51,21 @@ Apache CloudStack uses some ports, make sure at least those used by the manageme server are available and not blocked by any local firewall. Following ports are used by Apache CloudStack and its entities: - 8787: Apache CloudStack (Tomcat) debug socket - 9090, 8250, 8080: Apache CloudStack Management Server, User/Client API - 8096: User/Client to CloudStack Management Server (unauthenticated) - 7080: AWS API Server - 3306: MySQL Server - 3922, 8250, 80/443, 111/2049, 53: Secondary Storage VM - 3922, 8250, 53: Console Proxy VM - 3922, 8250, 53: Virtual Router + 8080: API Server (authenticated), browser or CLI client to management server + 8096: API Server (unauthenticated), browser or CLI client to management server + 8787: Remote java debug debugging port, from IDE to management server + 9090: Management server to management server (cluster) + 7080: AWS API Server to which an AWS client can connect + 80/443: HTTP client to Secondary Storage VM (template download) + 111/2049: Secondary Storage to NFS server + 3922: Port used to ssh/scp into system vms (SSVM, CPVM, VR) + 8250: Agent (SSVM, CPVM, VR) to management server 22, 80, 443: XenServer, XAPI 22: KVM 443: vCenter - DNS: 53 - NFS: 111/2049 + 53: DNS + 111/2049: NFS + 3306: MySQL Server to which the management server connects ### Configuring MySQL Server @@ -93,8 +95,7 @@ For example, for master: Clean and build: - $ mvn clean - $ mvn install + $ mvn clean install -P systemvm,developer In case you want support for VMWare, SRX and other non-Apache (referred to as nonoss) compliant libs, you may download the following jar artifacts from respective vendors: @@ -112,9 +113,9 @@ Install them to ~/.m2 so maven can get them as dependencies: $ cd deps $ ./install-non-oss.sh -And build them with the nonoss flag: +To build with nonoss components, use the build command with the nonoss flag: - $ mvn install -Dnonoss + $ mvn clean install -P systemvm,developer -Dnonoss Clear old database (if any) and deploy the database schema: @@ -122,7 +123,7 @@ Clear old database (if any) and deploy the database schema: Export the following variable if you need to run and debug the management server: - $ export MAVEN_OPTS="-Xmx1024m -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n" + $ export MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=500m -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n" Start the management server: diff --git a/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java b/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java index 85011175536..eb862e62f47 100644 --- a/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java @@ -52,6 +52,8 @@ public class ListCapabilitiesCmd extends BaseCmd { response.setProjectInviteRequired((Boolean)capabilities.get("projectInviteRequired")); response.setAllowUsersCreateProjects((Boolean)capabilities.get("allowusercreateprojects")); response.setDiskOffMaxSize((Long)capabilities.get("customDiskOffMaxSize")); + response.setApiLimitInterval((Integer)capabilities.get("apiLimitInterval")); + response.setApiLimitMax((Integer)capabilities.get("apiLimitMax")); response.setObjectName("capability"); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java b/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java index 4afa604577f..c2996f0aa0a 100644 --- a/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java +++ b/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java @@ -46,6 +46,12 @@ public class CapabilitiesResponse extends BaseResponse { "create disk from disk offering with custom size") private Long diskOffMaxSize; + @SerializedName("apilimitinterval") @Param(description="time interval (in seconds) to reset api count") + private Integer apiLimitInterval; + + @SerializedName("apilimitmax") @Param(description="Max allowed number of api requests within the specified interval") + private Integer apiLimitMax; + public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) { this.securityGroupsEnabled = securityGroupsEnabled; @@ -75,4 +81,13 @@ public class CapabilitiesResponse extends BaseResponse { this.diskOffMaxSize = diskOffMaxSize; } + public void setApiLimitInterval(Integer apiLimitInterval) { + this.apiLimitInterval = apiLimitInterval; + } + + public void setApiLimitMax(Integer apiLimitMax) { + this.apiLimitMax = apiLimitMax; + } + + } diff --git a/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java b/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java index 57a32a48289..0186db4ad08 100644 --- a/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java +++ b/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java @@ -87,6 +87,7 @@ import com.amazon.ec2.DetachVolumeResponse; import com.amazon.ec2.DisassociateAddressResponse; import com.amazon.ec2.GetPasswordDataResponse; import com.amazon.ec2.ImportKeyPairResponse; +import com.amazon.ec2.LaunchPermissionItemType; import com.amazon.ec2.ModifyImageAttributeResponse; import com.amazon.ec2.RebootInstancesResponse; import com.amazon.ec2.RegisterImageResponse; @@ -104,14 +105,17 @@ import com.cloud.bridge.persist.dao.CloudStackUserDaoImpl; import com.cloud.bridge.persist.dao.OfferingDaoImpl; import com.cloud.bridge.persist.dao.UserCredentialsDaoImpl; import com.cloud.bridge.service.controller.s3.ServiceProvider; +import com.cloud.bridge.service.core.ec2.EC2AddressFilterSet; import com.cloud.bridge.service.core.ec2.EC2AssociateAddress; import com.cloud.bridge.service.core.ec2.EC2AuthorizeRevokeSecurityGroup; +import com.cloud.bridge.service.core.ec2.EC2AvailabilityZonesFilterSet; import com.cloud.bridge.service.core.ec2.EC2CreateImage; import com.cloud.bridge.service.core.ec2.EC2CreateKeyPair; import com.cloud.bridge.service.core.ec2.EC2CreateVolume; import com.cloud.bridge.service.core.ec2.EC2DeleteKeyPair; import com.cloud.bridge.service.core.ec2.EC2DescribeAddresses; import com.cloud.bridge.service.core.ec2.EC2DescribeAvailabilityZones; +import com.cloud.bridge.service.core.ec2.EC2DescribeImageAttribute; import com.cloud.bridge.service.core.ec2.EC2DescribeImages; import com.cloud.bridge.service.core.ec2.EC2DescribeInstances; import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairs; @@ -123,10 +127,13 @@ import com.cloud.bridge.service.core.ec2.EC2Engine; import com.cloud.bridge.service.core.ec2.EC2Filter; import com.cloud.bridge.service.core.ec2.EC2GroupFilterSet; import com.cloud.bridge.service.core.ec2.EC2Image; +import com.cloud.bridge.service.core.ec2.EC2ImageAttributes.ImageAttribute; +import com.cloud.bridge.service.core.ec2.EC2ImageLaunchPermission; import com.cloud.bridge.service.core.ec2.EC2ImportKeyPair; import com.cloud.bridge.service.core.ec2.EC2InstanceFilterSet; import com.cloud.bridge.service.core.ec2.EC2IpPermission; import com.cloud.bridge.service.core.ec2.EC2KeyPairFilterSet; +import com.cloud.bridge.service.core.ec2.EC2ModifyImageAttribute; import com.cloud.bridge.service.core.ec2.EC2RebootInstances; import com.cloud.bridge.service.core.ec2.EC2RegisterImage; import com.cloud.bridge.service.core.ec2.EC2ReleaseAddress; @@ -1021,38 +1028,105 @@ public class EC2RestServlet extends HttpServlet { serializeResponse(response, EC2response); } - private void modifyImageAttribute( HttpServletRequest request, HttpServletResponse response ) + private void modifyImageAttribute( HttpServletRequest request, HttpServletResponse response ) throws ADBException, XMLStreamException, IOException { - EC2Image image = new EC2Image(); + EC2ModifyImageAttribute ec2request = new EC2ModifyImageAttribute(); - // -> its interesting to note that the SOAP API docs has description but the REST API docs do not - String[] imageId = request.getParameterValues( "ImageId" ); - if ( null != imageId && 0 < imageId.length ) - image.setId( imageId[0] ); - else { response.sendError(530, "Missing ImageId parameter" ); return; } + String[] imageId = request.getParameterValues( "ImageId" ); + if ( imageId != null && imageId.length > 0 ) + ec2request.setImageId( imageId[0]); + else { + response.sendError(530, "Missing ImageId parameter" ); + return; + } - String[] description = request.getParameterValues( "Description" ); - if ( null != description && 0 < description.length ) - image.setDescription( description[0] ); - else { response.sendError(530, "Missing Description parameter" ); return; } + String[] description = request.getParameterValues( "Description.Value" ); + if ( description != null && description.length > 0 ) { + ec2request.setAttribute(ImageAttribute.description); + ec2request.setDescription(description[0]); + } else { + //add all launch permissions to ec2request + ec2request = addLaunchPermImageAttribute(request, ec2request); + if (ec2request.getLaunchPermissionSet().length > 0) + ec2request.setAttribute(ImageAttribute.launchPermission); + else { + response.sendError(530, "Missing Attribute parameter - Description/LaunchPermission should be provided" ); + return; + } + } // -> execute the request - ModifyImageAttributeResponse EC2response = EC2SoapServiceImpl.toModifyImageAttributeResponse( ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute( image )); + ModifyImageAttributeResponse EC2response = EC2SoapServiceImpl.toModifyImageAttributeResponse( + ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute( ec2request )); serializeResponse(response, EC2response); } + private EC2ModifyImageAttribute addLaunchPermImageAttribute(HttpServletRequest request, EC2ModifyImageAttribute ec2request) { + String[] users = {".UserId", ".Group"}; + String[] operations = {"LaunchPermission.Add.", "LaunchPermission.Remove."}; + int nCount = 1; + + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + List launchPermissionList = new ArrayList(); + do { + String[] launchPermissionAddGroup = request.getParameterValues( operations[j] + nCount + users[i] ); + if (launchPermissionAddGroup != null && launchPermissionAddGroup.length > 0) + launchPermissionList.add(launchPermissionAddGroup[0]); + else + break; + nCount++; + } while (true); + if (nCount != 1) { + EC2ImageLaunchPermission ec2LaunchPermission = new EC2ImageLaunchPermission(); + if (operations[j].contains("Add")) + ec2LaunchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.add); + else + ec2LaunchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.remove); + for (String launchPerm : launchPermissionList) { + ec2LaunchPermission.addLaunchPermission(launchPerm); + } + ec2request.addLaunchPermission(ec2LaunchPermission); + nCount = 1; + } + } + } + + return ec2request; + } + private void resetImageAttribute( HttpServletRequest request, HttpServletResponse response ) throws ADBException, XMLStreamException, IOException { - EC2Image image = new EC2Image(); + EC2ModifyImageAttribute ec2request = new EC2ModifyImageAttribute(); String[] imageId = request.getParameterValues( "ImageId" ); - if ( null != imageId && 0 < imageId.length ) - image.setId( imageId[0] ); - else { response.sendError(530, "Missing ImageId parameter" ); return; } + if ( imageId != null && imageId.length > 0) + ec2request.setImageId(imageId[0]); + else { + response.sendError(530, "Missing ImageId parameter" ); + return; + } + + String[] attribute = request.getParameterValues( "Attribute" ); + if ( attribute != null && attribute.length > 0 ) { + if (attribute[0].equalsIgnoreCase("launchPermission")) + ec2request.setAttribute(ImageAttribute.launchPermission); + else { + response.sendError(501, "Unsupported Attribute - only launchPermission supported" ); + return; + } + } else { + response.sendError(530, "Missing Attribute parameter" ); + return; + } + + EC2ImageLaunchPermission launchPermission = new EC2ImageLaunchPermission(); + launchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.reset); + ec2request.addLaunchPermission(launchPermission); // -> execute the request - image.setDescription( "" ); - ResetImageAttributeResponse EC2response = EC2SoapServiceImpl.toResetImageAttributeResponse( ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute( image )); + ResetImageAttributeResponse EC2response = EC2SoapServiceImpl.toResetImageAttributeResponse( + ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute( ec2request )); serializeResponse(response, EC2response); } @@ -1214,6 +1288,17 @@ public class EC2RestServlet extends HttpServlet { if (null != value && 0 < value.length) EC2request.addZone( value[0] ); } } + + // add filters + EC2Filter[] filterSet = extractFilters( request ); + if ( filterSet != null ) { + EC2AvailabilityZonesFilterSet afs = new EC2AvailabilityZonesFilterSet(); + for( int i=0; i < filterSet.length; i++ ) { + afs.addFilter(filterSet[i]); + } + EC2request.setFilterSet( afs ); + } + // -> execute the request DescribeAvailabilityZonesResponse EC2response = EC2SoapServiceImpl.toDescribeAvailabilityZonesResponse( ServiceProvider.getInstance().getEC2Engine().handleRequest( EC2request )); serializeResponse(response, EC2response); @@ -1240,25 +1325,35 @@ public class EC2RestServlet extends HttpServlet { private void describeImageAttribute( HttpServletRequest request, HttpServletResponse response ) throws ADBException, XMLStreamException, IOException { - EC2DescribeImages EC2request = new EC2DescribeImages(); + EC2DescribeImageAttribute ec2request = new EC2DescribeImageAttribute(); - // -> only works for queries about descriptions - String[] descriptions = request.getParameterValues( "Description" ); - if ( null != descriptions && 0 < descriptions.length ) { - String[] value = request.getParameterValues( "ImageId" ); - EC2request.addImageSet( value[0] ); - } + String[] imageId = request.getParameterValues( "ImageId" ); + if (imageId != null && imageId.length > 0) + ec2request.setImageId(imageId[0]); else { - response.sendError(501, "Unsupported - only description supported" ); + response.sendError(530, "Missing ImageId parameter"); return; } - // -> execute the request - DescribeImageAttributeResponse EC2response = EC2SoapServiceImpl.toDescribeImageAttributeResponse( ServiceProvider.getInstance().getEC2Engine().describeImages( EC2request )); + String[] attribute = request.getParameterValues( "Attribute" ); + if (attribute != null && attribute.length > 0) { + if (attribute[0].equalsIgnoreCase("description")) + ec2request.setAttribute(ImageAttribute.description); + else if (attribute[0].equalsIgnoreCase("launchPermission")) + ec2request.setAttribute(ImageAttribute.launchPermission); + else { + response.sendError(501, "Unsupported Attribute - description and launchPermission supported" ); + return; + } + } else { + response.sendError(530, "Missing Attribute parameter"); + return; + } + + DescribeImageAttributeResponse EC2response = EC2SoapServiceImpl.toDescribeImageAttributeResponse( ServiceProvider.getInstance().getEC2Engine().describeImageAttribute( ec2request )); serializeResponse(response, EC2response); } - private void describeInstances( HttpServletRequest request, HttpServletResponse response ) throws ADBException, XMLStreamException, IOException { @@ -1303,6 +1398,15 @@ public class EC2RestServlet extends HttpServlet { if (null != value && 0 < value.length) ec2Request.addPublicIp( value[0] ); } } + + // add filters + EC2Filter[] filterSet = extractFilters( request ); + if ( filterSet != null ) { + EC2AddressFilterSet afs = new EC2AddressFilterSet(); + for ( int i=0; i < filterSet.length; i++ ) + afs.addFilter( filterSet[i] ); + ec2Request.setFilterSet( afs ); + } // -> execute the request EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); serializeResponse(response, EC2SoapServiceImpl.toDescribeAddressesResponse( engine.describeAddresses( ec2Request))); diff --git a/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java b/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java index b2451c6a0cb..6fae480e222 100644 --- a/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java +++ b/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java @@ -47,6 +47,7 @@ import com.cloud.bridge.service.core.ec2.EC2DescribeInstances; import com.cloud.bridge.service.core.ec2.EC2DescribeInstancesResponse; import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairs; import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairsResponse; +import com.cloud.bridge.service.core.ec2.EC2ImageLaunchPermission; import com.cloud.bridge.service.core.ec2.EC2ResourceTag; import com.cloud.bridge.service.core.ec2.EC2DescribeSecurityGroups; import com.cloud.bridge.service.core.ec2.EC2DescribeSecurityGroupsResponse; @@ -595,31 +596,32 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface { request.setImageId(miat.getImageId()); request.setAttribute(ImageAttribute.launchPermission); if(launchPermOp.getAdd() != null){ - request.setLaunchPermOperation(EC2ModifyImageAttribute.Operation.add); - setAccountOrGroupList(launchPermOp.getAdd().getItem(), request); + setAccountOrGroupList(launchPermOp.getAdd().getItem(), request, "add"); }else if(launchPermOp.getRemove() != null){ - request.setLaunchPermOperation(EC2ModifyImageAttribute.Operation.remove); - setAccountOrGroupList(launchPermOp.getRemove().getItem(), request); + setAccountOrGroupList(launchPermOp.getRemove().getItem(), request, "remove"); } return toModifyImageAttributeResponse( engine.modifyImageAttribute( request )); } throw new EC2ServiceException( ClientError.Unsupported, "Unsupported - can only modify image description or launchPermission"); } - private void setAccountOrGroupList(LaunchPermissionItemType[] items, EC2ModifyImageAttribute request){ - - List launchPermissionAccountsOrGroupList = new ArrayList(); - + private void setAccountOrGroupList(LaunchPermissionItemType[] items, EC2ModifyImageAttribute request, String operation){ + EC2ImageLaunchPermission launchPermission = new EC2ImageLaunchPermission(); + + if (operation.equalsIgnoreCase("add")) + launchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.add); + else + launchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.remove); + for (LaunchPermissionItemType lpItem : items) { if(lpItem.getGroup() != null){ - launchPermissionAccountsOrGroupList.add(lpItem.getGroup()); + launchPermission.addLaunchPermission(lpItem.getGroup()); }else if(lpItem.getUserId() != null){ - launchPermissionAccountsOrGroupList.add(lpItem.getUserId()); + launchPermission.addLaunchPermission(lpItem.getUserId()); } } - - request.setLaunchPermissionAccountsOrGroupList(launchPermissionAccountsOrGroupList); + request.addLaunchPermission(launchPermission); } /** * Did not find a matching service offering so for now we just return disabled @@ -702,7 +704,9 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface { if(elementType != null){ request.setImageId( riat.getImageId()); request.setAttribute(ImageAttribute.launchPermission); - request.setLaunchPermOperation(EC2ModifyImageAttribute.Operation.reset); + EC2ImageLaunchPermission launchPermission = new EC2ImageLaunchPermission(); + launchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.reset); + request.addLaunchPermission(launchPermission); return toResetImageAttributeResponse( engine.modifyImageAttribute( request )); } throw new EC2ServiceException( ClientError.Unsupported, "Unsupported - can only reset image launchPermission" ); diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java index 8a5a733c4fb..2f45b03ae06 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java @@ -535,32 +535,6 @@ public class EC2Engine extends ManagerBase { } - /** REST API calls this method. - * Modify an existing template - * - * @param request - * @return - */ - public boolean modifyImageAttribute( EC2Image request ) - { - // TODO: This is incomplete - EC2DescribeImagesResponse images = new EC2DescribeImagesResponse(); - - try { - images = listTemplates( request.getId(), images ); - EC2Image[] imageSet = images.getImageSet(); - - CloudStackTemplate resp = getApi().updateTemplate(request.getId(), null, request.getDescription(), null, imageSet[0].getName(), null, null); - if (resp != null) { - return true; - } - return false; - } catch( Exception e ) { - logger.error( "EC2 ModifyImage - ", e); - throw new EC2ServiceException(ServerError.InternalError, e.getMessage()); - } - } - /** * Modify an existing template @@ -572,32 +546,35 @@ public class EC2Engine extends ManagerBase { { try { if(request.getAttribute().equals(ImageAttribute.launchPermission)){ - - String accounts = ""; - Boolean isPublic = null; - EC2ModifyImageAttribute.Operation operation = request.getLaunchPermOperation(); - - List accountOrGroupList = request.getLaunchPermissionAccountsList(); - if(accountOrGroupList != null && !accountOrGroupList.isEmpty()){ - boolean first = true; - for(String accountOrGroup : accountOrGroupList){ - if("all".equalsIgnoreCase(accountOrGroup)){ - if(operation.equals(EC2ModifyImageAttribute.Operation.add)){ - isPublic = true; + EC2ImageLaunchPermission[] launchPermissions = request.getLaunchPermissionSet(); + for (EC2ImageLaunchPermission launchPermission : launchPermissions) { + String accounts = ""; + Boolean isPublic = null; + EC2ImageLaunchPermission.Operation operation = launchPermission.getLaunchPermOp(); + List accountOrGroupList = launchPermission.getLaunchPermissionList(); + if(accountOrGroupList != null && !accountOrGroupList.isEmpty()){ + boolean first = true; + for(String accountOrGroup : accountOrGroupList){ + if("all".equalsIgnoreCase(accountOrGroup)){ + if(operation.equals(EC2ImageLaunchPermission.Operation.add)){ + isPublic = true; + }else{ + isPublic = false; + } }else{ - isPublic = false; + if(!first){ + accounts = accounts + ","; + } + accounts = accounts + accountOrGroup; + first = false; } - }else{ - if(!first){ - accounts = accounts + ","; - } - accounts = accounts + accountOrGroup; - first = false; } } + CloudStackInfoResponse resp = getApi().updateTemplatePermissions(request.getImageId(), accounts, null, null, isPublic, operation.toString()); + if (!resp.getSuccess()) + return false; } - CloudStackInfoResponse resp = getApi().updateTemplatePermissions(request.getImageId(), accounts, null, null, isPublic, operation.toString()); - return resp.getSuccess(); + return true; }else if(request.getAttribute().equals(ImageAttribute.description)){ CloudStackTemplate resp = getApi().updateTemplate(request.getImageId(), null, request.getDescription(), null, null, null, null); if (resp != null) { diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ImageLaunchPermission.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ImageLaunchPermission.java new file mode 100644 index 00000000000..552ffbe77d9 --- /dev/null +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ImageLaunchPermission.java @@ -0,0 +1,53 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.bridge.service.core.ec2; + +import java.util.ArrayList; +import java.util.List; + +public class EC2ImageLaunchPermission { + + private Operation launchPermOperation; + public enum Operation{ + add, + remove, + reset; + } + + private List launchPermissionList = new ArrayList(); + + public EC2ImageLaunchPermission() { + launchPermOperation = null; + } + + public void addLaunchPermission(String launchPermission) { + launchPermissionList.add(launchPermission); + } + + public List getLaunchPermissionList() { + return launchPermissionList; + } + + public void setLaunchPermOp( Operation launchPermOperation ) { + this.launchPermOperation = launchPermOperation; + } + + public Operation getLaunchPermOp() { + return this.launchPermOperation; + } + +} diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ModifyImageAttribute.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ModifyImageAttribute.java index 16f5ef750c7..e88d2d191aa 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ModifyImageAttribute.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ModifyImageAttribute.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.bridge.service.core.ec2; - +import java.util.ArrayList; import java.util.List; import com.cloud.bridge.service.core.ec2.EC2ImageAttributes.ImageAttribute; @@ -28,15 +28,7 @@ public class EC2ModifyImageAttribute { private String description; private Boolean isPublic = null; - private Operation launchPermOperation = null; - public enum Operation{ - add, - remove, - reset; - } - - private List launchPermissionAccountsOrGroupList; - + private List launchPermissionList = new ArrayList(); public EC2ModifyImageAttribute() { } @@ -65,31 +57,20 @@ public class EC2ModifyImageAttribute { return this.description; } - public void setLaunchPermissionAccountsOrGroupList(List launchPermissionAccountsOrGroupList) { - this.launchPermissionAccountsOrGroupList = launchPermissionAccountsOrGroupList; - } - - public List getLaunchPermissionAccountsList() { - return launchPermissionAccountsOrGroupList; - } - - public void setLaunchPermOperation( Operation launchPermOperation ) { - this.launchPermOperation = launchPermOperation; - } - - public Operation getLaunchPermOperation() { - return this.launchPermOperation; - } - - public void setIsPublic(Boolean isPublic) { this.isPublic = isPublic; } - public Boolean getIsPublic() { return isPublic; } - + + public void addLaunchPermission( EC2ImageLaunchPermission param ) { + launchPermissionList.add( param ); + } + + public EC2ImageLaunchPermission[] getLaunchPermissionSet() { + return launchPermissionList.toArray(new EC2ImageLaunchPermission[0]); + } } diff --git a/client/tomcatconf/componentContext.xml.in b/client/tomcatconf/componentContext.xml.in index de013de60de..43d31fb4b95 100644 --- a/client/tomcatconf/componentContext.xml.in +++ b/client/tomcatconf/componentContext.xml.in @@ -52,9 +52,8 @@ - - - + + @@ -125,8 +124,6 @@ - - diff --git a/docs/en-US/hypervisor-host-install-libvirt.xml b/docs/en-US/hypervisor-host-install-libvirt.xml index 4649d8522db..d7dc47f8dbd 100644 --- a/docs/en-US/hypervisor-host-install-libvirt.xml +++ b/docs/en-US/hypervisor-host-install-libvirt.xml @@ -31,7 +31,7 @@ Set the following paramaters: listen_tls = 0 listen_tcp = 1 - tcp_port = "16059" + tcp_port = "16509" auth_tcp = "none" mdns_adv = 0 diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec index b2eb3527347..d8143214b6b 100644 --- a/packaging/centos63/cloud.spec +++ b/packaging/centos63/cloud.spec @@ -185,7 +185,7 @@ install -D console-proxy/dist/systemvm.iso ${RPM_BUILD_ROOT}%{_datadir}/%{name}- install -D console-proxy/dist/systemvm.zip ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/vms/systemvm.zip install python/lib/cloud_utils.py ${RPM_BUILD_ROOT}%{_libdir}/python2.6/site-packages/cloud_utils.py cp -r python/lib/cloudutils ${RPM_BUILD_ROOT}%{_libdir}/python2.6/site-packages/ -python -m compileall ${RPM_BUILD_ROOT}%{_libdir}/python2.6/site-packages/cloud_utils.py +python -m py_compile ${RPM_BUILD_ROOT}%{_libdir}/python2.6/site-packages/cloud_utils.py python -m compileall ${RPM_BUILD_ROOT}%{_libdir}/python2.6/site-packages/cloudutils # Management @@ -382,6 +382,7 @@ fi %attr(0644, root, root) %{_datadir}/%{name}-common/vms/systemvm.iso %attr(0644, root, root) %{_datadir}/%{name}-common/vms/systemvm.zip %attr(0644,root,root) %{_libdir}/python2.6/site-packages/cloud_utils.py +%attr(0644,root,root) %{_libdir}/python2.6/site-packages/cloud_utils.pyc %attr(0644,root,root) %{_libdir}/python2.6/site-packages/cloudutils/* %doc LICENSE %doc NOTICE diff --git a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java index 087b166575a..30123c79df2 100644 --- a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java +++ b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java @@ -68,9 +68,7 @@ public class ApiDiscoveryServiceImpl implements ApiDiscoveryService { if (s_apiNameDiscoveryResponseMap == null) { long startTime = System.nanoTime(); s_apiNameDiscoveryResponseMap = new HashMap(); - //TODO: Fix and use PluggableService to get the classes - Set> cmdClasses = ReflectUtil.getClassesWithAnnotation(APICommand.class, - new String[]{"org.apache.cloudstack.api", "com.cloud.api"}); + Set> cmdClasses = new HashSet>(); for(PluggableService service: _services) cmdClasses.addAll(service.getCommands()); cacheResponseMap(cmdClasses); diff --git a/plugins/api/discovery/test/org/apache/cloudstack/discovery/ApiDiscoveryTest.java b/plugins/api/discovery/test/org/apache/cloudstack/discovery/ApiDiscoveryTest.java index 320d20aa71d..afff746c848 100644 --- a/plugins/api/discovery/test/org/apache/cloudstack/discovery/ApiDiscoveryTest.java +++ b/plugins/api/discovery/test/org/apache/cloudstack/discovery/ApiDiscoveryTest.java @@ -83,7 +83,7 @@ public class ApiDiscoveryTest { @Test public void verifyListApis() throws Exception { ListResponse responses = (ListResponse) _discoveryService.listApis(testUser, null); - assertTrue("No. of response items > 1", responses.getCount() > 1); + assertTrue("No. of response items > 1", responses.getCount() == 1); for (ApiDiscoveryResponse response: responses.getResponses()) { assertFalse("API name is empty", response.getName().isEmpty()); assertFalse("API description is empty", response.getDescription().isEmpty()); diff --git a/plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/ApiRateLimitServiceImpl.java b/plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/ApiRateLimitServiceImpl.java index 5f38ccf6141..1f84ca18bbb 100644 --- a/plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/ApiRateLimitServiceImpl.java +++ b/plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/ApiRateLimitServiceImpl.java @@ -29,10 +29,13 @@ import net.sf.ehcache.CacheManager; import org.apache.log4j.Logger; import org.apache.cloudstack.acl.APIChecker; +import org.apache.cloudstack.api.ApiConstants.LDAPParams; import org.apache.cloudstack.api.command.admin.ratelimit.ResetApiLimitCmd; import org.apache.cloudstack.api.command.user.ratelimit.GetApiLimitCmd; import org.apache.cloudstack.api.response.ApiLimitResponse; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.RequestLimitException; import com.cloud.user.Account; @@ -56,34 +59,34 @@ public class ApiRateLimitServiceImpl extends AdapterBase implements APIChecker, */ private int maxAllowed = 30; - private static LimitStore _store = null; + private LimitStore _store = null; @Inject AccountService _accountService; + @Inject + ConfigurationDao _configDao; + @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); if (_store == null) { - // not configured yet, note that since this class is both adapter - // and pluggableService, so this method - // may be invoked twice in ComponentLocator. // get global configured duration and max values - Object duration = params.get("api.throttling.interval"); + String duration = _configDao.getValue(Config.ApiLimitInterval.key()); if (duration != null) { - timeToLive = Integer.parseInt((String) duration); + timeToLive = Integer.parseInt(duration); } - Object maxReqs = params.get("api.throttling.max"); + String maxReqs = _configDao.getValue(Config.ApiLimitMax.key()); if (maxReqs != null) { - maxAllowed = Integer.parseInt((String) maxReqs); + maxAllowed = Integer.parseInt(maxReqs); } // create limit store EhcacheLimitStore cacheStore = new EhcacheLimitStore(); int maxElements = 10000; - Object cachesize = params.get("api.throttling.cachesize"); + String cachesize = _configDao.getValue(Config.ApiLimitCacheSize.key()); if ( cachesize != null ){ - maxElements = Integer.parseInt((String)cachesize); + maxElements = Integer.parseInt(cachesize); } CacheManager cm = CacheManager.create(); Cache cache = new Cache("api-limit-cache", maxElements, false, false, timeToLive, timeToLive); diff --git a/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/ApiRateLimitTest.java b/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/ApiRateLimitTest.java index 502b15cf316..1a77a4ef3a6 100644 --- a/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/ApiRateLimitTest.java +++ b/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/ApiRateLimitTest.java @@ -29,6 +29,8 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.RequestLimitException; import com.cloud.user.Account; import com.cloud.user.AccountService; @@ -43,12 +45,18 @@ public class ApiRateLimitTest { static ApiRateLimitServiceImpl _limitService = new ApiRateLimitServiceImpl(); static AccountService _accountService = mock(AccountService.class); + static ConfigurationDao _configDao = mock(ConfigurationDao.class); private static long acctIdSeq = 5L; private static Account testAccount; @BeforeClass public static void setUp() throws ConfigurationException { + when(_configDao.getValue(Config.ApiLimitInterval.key())).thenReturn(null); + when(_configDao.getValue(Config.ApiLimitMax.key())).thenReturn(null); + when(_configDao.getValue(Config.ApiLimitCacheSize.key())).thenReturn(null); + _limitService._configDao = _configDao; + _limitService.configure("ApiRateLimitTest", Collections. emptyMap()); _limitService._accountService = _accountService; diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManager.java b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManager.java index 7216c50f428..1ee87f1a817 100644 --- a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManager.java +++ b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManager.java @@ -24,8 +24,9 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceInUseException; import com.cloud.utils.component.Manager; +import com.cloud.utils.component.PluggableService; -public interface NetappManager extends Manager { +public interface NetappManager extends Manager, PluggableService { enum AlgorithmType { RoundRobin, LeastFull diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java index 90bb9b205fd..8f7b6d8df8d 100644 --- a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java +++ b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.netapp; import java.io.IOException; +import java.lang.Override; import java.net.UnknownHostException; import java.rmi.ServerException; import java.util.ArrayList; @@ -40,6 +41,7 @@ import netapp.manage.NaServer; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.api.commands.netapp.*; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceInUseException; @@ -123,7 +125,25 @@ public class NetappManagerImpl extends ManagerBase implements NetappManager return s; } - + + @Override + public List> getCommands() { + List> cmdList = new ArrayList>(); + cmdList.add(CreateLunCmd.class); + cmdList.add(ListLunsCmd.class); + cmdList.add(DissociateLunCmd.class); + cmdList.add(CreateVolumeOnFilerCmd.class); + cmdList.add(ModifyVolumePoolCmd.class); + cmdList.add(ListVolumesOnFilerCmd.class); + cmdList.add(ListVolumePoolsCmd.class); + cmdList.add(DestroyLunCmd.class); + cmdList.add(CreateVolumePoolCmd.class); + cmdList.add(DeleteVolumePoolCmd.class); + cmdList.add(AssociateLunCmd.class); + cmdList.add(DestroyVolumeOnFilerCmd.class); + return cmdList; + } + @Override public void modifyPool(String poolName, String algorithm) throws InvalidParameterValueException { diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index f320a66b487..552afb1e665 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -368,10 +368,6 @@ ServerResource { NATIVE, OPENVSWITCH } - protected enum defineOps { - UNDEFINE_VM, DEFINE_VM - } - protected BridgeType _bridgeType; private String getEndIpFromStartIp(String startIp, int numIps) { @@ -979,77 +975,24 @@ ServerResource { } } - protected String startDomain(Connect conn, String vmName, String domainXML) + protected String startVM(Connect conn, String vmName, String domainXML) throws LibvirtException, InternalErrorException { - /* No duplicated vm, we will success, or failed */ - boolean failed = false; Domain dm = null; try { - dm = conn.domainDefineXML(domainXML); + /* + We create a transient domain here. When this method gets + called we receive a full XML specification of the guest, + so no need to define it persistent. + + This also makes sure we never have any old "garbage" defined + in libvirt which might haunt us. + */ + dm = conn.domainCreateXML(domainXML, 0); } catch (final LibvirtException e) { - /* Duplicated defined vm */ - s_logger.warn("Failed to define domain " + vmName + ": " + s_logger.warn("Failed to start domain " + vmName + ": " + e.getMessage()); - failed = true; - } finally { - try { - if (dm != null) { - dm.free(); - } - } catch (final LibvirtException e) { - - } } - /* If failed, undefine the vm */ - Domain dmOld = null; - Domain dmNew = null; - try { - if (failed) { - dmOld = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName - .getBytes())); - dmOld.undefine(); - dmNew = conn.domainDefineXML(domainXML); - } - } catch (final LibvirtException e) { - s_logger.warn("Failed to define domain (second time) " + vmName - + ": " + e.getMessage()); - throw e; - } catch (Exception e) { - s_logger.warn("Failed to define domain (second time) " + vmName - + ": " + e.getMessage()); - throw new InternalErrorException(e.toString()); - } finally { - try { - if (dmOld != null) { - dmOld.free(); - } - if (dmNew != null) { - dmNew.free(); - } - } catch (final LibvirtException e) { - - } - } - - /* Start the VM */ - try { - dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName - .getBytes())); - dm.create(); - } catch (LibvirtException e) { - s_logger.warn("Failed to start domain: " + vmName + ": " - + e.getMessage()); - throw e; - } finally { - try { - if (dm != null) { - dm.free(); - } - } catch (final LibvirtException e) { - - } - } return null; } @@ -1064,28 +1007,6 @@ ServerResource { return true; } - public static void main(String[] args) { - s_logger.addAppender(new org.apache.log4j.ConsoleAppender( - new org.apache.log4j.PatternLayout(), "System.out")); - LibvirtComputingResource test = new LibvirtComputingResource(); - Map params = new HashMap(); - try { - test.configure("test", params); - } catch (ConfigurationException e) { - System.out.println(e.getMessage()); - e.printStackTrace(); - } - String result = null; - // String result = test.startDomainRouter("domr1", - // "/var/lib/images/centos.5-4.x86-64/centos-small.img", 128, "0064", - // "02:00:30:00:01:01", "00:16:3e:77:e2:a1", "02:00:30:00:64:01"); - boolean created = (result == null); - s_logger.info("Domain " + (created ? " " : " not ") + " created"); - - s_logger.info("Rule " + (created ? " " : " not ") + " created"); - test.stop(); - } - @Override public Answer executeRequest(Command cmd) { @@ -2867,7 +2788,7 @@ ServerResource { List ifaces = getInterfaces(conn, vmName); destroy_network_rules_for_vm(conn, vmName); - String result = stopVM(conn, vmName, defineOps.UNDEFINE_VM); + String result = stopVM(conn, vmName); if (result == null) { for (DiskDef disk : disks) { if (disk.getDeviceType() == DiskDef.deviceType.CDROM @@ -3085,7 +3006,7 @@ ServerResource { createVifs(vmSpec, vm); s_logger.debug("starting " + vmName + ": " + vm.toString()); - startDomain(conn, vmName, vm.toString()); + startVM(conn, vmName, vm.toString()); NicTO[] nics = vmSpec.getNics(); for (NicTO nic : nics) { @@ -3910,8 +3831,8 @@ ServerResource { .getBytes())); String vmDef = dm.getXMLDesc(0); s_logger.debug(vmDef); - msg = stopVM(conn, vmName, defineOps.UNDEFINE_VM); - msg = startDomain(conn, vmName, vmDef); + msg = stopVM(conn, vmName); + msg = startVM(conn, vmName, vmDef); return null; } catch (LibvirtException e) { s_logger.warn("Failed to create vm", e); @@ -3932,7 +3853,7 @@ ServerResource { return msg; } - protected String stopVM(Connect conn, String vmName, defineOps df) { + protected String stopVM(Connect conn, String vmName) { DomainInfo.DomainState state = null; Domain dm = null; @@ -3982,23 +3903,6 @@ ServerResource { } } - if (df == defineOps.UNDEFINE_VM) { - try { - dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName - .getBytes())); - dm.undefine(); - } catch (LibvirtException e) { - - } finally { - try { - if (dm != null) { - dm.free(); - } - } catch (LibvirtException l) { - - } - } - } return null; } diff --git a/plugins/network-elements/bigswitch-vns/src/com/cloud/api/commands/AddBigSwitchVnsDeviceCmd.java b/plugins/network-elements/bigswitch-vns/src/com/cloud/api/commands/AddBigSwitchVnsDeviceCmd.java index c4c4ba9aa80..30f631dd5d6 100644 --- a/plugins/network-elements/bigswitch-vns/src/com/cloud/api/commands/AddBigSwitchVnsDeviceCmd.java +++ b/plugins/network-elements/bigswitch-vns/src/com/cloud/api/commands/AddBigSwitchVnsDeviceCmd.java @@ -37,7 +37,7 @@ import com.cloud.network.element.BigSwitchVnsElementService; import com.cloud.user.UserContext; import com.cloud.utils.exception.CloudRuntimeException; -@APICommand(name = "addBigSwitchVnsDevice", responseObject=BigSwitchVnsDeviceResponse.class, description="Adds a BigSwitch VNS device") +@APICommand(name = "addBigSwitchVnsDevice", responseObject=BigSwitchVnsDeviceResponse.class, description="Adds a BigSwitch VNS device", since = "4.1.0") public class AddBigSwitchVnsDeviceCmd extends BaseAsyncCmd { private static final String s_name = "addbigswitchvnsdeviceresponse"; @Inject BigSwitchVnsElementService _bigswitchVnsElementService; diff --git a/plugins/network-elements/bigswitch-vns/src/com/cloud/api/commands/DeleteBigSwitchVnsDeviceCmd.java b/plugins/network-elements/bigswitch-vns/src/com/cloud/api/commands/DeleteBigSwitchVnsDeviceCmd.java index 06eee15f614..f26bddedcb0 100644 --- a/plugins/network-elements/bigswitch-vns/src/com/cloud/api/commands/DeleteBigSwitchVnsDeviceCmd.java +++ b/plugins/network-elements/bigswitch-vns/src/com/cloud/api/commands/DeleteBigSwitchVnsDeviceCmd.java @@ -35,7 +35,7 @@ import com.cloud.network.element.BigSwitchVnsElementService; import com.cloud.user.UserContext; import com.cloud.utils.exception.CloudRuntimeException; -@APICommand(name = "deleteBigSwitchVnsDevice", responseObject=SuccessResponse.class, description=" delete a bigswitch vns device") +@APICommand(name = "deleteBigSwitchVnsDevice", responseObject=SuccessResponse.class, description=" delete a bigswitch vns device", since = "4.1.0") public class DeleteBigSwitchVnsDeviceCmd extends BaseAsyncCmd { private static final String s_name = "deletebigswitchvnsdeviceresponse"; @Inject BigSwitchVnsElementService _bigswitchVnsElementService; diff --git a/plugins/network-elements/bigswitch-vns/src/com/cloud/api/commands/ListBigSwitchVnsDevicesCmd.java b/plugins/network-elements/bigswitch-vns/src/com/cloud/api/commands/ListBigSwitchVnsDevicesCmd.java index c0710ea7537..002d750604d 100644 --- a/plugins/network-elements/bigswitch-vns/src/com/cloud/api/commands/ListBigSwitchVnsDevicesCmd.java +++ b/plugins/network-elements/bigswitch-vns/src/com/cloud/api/commands/ListBigSwitchVnsDevicesCmd.java @@ -41,7 +41,7 @@ import com.cloud.network.BigSwitchVnsDeviceVO; import com.cloud.network.element.BigSwitchVnsElementService; import com.cloud.utils.exception.CloudRuntimeException; -@APICommand(name = "listBigSwitchVnsDevices", responseObject=BigSwitchVnsDeviceResponse.class, description="Lists BigSwitch Vns devices") +@APICommand(name = "listBigSwitchVnsDevices", responseObject=BigSwitchVnsDeviceResponse.class, description="Lists BigSwitch Vns devices", since = "4.1.0") public class ListBigSwitchVnsDevicesCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListBigSwitchVnsDevicesCmd.class.getName()); private static final String s_name = "listbigswitchvnsdeviceresponse"; diff --git a/plugins/network-elements/bigswitch-vns/src/com/cloud/network/element/BigSwitchVnsElement.java b/plugins/network-elements/bigswitch-vns/src/com/cloud/network/element/BigSwitchVnsElement.java index 67d0d8df86a..95c9e18304a 100644 --- a/plugins/network-elements/bigswitch-vns/src/com/cloud/network/element/BigSwitchVnsElement.java +++ b/plugins/network-elements/bigswitch-vns/src/com/cloud/network/element/BigSwitchVnsElement.java @@ -88,7 +88,9 @@ import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; +import org.springframework.stereotype.Component; +@Component @Local(value = {NetworkElement.class, ConnectivityProvider.class}) public class BigSwitchVnsElement extends AdapterBase implements BigSwitchVnsElementService, ConnectivityProvider, ResourceStateAdapter { diff --git a/scripts/storage/secondary/cloud-install-sys-tmplt b/scripts/storage/secondary/cloud-install-sys-tmplt index 63a04d8cb07..2172b287848 100755 --- a/scripts/storage/secondary/cloud-install-sys-tmplt +++ b/scripts/storage/secondary/cloud-install-sys-tmplt @@ -20,7 +20,7 @@ usage() { - printf "Usage: %s: -m -f [-h ] [ -s ][-u ] [-F ] [-e