Blame SOURCES/ovt-Workaround-for-false-negative-result-when-detecting.patch

6e701c
From c567bef4b4f7721ef5c0444f464a9843ba609ae2 Mon Sep 17 00:00:00 2001
6e701c
From: Miroslav Rezanina <mrezanin@redhat.com>
6e701c
Date: Thu, 2 Aug 2018 17:14:28 +0200
6e701c
Subject: [PATCH] Workaround for false negative result when detecting
6e701c
 cloud-init existance
6e701c
6e701c
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
6e701c
Message-id: <1533230068-14044-1-git-send-email-mrezanin@redhat.com>
6e701c
Patchwork-id: 81615
6e701c
O-Subject: [RHEL-7.6 open-vm-tools PATCH] Workaround for false negative result when detecting cloud-init existance
6e701c
Bugzilla: 1601559
6e701c
RH-Acked-by: Richard Jones <rjones@redhat.com>
6e701c
RH-Acked-by: Cathy Avery <cavery@redhat.com>
6e701c
6e701c
From: Oliver Kurth <okurth@vmware.com>
6e701c
6e701c
"cloud-init -v" cmd is used to detect if cloud-init is properly configured and
6e701c
it works on most linux distros. However in some linux distro like Amazon Linux 2,
6e701c
"cloud-init -v" will print result to stderr instead of stdout and it makes
6e701c
"forkExecAndWaitCommand" give false negative result.
6e701c
6e701c
1. added a new bool switch in  "ForkExecAndWaitCommand" to choose
6e701c
   if we should ignore the stderr output when the return code is 0
6e701c
2. removed unnecessary reference for "ForkExecAndWaitCommand" in linuxDeploymentUtilities.c
6e701c
3. trivial change for some formatting
6e701c
6e701c
(cherry picked from commit 443eced089b634176c6ad1f56512a43381997abc)
6e701c
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
6e701c
---
6e701c
 libDeployPkg/linuxDeployment.c       | 55 ++++++++++++++--------
6e701c
 libDeployPkg/linuxDeploymentUtilities.c        |  3 +-
6e701c
 2 files changed, 37 insertions(+), 21 deletions(-)
6e701c
6e701c
diff --git a/libDeployPkg/linuxDeployment.c b/libDeployPkg/linuxDeployment.c
6e701c
index 023d41f..7bcdd0a 100644
6e701c
--- a/libDeployPkg/linuxDeployment.c
6e701c
+++ b/libDeployPkg/linuxDeployment.c
6e701c
@@ -143,7 +143,7 @@ static bool CopyFileToDirectory(const char* srcPath, const char* destPath,
6e701c
                                 const char* fileName);
6e701c
 static int Deploy(const char* pkgName);
6e701c
 static char** GetFormattedCommandLine(const char* command);
6e701c
-int ForkExecAndWaitCommand(const char* command);
6e701c
+int ForkExecAndWaitCommand(const char* command, bool ignoreStdErr);
6e701c
 static void SetDeployError(const char* format, ...);
6e701c
 static const char* GetDeployError(void);
6e701c
 static void NoLogging(int level, const char* fmtstr, ...);
6e701c
@@ -920,7 +920,7 @@ CloudInitSetup(const char *tmpDirPath)
6e701c
             "/bin/mkdir -p %s", cloudInitTmpDirPath);
6e701c
    command[sizeof(command) - 1] = '\0';
6e701c
 
