/*********************************************************
- * Copyright (C) 2006-2018 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2019 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
#include "mspackWrapper.h"
#include "vmware/guestrpc/deploypkg.h"
#include "vmware/tools/guestrpc.h"
+#include <file.h>
#include <strutil.h>
#include <util.h>
#define IMC_TMP_PATH_VAR "@@IMC_TMP_PATH_VAR@@"
#endif
-// '/tmp' below will be addressed by PR 1601405.
-#ifndef TMP_DIR_PATH_PATTERN
-#define TMP_DIR_PATH_PATTERN "/tmp/.vmware-imgcust-dXXXXXX"
+// Use it to create random name folder for extracting the package
+#ifndef IMC_DIR_PATH_PATTERN
+#define IMC_DIR_PATH_PATTERN "/.vmware-imgcust-dXXXXXX"
#endif
#ifndef BASEFILENAME
static const char* INPROGRESS = "INPROGRESS";
static const char* DONE = "Done";
static const char* ERRORED = "ERRORED";
+static const char* RUNDIR = "/run";
+static const char* VARRUNDIR = "/var/run";
+static const char* TMPDIR = "/tmp";
// Possible return codes from perl script
static const int CUST_SUCCESS = 0;
* - nics.tx
* - cust.cfg to a predefined location.
*
- * @param [IN] tmpDirPath Path where nics.txt and cust.cfg exist
+ * @param [IN] imcDirPath Path where nics.txt and cust.cfg exist
* @returns DEPLOYPKG_STATUS_CLOUD_INIT_DELEGATED on success
* DEPLOYPKG_STATUS_ERROR on error
*
*----------------------------------------------------------------------------
* */
static DeployPkgStatus
-CloudInitSetup(const char *tmpDirPath)
+CloudInitSetup(const char *imcDirPath)
{
DeployPkgStatus deployPkgStatus = DEPLOYPKG_STATUS_ERROR;
static const char *cloudInitTmpDirPath = "/var/run/vmware-imc";
// rename in order to avoid race conditions with partial writes.
sLog(log_info, "Check if nics.txt exists. Copy if exists, skip otherwise");
snprintf(command, sizeof(command),
- "/usr/bin/test -f %s/nics.txt", tmpDirPath);
+ "/usr/bin/test -f %s/nics.txt", imcDirPath);
command[sizeof(command) - 1] = '\0';
forkExecResult = ForkExecAndWaitCommand(command, false);
*/
if (forkExecResult == 0) {
sLog(log_info, "nics.txt file exists. Copying..");
- if (!CopyFileToDirectory(tmpDirPath, cloudInitTmpDirPath, "nics.txt")) {
+ if (!CopyFileToDirectory(imcDirPath, cloudInitTmpDirPath, "nics.txt")) {
goto done;
}
}
// Get custom script name.
- if (HasCustomScript(tmpDirPath, &customScriptName)) {
+ customScriptName = GetCustomScript(imcDirPath);
+ if (customScriptName != NULL) {
char scriptPath[1024];
sLog(log_info, "Custom script present.");
sLog(log_info, "Copying script to execute post customization.");
- snprintf(scriptPath, sizeof(scriptPath), "%s/scripts", tmpDirPath);
+ snprintf(scriptPath, sizeof(scriptPath), "%s/scripts", imcDirPath);
scriptPath[sizeof(scriptPath) - 1] = '\0';
if (!CopyFileToDirectory(scriptPath, cloudInitTmpDirPath,
"post-customize-guest.sh")) {
sLog(log_info, "Copying user uploaded custom script %s",
customScriptName);
- if (!CopyFileToDirectory(tmpDirPath, cloudInitTmpDirPath,
+ if (!CopyFileToDirectory(imcDirPath, cloudInitTmpDirPath,
customScriptName)) {
goto done;
}
}
sLog(log_info, "Copying main configuration file cust.cfg");
- if (!CopyFileToDirectory(tmpDirPath, cloudInitTmpDirPath, "cust.cfg")) {
+ if (!CopyFileToDirectory(imcDirPath, cloudInitTmpDirPath, "cust.cfg")) {
goto done;
}
uint8 archiveType;
uint8 flags;
bool forceSkipReboot = false;
- char *tmpDirPath;
+ const char *baseDirPath = NULL;
+ char *imcDirPath = NULL;
bool useCloudInitWorkflow = false;
TransitionState(NULL, INPROGRESS);
SetCustomizationStatusInVmx(TOOLSDEPLOYPKG_RUNNING,
TOOLSDEPLOYPKG_ERROR_SUCCESS,
NULL);
- tmpDirPath = mkdtemp((char *)Util_SafeStrdup(TMP_DIR_PATH_PATTERN));
- if (tmpDirPath == NULL) {
- SetDeployError("Error creating tmp dir: %s", strerror(errno));
+
+ // PR 2127543, Use /var/run or /run but /tmp firstly
+ if (File_IsDirectory(VARRUNDIR)) {
+ baseDirPath = VARRUNDIR;
+ } else if (File_IsDirectory(RUNDIR)) {
+ baseDirPath = RUNDIR;
+ } else {
+ baseDirPath = TMPDIR;
+ }
+
+ // Create a random name dir under base dir path
+ imcDirPath = malloc(strlen(baseDirPath) + strlen(IMC_DIR_PATH_PATTERN) + 1);
+ if (imcDirPath == NULL) {
+ SetDeployError("Error allocating memory to create imc dir.");
+ return DEPLOYPKG_STATUS_ERROR;
+ }
+ strcpy(imcDirPath, baseDirPath);
+ strcat(imcDirPath, IMC_DIR_PATH_PATTERN);
+ if (mkdtemp(imcDirPath) == NULL) {
+ free(imcDirPath);
+ SetDeployError("Error creating imc dir: %s", strerror(errno));
return DEPLOYPKG_STATUS_ERROR;
}
- sLog(log_info, "Reading cabinet file %s. \n", packageName);
+ sLog(log_info,
+ "Reading cabinet file %s and will extract it to %s. \n",
+ packageName,
+ imcDirPath);
// Get the command to execute
if (!GetPackageInfo(packageName, &pkgCommand, &archiveType, &flags)) {
SetDeployError("Error extracting package header information. (%s)",
GetDeployError());
- free(tmpDirPath);
+ free(imcDirPath);
return DEPLOYPKG_STATUS_CAB_ERROR;
}
sLog(log_info, "Original deployment command: %s\n", pkgCommand);
if (strstr(pkgCommand, IMC_TMP_PATH_VAR) != NULL) {
- command = StrUtil_ReplaceAll(pkgCommand, IMC_TMP_PATH_VAR, tmpDirPath);
+ command = StrUtil_ReplaceAll(pkgCommand, IMC_TMP_PATH_VAR, imcDirPath);
} else {
- command = StrUtil_ReplaceAll(pkgCommand, TMP_PATH_VAR, tmpDirPath);
+ command = StrUtil_ReplaceAll(pkgCommand, TMP_PATH_VAR, imcDirPath);
}
free(pkgCommand);
sLog(log_info, "Actual deployment command: %s\n", command);
if (archiveType == VMWAREDEPLOYPKG_PAYLOAD_TYPE_CAB) {
- if (!ExtractCabPackage(packageName, tmpDirPath)) {
- free(tmpDirPath);
+ if (!ExtractCabPackage(packageName, imcDirPath)) {
+ free(imcDirPath);
free(command);
return DEPLOYPKG_STATUS_CAB_ERROR;
}
} else if (archiveType == VMWAREDEPLOYPKG_PAYLOAD_TYPE_ZIP) {
- if (!ExtractZipPackage(packageName, tmpDirPath)) {
- free(tmpDirPath);
+ if (!ExtractZipPackage(packageName, imcDirPath)) {
+ free(imcDirPath);
free(command);
return DEPLOYPKG_STATUS_CAB_ERROR;
}
}
if (!(flags & VMWAREDEPLOYPKG_HEADER_FLAGS_IGNORE_CLOUD_INIT)) {
- useCloudInitWorkflow = UseCloudInitWorkflow(tmpDirPath);
+ useCloudInitWorkflow = UseCloudInitWorkflow(imcDirPath);
} else {
sLog(log_info, "Ignoring cloud-init.");
}
sLog(log_info, "Executing cloud-init workflow");
sSkipReboot = TRUE;
free(command);
- deployPkgStatus = CloudInitSetup(tmpDirPath);
+ deployPkgStatus = CloudInitSetup(imcDirPath);
} else {
sLog(log_info, "Executing traditional GOSC workflow");
deploymentResult = ForkExecAndWaitCommand(command, false);
sLog(log_error, "Deployment failed. "
"The forked off process returned error code. \n");
} else {
- nics = GetNicsToEnable(tmpDirPath);
+ nics = GetNicsToEnable(imcDirPath);
if (nics) {
// XXX: Sleep before the last SetCustomizationStatusInVmx
// This is a temporary-hack for PR 422790
}
}
- cleanupCommand = malloc(strlen(CLEANUPCMD) + strlen(tmpDirPath) + 1);
+ cleanupCommand = malloc(strlen(CLEANUPCMD) + strlen(imcDirPath) + 1);
if (!cleanupCommand) {
SetDeployError("Error allocating memory.");
- free(tmpDirPath);
+ free(imcDirPath);
return DEPLOYPKG_STATUS_ERROR;
}
strcpy(cleanupCommand, CLEANUPCMD);
- strcat(cleanupCommand, tmpDirPath);
+ strcat(cleanupCommand, imcDirPath);
sLog(log_info, "Launching cleanup. \n");
if (ForkExecAndWaitCommand(cleanupCommand, false) != 0) {
- sLog(log_warning, "Error while clean up tmp directory %s: (%s)",
- tmpDirPath, strerror (errno));
+ sLog(log_warning, "Error while cleaning up imc directory %s: (%s)",
+ imcDirPath, strerror (errno));
}
free (cleanupCommand);
- free(tmpDirPath);
+ free(imcDirPath);
if (flags & VMWAREDEPLOYPKG_HEADER_FLAGS_SKIP_REBOOT) {
forceSkipReboot = true;
/*********************************************************
- * Copyright (C) 2016-2018 VMware, Inc. All rights reserved.
+ * Copyright (C) 2016-2019 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
FILE *cloudFile;
char line[256];
regex_t regex;
- // Expected regex in cloud.cfg file
- const char *cloudInitRegex = "^\\s*disable_vmware_customization\\s*:\\s*false\\s*$";
- int reti = regcomp(®ex, cloudInitRegex, 0);
- if (reti) {
- char buf[256];
- regerror(reti, ®ex, buf, sizeof(buf));
- sLog(log_warning, "Error compiling regex for cloud-init flag: %s", buf);
- return isEnabled;
- }
+ const char *cloudInitRegex =
+ "^\\s*disable_vmware_customization\\s*:\\s*false\\s*$";
+ int reti;
sLog(log_info, "Checking if cloud.cfg exists and if cloud-init is enabled.");
- // Read cloud.cfg file and find expected string.
cloudFile = fopen(cloudFilePath, "r");
if (cloudFile == NULL) {
sLog(log_info, "Could not open file: %s", strerror(errno));
+ return isEnabled;
+ }
+
+ reti = regcomp(®ex, cloudInitRegex, 0);
+ if (reti != 0) {
+ char buf[256];
+ regerror(reti, ®ex, buf, sizeof(buf));
+ sLog(log_error, "Error compiling regex for cloud-init flag: %s", buf);
goto done;
}
- while(fgets(line, sizeof(line), cloudFile)) {
- if (!regexec(®ex, line, 0, NULL, 0)) {
+
+ while (fgets(line, sizeof(line), cloudFile) != NULL) {
+ if (regexec(®ex, line, 0, NULL, 0) == 0) {
isEnabled = true;
break;
}
}
- if (ferror(cloudFile)) {
+ if (ferror(cloudFile) != 0) {
sLog(log_warning, "Error reading file: %s", strerror(errno));
isEnabled = false;
}
- fclose(cloudFile);
+ regfree(®ex);
done:
- regfree(®ex);
+ fclose(cloudFile);
return isEnabled;
}
/**
*-----------------------------------------------------------------------------
*
- * HasCustomScript
+ * GetCustomScript
*
- * Get custom script name if it exists.
+ * Get custom script name if it exists. Returns the first script found.
*
* @param [IN] dirPath path to extracted cab files
- * @param [IN/OUT] scriptName name of the user uploaded custom script.
- * scriptName will be set only if custom script
- * exists.
- * @returns TRUE if custom script exists in dirPath
+ *
+ * @returns the script name of the user uploaded custom script if it
+ * is found in dirPath. Must be freed by caller.
+ *
+ * NULL on failure or if the script does not exist
*
* ----------------------------------------------------------------------------
**/
-bool
-HasCustomScript(const char* dirPath, char** scriptName)
+char *
+GetCustomScript(const char* dirPath)
{
- bool hasScript = false;
+ char *scriptName = NULL;
static const char *customScriptRegex = "^script[A-Za-z0-9]*\\.bat";
DIR *tempDir;
struct dirent *dir;
regex_t scriptRegex;
- int ret = regcomp(&scriptRegex, customScriptRegex, 0);
- if (ret) {
- char buf[256];
- regerror(ret, &scriptRegex, buf, sizeof(buf));
- sLog(log_warning, "Error compiling regex for custom script: %s",
- buf);
- return hasScript;
- }
+ int regRet;
+
sLog(log_info, "Check if custom script(pre/post customization) exists.");
tempDir = opendir(dirPath);
if (tempDir == NULL) {
sLog(log_warning, "Could not open directory %s: error: %s", dirPath,
strerror(errno));
+ return scriptName;
+ }
+
+ regRet = regcomp(&scriptRegex, customScriptRegex, 0);
+ if (regRet != 0) {
+ char buf[256];
+
+ regerror(regRet, &scriptRegex, buf, sizeof(buf));
+ sLog(log_error, "Error compiling regex for custom script: %s", buf);
goto done;
}
+
while ((dir = readdir(tempDir)) != NULL) {
- if (!regexec(&scriptRegex, dir->d_name, 0, NULL, 0)) {
- *scriptName = strdup(dir->d_name);
- if (*scriptName == NULL) {
+ if (regexec(&scriptRegex, dir->d_name, 0, NULL, 0) == 0) {
+ scriptName = strdup(dir->d_name);
+ if (scriptName == NULL) {
sLog(log_warning, "Could not allocate memory for scriptName: %s",
strerror(errno));
- closedir(tempDir);
- goto done;
+ break;
}
- hasScript = true;
+ break;
}
}
- closedir(tempDir);
-done:
regfree(&scriptRegex);
- return hasScript;
+
+done:
+ closedir(tempDir);
+ return scriptName;
}