This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch 4.20
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.20 by this push:
     new 011fced91ed ehancement: add password to configdrive vendor_data.json 
(#10061)
011fced91ed is described below

commit 011fced91ed4cdd6c839abf977fd2b0c8c27a544
Author: Phsm Qwerty <p...@users.noreply.github.com>
AuthorDate: Mon May 12 16:16:54 2025 +0200

    ehancement: add password to configdrive vendor_data.json (#10061)
---
 .../storage/configdrive/ConfigDriveBuilder.java    | 43 +++++++++++++++++++++-
 .../configdrive/ConfigDriveBuilderTest.java        | 20 +++++-----
 2 files changed, 51 insertions(+), 12 deletions(-)

diff --git 
a/engine/storage/configdrive/src/main/java/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java
 
b/engine/storage/configdrive/src/main/java/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java
index 58cc341a87b..d57afbb0a23 100644
--- 
a/engine/storage/configdrive/src/main/java/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java
+++ 
b/engine/storage/configdrive/src/main/java/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java
@@ -126,7 +126,26 @@ public class ConfigDriveBuilder {
 
             File openStackFolder = new File(tempDirName + 
ConfigDrive.openStackConfigDriveName);
 
-            writeVendorEmptyJsonFile(openStackFolder);
+            /*
+            Try to find VM password in the vmData.
+            If it is found, then write it into vendor-data.json
+            */
+            String vmPassword = "";
+            for (String[] item : vmData) {
+                String dataType = item[CONFIGDATA_DIR];
+                String fileName = item[CONFIGDATA_FILE];
+                String content = item[CONFIGDATA_CONTENT];
+                if (PASSWORD_FILE.equals(fileName)) {
+                    vmPassword = content;
+                    break;
+                }
+            }
+            if (vmPassword.equals("")) {
+                writeVendorDataJsonFile(openStackFolder);
+            } else {
+                writeVendorDataJsonFile(openStackFolder, vmPassword);
+            }
+
             writeNetworkData(nics, supportedServices, openStackFolder);
             for (NicProfile nic: nics) {
                 if 
(supportedServices.get(nic.getId()).contains(Network.Service.UserData)) {
@@ -253,7 +272,7 @@ public class ConfigDriveBuilder {
      *
      *  If the folder does not exist, and we cannot create it, we throw a 
{@link CloudRuntimeException}.
      */
-    static void writeVendorEmptyJsonFile(File openStackFolder) {
+    static void writeVendorDataJsonFile(File openStackFolder) {
         if (openStackFolder.exists() || openStackFolder.mkdirs()) {
             writeFile(openStackFolder, "vendor_data.json", "{}");
         } else {
@@ -261,6 +280,26 @@ public class ConfigDriveBuilder {
         }
     }
 
+    /**
+     *  Writes vendor data containing Cloudstack-generated password into 
vendor-data.json
+     *
+     *  If the folder does not exist, and we cannot create it, we throw a 
{@link CloudRuntimeException}.
+     */
+    static void writeVendorDataJsonFile(File openStackFolder, String password) 
{
+        if (openStackFolder.exists() || openStackFolder.mkdirs()) {
+            writeFile(
+                openStackFolder,
+                "vendor_data.json",
+                String.format(
+                    "{\"cloud-init\": \"#cloud-config\\npassword: 
%s\\nchpasswd:\\n  expire: False\"}",
+                    password
+                )
+            );
+        } else {
+            throw new CloudRuntimeException("Failed to create folder " + 
openStackFolder);
+        }
+    }
+
     /**
      * Creates the {@link JsonObject} with VM's metadata. The vmData is a list 
of arrays; we expect this list to have the following entries:
      * <ul>
diff --git 
a/engine/storage/configdrive/src/test/java/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java
 
b/engine/storage/configdrive/src/test/java/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java
index 3effdb5ba21..c04ff0a1601 100644
--- 
a/engine/storage/configdrive/src/test/java/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java
+++ 
b/engine/storage/configdrive/src/test/java/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java
@@ -134,7 +134,7 @@ public class ConfigDriveBuilderTest {
     @Test(expected = CloudRuntimeException.class)
     public void buildConfigDriveTestIoException() {
         try (MockedStatic<ConfigDriveBuilder> configDriveBuilderMocked = 
Mockito.mockStatic(ConfigDriveBuilder.class)) {
-            configDriveBuilderMocked.when(() -> 
ConfigDriveBuilder.writeVendorEmptyJsonFile(nullable(File.class))).thenThrow(CloudRuntimeException.class);
+            configDriveBuilderMocked.when(() -> 
ConfigDriveBuilder.writeVendorDataJsonFile(nullable(File.class))).thenThrow(CloudRuntimeException.class);
             Mockito.when(ConfigDriveBuilder.buildConfigDrive(null, new 
ArrayList<>(), "teste", "C:", null, supportedServices)).thenCallRealMethod();
             ConfigDriveBuilder.buildConfigDrive(null, new ArrayList<>(), 
"teste", "C:", null, supportedServices);
         }
@@ -144,7 +144,7 @@ public class ConfigDriveBuilderTest {
     public void buildConfigDriveTest() {
         try (MockedStatic<ConfigDriveBuilder> configDriveBuilderMocked = 
Mockito.mockStatic(ConfigDriveBuilder.class)) {
 
-            configDriveBuilderMocked.when(() -> 
ConfigDriveBuilder.writeVendorEmptyJsonFile(Mockito.any(File.class))).then(invocationOnMock
 -> null);
+            configDriveBuilderMocked.when(() -> 
ConfigDriveBuilder.writeVendorDataJsonFile(Mockito.any(File.class))).then(invocationOnMock
 -> null);
 
             configDriveBuilderMocked.when(() -> 
ConfigDriveBuilder.writeVmMetadata(Mockito.anyList(), Mockito.anyString(), 
Mockito.any(File.class), anyMap())).then(invocationOnMock -> null);
 
@@ -163,7 +163,7 @@ public class ConfigDriveBuilderTest {
             Assert.assertEquals("mockIsoDataBase64", returnedIsoData);
 
             configDriveBuilderMocked.verify(() -> {
-                
ConfigDriveBuilder.writeVendorEmptyJsonFile(Mockito.any(File.class));
+                
ConfigDriveBuilder.writeVendorDataJsonFile(Mockito.any(File.class));
                 ConfigDriveBuilder.writeVmMetadata(Mockito.anyList(), 
Mockito.anyString(), Mockito.any(File.class), anyMap());
                 ConfigDriveBuilder.linkUserData(Mockito.anyString());
                 
ConfigDriveBuilder.generateAndRetrieveIsoAsBase64Iso(Mockito.anyString(), 
Mockito.anyString(), Mockito.anyString());
@@ -172,23 +172,23 @@ public class ConfigDriveBuilderTest {
     }
 
     @Test(expected = CloudRuntimeException.class)
-    public void writeVendorEmptyJsonFileTestCannotCreateOpenStackFolder() {
+    public void writeVendorDataJsonFileTestCannotCreateOpenStackFolder() {
         File folderFileMock = Mockito.mock(File.class);
         Mockito.doReturn(false).when(folderFileMock).mkdirs();
 
-        ConfigDriveBuilder.writeVendorEmptyJsonFile(folderFileMock);
+        ConfigDriveBuilder.writeVendorDataJsonFile(folderFileMock);
     }
 
     @Test(expected = CloudRuntimeException.class)
-    public void writeVendorEmptyJsonFileTest() {
+    public void writeVendorDataJsonFileTest() {
         File folderFileMock = Mockito.mock(File.class);
         Mockito.doReturn(false).when(folderFileMock).mkdirs();
 
-        ConfigDriveBuilder.writeVendorEmptyJsonFile(folderFileMock);
+        ConfigDriveBuilder.writeVendorDataJsonFile(folderFileMock);
     }
 
     @Test
-    public void writeVendorEmptyJsonFileTestCreatingFolder() {
+    public void writeVendorDataJsonFileTestCreatingFolder() {
         try (MockedStatic<ConfigDriveBuilder> configDriveBuilderMocked = 
Mockito.mockStatic(ConfigDriveBuilder.class)) {
 
             File folderFileMock = Mockito.mock(File.class);
@@ -196,9 +196,9 @@ public class ConfigDriveBuilderTest {
             Mockito.doReturn(true).when(folderFileMock).mkdirs();
 
             //force execution of real method
-            configDriveBuilderMocked.when(() -> 
ConfigDriveBuilder.writeVendorEmptyJsonFile(folderFileMock)).thenCallRealMethod();
+            configDriveBuilderMocked.when(() -> 
ConfigDriveBuilder.writeVendorDataJsonFile(folderFileMock)).thenCallRealMethod();
 
-            ConfigDriveBuilder.writeVendorEmptyJsonFile(folderFileMock);
+            ConfigDriveBuilder.writeVendorDataJsonFile(folderFileMock);
 
             Mockito.verify(folderFileMock).exists();
             Mockito.verify(folderFileMock).mkdirs();

Reply via email to