6e701c
-   forkExecResult = ForkExecAndWaitCommand(command);
6e701c
+   forkExecResult = ForkExecAndWaitCommand(command, false);
6e701c
    if (forkExecResult != 0) {
6e701c
       SetDeployError("Error creating %s dir: %s",
6e701c
                      cloudInitTmpDirPath,
6e701c
@@ -937,7 +937,7 @@ CloudInitSetup(const char *tmpDirPath)
6e701c
             "/usr/bin/test -f %s/nics.txt", tmpDirPath);
6e701c
    command[sizeof(command) - 1] = '\0';
6e701c
 
6e701c
-   forkExecResult = ForkExecAndWaitCommand(command);
6e701c
+   forkExecResult = ForkExecAndWaitCommand(command, false);
6e701c
 
6e701c
    /*
6e701c
     * /usr/bin/test -f returns 0 if the file exists
6e701c
@@ -946,7 +946,7 @@ CloudInitSetup(const char *tmpDirPath)
6e701c
     */
6e701c
    if (forkExecResult == 0) {
6e701c
       sLog(log_info, "nics.txt file exists. Copying..");
6e701c
-      if(!CopyFileToDirectory(tmpDirPath, cloudInitTmpDirPath, "nics.txt")) {
6e701c
+      if (!CopyFileToDirectory(tmpDirPath, cloudInitTmpDirPath, "nics.txt")) {
6e701c
          goto done;
6e701c
        }
6e701c
    }
6e701c
@@ -973,7 +973,7 @@ CloudInitSetup(const char *tmpDirPath)
6e701c
    }
6e701c
 
6e701c
    sLog(log_info, "Copying main configuration file cust.cfg");
6e701c
-   if(!CopyFileToDirectory(tmpDirPath, cloudInitTmpDirPath, "cust.cfg")) {
6e701c
+   if (!CopyFileToDirectory(tmpDirPath, cloudInitTmpDirPath, "cust.cfg")) {
6e701c
       goto done;
6e701c
    }
6e701c
 
6e701c
@@ -992,7 +992,7 @@ done:
6e701c
                   "/bin/rm -rf %s",
6e701c
                   cloudInitTmpDirPath);
6e701c
          command[sizeof(command) - 1] = '\0';
6e701c
-         ForkExecAndWaitCommand(command);
6e701c
+         ForkExecAndWaitCommand(command, false);
6e701c
       }
6e701c
       sLog(log_error, "Setting generic error status in vmx. \n");
