diff --git a/VMwareIntegration-Installinstructions.docx b/VMwareIntegration-Installinstructions.docx new file mode 100644 index 0000000..0c6b429 Binary files /dev/null and b/VMwareIntegration-Installinstructions.docx differ diff --git a/bin/vmhalo b/bin/vmhalo new file mode 100755 index 0000000..a765705 Binary files /dev/null and b/bin/vmhalo differ diff --git a/halo_installers/cphalo-2.8.2-win64.exe b/halo_installers/cphalo-2.8.2-win64.exe new file mode 100644 index 0000000..6048321 Binary files /dev/null and b/halo_installers/cphalo-2.8.2-win64.exe differ diff --git a/halo_installers/halo_deb_install.sh b/halo_installers/halo_deb_install.sh new file mode 100755 index 0000000..bbc3863 --- /dev/null +++ b/halo_installers/halo_deb_install.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# CloudPassage Halo Daemon +# Unattended installation script for Vendor Integrations +# ------------------------------------------------------------------------- +# This script is intended to be used for an unattended installation +# of the CloudPassage Halo daemon. +# +# IMPORTANT NOTES +# +# * This script may require adjustment to conform to your server's +# configuration. Please review this script and test it on a server +# before using it to install the Halo daemon on multiple servers. +# +# * This script contains the CloudPassage Halo Daemon Registration Key owned by +# Vendor Integrations. Keep this script safe - handle it as +# you would the password to your CloudPassage portal account! +# + +# add CloudPassage repository +echo 'deb http://packages.cloudpassage.com/debian debian main' | sudo tee /etc/apt/sources.list.d/cloudpassage.list > /dev/null + +# install curl +sudo apt-get -y install curl + +# import CloudPassage public key +curl http://packages.cloudpassage.com/cloudpassage.packages.key | sudo apt-key add - + +# update apt repositories +sudo apt-get update > /dev/null + +# install the daemon +sudo apt-get -y install cphalo + +echo "Key=$1" ; echo "Tag=$2" + +# start the daemon for the first time +sudo /etc/init.d/cphalod start --daemon-key=$1 --tag=$2 + diff --git a/halo_installers/halo_rh_install.sh b/halo_installers/halo_rh_install.sh new file mode 100755 index 0000000..2353f5d --- /dev/null +++ b/halo_installers/halo_rh_install.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# CloudPassage Halo Daemon +# Unattended installation script for Vendor Integrations +# ------------------------------------------------------------------------- +# This script is intended to be used for an unattended installation +# of the CloudPassage Halo daemon. +# +# IMPORTANT NOTES +# +# * This script may require adjustment to conform to your server's +# configuration. Please review this script and test it on a server +# before using it to install the Halo daemon on multiple servers. +# +# * This script contains the CloudPassage Halo Daemon Registration Key owned by +# Vendor Integrations. Keep this script safe - handle it as +# you would the password to your CloudPassage portal account! +# + +# add CloudPassage repository +echo -e '[cloudpassage]\nname=CloudPassage\nbaseurl=http://packages.cloudpassage.com/redhat/$basearch\ngpgcheck=1' | tee /etc/yum.repos.d/cloudpassage.repo > /dev/null + +# import CloudPassage public key +rpm --import http://packages.cloudpassage.com/cloudpassage.packages.key + +# update yum repositories +yum check-update > /dev/null + +# install the daemon +yum -y install cphalo + +echo "Key=$1" ; echo "Tag=$2" + +# start the daemon for the first time +/etc/init.d/cphalod start --daemon-key=$1 --tag=$2 diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..9ccf0c5 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,20 @@ +# +# Makefile for vmhalo program +# +OBJS=vmhalo.o vixconnection.o vmhconfig.o + +vmhalo: $(OBJS) + g++ -g -o vmhalo $(OBJS) -lvixAllProducts -ldl -lpthread + cp vmhalo ../bin + +vmhalo.o: vmhalo.cpp vixconnection.hpp vmhconfig.hpp + g++ -g -c -I/usr/include/vmware-vix/ vmhalo.cpp + +vmhconfig.o: vmhconfig.cpp vmhconfig.hpp + g++ -g -c -I/usr/include/vmware-vix/ vmhconfig.cpp + +vixconnection.o: vixconnection.cpp vixconnection.hpp + g++ -g -c -I/usr/include/vmware-vix/ vixconnection.cpp + +clean: + rm -f vmhalo $(OBJS) diff --git a/src/vixconnection.cpp b/src/vixconnection.cpp new file mode 100644 index 0000000..fd84548 --- /dev/null +++ b/src/vixconnection.cpp @@ -0,0 +1,227 @@ +#include +#include +#include +#ifdef WIN32 +#define strcasecmp stricmp +#endif + +#include + +#include "vixconnection.hpp" +#include "vmhconfig.hpp" + +VixConnection::VixConnection() +{ + strcpy(hostname,""); + port = 0; + strcpy(username,""); + strcpy(password,""); + hostHandle = VIX_INVALID_HANDLE; + retryPasswordAllowed = true; +} + +bool VixConnection::connect() +{ + VixError err; + VixHandle jobHandle = VixHost_Connect(VIX_API_VERSION, serverType, hostname, port, + username, password, 0, + VIX_INVALID_HANDLE, NULL, NULL); + err = VixJob_Wait(jobHandle, VIX_PROPERTY_JOB_RESULT_HANDLE, &hostHandle, VIX_PROPERTY_NONE); + Vix_ReleaseHandle(jobHandle); + if (VIX_FAILED(err)) { + fprintf(stderr, "Connect failure: %s\n", Vix_GetErrorText(err, NULL)); + return false; + } else + return true; +} + +void VixConnection::setHostInfo(char *hostname, int port) +{ + strncpy(this->hostname,hostname,256); + this->port = port; +} + +void VixConnection::setUserInfo(char *username, char *password) +{ + strncpy(this->username,username,32); + strncpy(this->password,password,32); +} + +typedef struct s_server_type { + int typeNum; + const char *typeName; +} ServerType; + +static ServerType type_list[] = { + { VIX_SERVICEPROVIDER_VMWARE_SERVER, "server" }, + { VIX_SERVICEPROVIDER_VMWARE_WORKSTATION, "workstation" }, + { VIX_SERVICEPROVIDER_VMWARE_PLAYER, "player" }, + { VIX_SERVICEPROVIDER_VMWARE_VI_SERVER, "vi" }, + { VIX_SERVICEPROVIDER_VMWARE_WORKSTATION_SHARED, "shared" } +}; +static int type_count = sizeof(type_list)/sizeof(type_list[0]); + +void VixConnection::setServerType(const char *type) +{ + for (int i = 0; i < type_count; i++) { + if (strcasecmp(type_list[i].typeName,type) == 0) { + serverType = type_list[i].typeNum; + return; + } + } + fprintf(stderr,"Unknown vm host type: %s\n",type); +} + +typedef struct s_callback_info { + FinderCallback userCB; + VixConnection *vconn; + VmhConfig *config; +} CallbackInfo; +static CallbackInfo cbinfo = { NULL, NULL, NULL }; + +static void internalFinderCallback(VixHandle job, VixEventType event, VixHandle moreInfo, void *cd) +{ + char *location = NULL; + if (event != VIX_EVENTTYPE_FIND_ITEM) + return; + + VixError err = Vix_GetProperties(moreInfo, VIX_PROPERTY_FOUND_ITEM_LOCATION, &location, VIX_PROPERTY_NONE); + if (VIX_SUCCEEDED(err)) { + if (cbinfo.userCB != NULL) { + (*cbinfo.userCB)(location); + } else { + fprintf(stderr,"Found VM: %s\n",location); + } + } else { + fprintf(stderr,"GetProperties failed: %s",Vix_GetErrorText(err,NULL)); + } +} + +void VixConnection::findVMs(FinderCallback cb) +{ + cbinfo.userCB = cb; // store info for later, should pass as "Callback Data" (cd) argument + cbinfo.vconn = this; + VixHandle jobHandle = VixHost_FindItems(hostHandle,VIX_FIND_RUNNING_VMS,VIX_INVALID_HANDLE, + -1,internalFinderCallback,NULL); + VixError err = VixJob_Wait(jobHandle, VIX_PROPERTY_NONE); + Vix_ReleaseHandle(jobHandle); + if (VIX_FAILED(err)) { + fprintf(stderr,"Find VMs failed: %s\n",Vix_GetErrorText(err,NULL)); + return; + } +} + +void VixConnection::disconnect() +{ + VixHost_Disconnect(hostHandle); +} + +bool VixConnection::runCmd(char *cmd, char *args) +{ + VixHandle jobHandle = VixVM_RunProgramInGuest(vmHandle,cmd,args,0,VIX_INVALID_HANDLE,NULL,NULL); + VixError err = VixJob_Wait(jobHandle, VIX_PROPERTY_NONE); + Vix_ReleaseHandle(jobHandle); + if (VIX_FAILED(err)) { + fprintf(stderr,"Failed to run program %s: %s\n",cmd,Vix_GetErrorText(err,NULL)); + return false; + } + return true; +} + +bool VixConnection::runScript(char *shell, char *scriptText) +{ + VixHandle jobHandle = VixVM_RunScriptInGuest(vmHandle,shell,scriptText, + 0,VIX_INVALID_HANDLE,NULL,NULL); + VixError err = VixJob_Wait(jobHandle, VIX_PROPERTY_NONE); + Vix_ReleaseHandle(jobHandle); + if (VIX_FAILED(err)) { + fprintf(stderr,"Login to VM failed: %s\n",Vix_GetErrorText(err,NULL)); + return false; + } + return true; +} + +bool VixConnection::openVM(char *vmxpath, char *guestUsername, char *guestPassword) +{ + char username_buf[4096]; + char password_buf[4096]; + VixHandle jobHandle = VixVM_Open(hostHandle,vmxpath,NULL,NULL); + VixError err = VixJob_Wait(jobHandle, VIX_PROPERTY_JOB_RESULT_HANDLE, &vmHandle, VIX_PROPERTY_NONE); + Vix_ReleaseHandle(jobHandle); + if (VIX_FAILED(err)) { + fprintf(stderr,"Open VM failed: %s\n",Vix_GetErrorText(err,NULL)); + return false; + } else { + jobHandle = VixVM_LoginInGuest(vmHandle, guestUsername, guestPassword, 0, NULL, NULL); + err = VixJob_Wait(jobHandle, VIX_PROPERTY_NONE); + Vix_ReleaseHandle(jobHandle); + if (VIX_FAILED(err)) { + fprintf(stderr,"Login to VM failed: %s\n",Vix_GetErrorText(err,NULL)); + if (retryPasswordAllowed) { + printf("To retry login with different credentials, enter new username: "); + fflush(stdout); + fgets(username_buf,4000,stdin); + trim(username_buf); + if (strlen(username_buf) > 0) { + printf("Enter new password: "); + fflush(stdout); + fgets(password_buf,4000,stdin); + trim(password_buf); + jobHandle = VixVM_LoginInGuest(vmHandle, username_buf, password_buf, 0, NULL, NULL); + err = VixJob_Wait(jobHandle, VIX_PROPERTY_NONE); + Vix_ReleaseHandle(jobHandle); + if (VIX_FAILED(err)) { + fprintf(stderr,"Login to VM failed again: %s\n",Vix_GetErrorText(err,NULL)); + return false; + } + return true; // retry succeeded + } + } + return false; + } + return true; + } +} + +bool VixConnection::copyFromVM(char *remotePath, char *localPath) +{ + VixHandle jobHandle = VixVM_CopyFileFromGuestToHost(vmHandle, remotePath, localPath, + 0, VIX_INVALID_HANDLE, NULL, NULL); + VixError err = VixJob_Wait(jobHandle, VIX_PROPERTY_NONE); + Vix_ReleaseHandle(jobHandle); + if (VIX_FAILED(err)) { + fprintf(stderr,"File copy from VM failed: %s: %s\n",remotePath,Vix_GetErrorText(err,NULL)); + return false; + } + return true; +} + +bool VixConnection::copyToVM(char *localPath, char *remotePath) +{ + VixHandle jobHandle = VixVM_CopyFileFromHostToGuest(vmHandle, localPath, remotePath, + 0, VIX_INVALID_HANDLE, NULL, NULL); + VixError err = VixJob_Wait(jobHandle, VIX_PROPERTY_NONE); + Vix_ReleaseHandle(jobHandle); + if (VIX_FAILED(err)) { + fprintf(stderr,"File copy to VM failed: %s: %s\n",localPath,Vix_GetErrorText(err,NULL)); + return false; + } + return true; +} + +bool VixConnection::fileExistsInVM(char *remotePath) +{ + int fileExists = 0; + VixHandle jobHandle = VixVM_FileExistsInGuest(vmHandle, remotePath, NULL, NULL); + VixError err = VixJob_Wait(jobHandle, VIX_PROPERTY_NONE); + if (VIX_FAILED(err)) { + Vix_ReleaseHandle(jobHandle); + return false; + } + err = Vix_GetProperties(jobHandle,VIX_PROPERTY_JOB_RESULT_GUEST_OBJECT_EXISTS,&fileExists,VIX_PROPERTY_NONE); + Vix_ReleaseHandle(jobHandle); + if (VIX_FAILED(err)) { + return false; + } + return fileExists != 0; +} diff --git a/src/vixconnection.hpp b/src/vixconnection.hpp new file mode 100644 index 0000000..8a69940 --- /dev/null +++ b/src/vixconnection.hpp @@ -0,0 +1,37 @@ +#ifndef VIX_CONNECTION_HPP +#define VIX_CONNECTION_HPP + +class VixConnection; +class VmhConfig; + +typedef void (*FinderCallback)(char *vmxPath); + +class VixConnection +{ + public: + VixConnection(); + bool connect(); + void setHostInfo(char *hostname, int port = 0); + void setUserInfo(char *username, char *password); + void setServerType(int type) { serverType = type; } + void setServerType(const char *type); + void disconnect(); + void findVMs(FinderCallback cb); + bool openVM(char *vmxpath, char *guestUsername, char *guestPassword); + bool runCmd(char *cmd, char *args); + bool runScript(char *shell, char *scriptText); + bool copyFromVM(char *remotePath, char *localPath); + bool copyToVM(char *localPath, char *remotePath); + bool fileExistsInVM(char *remotePath); + private: + char hostname[256]; + int port; + char username[32]; + char password[32]; + int serverType; + VixHandle hostHandle; + VixHandle vmHandle; + bool retryPasswordAllowed; +}; + +#endif diff --git a/src/vixconnection.o b/src/vixconnection.o new file mode 100644 index 0000000..2fcdccc Binary files /dev/null and b/src/vixconnection.o differ diff --git a/src/vmhalo b/src/vmhalo new file mode 100755 index 0000000..a765705 Binary files /dev/null and b/src/vmhalo differ diff --git a/src/vmhalo.cpp b/src/vmhalo.cpp new file mode 100644 index 0000000..a01380d --- /dev/null +++ b/src/vmhalo.cpp @@ -0,0 +1,335 @@ +#include +#include +#include +#include +#ifndef WIN32 +#include +#else +#define strcasecmp stricmp +#endif +#include + +#include "vixconnection.hpp" +#include "vmhconfig.hpp" + +bool processCmdLineArgs(int argc, char **argv); +void installOnVM(VmhConfig *config, VixConnection *vconn, char *vmxpath); +void uninstallFromVM(VmhConfig *config, VixConnection *vconn, char *vmxpath); +void printUsage(char *progName); +void finderStoreVMX(char *vmxPath); +void finderWriteListFile(char *vmxpath); +void closeListFile(void); +bool isNumber(char *str); +bool readListFile(int index); +void displayVM(VixConnection *vconn, VmhConfig *config, char *vmxpath, int count); + +#ifdef WIN32 +extern "C" { + +char *basename(char *path) +{ + static char path_buffer[_MAX_PATH]; + static char drive[_MAX_DRIVE]; + static char dir[_MAX_DIR]; + static char fname[_MAX_FNAME]; + static char ext[_MAX_EXT]; + + _splitpath(path, drive, dir, fname, ext ); + if (strlen(ext) > 0) { + sprintf(path_buffer,"%s%s",fname,ext); + return path_buffer; + } else { + return fname; + } +} +void _forceCRTManifestCUR() +{ +} + +} + +char *haloTestDest = ".\\halo_test"; +char *dstBanner = ".\\issue.net"; + +#else + +char *haloTestDest = "/tmp/halo_test"; +char *dstBanner = "/tmp/issue.net"; + +#endif + +static const char *configFilename1 = "vmhalo.cfg"; +static const char *configFilename2 = "../vmhalo.cfg"; +static char *vmxpathList[20]; +static int vmxpathListMax = sizeof(vmxpathList)/sizeof(vmxpathList[0]); +static int vmxpathCount = 0; +static const char *vmlistFilename = "vmlist.txt"; +static char *overrideTag = NULL; + +bool verbose = false; +bool shouldUninstall = false; + +int main(int argc, char **argv) +{ + if (! processCmdLineArgs(argc,argv)) + return 1; + + VmhConfig *config = new VmhConfig(); + if (config->readFromFile(configFilename1)) { + if (verbose) { + fprintf(stderr,"Successfully read config from %s\n",configFilename1); + config->dump(); + } + } else if (config->readFromFile(configFilename2)) { + if (verbose) { + fprintf(stderr,"Successfully read config from %s\n",configFilename2); + config->dump(); + } + } else { + fprintf(stderr,"Unable to read config file (%s), exiting.\n",configFilename1); + return 1; + } + + VixConnection *vconn = new VixConnection(); + vconn->setServerType(config->getServerType()); + vconn->setHostInfo(config->getServerHost()); + vconn->setUserInfo(config->getServerUser(),config->getServerPass()); + + if (vconn->connect()) { + if (vmxpathCount == 0) { + vconn->findVMs(finderWriteListFile); + closeListFile(); + for (int i = 0; i < vmxpathCount; i++) + displayVM(vconn,config,vmxpathList[i],i + 1); + } else { + if ((vmxpathCount == 1) && (strcmp(vmxpathList[0],"ALL") == 0)) { + vmxpathCount = 0; // reset so it removes "ALL" from list + vconn->findVMs(finderStoreVMX); + } + for (int i = 0; i < vmxpathCount; i++) + if (shouldUninstall) + uninstallFromVM(config,vconn,vmxpathList[i]); + else + installOnVM(config,vconn,vmxpathList[i]); + } + // sleep(2); + vconn->disconnect(); + if (verbose) printf("Done!\n"); + } + return 0; +} + +char *getGuestType(VixConnection *vconn, char *vmxpath) +{ + static char *srcBanner = "/etc/issue.net"; + static char bannerPrefix[1024]; + + FILE *fp = NULL; + if (! vconn->fileExistsInVM(srcBanner)) + return "win64"; + + if (vconn->copyFromVM(srcBanner,dstBanner) && ((fp = fopen(dstBanner,"r")) != NULL)) { + fscanf(fp,"%s",bannerPrefix); + if ((strcasecmp(bannerPrefix,"CentOS") == 0) || (strcasecmp(bannerPrefix,"Fedora") == 0) || + (strcasecmp(bannerPrefix,"CentOS") == 0)) { + return "redhat"; + } else if ((strcasecmp(bannerPrefix,"Debian") == 0) || (strcasecmp(bannerPrefix,"Ubuntu") == 0)) { + return "debian"; + } else + return "redhat"; // for now, just assume + } + return "win64"; +} + +bool guestOsIsLinux(char *guestOSname) +{ + return strncmp("win",guestOSname,3) != 0; +} + +bool alreadyInstalledOnVM(VixConnection *vconn, char *guestOSname) +{ + if (guestOsIsLinux(guestOSname)) + return vconn->fileExistsInVM("/etc/init.d/cphalod"); + else + return vconn->fileExistsInVM("c:\\Program Files\\CloudPassage\\LICENSE"); +} + +void installOnVM(VmhConfig *config, VixConnection *vconn, char *vmxpath) +{ + char destName[512]; + char srcNameCopy[512]; + char script[1024]; + if (vconn->openVM(vmxpath,config->getGuestUser(NULL), + config->getGuestPass(NULL))) { + char *guestType = getGuestType(vconn,vmxpath); + if (verbose) fprintf(stderr,"Detected OS %s on %s\n",guestType,vmxpath); + if (alreadyInstalledOnVM(vconn,guestType)) { + fprintf(stderr,"Halo already installed on guest %s\n",vmxpath); + return; + } + char *srcName = config->getInstaller(guestType); + if (srcName == NULL) { + fprintf(stderr,"couldn't find installer name for guest type %s\n",guestType); + return; + } + char *tag = config->getHostTag(guestType); + if (overrideTag != NULL) + tag = overrideTag; + + strcpy(srcNameCopy,srcName); + if (guestOsIsLinux(guestType)) { + sprintf(destName,"/tmp/%s",basename(srcNameCopy)); + vconn->copyToVM(srcName,destName); + + sprintf(script,"%s %s %s > /tmp/halo_install.log 2>&1\n",destName,config->getHaloKey(),tag); + vconn->runScript("/bin/sh",script); + } else { + sprintf(destName,"c:\\%s",basename(srcNameCopy)); + sprintf(script,"/S /DAEMON-KEY=%s /TAG=%s",config->getHaloKey(),tag); + vconn->copyToVM(srcName,destName); + vconn->runCmd(destName,script); + } + } else { + fprintf(stderr,"Failed to login to %s\n",vmxpath); + } +} + +void uninstallFromVM(VmhConfig *config, VixConnection *vconn, char *vmxpath) +{ + if (vconn->openVM(vmxpath,config->getGuestUser(NULL), + config->getGuestPass(NULL))) { + char *guestType = getGuestType(vconn,vmxpath); + if (verbose) fprintf(stderr,"Detected OS %s on %s\n",guestType,vmxpath); + if (! alreadyInstalledOnVM(vconn,guestType)) { + fprintf(stderr,"Halo not installed on guest %s\n",vmxpath); + return; + } + char *cmd = config->getUninstallCmd(guestType); + char *args = config->getUninstallArgs(guestType); + vconn->runCmd(cmd,args); + } else { + fprintf(stderr,"Failed to login to %s\n",vmxpath); + } +} + +void printUsage(char *progName) +{ + fprintf(stderr,"Usage: %s [] [ ...]\n",progName); + fprintf(stderr," or: %s [] ALL\n",progName); + fprintf(stderr,"\n"); + fprintf(stderr,"Where identifies an individual VM, or ALL specifies all VMs on a host\n"); + fprintf(stderr,"\n"); + fprintf(stderr,"And can be one or more of the following:\n"); + fprintf(stderr,"-h\t\tThis message\n"); + fprintf(stderr,"-v\t\tSpecify verbose output messages\n"); + fprintf(stderr,"-u\t\tUninstall Halo daemon from VM\n--uninstall\tsame as above\n"); + fprintf(stderr,"--tag=\tOverride tag value in config file\n"); + fprintf(stderr,"\n"); + fprintf(stderr,"Config file is normally %s or %s\n",configFilename1,configFilename2); +} + +bool processCmdLineArgs(int argc, char **argv) +{ + for (int i = 0; i < vmxpathListMax; i++) + vmxpathList[i] = NULL; + + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i],"-v") == 0) { + verbose = true; + } else if ((strcmp(argv[i],"-h") == 0) || (strcmp(argv[i],"-?") == 0)) { + printUsage(argv[0]); + return false; + } else if ((strcmp(argv[i],"-u") == 0) || (strcmp(argv[i],"--uninstall") == 0)) { + shouldUninstall = true; + } else if (strncmp(argv[i],"--tag=",6) == 0) { + overrideTag = argv[i] + 6; + if (verbose) + fprintf(stderr,"Using \"%s\" to tag guests\n",overrideTag); + } else { + if (vmxpathCount < vmxpathListMax) { + if (isNumber(argv[i])) { + readListFile(atoi(argv[i])); + } else { + vmxpathList[vmxpathCount++] = argv[i]; + } + } + } + } + return true; +} + +void finderStoreVMX(char *vmxpath) +{ + if (vmxpathCount < vmxpathListMax) + vmxpathList[vmxpathCount++] = vmxpath; +} + + +static FILE *listFP = NULL; +static int listCount = 0; + +void finderWriteListFile(char *vmxpath) +{ + char *installed = ""; + if (listFP == NULL) { + if ((listFP = fopen(vmlistFilename,"w")) == NULL) { + perror(vmlistFilename); + return; + } + } + listCount++; + fprintf(listFP,"%s\n",vmxpath); + finderStoreVMX(vmxpath); +} + +void displayVM(VixConnection *vconn, VmhConfig *config, char *vmxpath, int count) +{ + if (verbose) fprintf(stderr,"Attempting to connect to: %s\n",vmxpath); + char *installed = ""; + if (vconn->openVM(vmxpath,config->getGuestUser(NULL), + config->getGuestPass(NULL))) { + char *guestType = getGuestType(vconn,vmxpath); + if (verbose) fprintf(stderr,"Detected OS %s on %s\n",guestType,vmxpath); + if (alreadyInstalledOnVM(vconn,guestType)) { + installed = " (Halo installed)"; + } + } + fprintf(stderr,"Found VM: %d: %s%s\n",count,vmxpath,installed); +} + +void closeListFile(void) +{ + if (listFP != NULL) + fclose(listFP); +} + +bool readListFile(int index) +{ + char buf[4096]; + if (listFP == NULL) { + if ((listFP = fopen(vmlistFilename,"r")) == NULL) { + perror(vmlistFilename); + return false; + } + } else { + rewind(listFP); + } + for (int i = 0; i < index; i++) { + if (fgets(buf,4095,listFP) == NULL) { + fprintf(stderr,"Specified index %d is greater than lines in file %d\n",index,i); + return false; + } + // trim(buf); fprintf(stderr,"Reading list file: %d: %s\n",i,buf); + } + trim(buf); + finderStoreVMX(strdup(buf)); + return true; +} + +bool isNumber(char *str) +{ + for (; *str; str++) + if (! isdigit(*str)) + return false; + return true; +} diff --git a/src/vmhalo.o b/src/vmhalo.o new file mode 100644 index 0000000..ada658a Binary files /dev/null and b/src/vmhalo.o differ diff --git a/src/vmhconfig.cpp b/src/vmhconfig.cpp new file mode 100644 index 0000000..c0dbc73 --- /dev/null +++ b/src/vmhconfig.cpp @@ -0,0 +1,185 @@ +#include +#include +#include +#ifndef WIN32 +#include +#endif +#include + +#include "vmhconfig.hpp" + +VmhConfig::VmhConfig() +{ + strcpy(serverType,"player"); // provide default value + strcpy(serverHost,""); + strcpy(serverUser,""); + strcpy(serverPass,""); + strcpy(guestUser,""); + strcpy(guestPass,""); + guestTypeCount = 0; + strcpy(halokey,""); +} + +char linebuf[4096]; + +static bool startsWith(char *str, const char *prefix) +{ + if (strncmp(str,prefix,strlen(prefix)) == 0) + return true; + else + return false; +} + +void trim(char *str) +{ + int n; + + if ((str == NULL) || (strlen(str) < 1)) + return; + while ((n = strlen(str)) > 0) { + char last = str[n - 1]; + if ((last == '\n') || (last == '\r')) + str[n - 1] = '\0'; + else + break; + } +} + +void VmhConfig::initGuest(GuestTypeInfo *guest, char *name) +{ + strcpy(guest->typeName,name); + strcpy(guest->installPackage,""); + strcpy(guest->uninstallCommand,""); + strcpy(guest->uninstallArgs,""); + strcpy(guest->guestUser,""); + strcpy(guest->guestPass,""); + strcpy(guest->hostTag,""); +} + +bool VmhConfig::readFromFile(const char *filename) +{ + char *line = NULL; + FILE *fp = fopen(filename,"r"); + if (fp == NULL) { + // perror(filename); + return false; + } + while ((line = fgets(linebuf,4095,fp)) != NULL) { + while ((*line == ' ') || (*line == '\t')) + line++; + trim(line); + + if (startsWith(line,"#")) + continue; + else if (startsWith(line,"type=")) + strncpy(serverType,line + 5,255); + else if (startsWith(line,"host=")) + strncpy(serverHost,line + 5,255); + else if (startsWith(line,"user=")) + strncpy(serverUser,line + 5,31); + else if (startsWith(line,"username=")) + strncpy(serverUser,line + 9,31); + else if (startsWith(line,"pass=")) + strncpy(serverPass,line + 5,31); + else if (startsWith(line,"password=")) + strncpy(serverPass,line + 9,31); + else if (startsWith(line,"guestuser=")) + strncpy(guestUser,line + 10,31); + else if (startsWith(line,"guestpass=")) + strncpy(guestPass,line + 10,31); + else if (startsWith(line,"guesttype=")) { + initGuest(guestTypes + guestTypeCount,line + 10); + guestTypeCount++; + } else if (startsWith(line,"installer=")) + strncpy(guestTypes[guestTypeCount - 1].installPackage,line + 10,511); + else if (startsWith(line,"uninstall=")) + strncpy(guestTypes[guestTypeCount - 1].uninstallCommand,line + 10,511); + else if (startsWith(line,"uninstallArgs=")) + strncpy(guestTypes[guestTypeCount - 1].uninstallArgs,line + 14,511); + else if (startsWith(line,"tag=")) + strncpy(guestTypes[guestTypeCount - 1].hostTag,line + 4,255); + else if (startsWith(line,"halokey=")) + strncpy(halokey,line + 8,255); + } + fclose(fp); + return true; +} + +GuestTypeInfo *VmhConfig::getTypeInfo(char *type) +{ + if (type != NULL) { + for (int i = 0; i < guestTypeCount; i++) + if (strcmp(guestTypes[i].typeName,type) == 0) + return guestTypes + i; + } + return NULL; +} + +char *VmhConfig::getInstaller(char *type) +{ + GuestTypeInfo *typeInfo = getTypeInfo(type); + if (typeInfo != NULL) + return typeInfo->installPackage; + else + return NULL; +} + +char *VmhConfig::getUninstallCmd(char *type) +{ + GuestTypeInfo *typeInfo = getTypeInfo(type); + if (typeInfo != NULL) + return typeInfo->uninstallCommand; + else + return NULL; +} + +char *VmhConfig::getUninstallArgs(char *type) +{ + GuestTypeInfo *typeInfo = getTypeInfo(type); + if (typeInfo != NULL) + return typeInfo->uninstallArgs; + else + return NULL; +} + +char *VmhConfig::getHostTag(char *type) +{ + GuestTypeInfo *typeInfo = getTypeInfo(type); + if (typeInfo != NULL) + return typeInfo->hostTag; + else + return NULL; +} + +char *VmhConfig::getGuestUser(char *type) +{ + GuestTypeInfo *typeInfo = getTypeInfo(type); + if ((typeInfo != NULL) && (strlen(typeInfo->guestUser) > 0)) + return typeInfo->guestUser; + else + return guestUser; +} + +char *VmhConfig::getGuestPass(char *type) +{ + GuestTypeInfo *typeInfo = getTypeInfo(type); + if ((typeInfo != NULL) && (strlen(typeInfo->guestPass) > 0)) + return typeInfo->guestPass; + else + return guestPass; +} + +void VmhConfig::dump(void) +{ + printf("--config--\n"); + printf("--config--\ntype=%s\nhost=%s\nuser=%s\npass=%s\n", + serverType,serverHost,serverUser,serverPass); + printf("guest.user=%s\nguest.pass=%s\n",guestUser,guestPass); + printf("daemon.key=%s\n",halokey); + for (int i = 0; i < guestTypeCount; i++) { + printf("installer[%s]=%s\n",guestTypes[i].typeName,guestTypes[i].installPackage); + printf("uninstaller[%s]=\"%s\" \"%s\"\n",guestTypes[i].typeName,guestTypes[i].uninstallCommand,guestTypes[i].uninstallArgs); + printf("tag[%s]=%s\n",guestTypes[i].typeName,guestTypes[i].hostTag); + } + printf("--end--\n"); +} diff --git a/src/vmhconfig.hpp b/src/vmhconfig.hpp new file mode 100644 index 0000000..7a515a5 --- /dev/null +++ b/src/vmhconfig.hpp @@ -0,0 +1,47 @@ +#ifndef VMH_CONFIG_HPP +#define VMH_CONFIG_HPP + +typedef struct s_guest_type_info { + char typeName[20]; + char installPackage[512]; + char uninstallCommand[512]; + char uninstallArgs[512]; + char guestUser[32]; + char guestPass[32]; + char hostTag[256]; +} GuestTypeInfo; + +void trim(char *str); + +class VmhConfig +{ + public: + VmhConfig(); + bool readFromFile(const char *filename); + void dump(void); + char *getServerType() { return serverType; } + char *getServerHost() { return serverHost; } + char *getServerUser() { return serverUser; } + char *getServerPass() { return serverPass; } + char *getGuestUser(char *type = NULL); + char *getGuestPass(char *type = NULL); + char *getInstaller(char *type); + char *getUninstallCmd(char *type); + char *getUninstallArgs(char *type); + char *getHostTag(char *type); + char *getHaloKey() { return halokey; } + private: + void initGuest(GuestTypeInfo *guest, char *name); + GuestTypeInfo *getTypeInfo(char *type); + char halokey[256]; + char serverType[256]; + char serverHost[256]; + char serverUser[32]; + char serverPass[32]; + char guestUser[32]; + char guestPass[32]; + GuestTypeInfo guestTypes[6]; + int guestTypeCount; +}; + +#endif diff --git a/src/vmhconfig.o b/src/vmhconfig.o new file mode 100644 index 0000000..6345326 Binary files /dev/null and b/src/vmhconfig.o differ diff --git a/vmhalo.cfg b/vmhalo.cfg new file mode 100644 index 0000000..ac9f36b --- /dev/null +++ b/vmhalo.cfg @@ -0,0 +1,26 @@ +# lots of lines of format "key=value" +# type can be one of: +# player if the host runs VMware Player +# server if the host runs VMware Server 1.0 +# workstation if the host runs VMware Workstation +# vi if the host runs VMware vCenter, ESX/ESXi, or VMware Server 2.0 +# shared if the host runs VMware Workstation in shared mode +type=player +guestuser=root +guestpass= +halokey= +guesttype=redhat +installer=../halo_installers/halo_rh_install.sh +uninstall=/usr/bin/yum +uninstallArgs=erase -y cphalo +tag=vmware-rpm +guesttype=debian +installer=../halo_installers/halo_deb_install.sh +uninstall=/usr/bin/apt-get +uninstallArgs=purge -y cphalo +tag=vmware-debian +guesttype=win64 +installer=../halo_installers/cphalo-2.8.2-win64.exe +uninstall=c:\Program Files\CloudPassage\Uninstall.exe +uninstallArgs=/S +tag=