diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index 3c1d7bb93c6..8714d50bae5 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -50,6 +50,7 @@ public class ApiConstants { public static final String CERTIFICATE_CHAIN = "certchain"; public static final String CERTIFICATE_FINGERPRINT = "fingerprint"; public static final String CERTIFICATE_ID = "certid"; + public static final String COPY_IMAGE_TAGS = "copyimagetags"; public static final String CSR = "csr"; public static final String PRIVATE_KEY = "privatekey"; public static final String DOMAIN_SUFFIX = "domainsuffix"; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java index 0874b4e8a8e..3d14b8998f6 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java @@ -203,6 +203,9 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG @Parameter(name = ApiConstants.EXTRA_CONFIG, type = CommandType.STRING, since = "4.12", description = "an optional URL encoded string that can be passed to the virtual machine upon successful deployment", length = 5120) private String extraConfig; + @Parameter(name = ApiConstants.COPY_IMAGE_TAGS, type = CommandType.BOOLEAN, since = "4.13", description = "if true the image tags (if any) will be copied to the VM, default value is false") + private Boolean copyImageTags; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -489,6 +492,10 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG return extraConfig; } + public boolean getCopyImageTags() { + return copyImageTags == null ? false : copyImageTags; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index f3731ab6ffe..e719d6f4f9f 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -223,6 +223,7 @@ import com.cloud.org.Grouping; import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; import com.cloud.server.ManagementService; +import com.cloud.server.ResourceTag; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.service.dao.ServiceOfferingDetailsDao; @@ -251,6 +252,8 @@ import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateApiService; import com.cloud.template.TemplateManager; import com.cloud.template.VirtualMachineTemplate; @@ -477,6 +480,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir private ConfigurationDao _configDao; @Inject private DpdkHelper dpdkHelper; + @Inject + private ResourceTagDao resourceTagDao; private ScheduledExecutorService _executor = null; private ScheduledExecutorService _vmIpFetchExecutor = null; @@ -4958,6 +4963,18 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir addExtraConfig(vm, caller, extraConfig); } + if (cmd.getCopyImageTags()) { + VMTemplateVO templateOrIso = _templateDao.findById(templateId); + if (templateOrIso != null) { + final ResourceTag.ResourceObjectType templateType = (templateOrIso.getFormat() == ImageFormat.ISO) ? ResourceTag.ResourceObjectType.ISO : ResourceTag.ResourceObjectType.Template; + final List resourceTags = resourceTagDao.listBy(templateId, templateType); + for (ResourceTag resourceTag : resourceTags) { + final ResourceTagVO copyTag = new ResourceTagVO(resourceTag.getKey(), resourceTag.getValue(), resourceTag.getAccountId(), resourceTag.getDomainId(), vm.getId(), ResourceTag.ResourceObjectType.UserVm, resourceTag.getCustomer(), vm.getUuid()); + resourceTagDao.persist(copyTag); + } + } + } + return vm; }