6e701c
       SetCustomizationStatusInVmx(TOOLSDEPLOYPKG_RUNNING,
6e701c
@@ -1016,7 +1016,7 @@ CopyFileToDirectory(const char* srcPath, const char* destPath,
6e701c
    snprintf(command, sizeof(command), "/bin/cp %s/%s %s/%s.tmp", srcPath,
6e701c
             fileName, destPath, fileName);
6e701c
    command[sizeof(command) - 1] = '\0';
6e701c
-   forkExecResult = ForkExecAndWaitCommand(command);
6e701c
+   forkExecResult = ForkExecAndWaitCommand(command, false);
6e701c
    if (forkExecResult != 0) {
6e701c
       SetDeployError("Error while copying file %s: %s", fileName,
6e701c
                      strerror(errno));
6e701c
@@ -1026,7 +1026,7 @@ CopyFileToDirectory(const char* srcPath, const char* destPath,
6e701c
             fileName, destPath, fileName);
6e701c
    command[sizeof(command) - 1] = '\0';
6e701c
 
6e701c
-   forkExecResult = ForkExecAndWaitCommand(command);
6e701c
+   forkExecResult = ForkExecAndWaitCommand(command, false);
6e701c
    if (forkExecResult != 0) {
6e701c
       SetDeployError("Error while renaming temp file %s: %s", fileName,
6e701c
                      strerror(errno));
6e701c
@@ -1090,7 +1090,7 @@ UseCloudInitWorkflow(const char* dirPath)
6e701c
       sLog(log_info, "cust.cfg is found in '%s' directory.", dirPath);
6e701c
    }
6e701c
 
6e701c
-   forkExecResult = ForkExecAndWaitCommand(cloudInitCommand);
6e701c
+   forkExecResult = ForkExecAndWaitCommand(cloudInitCommand, true);
6e701c
    if (forkExecResult != 0) {
6e701c
       sLog(log_info, "cloud-init is not installed");
6e701c
       free(cfgFullPath);
6e701c
@@ -1191,7 +1191,7 @@ Deploy(const char* packageName)
6e701c
       deployStatus =  CloudInitSetup(tmpDirPath);
6e701c
    } else {
6e701c
       sLog(log_info, "Executing traditional GOSC workflow");
6e701c
-      deploymentResult = ForkExecAndWaitCommand(command);
6e701c
+      deploymentResult = ForkExecAndWaitCommand(command, false);
6e701c
       free(command);
6e701c
 
6e701c
       if (deploymentResult != CUST_SUCCESS) {
6e701c
@@ -1257,7 +1257,7 @@ Deploy(const char* packageName)
6e701c
    strcat(cleanupCommand, tmpDirPath);
6e701c
 
6e701c
    sLog(log_info, "Launching cleanup. \n");
6e701c
-   if (ForkExecAndWaitCommand(cleanupCommand) != 0) {
6e701c
+   if (ForkExecAndWaitCommand(cleanupCommand, false) != 0) {
6e701c
       sLog(log_warning, "Error while clean up tmp directory %s: (%s)",
6e701c
            tmpDirPath, strerror (errno));
6e701c
    }
6e701c
@@ -1286,7 +1286,7 @@ Deploy(const char* packageName)
6e701c
          int rebootComandResult = 0;
6e701c
          do {
6e701c
             sLog(log_info, "Rebooting\n");
6e701c
-            rebootComandResult = ForkExecAndWaitCommand("/sbin/telinit 6");
6e701c
+            rebootComandResult = ForkExecAndWaitCommand("/sbin/telinit 6", false);
6e701c
             sleep(1);
6e701c
          } while (rebootComandResult == 0);
6e701c
          sLog(log_error, "telinit returned error %d\n", rebootComandResult);
6e701c
@@ -1497,11 +1497,12 @@ GetFormattedCommandLine(const char* command)
6e701c
  * fork-and-exec.
6e701c
  *
6e701c
  * @param   [IN]  command  Command to execute
6e701c
+ * @param   [IN]  ignoreStdErr  If we ignore stderr when cmd's return code is 0
6e701c
  * @return  Return code from the process (or DEPLOY_ERROR)
6e701c
  *
6e701c
  **/
6e701c
 int
6e701c
-ForkExecAndWaitCommand(const char* command)
6e701c
+ForkExecAndWaitCommand(const char* command, bool ignoreStdErr)
6e701c
 {
6e701c
    ProcessHandle hp;
6e701c
    int retval;
6e701c
@@ -1519,14 +1520,30 @@ ForkExecAndWaitCommand(const char* command)
6e701c
 
6e701c
    Process_RunToComplete(hp, 100);
6e701c
    sLog(log_info, "Customization command output: %s\n", Process_GetStdout(hp));
6e701c
-
6e701c
-   if(Process_GetExitCode(hp) == 0 && strlen(Process_GetStderr(hp)) > 0) {
6e701c
-      // Assume command failed if it wrote to stderr, even if exitCode is 0
6e701c
-      sLog(log_error, "Customization command failed: %s\n", Process_GetStderr(hp));
6e701c
-      retval = -1;
6e701c
+   retval = Process_GetExitCode(hp);
6e701c
+
6e701c
+   if (retval == 0) {
6e701c
+      if (strlen(Process_GetStderr(hp)) > 0) {
6e701c
+         if (!ignoreStdErr) {
6e701c
+            // Assume command failed if it wrote to stderr, even if exitCode is 0
6e701c
+            sLog(log_error,
6e701c
+                 "Customization command failed with stderr: %s\n",
6e701c
+                 Process_GetStderr(hp));
6e701c
+            retval = -1;
6e701c
+         } else {
6e701c
+            // If we choose to ignore stderr, we do not return -1 when return
6e701c
+            // code is 0. e.g, PR2148977, "cloud-init -v" will return 0
6e701c
+            // even there is output in stderr
6e701c
+            sLog(log_info, "Ignoring stderr output: %s\n", Process_GetStderr(hp));
6e701c
+         }
6e701c
+      }
6e701c
    } else {
6e701c
-      retval = Process_GetExitCode(hp);
6e701c
+      sLog(log_error,
6e701c
+           "Customization command failed with exitcode: %d, stderr: %s\n",
6e701c
+           retval,
6e701c
+           Process_GetStderr(hp));
6e701c
    }
6e701c
+
6e701c
    Process_Destroy(hp);
6e701c
    return retval;
6e701c
 }
6e701c
diff --git a/libDeployPkg/linuxDeploymentUtilities.c b/libDeployPkg/linuxDeploymentUtilities.c
6e701c
index 83f942d..93e1b0a 100644
6e701c
--- a/libDeployPkg/linuxDeploymentUtilities.c
6e701c
+++ b/libDeployPkg/linuxDeploymentUtilities.c
6e701c
@@ -1,5 +1,5 @@
6e701c
 /*********************************************************
6e701c
- * Copyright (C) 2016-2017 VMware, Inc. All rights reserved.
6e701c
+ * Copyright (C) 2016-2018 VMware, Inc. All rights reserved.
6e701c
  *
6e701c
  * This program is free software; you can redistribute it and/or modify it
6e701c
  * under the terms of the GNU Lesser General Public License as published
6e701c
@@ -24,7 +24,6 @@
6e701c
 #include <regex.h>
6e701c
 #include "linuxDeploymentUtilities.h"
6e701c
 
6e701c
-extern int ForkExecAndWaitCommand(const char* command);
6e701c
 extern LogFunction sLog;
6e701c
 
6e701c
 /**
6e701c
-- 
6e701c
1.8.3.1
6e701c