diff --git a/api/src/com/cloud/uservm/UserVm.java b/api/src/com/cloud/uservm/UserVm.java
index a0bd2bc08a5..0709baec361 100755
--- a/api/src/com/cloud/uservm/UserVm.java
+++ b/api/src/com/cloud/uservm/UserVm.java
@@ -60,8 +60,6 @@ public interface UserVm extends VirtualMachine, OwnedBy, PartOf {
String getDisplayName();
- String getGroup();
-
String getUserData();
void setUserData(String userData);
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index bd38848c3f3..251a496a288 100755
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -210,3 +210,10 @@ listNetworkGroups=com.cloud.api.commands.ListNetworkGroupsCmd;11
registerPreallocatedLun=com.cloud.server.api.commands.RegisterPreallocatedLunCmd;1
deletePreallocatedLun=com.cloud.server.api.commands.DeletePreallocatedLunCmd;1
listPreallocatedLuns=com.cloud.api.commands.ListPreallocatedLunsCmd;1
+
+
+#### vm group commands
+createInstanceGroup=com.cloud.api.commands.CreateVMGroupCmd;15
+deleteInstanceGroup=com.cloud.api.commands.DeleteVMGroupCmd;15
+updateInstanceGroup=com.cloud.api.commands.UpdateVMGroupCmd;15
+listInstanceGroups=com.cloud.api.commands.ListVMGroupsCmd;15
diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in
index 5298e5b4cee..db18e25a5a5 100755
--- a/client/tomcatconf/components.xml.in
+++ b/client/tomcatconf/components.xml.in
@@ -113,6 +113,8 @@
+
+
diff --git a/core/src/com/cloud/server/ManagementServer.java b/core/src/com/cloud/server/ManagementServer.java
index c3794a40303..073ae465ba6 100755
--- a/core/src/com/cloud/server/ManagementServer.java
+++ b/core/src/com/cloud/server/ManagementServer.java
@@ -96,6 +96,7 @@ import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.InstanceGroupVO;
import com.cloud.vm.VmStats;
/**
@@ -2201,4 +2202,36 @@ public interface ManagementServer {
VolumeVO getRootVolume(Long instanceId);
long getPsMaintenanceCount(long podId);
boolean isPoolUp(long instanceId);
+
+
+ //Move this part to UserVmManagerImpl after merge with api refactor branch
+ /**
+ * Creates a vm group
+ * @param name - group name
+ * @param accountId - account_id
+ *
+ */
+ InstanceGroupVO createVmGroup(String name, Long accountId);
+
+ /**
+ * Finds a vm group with the specified ID.
+ * @param groupId
+ * @return vmGroupVO
+ */
+ InstanceGroupVO findVmGroupById(long groupId);
+
+ InstanceGroupVO updateVmGroup(long groupId, String name);
+
+ /**
+ * Check if vm group name is already in use by this account
+ * @param name - name of the group
+ * @param accountId - accountId
+ */
+ boolean isVmGroupNameInUse(Long accountId, String name);
+
+ boolean deleteVmGroup(long groupId) throws InternalErrorException;
+
+ List searchForVmGroups(Criteria c);
+
+ InstanceGroupVO getGroupForVm(long vmId);
}
diff --git a/core/src/com/cloud/vm/InstanceGroupVMMapVO.java b/core/src/com/cloud/vm/InstanceGroupVMMapVO.java
new file mode 100644
index 00000000000..f51092c5dc7
--- /dev/null
+++ b/core/src/com/cloud/vm/InstanceGroupVMMapVO.java
@@ -0,0 +1,53 @@
+package com.cloud.vm;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.SecondaryTable;
+import javax.persistence.SecondaryTables;
+import javax.persistence.Table;
+
+@Entity
+@Table(name=("instance_group_vm_map"))
+@SecondaryTables({
+@SecondaryTable(name="user_vm",
+ pkJoinColumns={@PrimaryKeyJoinColumn(name="instance_id", referencedColumnName="id")}),
+@SecondaryTable(name="instance_group",
+ pkJoinColumns={@PrimaryKeyJoinColumn(name="group_id", referencedColumnName="id")})
+ })
+public class InstanceGroupVMMapVO {
+ @Id
+ @GeneratedValue(strategy=GenerationType.IDENTITY)
+ @Column(name="id")
+ private Long id;
+
+ @Column(name="group_id")
+ private long groupId;
+
+ @Column(name="instance_id")
+ private long instanceId;
+
+
+ public InstanceGroupVMMapVO() { }
+
+ public InstanceGroupVMMapVO(long groupId, long instanceId) {
+ this.groupId = groupId;
+ this.instanceId = instanceId;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public long getGroupId() {
+ return groupId;
+ }
+
+ public long getInstanceId() {
+ return instanceId;
+ }
+
+}
\ No newline at end of file
diff --git a/core/src/com/cloud/vm/InstanceGroupVO.java b/core/src/com/cloud/vm/InstanceGroupVO.java
new file mode 100644
index 00000000000..a16d784c3fb
--- /dev/null
+++ b/core/src/com/cloud/vm/InstanceGroupVO.java
@@ -0,0 +1,79 @@
+package com.cloud.vm;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.SecondaryTable;
+import javax.persistence.Table;
+
+import com.cloud.user.OwnedBy;
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name="instance_group")
+@SecondaryTable(name="account",
+ pkJoinColumns={@PrimaryKeyJoinColumn(name="account_id", referencedColumnName="id")})
+public class InstanceGroupVO implements OwnedBy{
+ @Id
+ @GeneratedValue(strategy=GenerationType.IDENTITY)
+ @Column(name="id")
+ private long id;
+
+ @Column(name="name")
+ String name;
+
+ @Column(name="account_id")
+ private long accountId;
+
+ @Column(name="domain_id", table="account", insertable=false, updatable=false)
+ private long domainId;
+
+ @Column(name=GenericDao.REMOVED_COLUMN)
+ private Date removed;
+
+ @Column(name=GenericDao.CREATED_COLUMN)
+ private Date created;
+
+ public InstanceGroupVO(String name, long accountId) {
+ this.name = name;
+ this.accountId = accountId;
+ }
+
+ protected InstanceGroupVO() {
+ super();
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public long getAccountId() {
+ return accountId;
+ }
+
+ public long getDomainId() {
+ return domainId;
+ }
+
+ public Date getRemoved() {
+ return removed;
+ }
+
+ public Date getCreated() {
+ return created;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
diff --git a/core/src/com/cloud/vm/UserVmVO.java b/core/src/com/cloud/vm/UserVmVO.java
index 0943ff72f2b..6ab4f55f2e4 100755
--- a/core/src/com/cloud/vm/UserVmVO.java
+++ b/core/src/com/cloud/vm/UserVmVO.java
@@ -60,9 +60,6 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
@Column(name="external_ip_address")
String externalIpAddress;
-
- @Column(name="group", updatable=true, nullable=true)
- private String group;
@Column(name="external_mac_address")
String externalMacAddress;
@@ -146,15 +143,6 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
return vnet;
}
- @Override
- public String getGroup() {
- return group;
- }
-
- public void setGroup(String group) {
- this.group = group;
- }
-
public UserVmVO(long id,
String instanceName,
String displayName,
@@ -164,10 +152,8 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
long domainId,
long accountId,
long serviceOfferingId,
- String group,
String userData) {
super(id, displayName, instanceName, Type.User, templateId, guestOsId, haEnabled);
- this.group = group;
this.userData = userData;
this.displayName = displayName;
@@ -191,7 +177,6 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
long dcId,
boolean haEnabled,
String displayName,
- String group,
String userData) {
super(id, name, name, Type.User, templateId, guestOSId, guestMacAddress, guestIpAddress, guestNetMask, dcId, podId, haEnabled, null);
this.serviceOfferingId = serviceOfferingId;
@@ -205,10 +190,8 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
this.externalMacAddress = externalMacAddress;
this.setUserData(userData);
this.setExternalVlanDbId(vlanDbId);
- this.group = group;
this.isoId = null;
this.displayName = displayName;
- this.group = group;
}
protected UserVmVO() {
diff --git a/core/src/com/cloud/vm/dao/InstanceGroupDao.java b/core/src/com/cloud/vm/dao/InstanceGroupDao.java
new file mode 100644
index 00000000000..6cfadce311b
--- /dev/null
+++ b/core/src/com/cloud/vm/dao/InstanceGroupDao.java
@@ -0,0 +1,20 @@
+package com.cloud.vm.dao;
+
+import java.util.List;
+
+import com.cloud.utils.db.GenericDao;
+import com.cloud.vm.InstanceGroupVO;
+
+public interface InstanceGroupDao extends GenericDao{
+ List listByAccountId(long id);
+ boolean isNameInUse(Long accountId, String name);
+ InstanceGroupVO findByAccountAndName(Long accountId, String name);
+
+ /**
+ * Updates name for the vm
+ * @param id - group id
+ * @param name
+ */
+ void updateVmGroup(long id, String name);
+
+}
diff --git a/core/src/com/cloud/vm/dao/InstanceGroupDaoImpl.java b/core/src/com/cloud/vm/dao/InstanceGroupDaoImpl.java
new file mode 100644
index 00000000000..fa1581e93c6
--- /dev/null
+++ b/core/src/com/cloud/vm/dao/InstanceGroupDaoImpl.java
@@ -0,0 +1,61 @@
+package com.cloud.vm.dao;
+
+import java.util.List;
+
+import javax.ejb.Local;
+
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.vm.InstanceGroupVO;
+
+@Local (value={InstanceGroupDao.class})
+public class InstanceGroupDaoImpl extends GenericDaoBase implements InstanceGroupDao{
+ private SearchBuilder AccountIdNameSearch;
+ protected final SearchBuilder AccountSearch;
+
+ protected InstanceGroupDaoImpl() {
+ AccountSearch = createSearchBuilder();
+ AccountSearch.and("account", AccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+ AccountSearch.done();
+
+ AccountIdNameSearch = createSearchBuilder();
+ AccountIdNameSearch.and("accountId", AccountIdNameSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+ AccountIdNameSearch.and("groupName", AccountIdNameSearch.entity().getName(), SearchCriteria.Op.EQ);
+ AccountIdNameSearch.done();
+
+ }
+
+ @Override
+ public boolean isNameInUse(Long accountId, String name) {
+ SearchCriteria sc = createSearchCriteria();
+ sc.addAnd("name", SearchCriteria.Op.EQ, name);
+ if (accountId != null) {
+ sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
+ }
+ List vmGroups = listActiveBy(sc);
+ return ((vmGroups != null) && !vmGroups.isEmpty());
+ }
+
+ @Override
+ public InstanceGroupVO findByAccountAndName(Long accountId, String name) {
+ SearchCriteria sc = AccountIdNameSearch.create();
+ sc.setParameters("accountId", accountId);
+ sc.setParameters("groupName", name);
+ return findOneActiveBy(sc);
+ }
+
+ @Override
+ public void updateVmGroup(long id, String name) {
+ InstanceGroupVO vo = createForUpdate();
+ vo.setName(name);
+ update(id, vo);
+ }
+
+ @Override
+ public List listByAccountId(long id) {
+ SearchCriteria sc = AccountSearch.create();
+ sc.setParameters("account", id);
+ return listActiveBy(sc);
+ }
+}
diff --git a/core/src/com/cloud/vm/dao/InstanceGroupVMMapDao.java b/core/src/com/cloud/vm/dao/InstanceGroupVMMapDao.java
new file mode 100644
index 00000000000..14d05cb4f7a
--- /dev/null
+++ b/core/src/com/cloud/vm/dao/InstanceGroupVMMapDao.java
@@ -0,0 +1,12 @@
+package com.cloud.vm.dao;
+
+import java.util.List;
+
+import com.cloud.utils.db.GenericDao;
+import com.cloud.vm.InstanceGroupVMMapVO;
+
+public interface InstanceGroupVMMapDao extends GenericDao{
+ List listByInstanceId(long instanceId);
+ List listByGroupId(long groupId);
+ InstanceGroupVMMapVO findByVmIdGroupId(long instanceId, long groupId);
+}
diff --git a/core/src/com/cloud/vm/dao/InstanceGroupVMMapDaoImpl.java b/core/src/com/cloud/vm/dao/InstanceGroupVMMapDaoImpl.java
new file mode 100644
index 00000000000..f64e3201714
--- /dev/null
+++ b/core/src/com/cloud/vm/dao/InstanceGroupVMMapDaoImpl.java
@@ -0,0 +1,56 @@
+package com.cloud.vm.dao;
+
+import java.util.List;
+
+import javax.ejb.Local;
+
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.vm.InstanceGroupVMMapVO;
+
+@Local(value={InstanceGroupVMMapDao.class})
+public class InstanceGroupVMMapDaoImpl extends GenericDaoBase implements InstanceGroupVMMapDao{
+
+ private SearchBuilder ListByVmId;
+ private SearchBuilder ListByGroupId;
+ private SearchBuilder ListByVmIdGroupId;
+
+ protected InstanceGroupVMMapDaoImpl() {
+ ListByVmId = createSearchBuilder();
+ ListByVmId.and("instanceId", ListByVmId.entity().getInstanceId(), SearchCriteria.Op.EQ);
+ ListByVmId.done();
+
+ ListByGroupId = createSearchBuilder();
+ ListByGroupId.and("groupId", ListByGroupId.entity().getGroupId(), SearchCriteria.Op.EQ);
+ ListByGroupId.done();
+
+ ListByVmIdGroupId = createSearchBuilder();
+ ListByVmIdGroupId.and("instanceId", ListByVmIdGroupId.entity().getInstanceId(), SearchCriteria.Op.EQ);
+ ListByVmIdGroupId.and("groupId", ListByVmIdGroupId.entity().getGroupId(), SearchCriteria.Op.EQ);
+ ListByVmIdGroupId.done();
+ }
+
+ @Override
+ public List listByInstanceId(long vmId) {
+ SearchCriteria sc = ListByVmId.create();
+ sc.setParameters("instanceId", vmId);
+ return listActiveBy(sc);
+ }
+
+ @Override
+ public List listByGroupId(long groupId) {
+ SearchCriteria sc = ListByGroupId.create();
+ sc.setParameters("groupId", groupId);
+ return listActiveBy(sc);
+ }
+
+ @Override
+ public InstanceGroupVMMapVO findByVmIdGroupId(long instanceId, long groupId) {
+ SearchCriteria sc = ListByVmIdGroupId.create();
+ sc.setParameters("groupId", groupId);
+ sc.setParameters("instanceId", instanceId);
+ return findOneBy(sc);
+ }
+
+}
diff --git a/core/src/com/cloud/vm/dao/UserVmDao.java b/core/src/com/cloud/vm/dao/UserVmDao.java
index 72faff705a2..6fc253085fa 100755
--- a/core/src/com/cloud/vm/dao/UserVmDao.java
+++ b/core/src/com/cloud/vm/dao/UserVmDao.java
@@ -61,9 +61,9 @@ public interface UserVmDao extends GenericDao {
/**
* Updates display name and group for vm; enables/disables ha
* @param id vm id.
- * @param displan name, group and enable for ha
+ * @param displan name and enable for ha
*/
- void updateVM(long id, String displayName, String group, boolean enable);
+ void updateVM(long id, String displayName, boolean enable);
List findDestroyedVms(Date date);
diff --git a/core/src/com/cloud/vm/dao/UserVmDaoImpl.java b/core/src/com/cloud/vm/dao/UserVmDaoImpl.java
index 4e909b7b9f3..92d7894f08c 100755
--- a/core/src/com/cloud/vm/dao/UserVmDaoImpl.java
+++ b/core/src/com/cloud/vm/dao/UserVmDaoImpl.java
@@ -152,10 +152,9 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use
}
@Override
- public void updateVM(long id, String displayName, String group, boolean enable) {
+ public void updateVM(long id, String displayName, boolean enable) {
UserVmVO vo = createForUpdate();
vo.setDisplayName(displayName);
- vo.setGroup(group);
vo.setHaEnabled(enable);
update(id, vo);
}
diff --git a/server/src/com/cloud/api/BaseCmd.java b/server/src/com/cloud/api/BaseCmd.java
index c84a46c862e..fc8bcb4cbfe 100644
--- a/server/src/com/cloud/api/BaseCmd.java
+++ b/server/src/com/cloud/api/BaseCmd.java
@@ -197,7 +197,7 @@ public abstract class BaseCmd {
FORMAT("format", BaseCmd.TYPE_STRING, "format"),
GATEWAY("gateway", BaseCmd.TYPE_STRING, "gateway"),
GROUP("group", BaseCmd.TYPE_STRING, "group"),
- GROUP_ID("group", BaseCmd.TYPE_LONG, "groupId"),
+ GROUP_ID("groupid", BaseCmd.TYPE_LONG, "groupId"),
GROUP_IDS("groupids", BaseCmd.TYPE_STRING, "groupIds"),
GUEST_OS_ID("guestosid", BaseCmd.TYPE_LONG, "guestOsId"),
HA_ENABLE("haenable", BaseCmd.TYPE_BOOLEAN, "haEnable"),
diff --git a/server/src/com/cloud/api/commands/CreateVMGroupCmd.java b/server/src/com/cloud/api/commands/CreateVMGroupCmd.java
new file mode 100644
index 00000000000..a9fbaf9cd93
--- /dev/null
+++ b/server/src/com/cloud/api/commands/CreateVMGroupCmd.java
@@ -0,0 +1,106 @@
+package com.cloud.api.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.BaseCmd;
+import com.cloud.api.ServerApiException;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+import com.cloud.vm.InstanceGroupVO;
+
+public class CreateVMGroupCmd extends BaseCmd{
+ public static final Logger s_logger = Logger.getLogger(CreateVMGroupCmd.class.getName());
+
+ private static final String s_name = "createinstancegroupresponse";
+ private static final List> s_properties = new ArrayList>();
+
+ static {
+ s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE));
+ s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT, Boolean.FALSE));
+ s_properties.add(new Pair(BaseCmd.Properties.DOMAIN_ID, Boolean.FALSE));
+ s_properties.add(new Pair(BaseCmd.Properties.NAME, Boolean.TRUE));
+ }
+
+ public String getName() {
+ return s_name;
+ }
+ public List> getProperties() {
+ return s_properties;
+ }
+
+ @Override
+ public List> execute(Map params) {
+ Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName());
+ Long domainId = (Long)params.get(BaseCmd.Properties.DOMAIN_ID.getName());
+ String accountName = (String)params.get(BaseCmd.Properties.ACCOUNT.getName());
+ String name = (String)params.get(BaseCmd.Properties.NAME.getName());
+ Long accountId = null;
+
+ if (account != null) {
+ if (isAdmin(account.getType())) {
+ if (domainId != null) {
+ if (!getManagementServer().isChildDomain(account.getDomainId(), domainId)) {
+ throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to create vm group in domain " + domainId + ", permission denied.");
+ }
+ } else {
+ // the admin must be creating the vm group
+ if (account != null) {
+ accountId = account.getId();
+ domainId = account.getDomainId();
+ accountName = account.getAccountName();
+ }
+ }
+ } else {
+ accountId = account.getId();
+ domainId = account.getDomainId();
+ accountName = account.getAccountName();
+ }
+ }
+
+ if (accountId == null) {
+ if ((accountName != null) && (domainId != null)) {
+ Account userAccount = getManagementServer().findActiveAccount(accountName, domainId);
+ if (userAccount != null) {
+ accountId = userAccount.getId();
+ accountName = userAccount.getAccountName();
+ } else {
+ throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "could not find account " + accountName + " in domain " + domainId);
+ }
+ }
+ }
+
+ if (accountId == null) {
+ throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to create vm group, no account specified.");
+ }
+
+ //Check if name is already in use by this account
+ boolean isNameInUse = getManagementServer().isVmGroupNameInUse(accountId, name);
+
+ if (isNameInUse) {
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to create vm group, a group with name " + name + " already exisits for account " + accountId);
+ }
+
+ InstanceGroupVO vmGroup = getManagementServer().createVmGroup(name, accountId);
+
+ List> embeddedObject = new ArrayList>();
+
+ List> returnValues = new ArrayList>();
+ returnValues.add(new Pair(BaseCmd.Properties.ID.getName(), Long.toString(vmGroup.getId())));
+ returnValues.add(new Pair(BaseCmd.Properties.NAME.getName(), vmGroup.getName()));
+ returnValues.add(new Pair(BaseCmd.Properties.CREATED.getName(), vmGroup.getCreated()));
+
+ Account accountTemp = getManagementServer().findAccountById(vmGroup.getAccountId());
+ if (accountTemp != null) {
+ returnValues.add(new Pair(BaseCmd.Properties.ACCOUNT.getName(), accountTemp.getAccountName()));
+ returnValues.add(new Pair(BaseCmd.Properties.DOMAIN_ID.getName(), accountTemp.getDomainId()));
+ returnValues.add(new Pair(BaseCmd.Properties.DOMAIN.getName(), getManagementServer().findDomainIdById(accountTemp.getDomainId()).getName()));
+ }
+ embeddedObject.add(new Pair("instancegroup", new Object[] { returnValues } ));
+ return embeddedObject;
+ }
+
+}
diff --git a/server/src/com/cloud/api/commands/DeleteVMGroupCmd.java b/server/src/com/cloud/api/commands/DeleteVMGroupCmd.java
new file mode 100644
index 00000000000..abd3f4b4b72
--- /dev/null
+++ b/server/src/com/cloud/api/commands/DeleteVMGroupCmd.java
@@ -0,0 +1,71 @@
+package com.cloud.api.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.BaseCmd;
+import com.cloud.api.ServerApiException;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+import com.cloud.vm.InstanceGroupVO;
+
+public class DeleteVMGroupCmd extends BaseCmd{
+ public static final Logger s_logger = Logger.getLogger(DeleteVMGroupCmd.class.getName());
+ private static final String s_name = "deleteinstancegroupresponse";
+ private static final List> s_properties = new ArrayList>();
+
+ static {
+ s_properties.add(new Pair(BaseCmd.Properties.ID, Boolean.TRUE));
+ s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE));
+ }
+
+ @Override
+ public String getName() {
+ return s_name;
+ }
+ @Override
+ public List> getProperties() {
+ return s_properties;
+ }
+
+ @Override
+ public List> execute(Map params) {
+ Long groupId = (Long)params.get(BaseCmd.Properties.ID.getName());
+ Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName());
+
+ // Verify input parameters
+ InstanceGroupVO group = getManagementServer().findVmGroupById(groupId.longValue());
+ if (group == null) {
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, "unable to find a vm group with id " + groupId);
+ }
+
+ if (account != null) {
+ Account tempAccount = getManagementServer().findAccountById(group.getAccountId());
+ if (!isAdmin(account.getType()) && (account.getId() != group.getAccountId())) {
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, "unable to find a group with id " + groupId);
+ } else if (!getManagementServer().isChildDomain(account.getDomainId(), tempAccount.getDomainId())) {
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, "Invalid group id (" + groupId + ") given, unable to update the group.");
+ }
+ }
+
+ boolean success = false;
+ try {
+ success = getManagementServer().deleteVmGroup(groupId);
+ } catch (Exception ex) {
+ s_logger.error("Exception deleting vm group", ex);
+ throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete vm group " + groupId + ": internal error.");
+ }
+
+ List> returnValues = new ArrayList>();
+ if (success) {
+ returnValues.add(new Pair(BaseCmd.Properties.SUCCESS.getName(), Boolean.TRUE));
+ } else {
+ throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete vm group " + groupId);
+ }
+ return returnValues;
+ }
+
+}
diff --git a/server/src/com/cloud/api/commands/DeployVMCmd.java b/server/src/com/cloud/api/commands/DeployVMCmd.java
index 63c4b9aa47f..c669efa99ac 100644
--- a/server/src/com/cloud/api/commands/DeployVMCmd.java
+++ b/server/src/com/cloud/api/commands/DeployVMCmd.java
@@ -89,7 +89,11 @@ public class DeployVMCmd extends BaseCmd {
String networkGroupList = (String)params.get(BaseCmd.Properties.NETWORK_GROUP_LIST.getName());
Long size = (Long)params.get(BaseCmd.Properties.SIZE.getName());
String password = null;
- Long accountId = null;
+ Long accountId = null;
+
+ //don't accept empty group names
+ if (group != null && group.isEmpty())
+ group = null;
if(size == null)
size = Long.valueOf(0);
diff --git a/server/src/com/cloud/api/commands/ListVMGroupsCmd.java b/server/src/com/cloud/api/commands/ListVMGroupsCmd.java
new file mode 100644
index 00000000000..faefe34bd5d
--- /dev/null
+++ b/server/src/com/cloud/api/commands/ListVMGroupsCmd.java
@@ -0,0 +1,144 @@
+package com.cloud.api.commands;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.BaseCmd;
+import com.cloud.api.ServerApiException;
+import com.cloud.domain.DomainVO;
+import com.cloud.host.HostVO;
+import com.cloud.server.Criteria;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+import com.cloud.vm.InstanceGroupVO;
+
+public class ListVMGroupsCmd extends BaseCmd{
+ public static final Logger s_logger = Logger.getLogger(ListVMGroupsCmd.class.getName());
+
+ private static final String s_name = "listinstancegroupsresponse";
+ private static final List> s_properties = new ArrayList>();
+
+ static {
+ s_properties.add(new Pair(BaseCmd.Properties.ID, Boolean.FALSE));
+ s_properties.add(new Pair(BaseCmd.Properties.NAME, Boolean.FALSE));
+ s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT, Boolean.FALSE));
+ s_properties.add(new Pair(BaseCmd.Properties.DOMAIN_ID, Boolean.FALSE));
+ s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE));
+ }
+
+ @Override
+ public String getName() {
+ return s_name;
+ }
+ @Override
+ public List> getProperties() {
+ return s_properties;
+ }
+
+ @Override
+ public List> execute(Map params) {
+ Long id = (Long)params.get(BaseCmd.Properties.ID.getName());
+ Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName());
+ String accountName = (String)params.get(BaseCmd.Properties.ACCOUNT.getName());
+ Long domainId = (Long)params.get(BaseCmd.Properties.DOMAIN_ID.getName());
+ String name = (String) params.get(BaseCmd.Properties.NAME.getName());
+ String keyword = (String)params.get(BaseCmd.Properties.KEYWORD.getName());
+ Integer page = (Integer)params.get(BaseCmd.Properties.PAGE.getName());
+ Integer pageSize = (Integer)params.get(BaseCmd.Properties.PAGESIZE.getName());
+ Long accountId = null;
+ Boolean isAdmin = false;
+
+ if ((account == null) || isAdmin(account.getType())) {
+ isAdmin = true;
+ if (domainId != null) {
+ if ((account != null) && !getManagementServer().isChildDomain(account.getDomainId(), domainId)) {
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, "Invalid domain id (" + domainId + ") given, unable to list vm groups.");
+ }
+
+ if (accountName != null) {
+ account = getManagementServer().findActiveAccount(accountName, domainId);
+ if (account == null) {
+ throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to find account " + accountName + " in domain " + domainId);
+ }
+ accountId = account.getId();
+ }
+ } else {
+ domainId = ((account == null) ? DomainVO.ROOT_DOMAIN : account.getDomainId());
+ }
+ } else {
+ accountName = account.getAccountName();
+ accountId = account.getId();
+ domainId = account.getDomainId();
+ }
+
+ Long[] accountIds = null;
+ if (accountId != null) {
+ accountIds = new Long[1];
+ accountIds[0] = accountId;
+ }
+
+ Long startIndex = Long.valueOf(0);
+ int pageSizeNum = 50;
+ if (pageSize != null) {
+ pageSizeNum = pageSize.intValue();
+ }
+ if (page != null) {
+ int pageNum = page.intValue();
+ if (pageNum > 0) {
+ startIndex = Long.valueOf(pageSizeNum * (pageNum-1));
+ }
+ }
+ Criteria c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum));
+
+ if (keyword != null) {
+ c.addCriteria(Criteria.KEYWORD, keyword);
+ } else {
+ c.addCriteria(Criteria.ID, id);
+ c.addCriteria(Criteria.NAME, name);
+
+ // ignore these search requests if it's not an admin
+ if (isAdmin == true) {
+ c.addCriteria(Criteria.DOMAINID, domainId);
+ }
+ }
+
+ c.addCriteria(Criteria.ACCOUNTID, accountIds);
+ c.addCriteria(Criteria.ISADMIN, isAdmin);
+
+ List extends InstanceGroupVO> vmGroups = getManagementServer().searchForVmGroups(c);
+
+ if (vmGroups == null) {
+ throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "unable to find vm groups for account id " + accountName.toString());
+ }
+
+ Object[] vmTag = new Object[vmGroups.size()];
+ int i = 0;
+
+ for (InstanceGroupVO vmGroup : vmGroups) {
+
+ List> vmData = new ArrayList>();
+
+ vmData.add(new Pair(BaseCmd.Properties.ID.getName(), Long.toString(vmGroup.getId())));
+ vmData.add(new Pair(BaseCmd.Properties.NAME.getName(), vmGroup.getName()));
+ vmData.add(new Pair(BaseCmd.Properties.CREATED.getName(), vmGroup.getCreated()));
+
+ Account acct = getManagementServer().findAccountById(Long.valueOf(vmGroup.getAccountId()));
+ if (acct != null) {
+ vmData.add(new Pair(BaseCmd.Properties.ACCOUNT.getName(), acct.getAccountName()));
+ vmData.add(new Pair(BaseCmd.Properties.DOMAIN_ID.getName(), Long.toString(acct.getDomainId())));
+ vmData.add(new Pair(BaseCmd.Properties.DOMAIN.getName(), getManagementServer().findDomainIdById(acct.getDomainId()).getName()));
+ }
+
+ vmTag[i++] = vmData;
+ }
+ List> returnTags = new ArrayList>();
+ Pair vmTags = new Pair("instancegroup", vmTag);
+ returnTags.add(vmTags);
+ return returnTags;
+ }
+
+}
diff --git a/server/src/com/cloud/api/commands/ListVMsCmd.java b/server/src/com/cloud/api/commands/ListVMsCmd.java
index 68ffa17b314..0041fcc31af 100644
--- a/server/src/com/cloud/api/commands/ListVMsCmd.java
+++ b/server/src/com/cloud/api/commands/ListVMsCmd.java
@@ -21,6 +21,7 @@ package com.cloud.api.commands;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -42,6 +43,7 @@ import com.cloud.storage.VolumeVO;
import com.cloud.user.Account;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
+import com.cloud.vm.InstanceGroupVO;
import com.cloud.vm.VmStats;
public class ListVMsCmd extends BaseCmd {
@@ -56,7 +58,7 @@ public class ListVMsCmd extends BaseCmd {
s_properties.add(new Pair(BaseCmd.Properties.STATE, Boolean.FALSE));
s_properties.add(new Pair(BaseCmd.Properties.ZONE_ID, Boolean.FALSE));
s_properties.add(new Pair(BaseCmd.Properties.POD_ID, Boolean.FALSE));
- s_properties.add(new Pair(BaseCmd.Properties.GROUP, Boolean.FALSE));
+ s_properties.add(new Pair(BaseCmd.Properties.GROUP_ID, Boolean.FALSE));
s_properties.add(new Pair(BaseCmd.Properties.HOST_ID, Boolean.FALSE));
s_properties.add(new Pair(BaseCmd.Properties.KEYWORD, Boolean.FALSE));
s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT, Boolean.FALSE));
@@ -86,7 +88,7 @@ public class ListVMsCmd extends BaseCmd {
Long zoneId = (Long)params.get(BaseCmd.Properties.ZONE_ID.getName());
Long podId = (Long)params.get(BaseCmd.Properties.POD_ID.getName());
Long hostId = (Long)params.get(BaseCmd.Properties.HOST_ID.getName());
- String group = (String)params.get(BaseCmd.Properties.GROUP.getName());
+ Long groupId = (Long)params.get(BaseCmd.Properties.GROUP_ID.getName());
String keyword = (String)params.get(BaseCmd.Properties.KEYWORD.getName());
Integer page = (Integer)params.get(BaseCmd.Properties.PAGE.getName());
Integer pageSize = (Integer)params.get(BaseCmd.Properties.PAGESIZE.getName());
@@ -145,14 +147,6 @@ public class ListVMsCmd extends BaseCmd {
if(zoneId != null)
c.addCriteria(Criteria.DATACENTERID, zoneId);
- if(group != null)
- {
- if(group.equals(""))
- c.addCriteria(Criteria.EMPTY_GROUP, group);
- else
- c.addCriteria(Criteria.GROUP, group);
- }
-
// ignore these search requests if it's not an admin
if (isAdmin == true) {
c.addCriteria(Criteria.DOMAINID, domainId);
@@ -165,13 +159,14 @@ public class ListVMsCmd extends BaseCmd {
c.addCriteria(Criteria.ACCOUNTID, accountIds);
c.addCriteria(Criteria.ISADMIN, isAdmin);
+ c.addCriteria(Criteria.GROUPID, groupId);
List extends UserVm> virtualMachines = getManagementServer().searchForUserVMs(c);
if (virtualMachines == null) {
throw new ServerApiException(BaseCmd.VM_LIST_ERROR, "unable to find virtual machines for account id " + accountName.toString());
}
-
+
Object[] vmTag = new Object[virtualMachines.size()];
int i = 0;
@@ -220,11 +215,14 @@ public class ListVMsCmd extends BaseCmd {
else {
vmData.add(new Pair(BaseCmd.Properties.DISPLAY_NAME.getName(), vmInstance.getName()));
}
-
- if (vmInstance.getGroup() != null) {
- vmData.add(new Pair(BaseCmd.Properties.GROUP.getName(), vmInstance.getGroup()));
- }
-
+
+ //Groups
+ InstanceGroupVO group = getManagementServer().getGroupForVm(vmInstance.getId());
+ if (group != null) {
+ vmData.add(new Pair(BaseCmd.Properties.GROUP_ID.getName(), group.getId()));
+ vmData.add(new Pair(BaseCmd.Properties.GROUP.getName(), group.getName()));
+ }
+
// Data Center Info
vmData.add(new Pair(BaseCmd.Properties.ZONE_ID.getName(), Long.valueOf(vmInstance.getDataCenterId()).toString()));
vmData.add(new Pair(BaseCmd.Properties.ZONE_NAME.getName(), getManagementServer().findDataCenterById(vmInstance.getDataCenterId()).getName()));
diff --git a/server/src/com/cloud/api/commands/UpdateVMCmd.java b/server/src/com/cloud/api/commands/UpdateVMCmd.java
index 6269e453fea..ff788e42e51 100644
--- a/server/src/com/cloud/api/commands/UpdateVMCmd.java
+++ b/server/src/com/cloud/api/commands/UpdateVMCmd.java
@@ -66,7 +66,11 @@ public class UpdateVMCmd extends BaseCmd{
// default userId to SYSTEM user
if (userId == null) {
userId = Long.valueOf(1);
- }
+ }
+
+ //don't accept empty parameter for the group
+ if (group != null && group.isEmpty())
+ group = null;
// Verify input parameters
try {
@@ -85,11 +89,7 @@ public class UpdateVMCmd extends BaseCmd{
} else if (!getManagementServer().isChildDomain(account.getDomainId(), vmInstance.getDomainId())) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Invalid virtual machine id (" + vmId + ") given, unable to update virtual machine.");
}
- }
-
- if (group == null) {
- group = vmInstance.getGroup();
- }
+ }
if (displayName == null) {
displayName = vmInstance.getDisplayName();
diff --git a/server/src/com/cloud/api/commands/UpdateVMGroupCmd.java b/server/src/com/cloud/api/commands/UpdateVMGroupCmd.java
new file mode 100644
index 00000000000..fcc80e9959b
--- /dev/null
+++ b/server/src/com/cloud/api/commands/UpdateVMGroupCmd.java
@@ -0,0 +1,79 @@
+package com.cloud.api.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.BaseCmd;
+import com.cloud.api.ServerApiException;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+import com.cloud.vm.InstanceGroupVO;
+
+public class UpdateVMGroupCmd extends BaseCmd{
+
+ private static final String s_name = "updateinstancegroupresponse";
+ public static final Logger s_logger = Logger.getLogger(UpdateVMGroupCmd.class.getName());
+ private static final List> s_properties = new ArrayList>();
+
+ static {
+ s_properties.add(new Pair(BaseCmd.Properties.ID, Boolean.TRUE));
+ s_properties.add(new Pair(BaseCmd.Properties.NAME, Boolean.FALSE));
+ s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE));
+ }
+
+ public String getName() {
+ return s_name;
+ }
+
+ public List> getProperties() {
+ return s_properties;
+ }
+
+ @Override
+ public List> execute(Map params) {
+ Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName());
+ Long groupId = (Long)params.get(BaseCmd.Properties.ID.getName());
+ String name = (String)params.get(BaseCmd.Properties.NAME.getName());
+
+ // Verify input parameters
+ InstanceGroupVO group = getManagementServer().findVmGroupById(groupId.longValue());
+ if (group == null) {
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, "unable to find a vm group with id " + groupId);
+ }
+
+ if (account != null) {
+ Account tempAccount = getManagementServer().findAccountById(group.getAccountId());
+ if (!isAdmin(account.getType()) && (account.getId() != group.getAccountId())) {
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, "unable to find a group with id " + groupId + " for this account");
+ } else if (!getManagementServer().isChildDomain(account.getDomainId(), tempAccount.getDomainId())) {
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, "Invalid group id (" + groupId + ") given, unable to update the group.");
+ }
+ }
+
+ //Check if name is already in use by this account (exclude this group)
+ boolean isNameInUse = getManagementServer().isVmGroupNameInUse(group.getAccountId(), name);
+
+ if (isNameInUse && !group.getName().equals(name)) {
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to update vm group, a group with name " + name + " already exisits for account");
+ }
+
+ InstanceGroupVO vmGroup = getManagementServer().updateVmGroup(groupId, name);
+ List> embeddedObject = new ArrayList>();
+
+ List> returnValues = new ArrayList>();
+ returnValues.add(new Pair(BaseCmd.Properties.ID.getName(), Long.toString(vmGroup.getId())));
+ returnValues.add(new Pair(BaseCmd.Properties.NAME.getName(), vmGroup.getName()));
+
+ Account accountTemp = getManagementServer().findAccountById(vmGroup.getAccountId());
+ if (accountTemp != null) {
+ returnValues.add(new Pair(BaseCmd.Properties.ACCOUNT.getName(), accountTemp.getAccountName()));
+ returnValues.add(new Pair(BaseCmd.Properties.DOMAIN_ID.getName(), accountTemp.getDomainId()));
+ returnValues.add(new Pair(BaseCmd.Properties.DOMAIN.getName(), getManagementServer().findDomainIdById(accountTemp.getDomainId()).getName()));
+ }
+ embeddedObject.add(new Pair("instancegroup", new Object[] { returnValues } ));
+ return embeddedObject;
+ }
+}
diff --git a/server/src/com/cloud/async/executor/DeployVMExecutor.java b/server/src/com/cloud/async/executor/DeployVMExecutor.java
index 23fcc8c7493..8cf6f7f8ec7 100644
--- a/server/src/com/cloud/async/executor/DeployVMExecutor.java
+++ b/server/src/com/cloud/async/executor/DeployVMExecutor.java
@@ -42,6 +42,7 @@ import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.uservm.UserVm;
import com.cloud.utils.exception.ExecutionException;
+import com.cloud.vm.InstanceGroupVO;
import com.google.gson.Gson;
public class DeployVMExecutor extends VMOperationExecutor {
@@ -155,14 +156,17 @@ public class DeployVMExecutor extends VMOperationExecutor {
resultObject.setDisplayName(vm.getDisplayName());
}
- if (vm.getGroup() != null) {
- resultObject.setGroup(vm.getGroup());
- }
-
if(vm.getState() != null)
resultObject.setState(vm.getState().toString());
- ManagementServer managementServer = getAsyncJobMgr().getExecutorContext().getManagementServer();
+ ManagementServer managementServer = getAsyncJobMgr().getExecutorContext().getManagementServer();
+
+ InstanceGroupVO group = managementServer.getGroupForVm(vm.getId());
+ if (group != null) {
+ resultObject.setGroupId(group.getId());
+ resultObject.setGroup(group.getName());
+ }
+
VMTemplateVO template = managementServer.findTemplateById(vm.getTemplateId());
Account acct = managementServer.findAccountById(Long.valueOf(vm.getAccountId()));
diff --git a/server/src/com/cloud/async/executor/DeployVMResultObject.java b/server/src/com/cloud/async/executor/DeployVMResultObject.java
index 7a9e662751e..63e202eb182 100644
--- a/server/src/com/cloud/async/executor/DeployVMResultObject.java
+++ b/server/src/com/cloud/async/executor/DeployVMResultObject.java
@@ -102,7 +102,10 @@ public class DeployVMResultObject {
private String displayName;
@Param(name="group")
- private String group;
+ private String group;
+
+ @Param(name="groupid")
+ private Long groupId;
@Param(name="domainid")
private Long domainId;
@@ -336,6 +339,14 @@ public class DeployVMResultObject {
public void setGroup(String group) {
this.group = group;
+ }
+
+ public Long getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(Long groupId) {
+ this.groupId = groupId;
}
public Long getDomainId() {
diff --git a/server/src/com/cloud/async/executor/VMExecutorHelper.java b/server/src/com/cloud/async/executor/VMExecutorHelper.java
index 227742d24f5..dbee8b9124c 100644
--- a/server/src/com/cloud/async/executor/VMExecutorHelper.java
+++ b/server/src/com/cloud/async/executor/VMExecutorHelper.java
@@ -18,15 +18,13 @@
package com.cloud.async.executor;
-import java.util.List;
-
import com.cloud.api.BaseCmd;
-import com.cloud.network.security.NetworkGroupVO;
import com.cloud.server.ManagementServer;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.user.Account;
import com.cloud.vm.UserVmVO;
+import com.cloud.vm.InstanceGroupVO;
public class VMExecutorHelper {
public static VMOperationResultObject composeResultObject(ManagementServer managementServer, UserVmVO vm, String vmPassword) {
@@ -48,12 +46,14 @@ public class VMExecutorHelper {
resultObject.setDisplayName(vm.getDisplayName());
}
- if (vm.getGroup() != null) {
- resultObject.setGroup(vm.getGroup());
- }
-
if(vm.getState() != null)
- resultObject.setState(vm.getState().toString());
+ resultObject.setState(vm.getState().toString());
+
+ InstanceGroupVO group = managementServer.getGroupForVm(vm.getId());
+ if (group != null) {
+ resultObject.setGroupId(group.getId());
+ resultObject.setGroup(group.getName());
+ }
VMTemplateVO template = managementServer.findTemplateById(vm.getTemplateId());
diff --git a/server/src/com/cloud/async/executor/VMOperationResultObject.java b/server/src/com/cloud/async/executor/VMOperationResultObject.java
index 9ae292fa467..4bc96135c53 100644
--- a/server/src/com/cloud/async/executor/VMOperationResultObject.java
+++ b/server/src/com/cloud/async/executor/VMOperationResultObject.java
@@ -97,7 +97,10 @@ public class VMOperationResultObject {
private String displayName;
@Param(name="group")
- private String group;
+ private String group;
+
+ @Param(name="groupid")
+ private Long groupId;
@Param(name="domainid")
private Long domainId;
@@ -324,6 +327,14 @@ public class VMOperationResultObject {
public void setGroup(String group) {
this.group = group;
}
+
+ public Long getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(Long groupId) {
+ this.groupId = groupId;
+ }
public Long getDomainId() {
return domainId;
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 4ecb921ebc9..641ceddb94b 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -247,6 +247,7 @@ import com.cloud.utils.StringUtils;
import com.cloud.utils.DateUtil.IntervalType;
import com.cloud.utils.component.Adapters;
import com.cloud.utils.component.ComponentLocator;
+import com.cloud.utils.component.Inject;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
@@ -261,18 +262,22 @@ import com.cloud.utils.net.NetUtils;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.DomainRouter;
import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.InstanceGroupVMMapVO;
import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.State;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.InstanceGroupVO;
import com.cloud.vm.VmStats;
import com.cloud.vm.dao.ConsoleProxyDao;
import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.InstanceGroupVMMapDao;
import com.cloud.vm.dao.SecondaryStorageVmDao;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.vm.dao.InstanceGroupDao;
import com.google.gson.Gson;
public class ManagementServerImpl implements ManagementServer {
@@ -343,6 +348,8 @@ public class ManagementServerImpl implements ManagementServer {
private final int _purgeDelay;
private final boolean _directAttachNetworkExternalIpAllocator;
private final PreallocatedLunDao _lunDao;
+ private final InstanceGroupDao _vmGroupDao;
+ private final InstanceGroupVMMapDao _groupVMMapDao;
private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AccountChecker"));
private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker"));
@@ -419,6 +426,8 @@ public class ManagementServerImpl implements ManagementServer {
_poolDao = locator.getDao(StoragePoolDao.class);
_poolHostDao = locator.getDao(StoragePoolHostDao.class);
_vmDao = locator.getDao(UserVmDao.class);
+ _vmGroupDao = locator.getDao(InstanceGroupDao.class);
+ _groupVMMapDao = locator.getDao(InstanceGroupVMMapDao.class);
_configs = _configDao.getConfiguration();
_userStatsDao = locator.getDao(UserStatisticsDao.class);
@@ -898,6 +907,15 @@ public class ManagementServerImpl implements ManagementServer {
boolean accountCleanupNeeded = false;
try {
+ //delete all vm groups belonging to accont
+ List groups = _vmGroupDao.listByAccountId(accountId);
+ for (InstanceGroupVO group : groups) {
+ if (!_vmMgr.deleteVmGroup(group.getId())) {
+ s_logger.error("Unable to delete group: " + group.getId());
+ accountCleanupNeeded = true;
+ }
+ }
+
// Delete the snapshots dir for the account. Have to do this before destroying the VMs.
boolean success = _snapMgr.deleteSnapshotDirsForAccount(accountId);
if (success) {
@@ -2291,7 +2309,7 @@ public class ManagementServerImpl implements ManagementServer {
ArrayList a = new ArrayList(avoids.values());
if (_directAttachNetworkExternalIpAllocator) {
try {
- created = _vmMgr.createDirectlyAttachedVMExternal(vmId, userId, account, dc, offering, template, diskOffering, displayName, group, userData, a, networkGroupVOs, startEventId, size);
+ created = _vmMgr.createDirectlyAttachedVMExternal(vmId, userId, account, dc, offering, template, diskOffering, displayName, userData, a, networkGroupVOs, startEventId, size);
} catch (ResourceAllocationException rae) {
throw rae;
}
@@ -2312,19 +2330,32 @@ public class ManagementServerImpl implements ManagementServer {
}
try {
- created = _vmMgr.createVirtualMachine(vmId, userId, account, dc, offering, template, diskOffering, displayName, group, userData, a, startEventId, size);
+ created = _vmMgr.createVirtualMachine(vmId, userId, account, dc, offering, template, diskOffering, displayName, userData, a, startEventId, size);
} catch (ResourceAllocationException rae) {
throw rae;
}
} else {
try {
- created = _vmMgr.createDirectlyAttachedVM(vmId, userId, account, dc, offering, template, diskOffering, displayName, group, userData, a, networkGroupVOs, startEventId, size);
+ created = _vmMgr.createDirectlyAttachedVM(vmId, userId, account, dc, offering, template, diskOffering, displayName, userData, a, networkGroupVOs, startEventId, size);
} catch (ResourceAllocationException rae) {
throw rae;
}
}
}
+ //assign vm to the group
+ try{
+ if (group != null) {
+ boolean addToGroup = _vmMgr.addInstanceToGroup(Long.valueOf(vmId), group);
+ if (!addToGroup) {
+ throw new InternalErrorException("Unable to assing Vm to the group " + group);
+ }
+ }
+ } catch (Exception ex) {
+ throw new InternalErrorException("Unable to assing Vm to the group " + group);
+ }
+
+
if (created == null) {
throw new InternalErrorException("Unable to create VM for account (" + accountId + "): " + account.getAccountName());
}
@@ -2743,9 +2774,16 @@ public class ManagementServerImpl implements ManagementServer {
if (vm == null) {
throw new CloudRuntimeException("Unable to find virual machine with id " + vmId);
}
+
+ if (group != null) {
+ boolean addToGroup = _vmMgr.addInstanceToGroup(Long.valueOf(vmId), group);
+ if (!addToGroup) {
+ throw new CloudRuntimeException("Unable to update Vm with the the group " + group);
+ }
+ }
boolean haEnabled = vm.isHaEnabled();
- _userVmDao.updateVM(vmId, displayName, group, enable);
+ _userVmDao.updateVM(vmId, displayName, enable);
if (haEnabled != enable) {
String description = null;
String type = null;
@@ -5044,11 +5082,13 @@ public class ManagementServerImpl implements ManagementServer {
@Override
public List searchForUserVMs(Criteria c) {
Filter searchFilter = new Filter(UserVmVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit());
+
SearchBuilder sb = _userVmDao.createSearchBuilder();
+
// some criteria matter for generating the join condition
Object[] accountIds = (Object[]) c.getCriteria(Criteria.ACCOUNTID);
Object domainId = c.getCriteria(Criteria.DOMAINID);
-
+
// get the rest of the criteria
Object id = c.getCriteria(Criteria.ID);
Object name = c.getCriteria(Criteria.NAME);
@@ -5061,8 +5101,8 @@ public class ManagementServerImpl implements ManagementServer {
Object keyword = c.getCriteria(Criteria.KEYWORD);
Object isAdmin = c.getCriteria(Criteria.ISADMIN);
Object ipAddress = c.getCriteria(Criteria.IPADDRESS);
- Object vmGroup = c.getCriteria(Criteria.GROUP);
- Object emptyGroup = c.getCriteria(Criteria.EMPTY_GROUP);
+ Object groupId = c.getCriteria(Criteria.GROUPID);
+
sb.and("displayName", sb.entity().getDisplayName(), SearchCriteria.Op.LIKE);
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("accountIdEQ", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
@@ -5076,7 +5116,6 @@ public class ManagementServerImpl implements ManagementServer {
sb.and("hostIdEQ", sb.entity().getHostId(), SearchCriteria.Op.EQ);
sb.and("hostIdIN", sb.entity().getHostId(), SearchCriteria.Op.IN);
sb.and("guestIP", sb.entity().getGuestIpAddress(), SearchCriteria.Op.EQ);
- sb.and("groupEQ", sb.entity().getGroup(),SearchCriteria.Op.EQ);
if ((accountIds == null) && (domainId != null)) {
// if accountId isn't specified, we can do a domain match for the admin case
@@ -5084,15 +5123,24 @@ public class ManagementServerImpl implements ManagementServer {
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId());
}
+
+ if (groupId != null) {
+ SearchBuilder groupSearch = _groupVMMapDao.createSearchBuilder();
+ groupSearch.and("groupId", groupSearch.entity().getGroupId(), SearchCriteria.Op.EQ);
+ sb.join("groupSearch", groupSearch, sb.entity().getId(), groupSearch.entity().getInstanceId());
+ }
// populate the search criteria with the values passed in
SearchCriteria sc = sb.create();
+
+ if (groupId != null) {
+ sc.setJoinParameters("groupSearch", "groupId", groupId);
+ }
if (keyword != null) {
SearchCriteria ssc = _userVmDao.createSearchCriteria();
ssc.addOr("displayName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("group", SearchCriteria.Op.LIKE, "%" + keyword + "%");
ssc.addOr("instanceName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%");
@@ -5167,22 +5215,6 @@ public class ManagementServerImpl implements ManagementServer {
sc.setParameters("guestIP", ipAddress);
}
- if(vmGroup!=null)
- sc.setParameters("groupEQ", vmGroup);
-
- if (emptyGroup!= null)
- {
- SearchBuilder emptyGroupSearch = _userVmDao.createSearchBuilder();
- emptyGroupSearch.and("group", emptyGroupSearch.entity().getGroup(), SearchCriteria.Op.EQ);
- emptyGroupSearch.or("null", emptyGroupSearch.entity().getGroup(), SearchCriteria.Op.NULL);
-
- SearchCriteria sc1 = _userVmDao.createSearchCriteria();
- sc1 = emptyGroupSearch.create();
- sc1.setParameters("group", "");
-
- sc.addAnd("group", SearchCriteria.Op.SC, sc1);
- }
-
return _userVmDao.search(sc, searchFilter);
}
@@ -8759,5 +8791,99 @@ public class ManagementServerImpl implements ManagementServer {
return false;
}
+
+ //Move this section to UserVmManager when merge with api refactor branch is done
+ @Override
+ public InstanceGroupVO createVmGroup(String name, Long accountId){
+ return _vmMgr.createVmGroup(name, accountId);
+ }
+
+ @Override
+ public InstanceGroupVO findVmGroupById(long groupId) {
+ InstanceGroupVO group = _vmGroupDao.findById(groupId);
+ //return only active vm groups
+ if (group.getRemoved() == null) {
+ return group;
+ }
+ else {
+ return null;
+ }
+ }
+
+ @Override
+ public InstanceGroupVO updateVmGroup(long groupId, String name){
+
+ if (name != null) {
+ _vmGroupDao.updateVmGroup(groupId, name);
+ }
+ InstanceGroupVO vmGroup = _vmGroupDao.findById(groupId);
+ return vmGroup;
+ }
+
+ @Override
+ public boolean isVmGroupNameInUse(Long accountId, String name) {
+ return _vmGroupDao.isNameInUse(accountId, name);
+ }
+
+ @Override
+ public boolean deleteVmGroup(long groupId) throws InternalErrorException{
+ return _vmMgr.deleteVmGroup(groupId);
+ }
+
+ @Override
+ public List searchForVmGroups(Criteria c) {
+ Filter searchFilter = new Filter(InstanceGroupVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit());
+
+ Object[] accountIds = (Object[]) c.getCriteria(Criteria.ACCOUNTID);
+ Object id = c.getCriteria(Criteria.ID);
+ Object name = c.getCriteria(Criteria.NAME);
+ Object domainId = c.getCriteria(Criteria.DOMAINID);
+ Object keyword = c.getCriteria(Criteria.KEYWORD);
+
+ SearchBuilder sb = _vmGroupDao.createSearchBuilder();
+ sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+ sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
+ sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.IN);
+
+ if ((accountIds == null) && (domainId != null)) {
+ // if accountId isn't specified, we can do a domain match for the admin case
+ SearchBuilder domainSearch = _domainDao.createSearchBuilder();
+ domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
+ sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId());
+ }
+
+ SearchCriteria sc = sb.create();
+ if (keyword != null) {
+ SearchCriteria ssc = _vmGroupDao.createSearchCriteria();
+ ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+ }
+
+ if (id != null) {
+ sc.setParameters("id", id);
+ }
+
+ if (name != null) {
+ sc.setParameters("name", "%" + name + "%");
+ }
+
+ if (accountIds != null) {
+ sc.setParameters("accountId", accountIds);
+ } else if (domainId != null) {
+ DomainVO domain = _domainDao.findById((Long)domainId);
+ if (domain != null){
+ sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
+ }
+ }
+
+ return _vmGroupDao.search(sc, searchFilter);
+ }
+
+ @Override
+ public InstanceGroupVO getGroupForVm(long vmId){
+ return _vmMgr.getGroupForVm(vmId);
+ }
+
+
+ //Move section above to UserVmManager when merge with api refactor branch is done
}
diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java
index f4f09bc81eb..6c70f3c3f42 100644
--- a/server/src/com/cloud/vm/UserVmManager.java
+++ b/server/src/com/cloud/vm/UserVmManager.java
@@ -80,11 +80,11 @@ public interface UserVmManager extends Manager, VirtualMachineManager
* @param diskOffering the disk offering for the root disk (deploying from ISO) or the data disk (deploying from a normal template)
* @return UserVmVO if created; null if not.
*/
- UserVmVO createVirtualMachine(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List avoids, long startEventId, long size) throws InsufficientStorageCapacityException, InternalErrorException, ResourceAllocationException;
+ UserVmVO createVirtualMachine(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String userData, List avoids, long startEventId, long size) throws InsufficientStorageCapacityException, InternalErrorException, ResourceAllocationException;
- UserVmVO createDirectlyAttachedVM(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List a, List networkGroupVO, long startEventId, long size) throws InternalErrorException, ResourceAllocationException;
+ UserVmVO createDirectlyAttachedVM(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String userData, List a, List networkGroupVO, long startEventId, long size) throws InternalErrorException, ResourceAllocationException;
- UserVmVO createDirectlyAttachedVMExternal(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List a, List networkGroupVO, long startEventId, long size) throws InternalErrorException, ResourceAllocationException;
+ UserVmVO createDirectlyAttachedVMExternal(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String userData, List a, List networkGroupVO, long startEventId, long size) throws InternalErrorException, ResourceAllocationException;
/**
* Destroys one virtual machine
@@ -219,5 +219,18 @@ public interface UserVmManager extends Manager, VirtualMachineManager
* @param userVm
*/
void releaseGuestIpAddress(UserVmVO userVm);
+
+ /**
+ * Creates a vm group.
+ * @param name - name of the group
+ * @param accountId - accountId
+ */
+ InstanceGroupVO createVmGroup(String name, Long accountId);
+
+ boolean deleteVmGroup(long groupId);
+
+ boolean addInstanceToGroup(long userVmId, String group);
+
+ InstanceGroupVO getGroupForVm(long vmId);
}
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 2e116761556..1efdbde6783 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -82,8 +82,8 @@ import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.configuration.dao.ResourceLimitDao;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
-import com.cloud.dc.VlanVO;
import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.dc.dao.VlanDao;
@@ -128,18 +128,18 @@ import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.Snapshot;
+import com.cloud.storage.Snapshot.SnapshotType;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePoolVO;
import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.Snapshot.SnapshotType;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.Volume.VolumeType;
+import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.DiskTemplateDao;
import com.cloud.storage.dao.GuestOSCategoryDao;
@@ -150,8 +150,8 @@ import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VolumeDao;
-import com.cloud.template.VirtualMachineTemplate.BootloaderType;
import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.User;
@@ -169,6 +169,7 @@ import com.cloud.utils.component.Inject;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExecutionException;
@@ -177,7 +178,9 @@ import com.cloud.vm.DomainRouter.Role;
import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.InstanceGroupVMMapDao;
import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.InstanceGroupDao;
@Local(value={UserVmManager.class})
public class UserVmManagerImpl implements UserVmManager {
@@ -226,6 +229,8 @@ public class UserVmManagerImpl implements UserVmManager {
@Inject NetworkGroupManager _networkGroupManager;
@Inject ServiceOfferingDao _serviceOfferingDao;
@Inject EventDao _eventDao = null;
+ @Inject InstanceGroupDao _vmGroupDao;
+ @Inject InstanceGroupVMMapDao _groupVMMapDao;
private IpAddrAllocator _IpAllocator;
ScheduledExecutorService _executor = null;
@@ -1401,7 +1406,7 @@ public class UserVmManagerImpl implements UserVmManager {
}
@Override @DB
- public UserVmVO createVirtualMachine(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List avoids, long startEventId, long size) throws InternalErrorException, ResourceAllocationException {
+ public UserVmVO createVirtualMachine(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String userData, List avoids, long startEventId, long size) throws InternalErrorException, ResourceAllocationException {
long accountId = account.getId();
long dataCenterId = dc.getId();
long serviceOfferingId = offering.getId();
@@ -1475,7 +1480,7 @@ public class UserVmManagerImpl implements UserVmManager {
serviceOfferingId, null, null, router.getGuestNetmask(),
null,null,null,
routerId, pod.first().getId(), dataCenterId,
- offering.getOfferHA(), displayName, group, userData);
+ offering.getOfferHA(), displayName, userData);
if (diskOffering != null) {
vm.setMirroredVols(diskOffering.isMirrored());
@@ -2170,6 +2175,7 @@ public class UserVmManagerImpl implements UserVmManager {
_vmDao.remove(vm.getId());
_networkGroupManager.removeInstanceFromGroups(vm.getId());
+ removeInstanceFromGroup(vm.getId());
s_logger.debug("vm is destroyed");
} catch (Exception e) {
@@ -2588,7 +2594,7 @@ public class UserVmManagerImpl implements UserVmManager {
@DB
@Override
- public UserVmVO createDirectlyAttachedVM(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List a, List networkGroups, long startEventId, long size) throws InternalErrorException, ResourceAllocationException {
+ public UserVmVO createDirectlyAttachedVM(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String userData, List a, List networkGroups, long startEventId, long size) throws InternalErrorException, ResourceAllocationException {
long accountId = account.getId();
long dataCenterId = dc.getId();
@@ -2698,7 +2704,7 @@ public class UserVmManagerImpl implements UserVmManager {
serviceOfferingId, guestMacAddress, guestIp, guestVlan.getVlanNetmask(),
null, externalMacAddress, externalVlanDbId,
routerId, pod.first().getId(), dataCenterId,
- offering.getOfferHA(), displayName, group, userData);
+ offering.getOfferHA(), displayName, userData);
if (diskOffering != null) {
vm.setMirroredVols(diskOffering.isMirrored());
@@ -2790,7 +2796,7 @@ public class UserVmManagerImpl implements UserVmManager {
@DB
@Override
- public UserVmVO createDirectlyAttachedVMExternal(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List a, List networkGroups, long startEventId, long size) throws InternalErrorException, ResourceAllocationException {
+ public UserVmVO createDirectlyAttachedVMExternal(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String userData, List a, List networkGroups, long startEventId, long size) throws InternalErrorException, ResourceAllocationException {
long accountId = account.getId();
long dataCenterId = dc.getId();
long serviceOfferingId = offering.getId();
@@ -2858,7 +2864,7 @@ public class UserVmManagerImpl implements UserVmManager {
serviceOfferingId, guestMacAddress, publicIpAddr, publicIpNetMask,
null, externalMacAddress, null,
routerId, pod.first().getId(), dataCenterId,
- offering.getOfferHA(), displayName, group, userData);
+ offering.getOfferHA(), displayName, userData);
if (diskOffering != null) {
vm.setMirroredVols(diskOffering.isMirrored());
@@ -2971,4 +2977,133 @@ public class UserVmManagerImpl implements UserVmManager {
}
}
}
+
+ @DB
+ @Override
+ public InstanceGroupVO createVmGroup(String name, Long accountId) {
+ final Transaction txn = Transaction.currentTxn();
+ AccountVO account = null;
+ txn.start();
+ try {
+ account = _accountDao.acquire(accountId); //to ensure duplicate vm group names are not created.
+ if (account == null) {
+ s_logger.warn("Failed to acquire lock on account");
+ return null;
+ }
+ InstanceGroupVO group = _vmGroupDao.findByAccountAndName(accountId, name);
+ if (group == null){
+ group = new InstanceGroupVO(name, accountId);
+ group = _vmGroupDao.persist(group);
+ }
+ return group;
+ } finally {
+ if (account != null) {
+ _accountDao.release(accountId);
+ }
+ txn.commit();
+ }
+ }
+
+ @Override
+ public boolean deleteVmGroup(long groupId){
+
+ //delete all the mappings from group_vm_map table
+ List groupVmMaps = _groupVMMapDao.listByGroupId(groupId);
+ for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
+ SearchCriteria sc = _groupVMMapDao.createSearchCriteria();
+ sc.addAnd("instanceId", SearchCriteria.Op.EQ, groupMap.getInstanceId());
+ _groupVMMapDao.expunge(sc);
+ }
+
+ if (_vmGroupDao.remove(groupId)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ @DB
+ public boolean addInstanceToGroup(long userVmId, String groupName) {
+
+ UserVmVO vm = _vmDao.findById(userVmId);
+
+ InstanceGroupVO group = _vmGroupDao.findByAccountAndName(vm.getAccountId(), groupName);
+ //Create vm group if the group doesn't exist for this account
+ if (group == null) {
+ group = createVmGroup(groupName, vm.getAccountId());
+ }
+
+ if (group != null) {
+ final Transaction txn = Transaction.currentTxn();
+ txn.start();
+ UserVm userVm = _vmDao.acquire(userVmId);
+ if (userVm == null) {
+ s_logger.warn("Failed to acquire lock on user vm id=" + userVmId);
+ }
+ try {
+ //don't let the group be deleted when we are assigning vm to it.
+ InstanceGroupVO ngrpLock = _vmGroupDao.lock(group.getId(), false);
+ if (ngrpLock == null) {
+ s_logger.warn("Failed to acquire lock on vm group id=" + group.getId() + " name=" + group.getName());
+ txn.rollback();
+ return false;
+ }
+
+ //Currently don't allow to assign a vm to more than one group
+ if (_groupVMMapDao.listByInstanceId(userVmId) != null) {
+ //Delete all mappings from group_vm_map table
+ List groupVmMaps = _groupVMMapDao.listByInstanceId(userVmId);
+ for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
+ SearchCriteria sc = _groupVMMapDao.createSearchCriteria();
+ sc.addAnd("instanceId", SearchCriteria.Op.EQ, groupMap.getInstanceId());
+ _groupVMMapDao.expunge(sc);
+ }
+ }
+ InstanceGroupVMMapVO groupVmMapVO = new InstanceGroupVMMapVO(group.getId(), userVmId);
+ _groupVMMapDao.persist(groupVmMapVO);
+
+ txn.commit();
+ return true;
+ } finally {
+ if (userVm != null) {
+ _vmDao.release(userVmId);
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public InstanceGroupVO getGroupForVm(long vmId) {
+ //TODO - in future releases vm can be assigned to multiple groups; but currently return just one group per vm
+ try {
+ List groupsToVmMap = _groupVMMapDao.listByInstanceId(vmId);
+
+ if(groupsToVmMap != null && groupsToVmMap.size() != 0){
+ InstanceGroupVO group = _vmGroupDao.findById(groupsToVmMap.get(0).getGroupId());
+ return group;
+ } else {
+ return null;
+ }
+ }
+ catch (Exception e){
+ s_logger.warn("Error trying to get group for a vm: "+e);
+ return null;
+ }
+ }
+
+ public void removeInstanceFromGroup(long vmId) {
+ try {
+ List groupVmMaps = _groupVMMapDao.listByInstanceId(vmId);
+ for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
+ SearchCriteria sc = _groupVMMapDao.createSearchCriteria();
+ sc.addAnd("instanceId", SearchCriteria.Op.EQ, groupMap.getInstanceId());
+ _groupVMMapDao.expunge(sc);
+ }
+ } catch (Exception e){
+ s_logger.warn("Error trying to remove vm from group: "+e);
+ }
+ }
+
}
diff --git a/setup/db/create-index-fk.sql b/setup/db/create-index-fk.sql
index 666aae7ad3d..5b80a2cabc6 100644
--- a/setup/db/create-index-fk.sql
+++ b/setup/db/create-index-fk.sql
@@ -253,3 +253,8 @@ ALTER TABLE `cloud`.`op_nwgrp_work` ADD INDEX `i_op_nwgrp_work__mgmt_server_id`(
ALTER TABLE `cloud`.`host_master` ADD UNIQUE `i_host_master__service_address`(`service_address`);
+ALTER TABLE `cloud`.`instance_group` ADD CONSTRAINT `fk_instance_group__account_id` FOREIGN KEY `fk_instance_group__account_id` (`account_id`) REFERENCES `account` (`id`);
+
+ALTER TABLE `cloud`.`instance_group_vm_map` ADD CONSTRAINT `fk_instance_group_vm_map___group_id` FOREIGN KEY `fk_instance_group_vm_map___group_id` (`group_id`) REFERENCES `instance_group` (`id`) ON DELETE CASCADE;
+ALTER TABLE `cloud`.`instance_group_vm_map` ADD CONSTRAINT `fk_instance_group_vm_map___instance_id` FOREIGN KEY `fk_instance_group_vm_map___instance_id` (`instance_id`) REFERENCES `user_vm` (`id`) ON DELETE CASCADE;
+
diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql
index d636a34afb2..c9b225ca384 100755
--- a/setup/db/create-schema.sql
+++ b/setup/db/create-schema.sql
@@ -79,6 +79,8 @@ DROP TABLE IF EXISTS `cloud`.`network_offerings`;
DROP TABLE IF EXISTS `cloud`.`host_master`;
DROP TABLE IF EXISTS `cloud`.`hypervisor_properties`;
DROP TABLE IF EXISTS `cloud`.`account_network_ref`;
+DROP TABLE IF EXISTS `cloud`.`instance_group`;
+DROP TABLE IF EXISTS `cloud`.`instance_group_vm_map`;
CREATE TABLE `cloud`.`hypervsior_properties` (
`hypervisor` varchar(32) NOT NULL UNIQUE COMMENT 'hypervisor type',
@@ -582,7 +584,6 @@ CREATE TABLE `cloud`.`vm_instance` (
CREATE TABLE `cloud`.`user_vm` (
`id` bigint unsigned UNIQUE NOT NULL,
- `group` varchar(255),
`iso_id` bigint unsigned,
`display_name` varchar(255),
`domain_router_id` bigint unsigned COMMENT 'router id',
@@ -1088,4 +1089,20 @@ CREATE TABLE `cloud`.`host_master` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE `cloud`.`instance_group` (
+ `id` bigint unsigned NOT NULL UNIQUE auto_increment,
+ `account_id` bigint unsigned NOT NULL COMMENT 'owner. foreign key to account table',
+ `name` varchar(255) NOT NULL,
+ `removed` datetime COMMENT 'date the group was removed',
+ `created` datetime COMMENT 'date the group was created',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+
+CREATE TABLE `cloud`.`instance_group_vm_map` (
+ `id` bigint unsigned NOT NULL auto_increment,
+ `group_id` bigint unsigned NOT NULL,
+ `instance_id` bigint unsigned NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
SET foreign_key_checks = 1;