Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 4416B200BE8 for ; Thu, 8 Dec 2016 12:47:50 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 42F2F160B27; Thu, 8 Dec 2016 11:47:50 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 29EFB160B1E for ; Thu, 8 Dec 2016 12:47:49 +0100 (CET) Received: (qmail 86999 invoked by uid 500); 8 Dec 2016 11:47:48 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 86980 invoked by uid 99); 8 Dec 2016 11:47:48 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 08 Dec 2016 11:47:48 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 2C0B8E36E0; Thu, 8 Dec 2016 11:47:48 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: bhaisaab@apache.org To: commits@cloudstack.apache.org Date: Thu, 08 Dec 2016 11:47:48 -0000 Message-Id: <71e6a0b5b706411b90f6599af2da21bb@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [1/6] git commit: updated refs/heads/4.9 to 26a2c9e archived-at: Thu, 08 Dec 2016 11:47:50 -0000 Repository: cloudstack Updated Branches: refs/heads/4.9 de7a06efe -> 26a2c9ee9 CLOUDSTACK-9637: Template create from snapshot does not populate vm_template_details Summary: Retrieve and add source template details to VMTemplateVO. Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/545a214a Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/545a214a Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/545a214a Branch: refs/heads/4.9 Commit: 545a214a4229daad5fa4cc66a512979707dbe747 Parents: f231c8c Author: Sudhansu Authored: Fri Dec 2 00:08:12 2016 +0530 Committer: Sudhansu Committed: Sat Dec 3 18:45:08 2016 +0530 ---------------------------------------------------------------------- .../com/cloud/template/TemplateManagerImpl.java | 10 +- ...template_from_snapshot_with_template_details | 386 +++++++++++++++++++ 2 files changed, 395 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/545a214a/server/src/com/cloud/template/TemplateManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index c03db35..ae1a649 100644 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1737,6 +1737,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, // Increment the number of templates if (template != null) { Map details = new HashMap(); + + if (sourceTemplateId != null) { + VMTemplateVO sourceTemplate = _tmpltDao.findById(sourceTemplateId); + if(sourceTemplate != null){ + details.putAll(sourceTemplate.getDetails()); + } + } + if (volume != null) { Long vmId = volume.getInstanceId(); if (vmId != null) { @@ -1903,7 +1911,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, sortKey == null && isDynamicallyScalable == null && isRoutingTemplate == null && - details == null); + details == null); if (!updateNeeded) { return template; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/545a214a/test/integration/component/test_template_from_snapshot_with_template_details ---------------------------------------------------------------------- diff --git a/test/integration/component/test_template_from_snapshot_with_template_details b/test/integration/component/test_template_from_snapshot_with_template_details new file mode 100644 index 0000000..f8269e2 --- /dev/null +++ b/test/integration/component/test_template_from_snapshot_with_template_details @@ -0,0 +1,386 @@ +# 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. +""" P1 tests for Templates +""" +# Import Local Modules +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.cloudstackAPI import listZones +from marvin.lib.utils import (cleanup_resources) +from marvin.lib.base import (Account, + Domain, + Template, + ServiceOffering, + VirtualMachine, + Snapshot, + Volume) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + get_builtin_template_info, + list_volumes, + list_snapshots) +# Import System modules +import time + + +class Services: + + """Test Templates Services + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + }, + "testdomain": {"name": "test"}, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, # in MHz + "memory": 128, # In MBs + }, + "disk_offering": { + "displaytext": "Small", + "name": "Small", + "disksize": 1 + }, + "virtual_machine": { + "displayname": "testVM", + "hypervisor": 'XenServer', + "protocol": 'TCP', + "ssh_port": 22, + "username": "root", + "password": "password", + "privateport": 22, + "publicport": 22, + }, + "volume": { + "diskname": "Test Volume", + }, + "templates": { + # Configs for different Template formats + # For Eg. raw image, zip etc + 0: { + "displaytext": "Public Template", + "name": "Public template", + "ostype": 'CentOS 5.3 (64-bit)', + "url": "http://download.cloud.com/releases/2.0.0/UbuntuServer-10-04-64bit.vhd.bz2", + "hypervisor": 'XenServer', + "format": 'VHD', + "isfeatured": True, + "ispublic": True, + "isextractable": True, + }, + }, + "template": { + "displaytext": "Cent OS Template", + "name": "Cent OS Template", + "ostype": 'CentOS 5.3 (64-bit)', + "templatefilter": 'self', + "isfeatured": True, + "ispublic": True, + }, + "templatefilter": 'self', + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + "timeout": 10, + } + + +class TestCreateTemplate(cloudstackTestCase): + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + + if self.unsupportedHypervisor: + self.skipTest( + "Template creation from root volume is not supported in LXC") + return + + def tearDown(self): + try: + # Clean up, terminate the created templates + cleanup_resources(self.apiclient, self.cleanup) + + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @classmethod + def setUpClass(cls): + cls.testClient = super(TestCreateTemplate, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.services['mode'] = cls.zone.networktype + cls._cleanup = [] + cls.unsupportedHypervisor = False + cls.hypervisor = cls.testClient.getHypervisorInfo() + if cls.hypervisor.lower() in ['lxc']: + cls.unsupportedHypervisor = True + return + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + cls._cleanup.append(cls.account) + cls.services["account"] = cls.account.name + return + + @classmethod + def tearDownClass(cls): + try: + cls.api_client = super( + TestCreateTemplate, + cls).getClsTestClient().getApiClient() + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + return + @attr(tags=["advanced", "advancedns"], required_hardware="true") + def test_01_create_template_snampshot(self): + + + builtin_info = get_builtin_template_info(self.apiclient, self.zone.id) + self.services["templates"][0]["url"] = builtin_info[0] + self.services["templates"][0]["hypervisor"] = builtin_info[1] + self.services["templates"][0]["format"] = builtin_info[2] + + # Register new template + template = Template.register( + self.apiclient, + self.services["templates"][0], + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid, + hypervisor=self.hypervisor, + details=[{"keyboard":"us","nicAdapter":"e1000","rootDiskController":"scsi"}] + ) + self.debug( + "Registered a template of format: %s with ID: %s" % ( + self.services["templates"][0]["format"], + template.id + )) + # Wait for template to download + template.download(self.apiclient) + self.cleanup.append(template) + + # Wait for template status to be changed across + time.sleep(self.services["sleep"]) + timeout = self.services["timeout"] + while True: + list_template_response = Template.list( + self.apiclient, + templatefilter='all', + id=template.id, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid) + if isinstance(list_template_response, list): + break + elif timeout == 0: + raise Exception("List template failed!") + + time.sleep(5) + timeout = timeout - 1 + # Verify template response to check whether template added successfully + self.assertEqual( + isinstance(list_template_response, list), + True, + "Check for list template response return valid data" + ) + + self.assertNotEqual( + len(list_template_response), + 0, + "Check template available in List Templates" + ) + + template_response = list_template_response[0] + self.assertEqual( + template_response.isready, + True, + "Template state is not ready, it is %s" % template_response.isready + ) + + self.assertIsNotNone( + template_response.details, + "Template details is %s" % template_response.details + ) + + # Deploy new virtual machine using template + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + templateid=template.id, + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + mode=self.services["mode"] + ) + self.debug("creating an instance with template ID: %s" % template.id) + vm_response = VirtualMachine.list(self.apiclient, + id=virtual_machine.id, + account=self.account.name, + domainid=self.account.domainid) + self.assertEqual( + isinstance(vm_response, list), + True, + "Check for list VMs response after VM deployment" + ) + # Verify VM response to check whether VM deployment was successful + self.assertNotEqual( + len(vm_response), + 0, + "Check VMs available in List VMs response" + ) + vm = vm_response[0] + self.assertEqual( + vm.state, + 'Running', + "Check the state of VM created from Template" + ) + + volumes = list_volumes( + self.apiclient, + virtualmachineid=vm.id, + type='ROOT', + listall=True + ) + + snapshot = Snapshot.create( + self.apiclient, + volumes[0].id, + account=self.account.name, + domainid=self.account.domainid + ) + time.sleep(self.services["sleep"]) + self.cleanup.append(snapshot) + self.debug("Snapshot created: ID - %s" % snapshot.id) + + snapshots = list_snapshots( + self.apiclient, + id=snapshot.id + ) + self.assertEqual( + isinstance(snapshots, list), + True, + "Check list response returns a valid list" + ) + + self.assertNotEqual( + snapshots, + None, + "Check if result exists in list item call" + ) + self.assertEqual( + snapshots[0].id, + snapshot.id, + "Check resource id in list resources call" + ) + + virtual_machine.delete(self.apiclient, expunge=False) + + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + + self.assertNotEqual( + len(list_vm_response), + 0, + "Check VM avaliable in List Virtual Machines" + ) + + list_vm_response = VirtualMachine.list( + self.apiclient, + id=self.small_virtual_machine.id + ) + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + + self.assertNotEqual( + len(list_vm_response), + 0, + "Check VM avaliable in List Virtual Machines" + ) + + template = Template.create_from_snapshot( + self.apiclient, + snapshot, + self.services["template"] + ) + self.cleanup.append(template) + # Verify created template + templates = Template.list( + self.apiclient , + templatefilter=self.services["template"]["templatefilter"], + id=template.id + ) + self.assertNotEqual( + templates, + None, + "Check if result exists in list item call" + ) + + self.assertEqual( + templates[0].id, + template.id, + "Check new template id in list resources call" + ) + + + self.assertIsNotNone( + templates[0].details, + "Template details is %s" % template_response.details + ) + + return