You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ro...@apache.org on 2021/07/15 07:19:57 UTC
[cloudstack] branch 4.15 updated: configdrive: fix some failures in
tests/component/test_configdrive.py (#5144)
This is an automated email from the ASF dual-hosted git repository.
rohit pushed a commit to branch 4.15
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.15 by this push:
new cf0f1fe configdrive: fix some failures in tests/component/test_configdrive.py (#5144)
cf0f1fe is described below
commit cf0f1feb5e862b61b5b296240988ce14c7a91425
Author: Wei Zhou <57...@users.noreply.github.com>
AuthorDate: Thu Jul 15 09:19:37 2021 +0200
configdrive: fix some failures in tests/component/test_configdrive.py (#5144)
* server: fix failed to apply userdata when enable static nat
* server: fix cannot expunge vm as applyUserdata fails
* configdrive: fix ISO is not recognized when plug a new nic
* configdrive: detach and attach configdrive ISO as it is changed when plug a new nic or migrate vm
* configdrive test: (1) password file does not exists in recreated ISO; (2) vm hostname should be changed after migration
* configdrive: use centos55 template with sshkey and configdrive support
* configdrive: disklabel is 'config-2' for configdrive ISO
* configdrive: use copy for configdrive ISO and move for other template/volume/iso
* configdrive: use public-keys.txt
* configdrive test: fix (1) update_template ; (2) ssh into vm by keypair
---
.../kvm/resource/LibvirtComputingResource.java | 28 +++++++++++++++++++
.../wrapper/LibvirtMigrateCommandWrapper.java | 5 ++++
.../wrapper/LibvirtPlugNicCommandWrapper.java | 4 +++
scripts/storage/secondary/createvolume.sh | 16 ++++++++++-
.../com/cloud/network/rules/RulesManagerImpl.java | 19 +++++++------
setup/bindir/cloud-set-guest-sshkey-configdrive.in | 4 +--
test/integration/component/test_configdrive.py | 32 ++++++++++++++--------
7 files changed, 85 insertions(+), 23 deletions(-)
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index a7d5ee3..bd734c1 100644
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -303,6 +303,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected String _agentHooksVmOnStopScript = "libvirt-vm-state-change.groovy";
protected String _agentHooksVmOnStopMethod = "onStop";
+ private static final String CONFIG_DRIVE_ISO_DISK_LABEL = "hdd";
+ private static final int CONFIG_DRIVE_ISO_DEVICE_ID = 4;
protected File _qemuSocketsPath;
private final String _qemuGuestAgentSocketName = "org.qemu.guest_agent.0";
@@ -2756,6 +2758,32 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return _storagePoolMgr;
}
+ public void detachAndAttachConfigDriveISO(final Connect conn, final String vmName) {
+ // detach and re-attach configdrive ISO
+ List<DiskDef> disks = getDisks(conn, vmName);
+ DiskDef configdrive = null;
+ for (DiskDef disk : disks) {
+ if (disk.getDeviceType() == DiskDef.DeviceType.CDROM && disk.getDiskLabel() == CONFIG_DRIVE_ISO_DISK_LABEL) {
+ configdrive = disk;
+ }
+ }
+ if (configdrive != null) {
+ try {
+ String result = attachOrDetachISO(conn, vmName, configdrive.getDiskPath(), false, CONFIG_DRIVE_ISO_DEVICE_ID);
+ if (result != null) {
+ s_logger.warn("Detach ConfigDrive ISO with result: " + result);
+ }
+ result = attachOrDetachISO(conn, vmName, configdrive.getDiskPath(), true, CONFIG_DRIVE_ISO_DEVICE_ID);
+ if (result != null) {
+ s_logger.warn("Attach ConfigDrive ISO with result: " + result);
+ }
+ } catch (final LibvirtException | InternalErrorException | URISyntaxException e) {
+ final String msg = "Detach and attach ConfigDrive ISO failed due to " + e.toString();
+ s_logger.warn(msg, e);
+ }
+ }
+ }
+
public synchronized String attachOrDetachISO(final Connect conn, final String vmName, String isoPath, final boolean isAttach, final Integer diskSeq) throws LibvirtException, URISyntaxException,
InternalErrorException {
final DiskDef iso = new DiskDef();
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
index 841eadf..60261a4 100644
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
@@ -76,6 +76,7 @@ import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ResourceWrapper;
import com.cloud.utils.Ternary;
import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine;
import com.google.common.base.Strings;
@ResourceWrapper(handles = MigrateCommand.class)
@@ -180,6 +181,10 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCo
dconn = libvirtUtilitiesHelper.retrieveQemuConnection(destinationUri);
+ if (to.getType() == VirtualMachine.Type.User) {
+ libvirtComputingResource.detachAndAttachConfigDriveISO(conn, vmName);
+ }
+
//run migration in thread so we can monitor it
s_logger.info("Live migration of instance " + vmName + " initiated to destination host: " + dconn.getURI());
final ExecutorService executor = Executors.newFixedThreadPool(1);
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java
index 553a71a..ca78c71 100644
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java
@@ -72,6 +72,10 @@ public final class LibvirtPlugNicCommandWrapper extends CommandWrapper<PlugNicCo
libvirtComputingResource.applyDefaultNetworkRulesOnNic(conn, vmName, vmId, nic, false, false);
}
+ if (vmType == VirtualMachine.Type.User) {
+ libvirtComputingResource.detachAndAttachConfigDriveISO(conn, vmName);
+ }
+
return new PlugNicAnswer(command, true, "success");
} catch (final LibvirtException e) {
final String msg = " Plug Nic failed due to " + e.toString();
diff --git a/scripts/storage/secondary/createvolume.sh b/scripts/storage/secondary/createvolume.sh
index 12f73eb..14bbee4 100755
--- a/scripts/storage/secondary/createvolume.sh
+++ b/scripts/storage/secondary/createvolume.sh
@@ -139,6 +139,16 @@ create_from_file() {
}
+copy_from_file() {
+ local tmpltfs=$1
+ local tmpltimg=$2
+ local tmpltname=$3
+
+ [ -n "$verbose" ] && echo "Copying to $tmpltfs/$tmpltname...could take a while" >&2
+ cp -rf $tmpltimg /$tmpltfs/$tmpltname
+ rm -rf $tmpltimg
+}
+
tflag=
nflag=
fflag=
@@ -228,7 +238,11 @@ fi
imgsize=$(ls -l $tmpltimg2| awk -F" " '{print $5}')
-create_from_file $tmpltfs $tmpltimg2 $tmpltname
+if [ "$descr" = "configDrive" ] && [ "$Sflag" = "" ];then
+ copy_from_file $tmpltfs $tmpltimg2 $tmpltname
+else
+ create_from_file $tmpltfs $tmpltimg2 $tmpltname
+fi
touch /$tmpltfs/volume.properties
rollback_if_needed $tmpltfs $? "Failed to create volume.properties file"
diff --git a/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java b/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java
index de56774..b743863 100644
--- a/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java
@@ -630,20 +630,23 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
}
protected void applyUserData(long vmId, Network network, Nic guestNic) throws ResourceUnavailableException {
- UserVmVO vm = _vmDao.findById(vmId);
- VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
- NicProfile nicProfile = new NicProfile(guestNic, network, null, null, null,
- _networkModel.isSecurityGroupSupportedInNetwork(network),
- _networkModel.getNetworkTag(template.getHypervisorType(), network));
- VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vm);
UserDataServiceProvider element = _networkModel.getUserDataUpdateProvider(network);
if (element == null) {
s_logger.error("Can't find network element for " + Service.UserData.getName() + " provider needed for UserData update");
} else {
- boolean result = element.saveUserData(network, nicProfile, vmProfile);
- if (!result) {
+ UserVmVO vm = _vmDao.findById(vmId);
+ try {
+ VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
+ NicProfile nicProfile = new NicProfile(guestNic, network, null, null, null,
+ _networkModel.isSecurityGroupSupportedInNetwork(network),
+ _networkModel.getNetworkTag(template.getHypervisorType(), network));
+ VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vm);
+ if (!element.saveUserData(network, nicProfile, vmProfile)) {
s_logger.error("Failed to update userdata for vm " + vm + " and nic " + guestNic);
}
+ } catch (Exception e) {
+ s_logger.error("Failed to update userdata for vm " + vm + " and nic " + guestNic + " due to " + e.getMessage(), e);
+ }
}
}
diff --git a/setup/bindir/cloud-set-guest-sshkey-configdrive.in b/setup/bindir/cloud-set-guest-sshkey-configdrive.in
index 31dc6df..7294871 100644
--- a/setup/bindir/cloud-set-guest-sshkey-configdrive.in
+++ b/setup/bindir/cloud-set-guest-sshkey-configdrive.in
@@ -31,7 +31,7 @@ mountdir=$(mktemp -d)
# If lable name is other than config, please change the below line as required
DefaultDisk=/dev/disk/by-label/config-2
-SSHKey_File=$mountdir/cloudstack/metadata/public_keys.txt
+SSHKey_File=$mountdir/cloudstack/metadata/public-keys.txt
keys_received=0
function prepare_mount
@@ -44,7 +44,7 @@ function prepare_mount
if [ -e $DefaultDisk ]; then
Disk=$DefaultDisk
else
- BLOCK_DEVICE=$(blkid -t LABEL='config' /dev/hd? /dev/sd? /dev/xvd? /dev/vd? -o device)
+ BLOCK_DEVICE=$(blkid -t LABEL='config-2' /dev/hd? /dev/sd? /dev/xvd? /dev/vd? -o device)
if [ -n $BLOCK_DEVICE ]; then
Disk=$BLOCK_DEVICE
else
diff --git a/test/integration/component/test_configdrive.py b/test/integration/component/test_configdrive.py
index 38a9a7d..fb2fb43 100644
--- a/test/integration/component/test_configdrive.py
+++ b/test/integration/component/test_configdrive.py
@@ -53,7 +53,8 @@ from marvin.lib.base import (Account,
Hypervisor, Template)
from marvin.lib.common import (get_domain,
get_template,
- get_zone, get_test_template,
+ get_zone,
+ get_test_template,
is_config_suitable)
from marvin.lib.utils import random_gen
# Import System Modules
@@ -104,12 +105,12 @@ class Services:
self.services = {
"test_templates": {
"kvm": {
- "name": "Centos-5.5-configdrive",
- "displaytext": "ConfigDrive enabled CentOS",
+ "name": "Centos-5.5-sshkey-and-configdrive",
+ "displaytext": "SSHkey and ConfigDrive enabled CentOS",
"format": "qcow2",
"hypervisor": "kvm",
"ostype": "CentOS 5.5 (64-bit)",
- "url": "http://people.apache.org/~fmaximus/centos55-extended.qcow2.bz2",
+ "url": "http://people.apache.org/~weizhou/centos55-sshkey-configdrive.qcow2.bz2",
"requireshvm": "False",
"ispublic": "True",
"isextractable": "True"
@@ -653,8 +654,7 @@ class ConfigDriveUtils:
orig_state = self.template.passwordenabled
self.debug("Updating guest VM template to password enabled "
"from %s to %s" % (orig_state, new_state))
- if orig_state != new_state:
- self.update_template(passwordenabled=new_state)
+ self.update_template(passwordenabled=new_state)
self.assertEqual(self.template.passwordenabled, new_state,
"Guest VM template is not password enabled")
return orig_state
@@ -850,7 +850,7 @@ class ConfigDriveUtils:
self.debug("SSHing into the VM %s" % vm.name)
- ssh = self.ssh_into_VM(vm, public_ip, reconnect=reconnect)
+ ssh = self.ssh_into_VM(vm, public_ip, reconnect=reconnect, keypair=vm.key_pair)
d = {x.name: x for x in ssh.logger.handlers}
ssh.logger.handlers = list(d.values())
@@ -974,6 +974,7 @@ class ConfigDriveUtils:
vm.add_nic(self.api_client, network.id)
self.debug("Added NIC in VM with ID - %s and network with ID - %s"
% (vm.id, network.id))
+ vm.password_test = ConfigDriveUtils.PasswordTest(expect_pw=False)
def unplug_nic(self, vm, network):
nic = self._find_nic(vm, network)
@@ -1530,12 +1531,14 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
self.debug("SSH into VM with ID - %s on public IP address - %s" %
(vm.id, public_ip.ipaddress.ipaddress))
tries = 1 if negative_test else 3
+ private_key_file_location = keypair.private_key_file if keypair else None
@retry(tries=tries)
def retry_ssh():
ssh_client = vm.get_ssh_client(
ipaddress=public_ip.ipaddress.ipaddress,
reconnect=reconnect,
+ keyPairFileLocation=private_key_file_location,
retries=3 if negative_test else 30
)
self.debug("Successful to SSH into VM with ID - %s on "
@@ -1702,6 +1705,7 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
"%s to Host: %s" % (vm.id, host.id))
try:
vm.migrate(self.api_client, hostid=host.id)
+ vm.password_test = ConfigDriveUtils.PasswordTest(expect_pw=False)
except Exception as e:
self.fail("Failed to migrate instance, %s" % e)
self.debug("Migrated VM with ID: "
@@ -1917,7 +1921,8 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
# =====================================================================
self.debug("+++ Scenario: "
"update userdata and reset password after migrate")
- self.migrate_VM(vm1)
+ host = self.migrate_VM(vm1)
+ vm1.hostname = host.name
self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)
self.debug("Updating userdata after migrating VM - %s" % vm1.name)
self.update_and_validate_userdata(vm1, "hello after migrate",
@@ -1955,7 +1960,7 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
# =====================================================================
self.debug("+++ Scenario: "
"Update Userdata on a VM that is not password enabled")
- self.update_template(passwordenabled=False)
+ self.given_template_password_enabled_is(False)
vm1 = self.when_I_deploy_a_vm_with_keypair_in(network1)
public_ip_1 = \
@@ -2112,7 +2117,8 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
# =====================================================================
self.debug("+++ Scenario: "
"update userdata and reset password after migrate")
- self.migrate_VM(vm)
+ host = self.migrate_VM(vm)
+ vm.hostname = host.name
self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)
self.update_and_validate_userdata(vm, "hello migrate", public_ip_1)
@@ -2150,7 +2156,7 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
self.debug("+++ Scenario: "
"Update Userdata on a VM that is not password enabled")
- self.update_template(passwordenabled=False)
+ self.given_template_password_enabled_is(False)
vm = self.when_I_deploy_a_vm(network1,
keypair=self.keypair.name)
@@ -2285,7 +2291,7 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
self.delete(vm1, expunge=True)
self.given_config_drive_provider_is("Enabled")
- self.update_template(passwordenabled=False)
+ self.given_template_password_enabled_is(False)
vm1 = self.create_VM(
[shared_network.network],
@@ -2362,6 +2368,7 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
self.debug("+++Deploy VM in the created Isolated network "
"with user data provider as configdrive")
+ self.given_template_password_enabled_is(True)
vm1 = self.when_I_deploy_a_vm(network1)
public_ip_1 = self.when_I_create_a_static_nat_ip_to(vm1, network1)
@@ -2476,6 +2483,7 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
# =====================================================================
self.debug("+++ Scenario: "
"Deploy VM in the Tier 1 with user data")
+ self.given_template_password_enabled_is(True)
vm = self.when_I_deploy_a_vm(network1)
public_ip_1 = self.when_I_create_a_static_nat_ip_to(vm, network1)