Merge branch 'master' into Health-Check-UI
Conflicts:
ui/css/cloudstack3.css
diff --git a/api/src/com/cloud/agent/api/BackupSnapshotCommand.java b/api/src/com/cloud/agent/api/BackupSnapshotCommand.java
index a0ac8d7..cac686d 100644
--- a/api/src/com/cloud/agent/api/BackupSnapshotCommand.java
+++ b/api/src/com/cloud/agent/api/BackupSnapshotCommand.java
@@ -35,6 +35,7 @@
private SwiftTO swift;
private S3TO s3;
StorageFilerTO pool;
+ private Long secHostId;
protected BackupSnapshotCommand() {
@@ -49,12 +50,14 @@
* @param firstBackupUuid This is the backup of the first ever snapshot taken by the volume.
* @param isFirstSnapshotOfRootVolume true if this is the first snapshot of a root volume. Set the parent of the backup to null.
* @param isVolumeInactive True if the volume belongs to a VM that is not running or is detached.
+ * @param secHostId This is the Id of the secondary storage.
*/
public BackupSnapshotCommand(String secondaryStoragePoolURL,
Long dcId,
Long accountId,
Long volumeId,
Long snapshotId,
+ Long secHostId,
String volumePath,
StoragePool pool,
String snapshotUuid,
@@ -71,6 +74,7 @@
this.prevBackupUuid = prevBackupUuid;
this.isVolumeInactive = isVolumeInactive;
this.vmName = vmName;
+ this.secHostId = secHostId;
setVolumePath(volumePath);
setWait(wait);
}
@@ -111,4 +115,7 @@
return snapshotId;
}
+ public Long getSecHostId() {
+ return secHostId;
+ }
}
diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java
index 9731a61..60e1f7f 100644
--- a/api/src/com/cloud/network/NetworkModel.java
+++ b/api/src/com/cloud/network/NetworkModel.java
@@ -257,4 +257,6 @@
void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException;
void checkRequestedIpAddresses(long networkId, String ip4, String ip6) throws InvalidParameterValueException;
+
+ String getStartIpv6Address(long id);
}
\ No newline at end of file
diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java
index ea89eda..9d6b221 100755
--- a/api/src/com/cloud/vm/UserVmService.java
+++ b/api/src/com/cloud/vm/UserVmService.java
@@ -356,8 +356,9 @@
* @param cmd
* - the command specifying vmId and new serviceOfferingId
* @return the vm
+ * @throws ResourceAllocationException
*/
- UserVm upgradeVirtualMachine(UpgradeVMCmd cmd);
+ UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) throws ResourceAllocationException;
UserVm stopVirtualMachine(long vmId, boolean forced) throws ConcurrentOperationException;
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java.orig b/api/src/org/apache/cloudstack/api/ApiConstants.java.orig
deleted file mode 100644
index 3801506..0000000
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java.orig
+++ /dev/null
@@ -1,468 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api;
-
-
-public class ApiConstants {
- public static final String ACCOUNT = "account";
- public static final String ACCOUNTS = "accounts";
- public static final String ACCOUNT_TYPE = "accounttype";
- public static final String ACCOUNT_ID = "accountid";
- public static final String ALGORITHM = "algorithm";
- public static final String ALLOCATED_ONLY = "allocatedonly";
- public static final String API_KEY = "userapikey";
- public static final String APPLIED = "applied";
- public static final String AVAILABLE = "available";
- public static final String BITS = "bits";
- public static final String BOOTABLE = "bootable";
- public static final String BIND_DN = "binddn";
- public static final String BIND_PASSWORD = "bindpass";
- public static final String CATEGORY = "category";
- public static final String CERTIFICATE = "certificate";
- public static final String PRIVATE_KEY = "privatekey";
- public static final String DOMAIN_SUFFIX = "domainsuffix";
- public static final String DNS_SEARCH_ORDER = "dnssearchorder";
- public static final String CIDR = "cidr";
- public static final String IP6_CIDR = "ip6cidr";
- public static final String CIDR_LIST = "cidrlist";
- public static final String CLEANUP = "cleanup";
- public static final String CLUSTER_ID = "clusterid";
- public static final String CLUSTER_NAME = "clustername";
- public static final String CLUSTER_TYPE = "clustertype";
- public static final String COMPONENT = "component";
- public static final String CPU_NUMBER = "cpunumber";
- public static final String CPU_SPEED = "cpuspeed";
- public static final String CREATED = "created";
- public static final String CUSTOMIZED = "customized";
- public static final String DESCRIPTION = "description";
- public static final String DESTINATION_ZONE_ID = "destzoneid";
- public static final String DETAILS = "details";
- public static final String DEVICE_ID = "deviceid";
- public static final String DISK_OFFERING_ID = "diskofferingid";
- public static final String DISK_SIZE = "disksize";
- public static final String DISPLAY_NAME = "displayname";
- public static final String DISPLAY_TEXT = "displaytext";
- public static final String DNS1 = "dns1";
- public static final String DNS2 = "dns2";
- public static final String DOMAIN = "domain";
- public static final String DOMAIN_ID = "domainid";
- public static final String DURATION = "duration";
- public static final String EMAIL = "email";
- public static final String END_DATE = "enddate";
- public static final String END_IP = "endip";
- public static final String END_IPV6 = "endipv6";
- public static final String END_PORT = "endport";
- public static final String ENTRY_TIME = "entrytime";
- public static final String FETCH_LATEST = "fetchlatest";
- public static final String FIRSTNAME = "firstname";
- public static final String FORCED = "forced";
- public static final String FORCED_DESTROY_LOCAL_STORAGE = "forcedestroylocalstorage";
- public static final String FORMAT = "format";
- public static final String FOR_VIRTUAL_NETWORK = "forvirtualnetwork";
- public static final String GATEWAY = "gateway";
- public static final String IP6_GATEWAY = "ip6gateway";
- public static final String GROUP = "group";
- public static final String GROUP_ID = "groupid";
- public static final String GUEST_CIDR_ADDRESS = "guestcidraddress";
- public static final String HA_ENABLE = "haenable";
- public static final String HOST_ID = "hostid";
- public static final String HOST_NAME = "hostname";
- public static final String HYPERVISOR = "hypervisor";
- public static final String INLINE = "inline";
- public static final String INSTANCE = "instance";
- public static final String ICMP_CODE = "icmpcode";
- public static final String ICMP_TYPE = "icmptype";
- public static final String ID = "id";
- public static final String IDS = "ids";
- public static final String INTERNAL_DNS1 = "internaldns1";
- public static final String INTERNAL_DNS2 = "internaldns2";
- public static final String INTERVAL_TYPE = "intervaltype";
- public static final String IP_ADDRESS = "ipaddress";
- public static final String IP6_ADDRESS = "ip6address";
- public static final String IP_ADDRESS_ID = "ipaddressid";
- public static final String IS_ASYNC = "isasync";
- public static final String IP_AVAILABLE = "ipavailable";
- public static final String IP_LIMIT = "iplimit";
- public static final String IP_TOTAL = "iptotal";
- public static final String IS_CLEANUP_REQUIRED = "iscleanuprequired";
- public static final String IS_EXTRACTABLE = "isextractable";
- public static final String IS_FEATURED = "isfeatured";
- public static final String IS_PUBLIC = "ispublic";
- public static final String IS_PERSISTENT = "ispersistent";
- public static final String IS_READY = "isready";
- public static final String IS_RECURSIVE = "isrecursive";
- public static final String ISO_FILTER = "isofilter";
- public static final String ISO_GUEST_OS_NONE = "None";
- public static final String JOB_ID = "jobid";
- public static final String JOB_STATUS = "jobstatus";
- public static final String LASTNAME = "lastname";
- public static final String LEVEL = "level";
- public static final String LENGTH = "length";
- public static final String LIMIT_CPU_USE = "limitcpuuse";
- public static final String LOCK = "lock";
- public static final String LUN = "lun";
- public static final String LBID = "lbruleid";
- public static final String MAX = "max";
- public static final String MAX_SNAPS = "maxsnaps";
- public static final String MEMORY = "memory";
- public static final String MODE = "mode";
- public static final String NAME = "name";
- public static final String METHOD_NAME = "methodname";
- public static final String NETWORK_DOMAIN = "networkdomain";
- public static final String NETMASK = "netmask";
- public static final String NEW_NAME = "newname";
- public static final String NUM_RETRIES = "numretries";
- public static final String OFFER_HA = "offerha";
- public static final String IS_SYSTEM_OFFERING = "issystem";
- public static final String IS_DEFAULT_USE = "defaultuse";
- public static final String OP = "op";
- public static final String OS_CATEGORY_ID = "oscategoryid";
- public static final String OS_TYPE_ID = "ostypeid";
- public static final String PARAMS = "params";
- public static final String PARENT_DOMAIN_ID = "parentdomainid";
- public static final String PASSWORD = "password";
- public static final String NEW_PASSWORD = "new_password";
- public static final String PASSWORD_ENABLED = "passwordenabled";
- public static final String SSHKEY_ENABLED = "sshkeyenabled";
- public static final String PATH = "path";
- public static final String POD_ID = "podid";
- public static final String POD_IDS = "podids";
- public static final String POLICY_ID = "policyid";
- public static final String PORT = "port";
- public static final String PORTAL = "portal";
- public static final String PORT_FORWARDING_SERVICE_ID = "portforwardingserviceid";
- public static final String PRIVATE_INTERFACE = "privateinterface";
- public static final String PRIVATE_IP = "privateip";
- public static final String PRIVATE_PORT = "privateport";
- public static final String PRIVATE_START_PORT = "privateport";
- public static final String PRIVATE_END_PORT = "privateendport";
- public static final String PRIVATE_ZONE = "privatezone";
- public static final String PROTOCOL = "protocol";
- public static final String PUBLIC_INTERFACE = "publicinterface";
- public static final String PUBLIC_IP_ID = "publicipid";
- public static final String PUBLIC_IP = "publicip";
- public static final String PUBLIC_PORT = "publicport";
- public static final String PUBLIC_START_PORT = "publicport";
- public static final String PUBLIC_END_PORT = "publicendport";
- public static final String PUBLIC_ZONE = "publiczone";
- public static final String RECEIVED_BYTES = "receivedbytes";
- public static final String REQUIRES_HVM = "requireshvm";
- public static final String RESOURCE_TYPE = "resourcetype";
- public static final String RESPONSE = "response";
- public static final String QUERY_FILTER = "queryfilter";
- public static final String SCHEDULE = "schedule";
- public static final String SCOPE = "scope";
- public static final String SECRET_KEY = "usersecretkey";
- public static final String SINCE = "since";
- public static final String KEY = "key";
- public static final String SEARCH_BASE = "searchbase";
- public static final String SECURITY_GROUP_IDS = "securitygroupids";
- public static final String SECURITY_GROUP_NAMES = "securitygroupnames";
- public static final String SECURITY_GROUP_NAME = "securitygroupname";
- public static final String SECURITY_GROUP_ID = "securitygroupid";
- public static final String SENT = "sent";
- public static final String SENT_BYTES = "sentbytes";
- public static final String SERVICE_OFFERING_ID = "serviceofferingid";
- public static final String SHOW_CAPACITIES = "showcapacities";
- public static final String SIZE = "size";
- public static final String SNAPSHOT_ID = "snapshotid";
- public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid";
- public static final String SNAPSHOT_TYPE = "snapshottype";
- public static final String SOURCE_ZONE_ID = "sourcezoneid";
- public static final String START_DATE = "startdate";
- public static final String START_IP = "startip";
- public static final String START_IPV6 = "startipv6";
- public static final String START_PORT = "startport";
- public static final String STATE = "state";
- public static final String STATUS = "status";
- public static final String STORAGE_TYPE = "storagetype";
- public static final String SYSTEM_VM_TYPE = "systemvmtype";
- public static final String TAGS = "tags";
- public static final String TARGET_IQN = "targetiqn";
- public static final String TEMPLATE_FILTER = "templatefilter";
- public static final String TEMPLATE_ID = "templateid";
- public static final String ISO_ID = "isoid";
- public static final String TIMEOUT = "timeout";
- public static final String TIMEZONE = "timezone";
- public static final String TYPE = "type";
- public static final String TRUST_STORE = "truststore";
- public static final String TRUST_STORE_PASSWORD = "truststorepass";
- public static final String URL = "url";
- public static final String USAGE_INTERFACE = "usageinterface";
- public static final String USER_DATA = "userdata";
- public static final String USER_ID = "userid";
- public static final String USE_SSL = "ssl";
- public static final String USERNAME = "username";
- public static final String USER_SECURITY_GROUP_LIST = "usersecuritygrouplist";
- public static final String USE_VIRTUAL_NETWORK = "usevirtualnetwork";
- public static final String VALUE = "value";
- public static final String VIRTUAL_MACHINE_ID = "virtualmachineid";
- public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
- public static final String VLAN = "vlan";
- public static final String VLAN_ID = "vlanid";
- public static final String VM_AVAILABLE = "vmavailable";
- public static final String VM_LIMIT = "vmlimit";
- public static final String VM_TOTAL = "vmtotal";
- public static final String VNET = "vnet";
- public static final String VOLUME_ID = "volumeid";
- public static final String ZONE_ID = "zoneid";
- public static final String ZONE_NAME = "zonename";
- public static final String NETWORK_TYPE = "networktype";
- public static final String PAGE = "page";
- public static final String PAGE_SIZE = "pagesize";
- public static final String COUNT = "count";
- public static final String TRAFFIC_TYPE = "traffictype";
- public static final String NETWORK_OFFERING_ID = "networkofferingid";
- public static final String NETWORK_IDS = "networkids";
- public static final String NETWORK_ID = "networkid";
- public static final String NIC_ID = "nicid";
- public static final String SPECIFY_VLAN = "specifyvlan";
- public static final String IS_DEFAULT = "isdefault";
- public static final String IS_SYSTEM = "issystem";
- public static final String AVAILABILITY = "availability";
- public static final String NETWORKRATE = "networkrate";
- public static final String HOST_TAGS = "hosttags";
- public static final String SSH_KEYPAIR = "keypair";
- public static final String HOST_CPU_CAPACITY = "hostcpucapacity";
- public static final String HOST_CPU_NUM = "hostcpunum";
- public static final String HOST_MEM_CAPACITY = "hostmemcapacity";
- public static final String HOST_MAC = "hostmac";
- public static final String HOST_TAG = "hosttag";
- public static final String PXE_SERVER_TYPE = "pxeservertype";
- public static final String LINMIN_USERNAME = "linminusername";
- public static final String LINMIN_PASSWORD = "linminpassword";
- public static final String LINMIN_APID = "linminapid";
- public static final String DHCP_SERVER_TYPE = "dhcpservertype";
- public static final String LINK_LOCAL_IP = "linklocalip";
- public static final String LINK_LOCAL_MAC_ADDRESS = "linklocalmacaddress";
- public static final String LINK_LOCAL_MAC_NETMASK = "linklocalnetmask";
- public static final String LINK_LOCAL_NETWORK_ID = "linklocalnetworkid";
- public static final String PRIVATE_MAC_ADDRESS = "privatemacaddress";
- public static final String PRIVATE_NETMASK = "privatenetmask";
- public static final String PRIVATE_NETWORK_ID = "privatenetworkid";
- public static final String ALLOCATION_STATE = "allocationstate";
- public static final String MANAGED_STATE = "managedstate";
- public static final String STORAGE_ID = "storageid";
- public static final String PING_STORAGE_SERVER_IP = "pingstorageserverip";
- public static final String PING_DIR = "pingdir";
- public static final String TFTP_DIR = "tftpdir";
- public static final String PING_CIFS_USERNAME = "pingcifsusername";
- public static final String PING_CIFS_PASSWORD = "pingcifspassword";
- public static final String CHECKSUM = "checksum";
- public static final String NETWORK_DEVICE_TYPE = "networkdevicetype";
- public static final String NETWORK_DEVICE_PARAMETER_LIST = "networkdeviceparameterlist";
- public static final String ZONE_TOKEN = "zonetoken";
- public static final String DHCP_PROVIDER = "dhcpprovider";
- public static final String RESULT = "success";
- public static final String LUN_ID = "lunId";
- public static final String IQN = "iqn";
- public static final String AGGREGATE_NAME = "aggregatename";
- public static final String POOL_NAME = "poolname";
- public static final String VOLUME_NAME = "volumename";
- public static final String SNAPSHOT_POLICY = "snapshotpolicy";
- public static final String SNAPSHOT_RESERVATION = "snapshotreservation";
- public static final String IP_NETWORK_LIST = "iptonetworklist";
- public static final String PARAM_LIST = "param";
- public static final String FOR_LOAD_BALANCING = "forloadbalancing";
- public static final String KEYBOARD = "keyboard";
- public static final String OPEN_FIREWALL = "openfirewall";
- public static final String TEMPLATE_TAG = "templatetag";
- public static final String HYPERVISOR_VERSION = "hypervisorversion";
- public static final String MAX_GUESTS_LIMIT = "maxguestslimit";
- public static final String PROJECT_ID = "projectid";
- public static final String PROJECT_IDS = "projectids";
- public static final String PROJECT = "project";
- public static final String ROLE = "role";
- public static final String USER = "user";
- public static final String ACTIVE_ONLY = "activeonly";
- public static final String TOKEN = "token";
- public static final String ACCEPT = "accept";
- public static final String SORT_KEY = "sortkey";
- public static final String ACCOUNT_DETAILS = "accountdetails";
- public static final String SERVICE_PROVIDER_LIST = "serviceproviderlist";
- public static final String SERVICE_CAPABILITY_LIST = "servicecapabilitylist";
- public static final String CAN_CHOOSE_SERVICE_CAPABILITY = "canchooseservicecapability";
- public static final String PROVIDER = "provider";
- public static final String NETWORK_SPEED = "networkspeed";
- public static final String BROADCAST_DOMAIN_RANGE = "broadcastdomainrange";
- public static final String ISOLATION_METHODS = "isolationmethods";
- public static final String PHYSICAL_NETWORK_ID = "physicalnetworkid";
- public static final String DEST_PHYSICAL_NETWORK_ID = "destinationphysicalnetworkid";
- public static final String ENABLED = "enabled";
- public static final String SERVICE_NAME = "servicename";
- public static final String DHCP_RANGE = "dhcprange";
- public static final String UUID = "uuid";
- public static final String SECURITY_GROUP_EANBLED = "securitygroupenabled";
- public static final String LOCAL_STORAGE_ENABLED = "localstorageenabled";
- public static final String GUEST_IP_TYPE = "guestiptype";
- public static final String XEN_NETWORK_LABEL = "xennetworklabel";
- public static final String KVM_NETWORK_LABEL = "kvmnetworklabel";
- public static final String VMWARE_NETWORK_LABEL = "vmwarenetworklabel";
- public static final String NETWORK_SERVICE_PROVIDER_ID = "nspid";
- public static final String SERVICE_LIST = "servicelist";
- public static final String CAN_ENABLE_INDIVIDUAL_SERVICE = "canenableindividualservice";
- public static final String SUPPORTED_SERVICES = "supportedservices";
- public static final String NSP_ID = "nspid";
- public static final String ACL_TYPE = "acltype";
- public static final String SUBDOMAIN_ACCESS = "subdomainaccess";
- public static final String LOAD_BALANCER_DEVICE_ID = "lbdeviceid";
- public static final String LOAD_BALANCER_DEVICE_NAME = "lbdevicename";
- public static final String LOAD_BALANCER_DEVICE_STATE = "lbdevicestate";
- public static final String LOAD_BALANCER_DEVICE_CAPACITY = "lbdevicecapacity";
- public static final String LOAD_BALANCER_DEVICE_DEDICATED = "lbdevicededicated";
- public static final String FIREWALL_DEVICE_ID = "fwdeviceid";
- public static final String FIREWALL_DEVICE_NAME = "fwdevicename";
- public static final String FIREWALL_DEVICE_STATE = "fwdevicestate";
- public static final String FIREWALL_DEVICE_CAPACITY = "fwdevicecapacity";
- public static final String FIREWALL_DEVICE_DEDICATED = "fwdevicededicated";
- public static final String SERVICE = "service";
- public static final String ASSOCIATED_NETWORK_ID = "associatednetworkid";
- public static final String ASSOCIATED_NETWORK_NAME = "associatednetworkname";
- public static final String SOURCE_NAT_SUPPORTED = "sourcenatsupported";
- public static final String RESOURCE_STATE = "resourcestate";
- public static final String PROJECT_INVITE_REQUIRED = "projectinviterequired";
- public static final String REQUIRED = "required";
- public static final String RESTART_REQUIRED = "restartrequired";
- public static final String ALLOW_USER_CREATE_PROJECTS = "allowusercreateprojects";
- public static final String CONSERVE_MODE = "conservemode";
- public static final String TRAFFIC_TYPE_IMPLEMENTOR = "traffictypeimplementor";
- public static final String KEYWORD = "keyword";
- public static final String LIST_ALL = "listall";
- public static final String SPECIFY_IP_RANGES = "specifyipranges";
- public static final String IS_SOURCE_NAT = "issourcenat";
- public static final String IS_STATIC_NAT = "isstaticnat";
- public static final String SORT_BY = "sortby";
- public static final String CHANGE_CIDR = "changecidr";
- public static final String PURPOSE = "purpose";
- public static final String IS_TAGGED = "istagged";
- public static final String INSTANCE_NAME = "instancename";
- public static final String START_VM = "startvm";
- public static final String HA_HOST = "hahost";
- public static final String CUSTOM_DISK_OFF_MAX_SIZE = "customdiskofferingmaxsize";
- public static final String DEFAULT_ZONE_ID = "defaultzoneid";
- public static final String GUID = "guid";
-
- public static final String EXTERNAL_SWITCH_MGMT_DEVICE_ID = "vsmdeviceid";
- public static final String EXTERNAL_SWITCH_MGMT_DEVICE_NAME = "vsmdevicename";
- public static final String EXTERNAL_SWITCH_MGMT_DEVICE_STATE = "vsmdevicestate";
- // Would we need to have a capacity field for Cisco N1KV VSM? Max hosts managed by it perhaps? May remove this later.
- public static final String EXTERNAL_SWITCH_MGMT_DEVICE_CAPACITY = "vsmdevicecapacity";
- public static final String CISCO_NEXUS_VSM_NAME = "vsmname";
- public static final String VSM_USERNAME = "vsmusername";
- public static final String VSM_PASSWORD = "vsmpassword";
- public static final String VSM_IPADDRESS = "vsmipaddress";
- public static final String VSM_MGMT_VLAN_ID = "vsmmgmtvlanid";
- public static final String VSM_PKT_VLAN_ID = "vsmpktvlanid";
- public static final String VSM_CTRL_VLAN_ID = "vsmctrlvlanid";
- public static final String VSM_STORAGE_VLAN_ID = "vsmstoragevlanid";
- public static final String VSM_DOMAIN_ID = "vsmdomainid";
- public static final String VSM_CONFIG_MODE = "vsmconfigmode";
- public static final String VSM_CONFIG_STATE = "vsmconfigstate";
- public static final String VSM_DEVICE_STATE = "vsmdevicestate";
- public static final String ADD_VSM_FLAG = "addvsmflag";
- public static final String END_POINT = "endpoint";
- public static final String REGION_ID = "regionid";
- public static final String IS_PROPAGATE = "ispropagate";
- public static final String VPC_OFF_ID = "vpcofferingid";
- public static final String NETWORK = "network";
- public static final String VPC_ID = "vpcid";
- public static final String GATEWAY_ID = "gatewayid";
- public static final String CAN_USE_FOR_DEPLOY = "canusefordeploy";
- public static final String RESOURCE_IDS = "resourceids";
- public static final String RESOURCE_ID = "resourceid";
- public static final String CUSTOMER = "customer";
- public static final String S2S_VPN_GATEWAY_ID = "s2svpngatewayid";
- public static final String S2S_CUSTOMER_GATEWAY_ID = "s2scustomergatewayid";
- public static final String IPSEC_PSK = "ipsecpsk";
- public static final String GUEST_IP = "guestip";
- public static final String REMOVED = "removed";
- public static final String IKE_POLICY = "ikepolicy";
- public static final String ESP_POLICY = "esppolicy";
- public static final String IKE_LIFETIME = "ikelifetime";
- public static final String ESP_LIFETIME = "esplifetime";
- public static final String DPD = "dpd";
- public static final String FOR_VPC = "forvpc";
- public static final String SHRINK_OK = "shrinkok";
- public static final String NICIRA_NVP_DEVICE_ID = "nvpdeviceid";
- public static final String NICIRA_NVP_TRANSPORT_ZONE_UUID = "transportzoneuuid";
- public static final String NICIRA_NVP_DEVICE_NAME = "niciradevicename";
- public static final String NICIRA_NVP_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid";
- public static final String S3_ACCESS_KEY = "accesskey";
- public static final String S3_SECRET_KEY = "secretkey";
- public static final String S3_END_POINT = "endpoint";
- public static final String S3_BUCKET_NAME = "bucket";
- public static final String S3_HTTPS_FLAG = "usehttps";
- public static final String S3_CONNECTION_TIMEOUT = "connectiontimeout";
- public static final String S3_MAX_ERROR_RETRY = "maxerrorretry";
- public static final String S3_SOCKET_TIMEOUT = "sockettimeout";
- public static final String INCL_ZONES = "includezones";
- public static final String EXCL_ZONES = "excludezones";
- public static final String SOURCE = "source";
- public static final String COUNTER_ID = "counterid";
- public static final String AGGR_OPERATOR = "aggroperator";
- public static final String AGGR_FUNCTION = "aggrfunction";
- public static final String AGGR_VALUE = "aggrvalue";
- public static final String THRESHOLD = "threshold";
- public static final String RELATIONAL_OPERATOR = "relationaloperator";
- public static final String OTHER_DEPLOY_PARAMS = "otherdeployparams";
- public static final String MIN_MEMBERS = "minmembers";
- public static final String MAX_MEMBERS = "maxmembers";
- public static final String AUTOSCALE_VM_DESTROY_TIME = "destroyvmgraceperiod";
- public static final String VMPROFILE_ID = "vmprofileid";
- public static final String VMGROUP_ID = "vmgroupid";
- public static final String CS_URL = "csurl";
- public static final String SCALEUP_POLICY_IDS = "scaleuppolicyids";
- public static final String SCALEDOWN_POLICY_IDS = "scaledownpolicyids";
- public static final String SCALEUP_POLICIES = "scaleuppolicies";
- public static final String SCALEDOWN_POLICIES = "scaledownpolicies";
- public static final String INTERVAL = "interval";
- public static final String QUIETTIME = "quiettime";
- public static final String ACTION = "action";
- public static final String CONDITION_ID = "conditionid";
- public static final String CONDITION_IDS = "conditionids";
- public static final String COUNTERPARAM_LIST = "counterparam";
- public static final String AUTOSCALE_USER_ID = "autoscaleuserid";
- public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername";
-<<<<<<< HEAD
- public static final String UCS_DN = "ucsdn";
-=======
- public static final String VM_SNAPSHOT_DESCRIPTION = "description";
- public static final String VM_SNAPSHOT_DISPLAYNAME = "name";
- public static final String VM_SNAPSHOT_ID = "vmsnapshotid";
- public static final String VM_SNAPSHOT_DISK_IDS = "vmsnapshotdiskids";
- public static final String VM_SNAPSHOT_MEMORY = "snapshotmemory";
->>>>>>> CLOUDSTACK-684 Support VM Snapshot
-
- public enum HostDetails {
- all, capacity, events, stats, min;
- }
-
- public enum VMDetails {
- all, group, nics, stats, secgrp, tmpl, servoff, iso, volume, min;
- }
-
- public enum LDAPParams {
- hostname, port, usessl, queryfilter, searchbase, dn, passwd, truststore, truststorepass;
-
- @Override
- public String toString() {
- return "ldap." + name();
- }
- }
-
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
index c48534e..aeb76f5 100644
--- a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
@@ -55,11 +55,14 @@
@Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the template name")
private String templateName;
- @Parameter(name=ApiConstants.TEMPLATE_FILTER, type=CommandType.STRING, required=true, description="possible values are \"featured\", \"self\", \"self-executable\", \"executable\", and \"community\"." +
- "* featured-templates that are featured and are public" +
- "* self-templates that have been registered/created by the owner" +
- "* selfexecutable-templates that have been registered/created by the owner that can be used to deploy a new VM" +
- "* executable-all templates that can be used to deploy a new VM* community-templates that are public.")
+ @Parameter(name=ApiConstants.TEMPLATE_FILTER, type=CommandType.STRING, required=true, description="possible values are \"featured\", \"self\", \"selfexecutable\",\"sharedexecutable\",\"executable\", and \"community\". " +
+ "* featured : templates that have been marked as featured and public. " +
+ "* self : templates that have been registered or created by the calling user. " +
+ "* selfexecutable : same as self, but only returns templates that can be used to deploy a new VM. " +
+ "* sharedexecutable : templates ready to be deployed that have been granted to the calling user by another user. " +
+ "* executable : templates that are owned by the calling user, or public templates, that can be used to deploy a VM. " +
+ "* community : templates that have been marked as public but not featured. " +
+ "* all : all templates (only usable by admins).")
private String templateFilter;
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class,
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java
index 6719b8f..fb62000 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java
@@ -22,12 +22,12 @@
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DiskOfferingResponse;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.log4j.Logger;
import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
import com.cloud.offering.ServiceOffering;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
@@ -88,7 +88,7 @@
}
@Override
- public void execute(){
+ public void execute() throws ResourceAllocationException{
UserContext.current().setEventDetails("Vm Id: "+getId());
ServiceOffering serviceOffering = _configService.getServiceOffering(serviceOfferingId);
diff --git a/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java b/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java
index ede86e9..7fd6e0b 100644
--- a/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java
+++ b/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java
@@ -37,7 +37,7 @@
StoragePool pool = Mockito.mock(StoragePool.class);
bsc = new BackupSnapshotCommand(
- "secondaryStoragePoolURL", 101L, 102L, 103L, 104L,
+ "secondaryStoragePoolURL", 101L, 102L, 103L, 104L, 105L,
"volumePath", pool, "snapshotUuid", "snapshotName",
"prevSnapshotUuid", "prevBackupUuid", false, "vmName", 5);
bsa = new BackupSnapshotAnswer(bsc, true, "results", "bussname", false);
diff --git a/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java b/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java
index 7100497..06697c4 100644
--- a/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java
+++ b/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java
@@ -147,14 +147,14 @@
BackupSnapshotCommand bsc = new BackupSnapshotCommand(
"http://secondary.Storage.Url",
- 101L, 102L, 103L, 104L, "vPath", pool,
+ 101L, 102L, 103L, 104L, 105L, "vPath", pool,
"420fa39c-4ef1-a83c-fd93-46dc1ff515ae", "sName",
"9012793e-0657-11e2-bebc-0050568b0057",
"7167e0b2-f5b0-11e1-8414-0050568b0057", false, "vmName", 5);
BackupSnapshotCommand bsc1 = new BackupSnapshotCommand(
"http://secondary.Storage.Url",
- 101L, 102L, 103L, 104L, "vPath", pool,
+ 101L, 102L, 103L, 104L, 105L,"vPath", pool,
"420fa39c-4ef1-a83c-fd93-46dc1ff515ae", "sName",
"9012793e-0657-11e2-bebc-0050568b0057",
"7167e0b2-f5b0-11e1-8414-0050568b0057", false, "vmName", 5);
diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties
index d167a5c..f0b6b36 100644
--- a/client/WEB-INF/classes/resources/messages.properties
+++ b/client/WEB-INF/classes/resources/messages.properties
@@ -17,6 +17,7 @@
#new labels (begin) **********************************************************************************************
+label.use.vm.ip=Use VM IP:
label.menu.regions=Regions
label.region=Region
label.add.region=Add Region
diff --git a/debian/cloudstack-management.install b/debian/cloudstack-management.install
index 12478e1..cecc311 100644
--- a/debian/cloudstack-management.install
+++ b/debian/cloudstack-management.install
@@ -5,9 +5,9 @@
# 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
@@ -18,6 +18,8 @@
/etc/cloudstack/server/*
/etc/cloudstack/management/*
/etc/init.d/cloudstack-management
+/etc/security/limits.d/cloudstack-limits.conf
+/etc/sudoers.d/cloudstack
/var/cache/cloudstack/management
/var/cache/cloudstack/management/work
/var/cache/cloudstack/management/temp
diff --git a/debian/rules b/debian/rules
index a135601..613d76a 100755
--- a/debian/rules
+++ b/debian/rules
@@ -38,12 +38,12 @@
-Dcs.replace.properties=replace.properties.tmp
touch $@
-clean:
+clean:
dh_testdir
dh_testroot
rm -f build-arch-stamp build-indep-stamp configure-stamp
rm -f replace.properties.tmp
- dh_clean
+ dh_clean
install:
dh_testdir
@@ -75,6 +75,8 @@
# cloudstack-management
mkdir $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/server
mkdir $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/management
+ mkdir -p $(DESTDIR)/$(SYSCONFDIR)/security/limits.d/
+ mkdir -p $(DESTDIR)/$(SYSCONFDIR)/sudoers.d/
mkdir -p $(DESTDIR)/usr/share/$(PACKAGE)-management
mkdir -p $(DESTDIR)/usr/share/$(PACKAGE)-management/webapps/client
mkdir $(DESTDIR)/usr/share/$(PACKAGE)-management/setup
@@ -89,6 +91,12 @@
cp -r client/target/cloud-client-ui-$(VERSION)-SNAPSHOT/* $(DESTDIR)/usr/share/$(PACKAGE)-management/webapps/client/
cp server/target/conf/* $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/server/
cp client/target/conf/* $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/management/
+
+ # nast hack for a couple of configuration files
+ mv $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/server/cloudstack-limits.conf $(DESTDIR)/$(SYSCONFDIR)/security/limits.d/
+ mv $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/server/cloudstack-sudoers $(DESTDIR)/$(SYSCONFDIR)/sudoers.d/cloudstack
+ chmod 0440 $(DESTDIR)/$(SYSCONFDIR)/sudoers.d/cloudstack
+
ln -s tomcat6-nonssl.conf $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/management/tomcat6.conf
mkdir -p $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/management/Catalina/localhost/client
install -D packaging/debian/init/cloud-management $(DESTDIR)/$(SYSCONFDIR)/init.d/$(PACKAGE)-management
diff --git a/docs/en-US/cloudmonkey.xml b/docs/en-US/cloudmonkey.xml
index 0057562..5665ed4 100644
--- a/docs/en-US/cloudmonkey.xml
+++ b/docs/en-US/cloudmonkey.xml
@@ -24,7 +24,7 @@
<section id="cloudmonkey">
<title>CloudMonkey</title>
- <para>CloudMonkey is the &PRODUCT; Command Line Interface (CLI). It is written in Python and leverages Marvin. CloudMonkey can be used both as an interactive shell and as a command line tool which simplifies &PRODUCT; configuration and management.</para>
+ <para>CloudMonkey is the &PRODUCT; Command Line Interface (CLI). It is written in Python. CloudMonkey can be used both as an interactive shell and as a command line tool which simplifies &PRODUCT; configuration and management. It can be used with &PRODUCT; CloudStack 4.0-incubating and above</para>
<warning>
<para>CloudMonkey is still under development and should be considered a Work In Progress (WIP), the wiki is the most up to date documentation:</para>
<para><ulink url="https://cwiki.apache.org/CLOUDSTACK/cloudstack-cloudmonkey-cli.html">https://cwiki.apache.org/CLOUDSTACK/cloudstack-cloudmonkey-cli.html</ulink></para>
@@ -32,13 +32,15 @@
<section id="gettingcloudmonkey">
<title>Installing CloudMonkey</title>
- <para>There are two ways to get CloudMonkey:</para>
- <para><itemizedlist>
+ <para>CloudMonkey is dependent on <emphasis>readline, pygments, prettytable</emphasis>, when installing from source you will need to resolve those dependencies. Using the cheese shop, the dependencies will be automatically installed.</para>
+ <para>There are three ways to get CloudMonkey. Via the official &PRODUCT; source releases or via a community maintained distribution at <ulink url="http://pypi.python.org/pypi/cloudmonkey/">the cheese shop</ulink>. Developers can also get it directly from the git repository in <emphasis>tools/cli/</emphasis>.</para>
+ <para>
+ <itemizedlist>
<listitem>
- <para>Via the official Apache &PRODUCT; releases (starting with 4.1).</para>
+ <para>Via the official Apache &PRODUCT; releases as well as the git repository.</para>
<programlisting>
<![CDATA[
-$ git clone https://git-wip-us.apache.org/repos/asf/incubator-cloudstack.git
+$ git clone https://git-wip-us.apache.org/repos/asf/incubator-cloudstack.git # (optional if using a release download)
$ mvn clean install -P developer
$ cd tools/cli # cloudmonkey-x.x.x.tar.gz will be built in dist
$ python setup.py build
@@ -56,42 +58,80 @@
<section id="configuringcloudmonkey">
<title>Configuration</title>
- <para>To configure CloudMonkey you can edit the .cloudmonkey_config file in the user's home directory as shown below. The values can also be set interactively at the cloudmonkey prompt</para>
+ <para>To configure CloudMonkey you can edit the ~/.cloudmonkey/config file in the user's home directory as shown below. The values can also be set interactively at the cloudmonkey prompt. Logs are kept in ~/.cloudmonkey/log, and history is stored in ~/.cloudmonkey/history. Discovered apis are listed in ~/.cloudmonkey/cache. Only the log and history files can be custom paths and can be configured by setting appropriate file paths in ~/.cloudmonkey/config</para>
<programlisting>
-$ cat .cloudmonkey_config
-[CLI]
-protocol = http
+$ cat ~/.cloudmonkey/config
+[core]
+log_file = /Users/sebastiengoasguen/.cloudmonkey/log
asyncblock = true
+paramcompletion = false
+history_file = /Users/sebastiengoasguen/.cloudmonkey/history
+
+[ui]
color = true
-prompt = cloudmonkey>
-history_file = /Users/sebastiengoasguen/.cloudmonkey_history
-host = localhost
+prompt = >
+tabularize = false
+
+[user]
+secretkey =VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ
+apikey = plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdMkAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg
+
+[server]
path = /client/api
+host = localhost
+protocol = http
port = 8080
-apikey = plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg
-secretkey = VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ
-timeout = 600
-log_file = /Users/sebastiengoasguen/.cloudmonkey_log
+timeout = 3600
</programlisting>
- <para>The values can also be set at the cloudmonkey prompt. The API and secret keys are obtained via the &PRODUCT; UI or via a raw api call.</para>
+ <para>The values can also be set at the CloudMonkey prompt. The API and secret keys are obtained via the &PRODUCT; UI or via a raw api call.</para>
<programlisting>
<![CDATA[
$ cloudmonkey
-☁ Apache CloudStack cloudmonkey 4.0.0. Type help or ? to list commands.
-cloudmonkey> set prompt myprompt>
+☁ Apache CloudStack cloudmonkey 4.1.0-snapshot. Type help or ? to list commands.
+
+> set prompt myprompt>
myprompt> set host localhost
myprompt> set port 8080
myprompt> set apikey <your api key>
myprompt> set secretkey <your secret key>
]]>
</programlisting>
- <para>You can use cloudmonkey to interact with a local cloud, and even with a remote public cloud. You just need to set the host value properly and obtain the keys from the cloud administrator.</para>
+ <para>You can use CloudMonkey to interact with a local cloud, and even with a remote public cloud. You just need to set the host value properly and obtain the keys from the cloud administrator.</para>
+ </section>
+
+ <section id="cliapidiscovery">
+ <title>API Discovery</title>
+ <note>
+ <para>In &PRODUCT; 4.0.* releases, the list of api calls available will be pre-cached, while starting with &PRODUCT; 4.1 releases and above an API discovery service is enabled. CloudMonkey will discover automatically the api calls available on the management server. The sync command in CloudMonkey pulls a list of apis which are accessible to your user role, along with help docs etc. and stores them in ~/.cloudmonkey/cache. This allows cloudmonkey to be adaptable to changes in mgmt server, so in case the sysadmin enables a plugin such as Nicira NVP for that user role, the users can get those changes. New verbs and grammar (DSL) rules are created on the fly.</para>
+ </note>
+ <para>To discover the APIs available do:</para>
+ <programlisting>
+ > sync
+324 APIs discovered and cached
+ </programlisting>
+ </section>
+
+ <section id="clitabularoutput">
+ <title>Tabular Output</title>
+ <para>The number of key/value pairs returned by the api calls can be large resulting in a very long output. To enable easier viewing of the output, a tabular formatting can be setup. You may enable tabular listing and even choose set of column fields, this allows you to create your own field using the filter param which takes in comma separated argument. If argument has a space, put them under double quotes. The create table will have the same sequence of field filters provided</para>
+ <para>To enable it, use the <emphasis>set</emphasis> function and create filters like so:</para>
+ <programlisting>
+> set tabularize true
+> list users filter=id,domain,account
+count = 1
+user:
++--------------------------------------+--------+---------+
+| id | domain | account |
++--------------------------------------+--------+---------+
+| 7ed6d5da-93b2-4545-a502-23d20b48ef2a | ROOT | admin |
++--------------------------------------+--------+---------+
+ </programlisting>
</section>
<section id="interactivecli">
<title>Interactive Shell Usage</title>
- <para>To start learning cloudmonkey, the best is to use the interactive shell. Simply type cloudmonkey at the prompt and you should get the interactive shell.</para>
- <para>At the cloudmonkey prompt press the tab key twice, you will see all potential verbs available. Pick on, enter a space and then press tab twice. You will see all actions available for that verb</para>
+ <para>To start learning CloudMonkey, the best is to use the interactive shell. Simply type CloudMonkey at the prompt and you should get the interactive shell.</para>
+ <para>At the CloudMonkey prompt press the tab key twice, you will see all potential verbs available. Pick on, enter a space and then press tab twice. You will see all actions available for that verb</para>
<programlisting>
<![CDATA[
cloudmonkey>
diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
index cfd9f40..3602bb1 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
@@ -660,7 +660,7 @@
Long accountId = baseVolume.getAccountId();
HostVO secHost = getSecHost(baseVolume.getId(), baseVolume.getDataCenterId());
-
+ Long secHostId = secHost.getId();
String secondaryStoragePoolUrl = secHost.getStorageUrl();
String snapshotUuid = srcSnapshot.getPath();
// In order to verify that the snapshot is not empty,
@@ -693,7 +693,7 @@
StoragePool srcPool = (StoragePool)dataStoreMgr.getPrimaryDataStore(baseVolume.getPoolId());
String value = configDao.getValue(Config.BackupSnapshotWait.toString());
int _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue()));
- BackupSnapshotCommand backupSnapshotCommand = new BackupSnapshotCommand(secondaryStoragePoolUrl, dcId, accountId, baseVolume.getId(), srcSnapshot.getId(), baseVolume.getPath(), srcPool, snapshotUuid,
+ BackupSnapshotCommand backupSnapshotCommand = new BackupSnapshotCommand(secondaryStoragePoolUrl, dcId, accountId, baseVolume.getId(), srcSnapshot.getId(), secHostId, baseVolume.getPath(), srcPool, snapshotUuid,
srcSnapshot.getName(), prevSnapshotUuid, prevBackupUuid, isVolumeInactive, vmName, _backupsnapshotwait);
if ( swift != null ) {
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 c2d5a94..8ee3ea4 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
@@ -110,6 +110,7 @@
import com.cloud.agent.api.ModifyStoragePoolAnswer;
import com.cloud.agent.api.ModifyStoragePoolCommand;
import com.cloud.agent.api.NetworkRulesSystemVmCommand;
+import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand;
import com.cloud.agent.api.NetworkUsageAnswer;
import com.cloud.agent.api.NetworkUsageCommand;
import com.cloud.agent.api.PingCommand;
@@ -1176,6 +1177,8 @@
return execute((ResizeVolumeCommand) cmd);
} else if (cmd instanceof CheckNetworkCommand) {
return execute((CheckNetworkCommand) cmd);
+ } else if (cmd instanceof NetworkRulesVmSecondaryIpCommand) {
+ return execute((NetworkRulesVmSecondaryIpCommand) cmd);
} else {
s_logger.warn("Unsupported command ");
return Answer.createUnsupportedCommandAnswer(cmd);
@@ -2339,7 +2342,7 @@
boolean result = add_network_rules(cmd.getVmName(),
Long.toString(cmd.getVmId()), cmd.getGuestIp(),
cmd.getSignature(), Long.toString(cmd.getSeqNum()),
- cmd.getGuestMac(), cmd.stringifyRules(), vif, brname);
+ cmd.getGuestMac(), cmd.stringifyRules(), vif, brname, cmd.getSecIpsString());
if (!result) {
s_logger.warn("Failed to program network rules for vm "
@@ -3096,7 +3099,18 @@
default_network_rules_for_systemvm(conn, vmName);
break;
} else {
- default_network_rules(conn, vmName, nic, vmSpec.getId());
+ List<String> nicSecIps = nic.getNicSecIps();
+ String secIpsStr;
+ StringBuilder sb = new StringBuilder();
+ if (nicSecIps != null) {
+ for (String ip : nicSecIps) {
+ sb.append(ip).append(":");
+ }
+ secIpsStr = sb.toString();
+ } else {
+ secIpsStr = "0:";
+ }
+ default_network_rules(conn, vmName, nic, vmSpec.getId(), secIpsStr);
}
}
}
@@ -4364,7 +4378,7 @@
}
protected boolean default_network_rules(Connect conn, String vmName,
- NicTO nic, Long vmId) {
+ NicTO nic, Long vmId, String secIpStr) {
if (!_can_bridge_firewall) {
return false;
}
@@ -4388,6 +4402,7 @@
cmd.add("--vmmac", nic.getMac());
cmd.add("--vif", vif);
cmd.add("--brname", brname);
+ cmd.add("--nicsecips", secIpStr);
String result = cmd.execute();
if (result != null) {
return false;
@@ -4450,7 +4465,7 @@
private boolean add_network_rules(String vmName, String vmId,
String guestIP, String sig, String seq, String mac, String rules,
- String vif, String brname) {
+ String vif, String brname, String secIps) {
if (!_can_bridge_firewall) {
return false;
}
@@ -4466,6 +4481,7 @@
cmd.add("--vmmac", mac);
cmd.add("--vif", vif);
cmd.add("--brname", brname);
+ cmd.add("--nicsecips", secIps);
if (rules != null) {
cmd.add("--rules", newRules);
}
@@ -4476,6 +4492,25 @@
return true;
}
+ private boolean network_rules_vmSecondaryIp (Connect conn, String vmName, String secIp, String action) {
+
+ if (!_can_bridge_firewall) {
+ return false;
+ }
+
+ Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
+ cmd.add("network_rules_vmSecondaryIp");
+ cmd.add("--vmname", vmName);
+ cmd.add("--nicsecips", secIp);
+ cmd.add("--action", action);
+
+ String result = cmd.execute();
+ if (result != null) {
+ return false;
+ }
+ return true;
+ }
+
private boolean cleanup_rules() {
if (!_can_bridge_firewall) {
return false;
@@ -4564,6 +4599,20 @@
return new Answer(cmd, success, "");
}
+ private Answer execute(NetworkRulesVmSecondaryIpCommand cmd) {
+ boolean success = false;
+ Connect conn;
+ try {
+ conn = LibvirtConnection.getConnection();
+ success = network_rules_vmSecondaryIp(conn, cmd.getVmName(), cmd.getVmSecIp(), cmd.getAction());
+ } catch (LibvirtException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ return new Answer(cmd, success, "");
+ }
+
@Override
public void setName(String name) {
// TODO Auto-generated method stub
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index f0cf2f0..52d992f 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -3552,7 +3552,7 @@
protected String backupSnapshot(Connection conn, String primaryStorageSRUuid, Long dcId, Long accountId,
- Long volumeId, String secondaryStorageMountPath, String snapshotUuid, String prevBackupUuid, Boolean isISCSI, int wait) {
+ Long volumeId, String secondaryStorageMountPath, String snapshotUuid, String prevBackupUuid, Boolean isISCSI, int wait, Long secHostId) {
String backupSnapshotUuid = null;
if (prevBackupUuid == null) {
@@ -3565,7 +3565,7 @@
String results = callHostPluginAsync(conn, "vmopsSnapshot", "backupSnapshot", wait,
"primaryStorageSRUuid", primaryStorageSRUuid, "dcId", dcId.toString(), "accountId", accountId.toString(),
"volumeId", volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath,
- "snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid, "isISCSI", isISCSI.toString());
+ "snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid, "isISCSI", isISCSI.toString(), "secHostId", secHostId.toString());
String errMsg = null;
if (results == null || results.isEmpty()) {
errMsg = "Could not copy backupUuid: " + backupSnapshotUuid + " of volumeId: " + volumeId
@@ -6837,6 +6837,7 @@
String prevBackupUuid = cmd.getPrevBackupUuid();
String prevSnapshotUuid = cmd.getPrevSnapshotUuid();
int wait = cmd.getWait();
+ Long secHostId = cmd.getSecHostId();
// By default assume failure
String details = null;
boolean success = false;
@@ -6915,7 +6916,7 @@
} else if (cmd.getS3() != null) {
backupSnapshotToS3(conn, cmd.getS3(), primaryStorageSRUuid, snapshotPaUuid, isISCSI, wait);
} else {
- snapshotBackupUuid = backupSnapshot(conn, primaryStorageSRUuid, dcId, accountId, volumeId, secondaryStorageMountPath, snapshotUuid, prevBackupUuid, isISCSI, wait);
+ snapshotBackupUuid = backupSnapshot(conn, primaryStorageSRUuid, dcId, accountId, volumeId, secondaryStorageMountPath, snapshotUuid, prevBackupUuid, isISCSI, wait, secHostId);
success = (snapshotBackupUuid != null);
}
}
diff --git a/scripts/vm/hypervisor/xenserver/vmopsSnapshot b/scripts/vm/hypervisor/xenserver/vmopsSnapshot
index 6fb1b18..87a5083 100755
--- a/scripts/vm/hypervisor/xenserver/vmopsSnapshot
+++ b/scripts/vm/hypervisor/xenserver/vmopsSnapshot
@@ -321,25 +321,24 @@
util.SMlog("Successfully unmounted " + localDir)
return
-def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, instanceId):
+def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, instanceId, secHostId):
# The aim is to mount secondaryStorageMountPath on
# And create <accountId>/<instanceId> dir on it, if it doesn't exist already.
# Assuming that secondaryStorageMountPath exists remotely
- # Alex's suggestion and currently implemented:
- # Just mount secondaryStorageMountPath/<relativeDir> everytime
+ # Just mount secondaryStorageMountPath/<relativeDir>/SecondaryStorageHost/ everytime
# Never unmount.
snapshotsDir = os.path.join(secondaryStorageMountPath, relativeDir)
# Mkdir local mount point dir, if it doesn't exist.
localMountPointPath = os.path.join(CLOUD_DIR, dcId)
- localMountPointPath = os.path.join(localMountPointPath, relativeDir)
+ localMountPointPath = os.path.join(localMountPointPath, relativeDir, secHostId)
makedirs(localMountPointPath)
- # if something is not mounted already on localMountPointPath,
+ # if something is not mounted already on localMountPointPath,
# mount secondaryStorageMountPath on localMountPath
if os.path.ismount(localMountPointPath):
- # There is only one secondary storage per zone.
+ # There is more than one secondary storage per zone.
# And we are mounting each sec storage under a zone-specific directory
# So two secondary storage snapshot dirs will never get mounted on the same point on the same XenServer.
util.SMlog("The remote snapshots directory has already been mounted on " + localMountPointPath)
@@ -352,11 +351,22 @@
makedirs(backupsDir)
return backupsDir
+def unmountAll(path):
+ try:
+ for dir in os.listdir(path):
+ if dir.isdigit():
+ util.SMlog("Unmounting Sub-Directory: " + dir)
+ localMountPointPath = os.path.join(path, dir)
+ umount(localMountPointPath)
+ except:
+ util.SMlog("Ignoring the error while trying to unmount the snapshots dir")
+
@echo
def unmountSnapshotsDir(session, args):
dcId = args['dcId']
localMountPointPath = os.path.join(CLOUD_DIR, dcId)
localMountPointPath = os.path.join(localMountPointPath, "snapshots")
+ unmountAll(localMountPointPath)
try:
umount(localMountPointPath)
except:
@@ -482,7 +492,8 @@
snapshotUuid = args['snapshotUuid']
prevBackupUuid = args['prevBackupUuid']
backupUuid = args['backupUuid']
- isISCSI = getIsTrueString(args['isISCSI'])
+ isISCSI = getIsTrueString(args['isISCSI'])
+ secHostId = args['secHostId']
primarySRPath = getPrimarySRPath(primaryStorageSRUuid, isISCSI)
util.SMlog("primarySRPath: " + primarySRPath)
@@ -496,10 +507,10 @@
# Mount secondary storage mount path on XenServer along the path
# /var/run/sr-mount/<dcId>/snapshots/ and create <accountId>/<volumeId> dir
# on it.
- backupsDir = mountSnapshotsDir(secondaryStorageMountPath, "snapshots", dcId, accountId, volumeId)
+ backupsDir = mountSnapshotsDir(secondaryStorageMountPath, "snapshots", dcId, accountId, volumeId, secHostId)
util.SMlog("Backups dir " + backupsDir)
- # Check existence of snapshot on primary storage
+ # Check existence of snapshot on primary storage
isfile(baseCopyPath, isISCSI)
if prevBackupUuid:
# Check existence of prevBackupFile
diff --git a/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot b/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot
index f7b2e0e..0536638 100644
--- a/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot
+++ b/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot
@@ -321,25 +321,24 @@
util.SMlog("Successfully unmounted " + localDir)
return
-def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, instanceId):
+def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, instanceId, secHostId):
# The aim is to mount secondaryStorageMountPath on
# And create <accountId>/<instanceId> dir on it, if it doesn't exist already.
# Assuming that secondaryStorageMountPath exists remotely
- # Alex's suggestion and currently implemented:
- # Just mount secondaryStorageMountPath/<relativeDir> everytime
+ # Just mount secondaryStorageMountPath/<relativeDir>/SecondaryStorageHost/ everytime
# Never unmount.
snapshotsDir = os.path.join(secondaryStorageMountPath, relativeDir)
# Mkdir local mount point dir, if it doesn't exist.
localMountPointPath = os.path.join(CLOUD_DIR, dcId)
- localMountPointPath = os.path.join(localMountPointPath, relativeDir)
+ localMountPointPath = os.path.join(localMountPointPath, relativeDir, secHostId)
makedirs(localMountPointPath)
# if something is not mounted already on localMountPointPath,
# mount secondaryStorageMountPath on localMountPath
if os.path.ismount(localMountPointPath):
- # There is only one secondary storage per zone.
+ # There can be more than one secondary storage per zone.
# And we are mounting each sec storage under a zone-specific directory
# So two secondary storage snapshot dirs will never get mounted on the same point on the same XenServer.
util.SMlog("The remote snapshots directory has already been mounted on " + localMountPointPath)
@@ -352,11 +351,22 @@
makedirs(backupsDir)
return backupsDir
+def unmountAll(path):
+ try:
+ for dir in os.listdir(path):
+ if dir.isdigit():
+ util.SMlog("Unmounting Sub-Directory: " + dir)
+ localMountPointPath = os.path.join(path, dir)
+ umount(localMountPointPath)
+ except:
+ util.SMlog("Ignoring the error while trying to unmount the snapshots dir")
+
@echo
def unmountSnapshotsDir(session, args):
dcId = args['dcId']
localMountPointPath = os.path.join(CLOUD_DIR, dcId)
localMountPointPath = os.path.join(localMountPointPath, "snapshots")
+ unmountAll(localMountPointPath)
try:
umount(localMountPointPath)
except:
@@ -490,7 +500,8 @@
snapshotUuid = args['snapshotUuid']
prevBackupUuid = args['prevBackupUuid']
backupUuid = args['backupUuid']
- isISCSI = getIsTrueString(args['isISCSI'])
+ isISCSI = getIsTrueString(args['isISCSI'])
+ secHostId = args['secHostId']
primarySRPath = getPrimarySRPath(session, primaryStorageSRUuid, isISCSI)
util.SMlog("primarySRPath: " + primarySRPath)
@@ -504,10 +515,10 @@
# Mount secondary storage mount path on XenServer along the path
# /var/run/sr-mount/<dcId>/snapshots/ and create <accountId>/<volumeId> dir
# on it.
- backupsDir = mountSnapshotsDir(secondaryStorageMountPath, "snapshots", dcId, accountId, volumeId)
+ backupsDir = mountSnapshotsDir(secondaryStorageMountPath, "snapshots", dcId, accountId, volumeId, secHostId)
util.SMlog("Backups dir " + backupsDir)
- # Check existence of snapshot on primary storage
+ # Check existence of snapshot on primary storage
isfile(baseCopyPath, isISCSI)
if prevBackupUuid:
# Check existence of prevBackupFile
diff --git a/scripts/vm/network/security_group.py b/scripts/vm/network/security_group.py
index 1bcbc3e..49d9be6 100755
--- a/scripts/vm/network/security_group.py
+++ b/scripts/vm/network/security_group.py
@@ -126,7 +126,12 @@
execute("iptables -X " + vmchain_egress)
except:
logging.debug("Ignoring failure to delete chain " + vmchain_egress)
-
+
+ try:
+ execute("ipset -F " + vm_name)
+ execute("ipset -X " + vm_name)
+ except:
+ logging.debug("Ignoring failure to delete ipset " + vmchain)
if vif is not None:
try:
@@ -139,7 +144,8 @@
except:
pass
remove_rule_log_for_vm(vm_name)
-
+ remove_secip_log_for_vm(vm_name)
+
if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-'] ]:
return 'true'
@@ -171,7 +177,7 @@
execute("ebtables -t nat " + cmd)
except:
logging.debug("Ignoring failure to delete ebtables rules for vm " + vm_name)
- chains = [vm_name+"-in", vm_name+"-out"]
+ chains = [vm_name+"-in", vm_name+"-out", vm_name+"-in-ips", vm_name+"-out-ips"]
for chain in chains:
try:
execute("ebtables -t nat -F " + chain)
@@ -182,8 +188,10 @@
def default_ebtables_rules(vm_name, vm_ip, vm_mac, vif):
vmchain_in = vm_name + "-in"
vmchain_out = vm_name + "-out"
+ vmchain_in_ips = vm_name + "-in-ips"
+ vmchain_out_ips = vm_name + "-out-ips"
- for chain in [vmchain_in, vmchain_out]:
+ for chain in [vmchain_in, vmchain_out, vmchain_in_ips, vmchain_out_ips]:
try:
execute("ebtables -t nat -N " + chain)
except:
@@ -193,6 +201,8 @@
# -s ! 52:54:0:56:44:32 -j DROP
execute("ebtables -t nat -A PREROUTING -i " + vif + " -j " + vmchain_in)
execute("ebtables -t nat -A POSTROUTING -o " + vif + " -j " + vmchain_out)
+ execute("ebtables -t nat -A " + vmchain_in_ips + " -j DROP")
+ execute("ebtables -t nat -A " + vmchain_out_ips + " -j DROP")
except:
logging.debug("Failed to program default rules")
return 'false'
@@ -202,7 +212,8 @@
execute("ebtables -t nat -A " + vmchain_in + " -p ARP -s ! " + vm_mac + " -j DROP")
execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-mac-src ! " + vm_mac + " -j DROP")
if vm_ip is not None:
- execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-ip-src ! " + vm_ip + " -j DROP")
+ execute("ebtables -t nat -A " + vmchain_in + " -p ARP -j " + vmchain_in_ips)
+ execute("ebtables -t nat -I " + vmchain_in_ips + " -p ARP --arp-ip-src " + vm_ip + " -j RETURN")
execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-op Request -j ACCEPT")
execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-op Reply -j ACCEPT")
execute("ebtables -t nat -A " + vmchain_in + " -p ARP -j DROP")
@@ -213,7 +224,8 @@
try:
execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Reply --arp-mac-dst ! " + vm_mac + " -j DROP")
if vm_ip is not None:
- execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-ip-dst ! " + vm_ip + " -j DROP")
+ execute("ebtables -t nat -A " + vmchain_out + " -p ARP -j " + vmchain_out_ips )
+ execute("ebtables -t nat -I " + vmchain_out_ips + " -p ARP --arp-ip-dst " + vm_ip + " -j RETURN")
execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Request -j ACCEPT")
execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Reply -j ACCEPT")
execute("ebtables -t nat -A " + vmchain_out + " -p ARP -j DROP")
@@ -255,12 +267,95 @@
logging.debug("Failed to log default network rules for systemvm, ignoring")
return 'true'
+def remove_secip_log_for_vm(vmName):
+ vm_name = vmName
+ logfilename = "/var/run/cloud/"+vm_name+".ip"
-def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname):
+ result = True
+ try:
+ os.remove(logfilename)
+ except:
+ util.SMlog("Failed to delete rule log file " + logfilename)
+ result = False
+
+ return result
+
+def write_secip_log_for_vm (vmName, secIps, vmId):
+ vm_name = vmName
+ logfilename = "/var/run/cloud/"+vm_name+".ip"
+ logging.debug("Writing log to " + logfilename)
+ logf = open(logfilename, 'w')
+ output = ','.join([vmName, secIps, vmId])
+ result = True
+
+ try:
+ logf.write(output)
+ logf.write('\n')
+ except:
+ logging.debug("Failed to write to rule log file " + logfilename)
+ result = False
+
+ logf.close()
+
+ return result
+
+def create_ipset_forvm (ipsetname):
+ result = True
+ try:
+ logging.debug("Creating ipset chain .... " + ipsetname)
+ execute("ipset -F " + ipsetname)
+ execute("ipset -X " + ipsetname)
+ execute("ipset -N " + ipsetname + " iphash")
+ except:
+ logging.debug("ipset chain not exists creating.... " + ipsetname)
+ execute("ipset -N " + ipsetname + " iphash")
+
+ return result
+
+def add_to_ipset(ipsetname, ips, action):
+ result = True
+ for ip in ips:
+ try:
+ logging.debug("vm ip " + ip)
+ execute("ipset " + action + " " + ipsetname + " " + ip)
+ except:
+ logging.debug("vm ip alreday in ip set " + ip)
+ continue
+
+ return result
+
+def network_rules_vmSecondaryIp(vm_name, ip_secondary, action):
+ logging.debug("vmName = "+ vm_name)
+ logging.debug("action = "+ action)
+
+ domid = getvmId(vm_name)
+
+ vmchain = vm_name
+ add_to_ipset(vmchain, [ip_secondary], action)
+
+ #add ebtables rules for the secondary ip
+ ebtables_rules_vmip(vm_name, [ip_secondary], action)
+
+ return 'true'
+
+def ebtables_rules_vmip (vmname, ips, action):
+ vmchain_inips = vmname + "-in-ips"
+ vmchain_outips = vmname + "-out-ips"
+
+ for ip in ips:
+ logging.debug("ip = "+ip)
+ try:
+ execute("ebtables -t nat -I " + vmchain_inips + " -p ARP --arp-ip-src " + ip + " -j RETURN")
+ execute("ebtables -t nat -I " + vmchain_outips + " -p ARP --arp-ip-dst " + ip + " -j RETURN")
+ except:
+ logging.debug("Failed to program ebtables rules for secondary ip "+ ip)
+ continue
+
+def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname, sec_ips):
if not addFWFramework(brname):
return False
- vmName = vm_name
+ vmName = vm_name
brfw = "BF-" + brname
domID = getvmId(vm_name)
delete_rules_for_vm_in_bridge_firewall_chain(vmName)
@@ -285,6 +380,31 @@
except:
execute("iptables -F " + vmchain_default)
+ action = "-A"
+ vmipsetName = vm_name
+ #create ipset and add vm ips to that ip set
+ if create_ipset_forvm(vmipsetName) == False:
+ logging.debug(" failed to create ipset for rule " + str(tokens))
+ return 'false'
+
+ #add primary nic ip to ipset
+ if add_to_ipset(vmipsetName, [vm_ip], action ) == False:
+ logging.debug(" failed to add vm " + vm_ip + " ip to set ")
+ return 'false'
+
+ #add secodnary nic ips to ipset
+ secIpSet = "1"
+ ips = sec_ips.split(':')
+ ips.pop()
+ if ips[0] == "0":
+ secIpSet = "0";
+
+ if secIpSet == "1":
+ logging.debug("Adding ipset for secondary ips")
+ add_to_ipset(vmipsetName, ips, action)
+ if write_secip_log_for_vm(vm_name, sec_ips, vm_id) == False:
+ logging.debug("Failed to log default network rules, ignoring")
+
try:
execute("iptables -A " + brfw + "-OUT" + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain_default)
execute("iptables -A " + brfw + "-IN" + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -j " + vmchain_default)
@@ -295,8 +415,8 @@
#don't let vm spoof its ip address
if vm_ip is not None:
- execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -p udp --dport 53 -j RETURN ")
- execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -j " + vmchain_egress)
+ execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --set " + vmipsetName + " src -p udp --dport 53 -j RETURN ")
+ execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --set " + vmipsetName + " src -j " + vmchain_egress)
execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain)
execute("iptables -A " + vmchain + " -j DROP")
except:
@@ -304,6 +424,8 @@
return 'false'
default_ebtables_rules(vmchain, vm_ip, vm_mac, vif)
+ #default ebtables rules for vm secondary ips
+ ebtables_rules_vmip(vm_name, ips, "-I")
if vm_ip is not None:
if write_rule_log_for_vm(vmName, vm_id, vm_ip, domID, '_initial_', '-1') == False:
@@ -598,7 +720,7 @@
def egress_chain_name(vm_name):
return vm_name + "-eg"
-def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif, brname):
+def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif, brname, sec_ips):
try:
vmName = vm_name
domId = getvmId(vmName)
@@ -614,7 +736,7 @@
return 'true'
if changes[0] or changes[1] or changes[2] or changes[3]:
- default_network_rules(vmName, vm_id, vm_ip, vmMac, vif, brname)
+ default_network_rules(vmName, vm_id, vm_ip, vmMac, vif, brname, sec_ips)
if rules == "" or rules == None:
lines = []
@@ -622,10 +744,14 @@
lines = rules.split(';')[:-1]
logging.debug(" programming network rules for IP: " + vm_ip + " vmname=" + vm_name)
- vmchain = vm_name
- execute("iptables -F " + vmchain)
- egress_vmchain = egress_chain_name(vm_name)
- execute("iptables -F " + egress_vmchain)
+ try:
+ vmchain = vm_name
+ execute("iptables -F " + vmchain)
+ egress_vmchain = egress_chain_name(vm_name)
+ execute("iptables -F " + egress_vmchain)
+ except:
+ logging.debug("Error flushing iptables rules for " + vmchain + ". Presuming firewall rules deleted, re-initializing." )
+ default_network_rules(vm_name, vm_id, vm_ip, vmMac, vif, brname)
egressrule = 0
for line in lines:
@@ -815,6 +941,8 @@
parser.add_option("--dhcpSvr", dest="dhcpSvr")
parser.add_option("--hostIp", dest="hostIp")
parser.add_option("--hostMacAddr", dest="hostMacAddr")
+ parser.add_option("--nicsecips", dest="nicSecIps")
+ parser.add_option("--action", dest="action")
(option, args) = parser.parse_args()
if len(args) == 0:
logging.debug("No command to execute")
@@ -823,7 +951,7 @@
if cmd == "can_bridge_firewall":
can_bridge_firewall(args[1])
elif cmd == "default_network_rules":
- default_network_rules(option.vmName, option.vmID, option.vmIP, option.vmMAC, option.vif, option.brname)
+ default_network_rules(option.vmName, option.vmID, option.vmIP, option.vmMAC, option.vif, option.brname, option.nicSecIps)
elif cmd == "destroy_network_rules_for_vm":
destroy_network_rules_for_vm(option.vmName, option.vif)
elif cmd == "default_network_rules_systemvm":
@@ -831,7 +959,9 @@
elif cmd == "get_rule_logs_for_vms":
get_rule_logs_for_vms()
elif cmd == "add_network_rules":
- add_network_rules(option.vmName, option.vmID, option.vmIP, option.sig, option.seq, option.vmMAC, option.rules, option.vif, option.brname)
+ add_network_rules(option.vmName, option.vmID, option.vmIP, option.sig, option.seq, option.vmMAC, option.rules, option.vif, option.brname, option.nicSecIps)
+ elif cmd == "network_rules_vmSecondaryIp":
+ network_rules_vmSecondaryIp(option.vmName, option.nicSecIps, option.action)
elif cmd == "cleanup_rules":
cleanup_rules()
elif cmd == "post_default_network_rules":
diff --git a/server/conf/cloudstack-limits.conf.in b/server/conf/cloudstack-limits.conf.in
new file mode 100644
index 0000000..c28ad8c
--- /dev/null
+++ b/server/conf/cloudstack-limits.conf.in
@@ -0,0 +1,21 @@
+# 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.
+
+# Specific limits for the CloudStack management server which
+# runs under the user 'cloud' by default
+@MSUSER hard nofile 4096
+@MSUSER soft nofile 4096
diff --git a/server/conf/cloudstack-sudoers.in b/server/conf/cloudstack-sudoers.in
new file mode 100644
index 0000000..c525d3c
--- /dev/null
+++ b/server/conf/cloudstack-sudoers.in
@@ -0,0 +1,22 @@
+# 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.
+
+# The CloudStack management server needs sudo permissions
+# without a password.
+
+@MSUSER ALL =NOPASSWD : ALL
+
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 64465a2..d01ea5b 100755
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -373,7 +373,7 @@
IntervalToEchoBaremetalSecurityGroupAgent("Advanced", ManagementServer.class, Integer.class, "interval.baremetal.securitygroup.agent.echo", "10", "Interval to echo baremetal security group agent, in seconds", null),
TimeoutToEchoBaremetalSecurityGroupAgent("Advanced", ManagementServer.class, Integer.class, "timeout.baremetal.securitygroup.agent.echo", "3600", "Timeout to echo baremetal security group agent, in seconds, the provisioning process will be treated as a failure", null),
- ApiLimitEnabled("Advanced", ManagementServer.class, Boolean.class, "api.throttling.enabled", "true", "Enable/disable Api rate limit", null),
+ ApiLimitEnabled("Advanced", ManagementServer.class, Boolean.class, "api.throttling.enabled", "false", "Enable/disable Api rate limit", null),
ApiLimitInterval("Advanced", ManagementServer.class, Integer.class, "api.throttling.interval", "1", "Time interval (in seconds) to reset API count", null),
ApiLimitMax("Advanced", ManagementServer.class, Integer.class, "api.throttling.max", "25", "Max allowed number of APIs within fixed interval", null),
ApiLimitCacheSize("Advanced", ManagementServer.class, Integer.class, "api.throttling.cachesize", "50000", "Account based API count cache size", null),
diff --git a/server/src/com/cloud/deploy/AbstractDeployPlannerSelector.java b/server/src/com/cloud/deploy/AbstractDeployPlannerSelector.java
index 62094eb..03e8774 100755
--- a/server/src/com/cloud/deploy/AbstractDeployPlannerSelector.java
+++ b/server/src/com/cloud/deploy/AbstractDeployPlannerSelector.java
@@ -18,15 +18,23 @@
import java.util.Map;
+import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.utils.component.AdapterBase;
import com.cloud.vm.UserVmVO;
-public abstract class AbstractDeployPlannerSelector implements DeployPlannerSelector {
+public abstract class AbstractDeployPlannerSelector extends AdapterBase implements DeployPlannerSelector {
protected Map<String, Object> params;
protected String name;
protected int runLevel;
-
+
+ @Inject
+ protected ConfigurationDao _configDao;
+ protected String _allocationAlgorithm = "random";
+
@Override
public String getName() {
return name;
@@ -59,6 +67,8 @@
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ super.configure(name, params);
+ _allocationAlgorithm = _configDao.getValue(Config.VmAllocationAlgorithm.key());
return true;
}
diff --git a/server/src/com/cloud/deploy/HypervisorVmPlannerSelector.java b/server/src/com/cloud/deploy/HypervisorVmPlannerSelector.java
index 034a9aa..8b2a144 100755
--- a/server/src/com/cloud/deploy/HypervisorVmPlannerSelector.java
+++ b/server/src/com/cloud/deploy/HypervisorVmPlannerSelector.java
@@ -18,6 +18,7 @@
import javax.ejb.Local;
+import com.cloud.deploy.DeploymentPlanner.AllocationAlgorithm;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.vm.UserVmVO;
@@ -26,8 +27,20 @@
@Override
public String selectPlanner(UserVmVO vm) {
if (vm.getHypervisorType() != HypervisorType.BareMetal) {
- return "FirstFitPlanner";
+ //check the allocation strategy
+ if (_allocationAlgorithm != null) {
+ if (_allocationAlgorithm.equals(AllocationAlgorithm.random.toString())
+ || _allocationAlgorithm.equals(AllocationAlgorithm.firstfit.toString())) {
+ return "FirstFitPlanner";
+ } else if (_allocationAlgorithm.equals(AllocationAlgorithm.userdispersing.toString())) {
+ return "UserDispersingPlanner";
+ } else if (_allocationAlgorithm.equals(AllocationAlgorithm.userconcentratedpod_random.toString())
+ || _allocationAlgorithm.equals(AllocationAlgorithm.userconcentratedpod_firstfit.toString())) {
+ return "UserConcentratedPodPlanner";
+ }
+ }
}
+
return null;
}
}
diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java
index 46790b3..52089df 100644
--- a/server/src/com/cloud/network/NetworkModelImpl.java
+++ b/server/src/com/cloud/network/NetworkModelImpl.java
@@ -1972,4 +1972,21 @@
}
}
}
+
+ @Override
+ public String getStartIpv6Address(long networkId) {
+ List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
+ if (vlans == null) {
+ return null;
+ }
+ String startIpv6 = null;
+ // Get the start ip of first create vlan(not the lowest, because if you add a lower vlan, lowest vlan would change)
+ for (Vlan vlan : vlans) {
+ if (vlan.getIp6Range() != null) {
+ startIpv6 = vlan.getIp6Range().split("-")[0];
+ break;
+ }
+ }
+ return startIpv6;
+ }
}
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 3cbd51d..ce65586 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -162,6 +162,7 @@
import com.cloud.network.dao.Site2SiteVpnConnectionDao;
import com.cloud.network.dao.Site2SiteVpnConnectionVO;
import com.cloud.network.dao.Site2SiteVpnGatewayDao;
+import com.cloud.network.dao.UserIpv6AddressDao;
import com.cloud.network.dao.VirtualRouterProviderDao;
import com.cloud.network.dao.VpnUserDao;
import com.cloud.network.lb.LoadBalancingRule;
@@ -340,6 +341,8 @@
Site2SiteVpnConnectionDao _s2sVpnConnectionDao;
@Inject
Site2SiteVpnManager _s2sVpnMgr;
+ @Inject
+ UserIpv6AddressDao _ipv6Dao;
int _routerRamSize;
@@ -1696,18 +1699,30 @@
boolean hasGuestNetwork = false;
if (guestNetwork != null) {
s_logger.debug("Adding nic for Virtual Router in Guest network " + guestNetwork);
- String defaultNetworkStartIp = null;
- if (guestNetwork.getCidr() != null && !setupPublicNetwork) {
- String startIp = _networkModel.getStartIpAddress(guestNetwork.getId());
- if (startIp != null && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) {
- defaultNetworkStartIp = startIp;
- } else if (s_logger.isDebugEnabled()){
- s_logger.debug("First ip " + startIp + " in network id=" + guestNetwork.getId() +
- " is already allocated, can't use it for domain router; will get random ip address from the range");
- }
+ String defaultNetworkStartIp = null, defaultNetworkStartIpv6 = null;
+ if (!setupPublicNetwork) {
+ if (guestNetwork.getCidr() != null) {
+ String startIp = _networkModel.getStartIpAddress(guestNetwork.getId());
+ if (startIp != null && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) {
+ defaultNetworkStartIp = startIp;
+ } else if (s_logger.isDebugEnabled()){
+ s_logger.debug("First ip " + startIp + " in network id=" + guestNetwork.getId() +
+ " is already allocated, can't use it for domain router; will get random ip address from the range");
+ }
+ }
+
+ if (guestNetwork.getIp6Cidr() != null) {
+ String startIpv6 = _networkModel.getStartIpv6Address(guestNetwork.getId());
+ if (startIpv6 != null && _ipv6Dao.findByNetworkIdAndIp(guestNetwork.getId(), startIpv6) == null) {
+ defaultNetworkStartIpv6 = startIpv6;
+ } else if (s_logger.isDebugEnabled()){
+ s_logger.debug("First ipv6 " + startIpv6 + " in network id=" + guestNetwork.getId() +
+ " is already allocated, can't use it for domain router; will get random ipv6 address from the range");
+ }
+ }
}
- NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp, null);
+ NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp, defaultNetworkStartIpv6);
if (setupPublicNetwork) {
if (isRedundant) {
gatewayNic.setIp4Address(_networkMgr.acquireGuestIpAddress(guestNetwork, null));
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 88086ce..82a69bd 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -750,7 +750,7 @@
/*
* TODO: cleanup eventually - Refactored API call
*/
- public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) {
+ public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) throws ResourceAllocationException {
Long vmId = cmd.getId();
Long svcOffId = cmd.getServiceOfferingId();
Account caller = UserContext.current().getCaller();
@@ -764,6 +764,24 @@
_accountMgr.checkAccess(caller, null, true, vmInstance);
+ // Check resource limits for CPU and Memory.
+ ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId);
+ ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId());
+
+ int newCpu = newServiceOffering.getCpu();
+ int newMemory = newServiceOffering.getRamSize();
+ int currentCpu = currentServiceOffering.getCpu();
+ int currentMemory = currentServiceOffering.getRamSize();
+
+ if (newCpu > currentCpu) {
+ _resourceLimitMgr.checkResourceLimit(caller, ResourceType.cpu,
+ newCpu - currentCpu);
+ }
+ if (newMemory > currentMemory) {
+ _resourceLimitMgr.checkResourceLimit(caller, ResourceType.memory,
+ newMemory - currentMemory);
+ }
+
// Check that the specified service offering ID is valid
_itMgr.checkIfCanUpgrade(vmInstance, svcOffId);
@@ -782,6 +800,18 @@
_itMgr.upgradeVmDb(vmId, svcOffId);
+ // Increment or decrement CPU and Memory count accordingly.
+ if (newCpu > currentCpu) {
+ _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long (newCpu - currentCpu));
+ } else if (currentCpu > newCpu) {
+ _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long (currentCpu - newCpu));
+ }
+ if (newMemory > currentMemory) {
+ _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long (newMemory - currentMemory));
+ } else if (currentMemory > newMemory) {
+ _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long (currentMemory - newMemory));
+ }
+
return _vmDao.findById(vmInstance.getId());
}
diff --git a/server/test/com/cloud/network/MockNetworkModelImpl.java b/server/test/com/cloud/network/MockNetworkModelImpl.java
index d7ffa7d..83dddf4 100644
--- a/server/test/com/cloud/network/MockNetworkModelImpl.java
+++ b/server/test/com/cloud/network/MockNetworkModelImpl.java
@@ -835,4 +835,10 @@
throws InvalidParameterValueException {
// TODO Auto-generated method stub
}
+
+ @Override
+ public String getStartIpv6Address(long id) {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
diff --git a/server/test/com/cloud/vpc/MockNetworkModelImpl.java b/server/test/com/cloud/vpc/MockNetworkModelImpl.java
index 5ac8777..7f1f945 100644
--- a/server/test/com/cloud/vpc/MockNetworkModelImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkModelImpl.java
@@ -848,4 +848,10 @@
// TODO Auto-generated method stub
}
+ @Override
+ public String getStartIpv6Address(long id) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css
index 5797428..7410568 100644
--- a/ui/css/cloudstack3.css
+++ b/ui/css/cloudstack3.css
@@ -1743,8 +1743,8 @@
overflow: auto;
position: relative;
top: 9px;
- float:left;
- width:245px;
+ float: left;
+ width: 245px;
}
.detail-group .main-groups table td.value .view-all {
@@ -1760,7 +1760,7 @@
float: right;
margin: 1px 0 0;
padding: 8px 33px 6px 15px;
- }
+}
.detail-group .main-groups table td.value .view-all:hover {
background-position: 100% -431px;
@@ -1793,6 +1793,10 @@
font-size: 10px;
}
+.detail-group .main-groups table td.value .view-all:hover {
+ background-position: 100% -431px;
+}
+
.panel.always-maximized .detail-group .main-groups table td.value span {
width: 565px;
}
@@ -3710,6 +3714,21 @@
float: left;
}
+.ui-dialog div.form-container div.value input.hasDatepicker {
+ color: #2F5D86;
+ cursor: pointer;
+ font-size: 13px;
+ text-indent: 3px;
+}
+
+.ui-dialog div.form-container div.value input.hasDatepicker:hover {
+ /*+box-shadow:inset 0px 0px 3px;*/
+ -moz-box-shadow: inset 0px 0px 3px;
+ -webkit-box-shadow: inset 0px 0px 3px;
+ -o-box-shadow: inset 0px 0px 3px;
+ box-shadow: inset 0px 0px 3px;
+}
+
.ui-dialog div.form-container div.value .range-edit {
width: 249px;
height: 33px;
@@ -7338,6 +7357,33 @@
background: #C3E0FC;
}
+/*List-view: subselect dropdown*/
+.list-view .subselect {
+ width: 116px;
+ display: block;
+ float: left;
+ background: url(../images/bg-gradients.png) 0px -42px;
+ padding: 0;
+ margin: 8px 0 1px 7px;
+ clear: both;
+ border: 1px solid #A8A7A7;
+ /*+border-radius:4px;*/
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ -khtml-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.list-view .subselect span {
+ margin: 4px 0 0 12px;
+}
+
+.list-view .subselect select {
+ width: 85%;
+ margin: 5px 0 4px;
+ font-size: 10px;
+}
+
/*Multi-edit*/
div.container div.panel div#details-tab-addloadBalancer.detail-group div.loadBalancer div.multi-edit form table.multi-edit thead tr th,
div.container div.panel div#details-tab-addloadBalancer.detail-group div.loadBalancer div.multi-edit form table.multi-edit tbody tr td {
@@ -11093,6 +11139,144 @@
font-size: 11px;
}
+/*UI datepicker*/
+.ui-datepicker {
+ background: #FFFFFF 0px -2470px;
+ width: 300px;
+ height: auto;
+ overflow: hidden;
+ padding: 4px 0 0;
+ /*+border-radius:4px;*/
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ -khtml-border-radius: 4px;
+ border-radius: 4px;
+ /*+box-shadow:0px 3px 8px #000000;*/
+ -moz-box-shadow: 0px 3px 8px #000000;
+ -webkit-box-shadow: 0px 3px 8px #000000;
+ -o-box-shadow: 0px 3px 8px #000000;
+ box-shadow: 0px 3px 8px #000000;
+ display: none;
+}
+
+.ui-datepicker .ui-datepicker-title {
+ width: 100%;
+ margin: auto;
+}
+
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+ font-size: 13px;
+ color: #FFFFFF;
+ /*+box-shadow:0px 1px 5px #444444;*/
+ -moz-box-shadow: 0px 1px 5px #444444;
+ -webkit-box-shadow: 0px 1px 5px #444444;
+ -o-box-shadow: 0px 1px 5px #444444;
+ box-shadow: 0px 1px 5px #444444;
+ /*+text-shadow:0px -1px 1px #050505;*/
+ -moz-text-shadow: 0px -1px 1px #050505;
+ -webkit-text-shadow: 0px -1px 1px #050505;
+ -o-text-shadow: 0px -1px 1px #050505;
+ text-shadow: 0px -1px 1px #050505;
+ padding: 6px;
+ margin: 6px 13px 6px 14px;
+ font-size: 12px;
+ background: url(../images/bg-gradients.png) 0px -182px;
+ cursor: pointer;
+ /*+border-radius:4px;*/
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ -khtml-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.ui-datepicker .ui-datepicker-prev:hover,
+.ui-datepicker .ui-datepicker-next:hover {
+ /*+box-shadow:inset 0px 0px 10px #000000;*/
+ -moz-box-shadow: inset 0px 0px 10px #000000;
+ -webkit-box-shadow: inset 0px 0px 10px #000000;
+ -o-box-shadow: inset 0px 0px 10px #000000;
+ box-shadow: inset 0px 0px 10px #000000;
+}
+
+.ui-datepicker .ui-datepicker-prev {
+ float: left;
+}
+
+.ui-datepicker .ui-datepicker-next {
+ float: right;
+}
+
+.ui-datepicker .ui-datepicker-title .ui-datepicker-month {
+ width: 85px;
+ font-size: 16px;
+ color: #2C363F;
+}
+
+.ui-datepicker .ui-datepicker-title .ui-datepicker-year {
+}
+
+.ui-datepicker .ui-datepicker-title {
+ text-align: center;
+ width: 188px;
+ height: 19px;
+ padding: 3px 0 0;
+ /*+placement:shift 0px 6px;*/
+ position: relative;
+ left: 0px;
+ top: 6px;
+}
+
+.ui-datepicker table {
+ width: 277px;
+ height: 9px;
+}
+
+.ui-datepicker table th,
+.ui-datepicker table td {
+ min-width: 24px;
+ text-align: center;
+ border: 1px solid #B9B6B6;
+ text-indent: 0px;
+ padding: 7px 0;
+ /*[empty]+placement:;*/
+}
+
+.ui-datepicker table td {
+ cursor: pointer;
+}
+
+.ui-datepicker table td.ui-state-disabled,
+.ui-datepicker table td.ui-state-disabled:hover {
+ background-color: #DCDCDC;
+ /*+box-shadow:none;*/
+ -moz-box-shadow: none;
+ -webkit-box-shadow: none;
+ -o-box-shadow: none;
+ box-shadow: none;
+ cursor: default;
+}
+
+.ui-datepicker table td a {
+ text-decoration: none;
+ color: #485867;
+ font-size: 12px;
+}
+
+.ui-datepicker table td:hover {
+ background-color: #6A839A;
+ /*+box-shadow:inset 0px 0px 4px #6B6B6B;*/
+ -moz-box-shadow: inset 0px 0px 4px #6B6B6B;
+ -webkit-box-shadow: inset 0px 0px 4px #6B6B6B;
+ -o-box-shadow: inset 0px 0px 4px #6B6B6B;
+ box-shadow: inset 0px 0px 4px #6B6B6B;
+}
+
+.ui-datepicker table td:hover a {
+ color: #FFFFFF;
+ text-shadow: 0px -1px #000000;
+}
+
/*Plugins listing*/
.plugins-listing {
}
diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp
index 3aecaaa..6c06a10 100644
--- a/ui/dictionary.jsp
+++ b/ui/dictionary.jsp
@@ -25,6 +25,7 @@
<% long now = System.currentTimeMillis(); %>
<script language="javascript">
dictionary = {
+'label.use.vm.ip': '<fmt:message key="label.use.vm.ip"/>',
'label.add.region': '<fmt:message key="label.add.region"/>',
'label.remove.region': '<fmt:message key="label.remove.region"/>',
'message.remove.region': '<fmt:message key="message.remove.region"/>',
diff --git a/ui/scripts/dashboard.js b/ui/scripts/dashboard.js
index 5f49e61..845ae52 100644
--- a/ui/scripts/dashboard.js
+++ b/ui/scripts/dashboard.js
@@ -91,7 +91,7 @@
var netTotal = json.listnetworksresponse.count ?
json.listnetworksresponse.count : 0;
- $.ajax({
+ $.ajax({
url: createURL('listPublicIpAddresses'),
success: function(json) {
var ipTotal = json.listpublicipaddressesresponse.count ?
@@ -102,7 +102,7 @@
ipTotal: ipTotal
}));
}
- });
+ });
}
});
}
@@ -128,7 +128,7 @@
}
}
},
-
+
dataProvider: function(args) {
var dataFns = {
zones: function(data) {
@@ -142,71 +142,24 @@
});
},
capacity: function(data) {
- var latestData =null;
- if(window.fetchLatestflag == 1)
- {
+ var latestData =null;
+ if(window.fetchLatestflag == 1)
+ {
latestData = {
- fetchLatest:true
- }
+ fetchLatest:true
+ }
}
- else
+ else
{
latestData = {
fetchLatest:false
- }
+ }
}
- window.fetchLatestflag = 0;
- if (data.zones) {
- $.ajax({
- url: createURL('listCapacity'),
- data: latestData,
- success: function(json) {
- var capacities = json.listcapacityresponse.capacity;
- var capacity = function(id, converter) {
- var result = $.grep(capacities, function(capacity) {
- return capacity.type == id;
- });
- return result[0] ? result[0] : {
- capacityused: 0,
- capacitytotal: 0,
- percentused: 0
- };
- };
+ window.fetchLatestflag = 0;
- dataFns.alerts($.extend(data, {
- publicIPAllocated: capacity(8).capacityused,
- publicIPTotal: capacity(8).capacitytotal,
- publicIPPercentage: parseInt(capacity(8).percentused),
- privateIPAllocated: capacity(5).capacityused,
- privateIPTotal: capacity(5).capacitytotal,
- privateIPPercentage: parseInt(capacity(8).percentused),
- memoryAllocated: cloudStack.converters.convertBytes(capacity(0).capacityused),
- memoryTotal: cloudStack.converters.convertBytes(capacity(0).capacitytotal),
- memoryPercentage: parseInt(capacity(0).percentused),
- cpuAllocated: cloudStack.converters.convertHz(capacity(1).capacityused),
- cpuTotal: cloudStack.converters.convertHz(capacity(1).capacitytotal),
- cpuPercentage: parseInt(capacity(1).percentused)
- }));
- }
- });
- } else {
- dataFns.alerts($.extend(data, {
- publicIPAllocated: 0,
- publicIPTotal: 0,
- publicIPPercentage: 0,
- privateIPAllocated: 0,
- privateIPTotal: 0,
- privateIPPercentage: 0,
- memoryAllocated: 0,
- memoryTotal: 0,
- memoryPercentage: 0,
- cpuAllocated: 0,
- cpuTotal: 0,
- cpuPercentage: 0
- }));
- }
+ dataFns.alerts(data);
},
alerts: function(data) {
@@ -273,11 +226,11 @@
complete($.extend(data, {
zoneCapacities: $.map(capacities, function(capacity) {
if (capacity.podname) {
- capacity.zonename = capacity.zonename.concat('<br/>' + _l('label.pod') + ': ' + capacity.podname);
+ capacity.zonename = capacity.zonename.concat(', ' + _l('label.pod') + ': ' + capacity.podname);
}
if (capacity.clustername) {
- capacity.zonename = capacity.zonename.concat('<br/>' + _l('label.cluster') + ': ' + capacity.clustername);
+ capacity.zonename = capacity.zonename.concat(', ' + _l('label.cluster') + ': ' + capacity.clustername);
}
capacity.zonename.replace('Zone:', _l('label.zone') + ':');
diff --git a/ui/scripts/events.js b/ui/scripts/events.js
index b18acd7..1c89b58 100644
--- a/ui/scripts/events.js
+++ b/ui/scripts/events.js
@@ -58,7 +58,11 @@
desc: '',
fields: {
type: { label: 'By event type' , docID:'helpEventsDeleteType'},
- date: { label: 'By date (older than)' ,docID:'helpEventsDeleteDate'}
+ date: {
+ label: 'By date (older than)',
+ docID:'helpEventsDeleteDate',
+ isDatepicker: true
+ }
}
},
action: function(args) {
@@ -104,7 +108,7 @@
desc: '',
fields: {
type: { label: 'By event type' , docID:'helpEventsArchiveType'},
- date: { label: 'By date (older than)' , docID:'helpEventsArchiveDate'}
+ date: { label: 'By date (older than)' , docID:'helpEventsArchiveDate', isDatepicker: true },
}
},
action: function(args) {
@@ -346,7 +350,7 @@
desc: '',
fields: {
type: { label: 'By event type' , docID:'helpAlertsDeleteType'},
- date: { label: 'By date (older than)' ,docID:'helpAlertsDeleteDate' }
+ date: { label: 'By date (older than)' ,docID:'helpAlertsDeleteDate', isDatepicker: true }
}
},
action: function(args) {
@@ -392,7 +396,7 @@
desc: '',
fields: {
type: { label: 'By event type', docID:'helpAlertsArchiveType' },
- date: { label: 'By date (older than)' , docID:'helpAlertsArchiveDate'}
+ date: { label: 'By date (older than)' , docID:'helpAlertsArchiveDate', isDatepicker: true }
}
},
action: function(args) {
diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js
index d9260b0..75d45aa 100644
--- a/ui/scripts/instanceWizard.js
+++ b/ui/scripts/instanceWizard.js
@@ -33,11 +33,10 @@
// Called in networks list, when VPC drop-down is changed
// -- if vpcID given, return true if in network specified by vpcID
- // -- if vpcID == -1, return true if network is not associated with a VPC
+ // -- if vpcID == -1, always show all networks
vpcFilter: function(data, vpcID) {
- return vpcID != -1?
- data.vpcid == vpcID :
- !data.vpcid;
+ return vpcID != -1 ?
+ data.vpcid == vpcID : true;
},
// Runs when advanced SG-enabled zone is run, before
@@ -401,7 +400,12 @@
includingSecurityGroup = true;
break;
}
- }
+ }
+
+ if (networkObj.vpcid) {
+ networkObj._singleSelect = true;
+ }
+
//for Advanced SG-enabled zone, list only SG network offerings
if(selectedZoneObj.networktype == 'Advanced' && selectedZoneObj.securitygroupsenabled == true) {
if(includingSecurityGroup == false)
diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js
index 8a7c7ad..787239d 100644
--- a/ui/scripts/instances.js
+++ b/ui/scripts/instances.js
@@ -1242,6 +1242,15 @@
}
}
],
+ viewAll: {
+ path: 'network.secondaryNicIps',
+ attachTo: 'ipaddress',
+ title: function(args) {
+ var title = _l('label.menu.ipaddresses') + ' - ' + args.context.nics[0].name;
+
+ return title;
+ }
+ },
dataProvider: function(args) {
$.ajax({
url:createURL("listVirtualMachines&details=nics&id=" + args.context.instances[0].id),
diff --git a/ui/scripts/network.js b/ui/scripts/network.js
index 697141a..65be302 100755
--- a/ui/scripts/network.js
+++ b/ui/scripts/network.js
@@ -34,6 +34,44 @@
return elemData;
};
+
+ var instanceSecondaryIPSubselect = function(args) {
+ var instance = args.context.instances[0];
+ var network = args.context.networks[0];
+ var nic = $.grep(instance.nic, function(nic) {
+ return nic.networkid == network.id;
+ })[0];
+
+ // Get NIC IPs
+ $.ajax({
+ url: createURL('listNics'),
+ data: {
+ virtualmachineid: instance.id,
+ nicId: nic.id
+ },
+ success: function(json) {
+ var nic = json.listnics.nic[0];
+ var ips = nic.secondaryip ? nic.secondaryip : [];
+ var ipSelection = [];
+
+ // Add primary IP as default
+ ipSelection.push({ id: -1, description: nic.ipaddress + ' (Primary)' });
+
+ // Add secondary IPs
+ $(ips).map(function(index, ip) {
+ ipSelection.push({
+ id: ip.ipaddress,
+ description: ip.ipaddress
+ });
+ });
+
+
+ args.response.success({
+ data: ipSelection
+ });
+ }
+ })
+ };
var ipChangeNotice = function() {
cloudStack.dialog.confirm({
@@ -620,33 +658,33 @@
var data = {
id: args.context.networks[0].id,
name: args.data.name,
- displaytext: args.data.displaytext,
+ displaytext: args.data.displaytext
};
-
+
//args.data.networkdomain is null when networkdomain field is hidden
if(args.data.networkdomain != null && args.data.networkdomain != args.context.networks[0].networkdomain) {
$.extend(data, {
networkdomain: args.data.networkdomain
});
}
-
+
var oldcidr;
- $.ajax({
+ $.ajax({
url: createURL("listNetworks&id=" + args.context.networks[0].id ),
dataType: "json",
async: false,
success: function(json) {
- oldcidr = json.listnetworksresponse.network[0].cidr;
-
- }
- });
+ oldcidr = json.listnetworksresponse.network[0].cidr;
+
+ }
+ });
- if(args.data.cidr !="" && args.data.cidr != oldcidr ){
- $.extend(data, {
- guestvmcidr: args.data.cidr
- });
- }
+ if(args.data.cidr !="" && args.data.cidr != oldcidr ){
+ $.extend(data, {
+ guestvmcidr: args.data.cidr
+ });
+ }
//args.data.networkofferingid is null when networkofferingid field is hidden
if(args.data.networkofferingid != null && args.data.networkofferingid != args.context.networks[0].networkofferingid) {
@@ -1070,400 +1108,164 @@
}
});
}
+ }
+ }
+ }
+ }
+ },
+ secondaryNicIps: {
+ title: 'label.menu.ipaddresses',
+ listView: {
+ id: 'secondaryNicIps',
+ label: 'label.ips',
+ fields: {
+ virtualmachinedisplayname: { label: 'label.vm.name' },
+ ipaddress: {
+ label: 'label.ips',
+ converter: function(text, item) {
+ if (item.issourcenat) {
+ return text + ' [' + _l('label.source.nat') + ']';
+ }
+
+ return text;
+ }
+ }
+ },
+ actions: {
+ add: {
+ label: 'label.acquire.new.ip',
+ addRow: 'true',
+ messages: {
+ confirm: function(args) {
+ return 'message.acquire.new.ip';
+ },
+ notification: function(args) {
+ return 'label.acquire.new.ip';
+ }
+ },
+ action: function(args) {
+ var dataObj = {};
+
+ $.ajax({
+ url: createURL('addIpToNic'),
+ data: {
+ nicId: args.context.nics[0].id
+ },
+ success: function(json) {
+ args.response.success({
+ _custom: {
+ getUpdatedItem: function(data) {
+ return $.extend(
+ data.queryasyncjobresultresponse.jobresult.nicsecondaryip,
+ {
+ zoneid: args.context.instances[0].zoneid,
+ virtualmachinedisplayname: args.context.instances[0].displayname
+ }
+ );
+ },
+ jobId: json.addiptovmnicresponse.jobid
+ }
+ });
+ }
+ });
},
- egressRules: {
- title: 'label.egress.rules',
- custom: function(args) {
- var context = args.context;
+ notification: {
+ poll: pollAsyncJobResult
+ }
+ }
+ },
- return $('<div>').multiEdit({
- context: context,
- noSelect: true,
- noHeaderActionsColumn: true,
- fields: {
- 'cidrlist': { edit: true, label: 'label.cidr.list', isOptional: true },
- 'protocol': {
- label: 'label.protocol',
- select: function(args) {
- args.$select.change(function() {
- var $inputs = args.$form.find('th, td');
- var $icmpFields = $inputs.filter(function() {
- var name = $(this).attr('rel');
+ dataProvider: function(args) {
+ var data = {};
- return $.inArray(name, [
- 'icmptype',
- 'icmpcode'
- ]) > -1;
- });
- var $otherFields = $inputs.filter(function() {
- var name = $(this).attr('rel');
+ $.ajax({
+ url: createURL('listNics'),
+ data: {
+ nicId: args.context.nics[0].id,
+ virtualmachineid: args.context.instances[0].id
+ },
+ success: function(json) {
+ var ips = json.listnics.nic ? json.listnics.nic[0].secondaryip : [];
- return name != 'cidrlist' &&
- name != 'icmptype' &&
- name != 'icmpcode' &&
- name != 'protocol' &&
- name != 'add-rule';
- });
+ args.response.success({
+ data: $(ips).map(function(index, ip) {
+ return $.extend(ip, {
+ zoneid: args.context.instances[0].zoneid,
+ virtualmachinedisplayname: args.context.instances[0].displayname
+ });
+ })
+ });
+ }
+ });
+ },
- if ($(this).val() == 'icmp') {
- $icmpFields.show();
- $otherFields.hide();
- } else if ($(this).val() == 'all') {
- $icmpFields.hide();
- $otherFields.hide();
- } else {
- $icmpFields.hide();
- $otherFields.show();
- }
- });
-
- args.response.success({
- data: [
- { name: 'tcp', description: 'TCP' },
- { name: 'udp', description: 'UDP' },
- { name: 'icmp', description: 'ICMP' },
- { name: 'all', description: 'All' }
- ]
- });
- }
- },
- 'startport': { edit: true, label: 'label.start.port', isOptional: true },
- 'endport': { edit: true, label: 'label.end.port', isOptional: true },
- 'icmptype': { edit: true, label: 'ICMP.type', isHidden: true, isOptional: true },
- 'icmpcode': { edit: true, label: 'ICMP.code', isHidden: true, isOptional: true },
- 'add-rule': {
- label: 'label.add',
- addButton: true
- }
+ // Detail view
+ detailView: {
+ name: 'Secondary IP address detail',
+ actions: {
+ remove: {
+ label: 'label.action.release.ip',
+ action: function(args) {
+ $.ajax({
+ url: createURL('removeIpFromNic'),
+ data: {
+ id: args.context.secondaryNicIps[0].id
},
- add: {
- label: 'label.add',
- action: function(args) {
- var data = {
- protocol: args.data.protocol,
- cidrlist: args.data.cidrlist,
- networkid: args.context.networks[0].id
- };
-
- if (args.data.icmptype && args.data.icmpcode) { // ICMP
- $.extend(data, {
- icmptype: args.data.icmptype,
- icmpcode: args.data.icmpcode
- });
- } else { // TCP/UDP
- $.extend(data, {
- startport: args.data.startport,
- endport: args.data.endport
- });
- }
-
- $.ajax({
- url: createURL('createEgressFirewallRule'),
- data: data,
- dataType: 'json',
- async: true,
- success: function(json) {
- var jobId = json.createegressfirewallruleresponse.jobid;
-
- args.response.success({
- _custom: {
- jobId: jobId
- },
- notification: {
- label: 'label.add.egress.rule',
- poll: pollAsyncJobResult
- }
- });
- },
- error: function(json) {
- args.response.error(parseXMLHttpResponse(json));
- }
- });
- }
- },
- actions: {
- destroy: {
- label: 'label.remove.rule',
- action: function(args) {
- $.ajax({
- url: createURL('deleteEgressFirewallRule'),
- data: {
- id: args.context.multiRule[0].id
- },
- dataType: 'json',
- async: true,
- success: function(data) {
- var jobID = data.deleteegressfirewallruleresponse.jobid;
-
- args.response.success({
- _custom: {
- jobId: jobID
- },
- notification: {
- label: 'label.remove.egress.rule',
- poll: pollAsyncJobResult
- }
- });
- },
- error: function(json) {
- args.response.error(parseXMLHttpResponse(json));
- }
- });
- }
- }
- },
- ignoreEmptyFields: true,
- dataProvider: function(args) {
- $.ajax({
- url: createURL('listEgressFirewallRules'),
- data: {
- listAll: true,
- networkid: args.context.networks[0].id
- },
- dataType: 'json',
- async: true,
- success: function(json) {
- var response = json.listegressfirewallrulesresponse.firewallrule ?
- json.listegressfirewallrulesresponse.firewallrule : [];
-
- args.response.success({
- data: $.map(response, function(rule) {
- if (rule.protocol == 'all') {
- $.extend(rule, {
- startport: 'All',
- endport: 'All'
- });
- } else if (rule.protocol == 'tcp' || rule.protocol == 'udp') {
- if (!rule.startport) {
- rule.startport = ' ';
- }
-
- if (!rule.endport) {
- rule.endport = ' ';
- }
- }
-
- return rule;
- })
- });
- }
+ success: function(json) {
+ args.response.success({
+ _custom: { jobId: json.removeipfromnicresponse.jobid }
});
}
});
- }
- },
+ },
+ messages: {
+ confirm: function(args) {
+ return 'message.action.release.ip';
+ },
+ notification: function(args) {
+ return 'label.action.release.ip';
+ }
+ },
+ notification: { poll: pollAsyncJobResult }
+ }
+ },
+ tabs: {
+ details: {
+ title: 'label.details',
+ fields: [
+ {
+ ipaddress: { label: 'label.ip' }
+ },
+ {
+ id: { label: 'label.id' },
+ virtualmachinedisplayname: { label: 'label.vm.name' },
+ zonename: { label: 'label.zone.name' }
+ }
+ ],
- addloadBalancer: { // EIP/ELB Basic zone: Add Load Balancer tab in network detailView
- title: 'label.add.load.balancer',
- custom: function(args) {
- var context = args.context;
+ dataProvider: function(args) {
+ $.ajax({
+ url: createURL('listNics'),
+ data: {
+ nicId: args.context.nics[0].id,
+ virtualmachineid: args.context.instances[0].id
+ },
+ success: function(json) {
+ var ips = json.listnics.nic[0].secondaryip
- return $('<div>').addClass('loadBalancer').multiEdit(
- {
- context: context,
- listView: $.extend(true, {}, cloudStack.sections.instances, {
- listView: {
- filters: false,
-
- dataProvider: function(args) {
- var data = {
- page: args.page,
- pageSize: pageSize,
- domainid: g_domainid,
- account: g_account,
- networkid: args.context.networks[0].id,
- listAll: true
- };
-
- $.ajax({
- url: createURL('listVirtualMachines'),
- data: data,
- dataType: 'json',
- async: true,
- success: function(data) {
- args.response.success({
- data: $.grep(
- data.listvirtualmachinesresponse.virtualmachine ?
- data.listvirtualmachinesresponse.virtualmachine : [],
- function(instance) {
- var nonAutoScale=0;
- if(instance.displayname == null)
- nonAutoScale = 1;
- else{
- if( instance.displayname.match(/AutoScale-LB-/)==null)
- nonAutoScale =1;
- else {
- if(instance.displayname.match(/AutoScale-LB-/).length)
- nonAutoScale =0;
- }
- }
- var isActiveState= $.inArray(instance.state, ['Destroyed','Expunging']) == -1;
- return nonAutoScale && isActiveState;
- }
- )
- });
- },
- error: function(data) {
- args.response.error(parseXMLHttpResponse(data));
- }
- });
- }
- }
- }),
- multipleAdd: true,
- fields: {
- 'name': { edit: true, label: 'label.name' },
- 'publicport': { edit: true, label: 'label.public.port' },
- 'privateport': { edit: true, label: 'label.private.port' },
- 'algorithm': {
- label: 'label.algorithm',
- select: function(args) {
- args.response.success({
- data: [
- { name: 'roundrobin', description: _l('label.round.robin') },
- { name: 'leastconn', description: _l('label.least.connections') },
- { name: 'source', description: _l('label.source') }
- ]
- });
- }
- },
- 'sticky': {
- label: 'label.stickiness',
- custom: {
- buttonLabel: 'label.configure',
- action: cloudStack.lbStickyPolicy.dialog()
- }
- },
- 'autoScale': {
- label: 'AutoScale',
- custom: {
- requireValidation: true,
- buttonLabel: 'label.configure',
- action: cloudStack.uiCustom.autoscaler(cloudStack.autoscaler)
- }
- },
- 'add-vm': {
- label: 'label.add.vms',
- addButton: true
- }
- },
-
- add: { //basic zone - elastic IP - Add Load Balancer tab - Add VMs button
- label: 'label.add.vms',
- action: function(args) {
- var data = {
- algorithm: args.data.algorithm,
- name: args.data.name,
- privateport: args.data.privateport,
- publicport: args.data.publicport,
- openfirewall: false,
- domainid: g_domainid,
- account: g_account
- };
-
- if('vpc' in args.context) { //from VPC section
- if(args.data.tier == null) {
- args.response.error('Tier is required');
- return;
- }
- $.extend(data, {
- networkid: args.data.tier
- });
- }
- else { //from Guest Network section
- $.extend(data, {
- networkid: args.context.networks[0].id
- });
- }
-
- var stickyData = $.extend(true, {}, args.data.sticky);
-
- $.ajax({
- url: createURL('createLoadBalancerRule'),
- data: data,
- dataType: 'json',
- async: true,
- success: function(data) {
- var itemData = args.itemData;
- //var jobID = data.createloadbalancerruleresponse.jobid; //CS-16964: use jobid from assignToLoadBalancerRule instead of createLoadBalancerRule
-
- $.ajax({
- url: createURL('assignToLoadBalancerRule'),
- data: {
- id: data.createloadbalancerruleresponse.id,
- virtualmachineids: $.map(itemData, function(elem) {
- return elem.id;
- }).join(',')
- },
- dataType: 'json',
- async: true,
- success: function(data) {
- var jobID = data.assigntoloadbalancerruleresponse.jobid; //CS-16964: use jobid from assignToLoadBalancerRule instead of createLoadBalancerRule
- var lbCreationComplete = false;
-
- args.response.success({
- _custom: {
- jobId: jobID
- },
- notification: {
- label: 'label.add.load.balancer',
- poll: function(args) {
- var complete = args.complete;
- var error = args.error;
-
- pollAsyncJobResult({
- _custom: args._custom,
- complete: function(args) {
- if (lbCreationComplete) {
- return;
- }
-
- lbCreationComplete = true;
- cloudStack.dialog.notice({
- message: _l('message.add.load.balancer.under.ip') +
- args.data.loadbalancer.publicip
- });
-
- if (stickyData &&
- stickyData.methodname &&
- stickyData.methodname != 'None') {
- cloudStack.lbStickyPolicy.actions.add(
- args.data.loadbalancer.id,
- stickyData,
- complete, // Complete
- complete // Error
- );
- } else {
- complete();
- }
- },
- error: error
- });
- }
- }
- });
- },
- error: function(data) {
- args.response.error(parseXMLHttpResponse(data));
- }
- });
- },
- error: function(data) {
- args.response.error(parseXMLHttpResponse(data));
- }
+ args.response.success({
+ data: $.grep($(ips).map(function(index, ip) {
+ return $.extend(ip, {
+ zonename: args.context.instances[0].zonename,
+ virtualmachinedisplayname: args.context.instances[0].displayname
});
- }
- },
-
-
- dataProvider: function(args) {
- args.response.success({ //no LB listing in AddLoadBalancer tab
- data: []
- });
- }
+ }), function(ip) {
+ return ip.ipaddress == args.context.secondaryNicIps[0].ipaddress;
+ })[0]
+ });
}
- );
+ });
}
}
}
@@ -1607,10 +1409,11 @@
account: g_account
});
}
- }
+ }
+
$.ajax({
url: createURL('associateIpAddress'),
- data: dataObj,
+ data: dataObj,
success: function(data) {
args.response.success({
_custom: {
@@ -1673,10 +1476,10 @@
async: true,
success: function(json) {
var items = json.listpublicipaddressesresponse.publicipaddress;
-
- $(items).each(function() {
- getExtaPropertiesForIpObj(this, args);
- });
+
+ $(items).each(function() {
+ getExtaPropertiesForIpObj(this, args);
+ });
args.response.success({
actionFilter: actionFilters.ipAddress,
@@ -1876,6 +1679,10 @@
listView: $.extend(true, {}, cloudStack.sections.instances, {
listView: {
filters: false,
+ subselect: {
+ label: 'label.use.vm.ip',
+ dataProvider: instanceSecondaryIPSubselect
+ },
dataProvider: function(args) {
var data = {
page: args.page,
@@ -1890,7 +1697,7 @@
args.response.success({ data: null });
return;
}
-
+
if('vpc' in args.context) {
if($tierSelect.size() && $tierSelect.val() != '-1' ){
data.networkid = $tierSelect.val();
@@ -1942,6 +1749,10 @@
ipaddressid: args.context.ipAddresses[0].id,
virtualmachineid: args.context.instances[0].id
};
+
+ if (args._subselect && args._subselect != -1) {
+ data.vmguestip = args._subselect;
+ }
if('vpc' in args.context) {
if(args.tierID == '-1') {
@@ -2136,19 +1947,17 @@
dataProvider: function(args) {
var items = args.context.ipAddresses;
- // Get network data
$.ajax({
url: createURL('listPublicIpAddresses'),
- data: {
- id: args.context.ipAddresses[0].id,
- listAll: true
+ data: {
+ id: args.context.ipAddresses[0].id
},
dataType: "json",
async: true,
success: function(json) {
var ipObj = json.listpublicipaddressesresponse.publicipaddress[0];
getExtaPropertiesForIpObj(ipObj, args);
-
+
var network = $.grep(
args.context.vpc ?
args.context.vpc[0].network : args.context.networks,
@@ -2619,6 +2428,20 @@
loadBalancing: {
listView: $.extend(true, {}, cloudStack.sections.instances, {
listView: {
+ fields: {
+ name: { label: 'label.name' },
+ displayname: { label: 'label.display.name' },
+ zonename: { label: 'label.zone.name' },
+ state: {
+ label: 'label.state',
+ indicator: {
+ 'Running': 'on',
+ 'Stopped': 'off',
+ 'Destroyed': 'off',
+ 'Error': 'off'
+ }
+ }
+ },
filters: false,
dataProvider: function(args) {
var itemData = $.isArray(args.context.multiRule) && args.context.multiRule[0]['_itemData'] ?
@@ -3213,6 +3036,10 @@
listView: $.extend(true, {}, cloudStack.sections.instances, {
listView: {
filters: false,
+ subselect: {
+ label: 'label.use.vm.ip',
+ dataProvider: instanceSecondaryIPSubselect
+ },
dataProvider: function(args) {
var networkid;
if('vpc' in args.context)
@@ -3308,6 +3135,10 @@
openfirewall: false
};
+ if (args.itemData[0]._subselect && args.itemData[0]._subselect != -1) {
+ data.vmguestip = args.itemData[0]._subselect;
+ }
+
if('vpc' in args.context) { //from VPC section
if(args.data.tier == null) {
args.response.error('Tier is required');
diff --git a/ui/scripts/ui-custom/dashboard.js b/ui/scripts/ui-custom/dashboard.js
index 960d100..6d92318 100644
--- a/ui/scripts/ui-custom/dashboard.js
+++ b/ui/scripts/ui-custom/dashboard.js
@@ -80,15 +80,15 @@
});
} else {
if ($li.attr('concat-value')) {
- var val = $(_l(arrayValue).toString().split('<br/>')).map(function() {
- var val = this.toString();
+ var val = $(_l(arrayValue).toString().split(', ')).map(function() {
+ var val = _s(this.toString());
var concatValue = parseInt($li.attr('concat-value'));
return val.length >= concatValue ?
val.substring(0, concatValue).concat('...') : val;
- }).toArray().join('<br/>');
+ }).toArray().join('<br />');
- $arrayElem.html(_s(val));
+ $arrayElem.html(val);
} else {
$arrayElem.html(_s(_l(arrayValue)));
}
diff --git a/ui/scripts/ui-custom/enableStaticNAT.js b/ui/scripts/ui-custom/enableStaticNAT.js
index 47d5dd2..1b2bf7b 100644
--- a/ui/scripts/ui-custom/enableStaticNAT.js
+++ b/ui/scripts/ui-custom/enableStaticNAT.js
@@ -92,9 +92,10 @@
var start = args.start;
start();
- $dataList.fadeOut(function() {
+ $dataList.fadeOut(function() {
action({
tierID: $dataList.find('.tier-select select').val(),
+ _subselect: $dataList.find('tr.multi-edit-selected .subselect select').val(),
context: $.extend(true, {}, context, {
instances: [
$dataList.find('tr.multi-edit-selected').data('json-obj')
diff --git a/ui/scripts/ui-custom/instanceWizard.js b/ui/scripts/ui-custom/instanceWizard.js
index 8e4ed7e..b55df79 100644
--- a/ui/scripts/ui-custom/instanceWizard.js
+++ b/ui/scripts/ui-custom/instanceWizard.js
@@ -91,7 +91,8 @@
options = options ? options : {};
$(data).each(function() {
- var id = this[fields.id];
+ var item = this;
+ var id = item[fields.id];
var $select = $('<div>')
.addClass('select')
@@ -107,17 +108,22 @@
.val(id)
.click(function() {
var $select = $(this).closest('.select');
+ var isSingleSelect = $select.hasClass('single-select');
var $radio = $select.find('input[type=radio]');
var $newNetwork = $(this).closest('.content').find('.select.new-network');
var $otherSelects = $select.siblings().filter(':visible');
var isCheckbox = $(this).attr('type') == 'checkbox';
- var isSingleSelect = $(this).closest('.select-container').hasClass('single-select');
if (isCheckbox) {
- if ((isSingleSelect || !$otherSelects.size()) &&
- $newNetwork.find('input[type=checkbox]').is(':unchecked')) {
- $otherSelects.find('input[type=checkbox]').attr('checked', false);
+ if (isSingleSelect) {
+ $select.siblings('.single-select:visible').find('input[type=checkbox]')
+ .attr('checked', false);
+
+ $(this).closest('.select').find('input[type=radio]').click();
+ }
+ if ((!$otherSelects.size()) &&
+ $newNetwork.find('input[type=checkbox]').is(':unchecked')) {
// Set as default
$(this).closest('.select').find('input[type=radio]').click();
}
@@ -144,6 +150,10 @@
$selects.append($select);
+ if (item._singleSelect) {
+ $select.addClass('single-select');
+ }
+
if (options.secondary) {
var $secondary = $('<div>').addClass('secondary-input').append(
$('<input>')
@@ -164,6 +174,11 @@
$(this).closest('.select').siblings().find('input[type=checkbox]')
.attr('checked', false);
}
+
+ if ($select.hasClass('single-select')) {
+ $select.siblings('.single-select:visible').find('input[type=checkbox]')
+ .attr('checked', false);
+ }
})
.after(
$('<div>').addClass('name').html(options.secondary.desc)
@@ -614,7 +629,7 @@
});
// 'No VPC' option
- $('<option>').attr('value', '-1').html('None').prependTo($vpcSelect);
+ $('<option>').attr('value', '-1').html(_l('ui.listView.filters.all')).prependTo($vpcSelect);
$vpcSelect.val(-1);
diff --git a/ui/scripts/ui/widgets/detailView.js b/ui/scripts/ui/widgets/detailView.js
index db7f524..0731dda 100644
--- a/ui/scripts/ui/widgets/detailView.js
+++ b/ui/scripts/ui/widgets/detailView.js
@@ -593,7 +593,8 @@
var $listView;
var isCustom = $.isFunction(viewAllID.custom);
var updateContext = options.updateContext;
-
+ var customTitle = options.title;
+
if (isCustom) {
$browser.cloudBrowser('addPanel', {
title: _l(viewAllID.label),
@@ -650,7 +651,7 @@
// Make panel
var $panel = $browser.cloudBrowser('addPanel', {
- title: _l(listViewArgs.title),
+ title: customTitle ? customTitle({ context: context }) : _l(listViewArgs.title),
data: '',
noSelectPanel: true,
maximizeIfSelected: true,
@@ -976,7 +977,7 @@
var tabs = args.tabs[targetTabID];
var dataProvider = tabs.dataProvider;
var isMultiple = tabs.multiple || tabs.isMultiple;
- var viewAll = args.viewAll;
+ var viewAllArgs = args.viewAll;
var $detailView = $tabContent.closest('.detail-view');
var jsonObj = $detailView.data('view-args').jsonObj;
@@ -1030,6 +1031,8 @@
if (isMultiple) {
$(data).each(function() {
+ var item = this;
+
var $fieldContent = makeFieldContent(
$.extend(true, {}, tabs, {
id: targetTabID
@@ -1040,6 +1043,26 @@
actionFilter: actionFilter
}
).appendTo($tabContent);
+
+ if (tabData.viewAll) {
+ $fieldContent.find('tr')
+ .filter('.' + tabData.viewAll.attachTo).find('td.value')
+ .append(
+ $('<div>').addClass('view-all').append(
+ $('<span>').html(_l('label.view.all'))
+ ).click(function() {
+ viewAll(
+ tabData.viewAll.path,
+ {
+ updateContext: function(args) {
+ return { nics: [item] };
+ },
+ title: tabData.viewAll.title
+ }
+ );
+ })
+ );
+ }
});
return true;
diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js
index 9e16ec2..76ce526 100644
--- a/ui/scripts/ui/widgets/listView.js
+++ b/ui/scripts/ui/widgets/listView.js
@@ -844,7 +844,10 @@
var rows = [];
var reorder = options.reorder;
var detailView = options.detailView;
- var uiCustom = $tbody.closest('.list-view').data('view-args').uiCustom;
+ var $listView = $tbody.closest('.list-view');
+ var listViewArgs = $listView.data('view-args');
+ var uiCustom = listViewArgs.uiCustom;
+ var subselect = uiCustom ? listViewArgs.listView.subselect : null;
if (!data || ($.isArray(data) && !data.length)) {
if (!$tbody.find('tr').size()) {
@@ -1037,6 +1040,59 @@
allowedActions: allowedActions
}
);
+
+ $listView.trigger('cloudStack.listView.addRow', { $tr: $tr });
+ }
+
+ // Add sub-select
+ if (subselect) {
+ var $td = $tr.find('td.first');
+ var $select = $('<div></div>').addClass('subselect').append(
+ $('<span>').html(_l(subselect.label)),
+ $('<select>')
+ ).hide();
+ var $selectionArea = $tr.find('td:last').find('input');
+
+ $td.append($select);
+
+ // Show and populate selection
+ $selectionArea.change(function() {
+ if ($(this).is(':checked')) {
+ // Populate data
+ subselect.dataProvider({
+ context: $.extend(true, {}, options.context, {
+ instances: [$tr.data('json-obj')]
+ }),
+ response: {
+ success: function(args) {
+ var data = args.data;
+
+ if (data.length) {
+ $(data).map(function(index, item) {
+ var $option = $('<option>');
+
+ $option.attr('value', item.id);
+ $option.append(item.description);
+ $option.appendTo($select.find('select'));
+ });
+ $select.show();
+ } else {
+ $select.hide();
+ }
+
+ $listView.find('.data-table').dataTable('refresh');
+ }
+ }
+ });
+
+ if ($(this).is('input[type=radio]')) {
+ $(this).closest('tr').siblings().find('input[type=radio]').change();
+ }
+ } else {
+ $select.find('option').remove();
+ $select.hide();
+ }
+ });
}
// Add quick view
diff --git a/ui/scripts/ui/widgets/multiEdit.js b/ui/scripts/ui/widgets/multiEdit.js
index 2480f56..0a05591 100755
--- a/ui/scripts/ui/widgets/multiEdit.js
+++ b/ui/scripts/ui/widgets/multiEdit.js
@@ -489,7 +489,17 @@
// Attach VM data to row
function(elem) {
- return $(elem).data('json-obj');
+ var itemData = $(elem).data('json-obj');
+ var $subselect = $(elem).find('.subselect select');
+
+ // Include subselect data
+ if ($subselect && $subselect.val()) {
+ return $.extend(itemData, {
+ _subselect: $subselect.val()
+ });
+ }
+
+ return itemData;
}
));
$dataList.remove();
diff --git a/usage/conf/db.properties.in b/usage/conf/db.properties.in
index e88e01a..0dd49ed 100644
--- a/usage/conf/db.properties.in
+++ b/usage/conf/db.properties.in
@@ -1,19 +1,19 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
+# 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.
# usage database settings
db.usage.username=@DBUSER@
diff --git a/usage/pom.xml b/usage/pom.xml
index 31df358..37501fe 100644
--- a/usage/pom.xml
+++ b/usage/pom.xml
@@ -74,7 +74,7 @@
<goal>copy-dependencies</goal>
</goals>
<configuration>
- <outputDirectory>target/dependencies</outputDirectory>
+ <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
<includeScope>runtime</includeScope>
</configuration>
</execution>
@@ -127,24 +127,6 @@
</execution>
</executions>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <version>2.5.1</version>
- <executions>
- <execution>
- <id>copy-dependencies</id>
- <phase>package</phase>
- <goals>
- <goal>copy-dependencies</goal>
- </goals>
- <configuration>
- <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
- <includeScope>runtime</includeScope>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
<profiles>
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java
index 1433148..04b4d8e 100755
--- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java
@@ -120,29 +120,29 @@
s_mapper.put("Other CentOS (64-bit)", VirtualMachineGuestOsIdentifier.CENTOS_64_GUEST);
s_mapper.put("Red Hat Enterprise Linux 2", VirtualMachineGuestOsIdentifier.RHEL_2_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 3(32-bit)", VirtualMachineGuestOsIdentifier.RHEL_3_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 3(64-bit)", VirtualMachineGuestOsIdentifier.RHEL_3_64_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 4(32-bit)", VirtualMachineGuestOsIdentifier.RHEL_4_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 4(64-bit)", VirtualMachineGuestOsIdentifier.RHEL_4_64_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 5(32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 5(64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 6(32-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 6(64-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_64_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 3 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_3_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 3 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_3_64_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 4 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_4_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 4 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_4_64_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 5 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 5 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 6 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 6 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_64_GUEST);
s_mapper.put("Red Hat Enterprise Linux 4.5 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_4_GUEST);
s_mapper.put("Red Hat Enterprise Linux 4.6 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_4_GUEST);
s_mapper.put("Red Hat Enterprise Linux 4.7 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_4_GUEST);
s_mapper.put("Red Hat Enterprise Linux 4.8 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_4_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 5.0(32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 5.0(64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 5.1(32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 5.1(64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 5.2(32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 5.2(64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 5.3(32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 5.3(64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 5.4(32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST);
- s_mapper.put("Red Hat Enterprise Linux 5.4(64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 5.0 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 5.0 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 5.1 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 5.1 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 5.2 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 5.2 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 5.3 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 5.3 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 5.4 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST);
+ s_mapper.put("Red Hat Enterprise Linux 5.4 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST);
s_mapper.put("Ubuntu 8.04 (32-bit)", VirtualMachineGuestOsIdentifier.UBUNTU_GUEST);
s_mapper.put("Ubuntu 8.04 (64-bit)", VirtualMachineGuestOsIdentifier.UBUNTU_64_GUEST);