1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-12-10 22:42:30 +03:00
Files
mariadb-columnstore-engine/oamapps/postConfigure/amazonInstaller.cpp
Andrew Hutchings 97bda78c3b Move config files
This patch:

* Moves config files from /usr/local/mariadb/columnstore/etc to
ENGINE_SYSCONFDIR/columnstore (ENGINE_SYSCONFDIR is /etc by default)
* Sets a define called MCSSYSCONFDIR whic contains the
ENGINE_SYSCONFDIR compile time setting
* Modifies scripts and code to use the new paths
* Removes a whole bunch of files we don't use
2019-09-09 14:13:56 +01:00

3207 lines
96 KiB
C++

/* Copyright (C) 2014 InfiniDB, Inc.
Copyright (C) 2016 MariaDB Corporation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/******************************************************************************************
* $Id: amazonInstaller.cpp 64 2006-10-12 22:21:51Z dhill $
*
*
******************************************************************************************/
/**
* @file
*/
#include <iterator>
#include <numeric>
#include <deque>
#include <iostream>
#include <ostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <limits.h>
#include <sstream>
#include <exception>
#include <stdexcept>
#include <vector>
#include <stdio.h>
#include <ctype.h>
#include <netdb.h>
#include <sys/sysinfo.h>
#include <readline/readline.h>
#include <readline/history.h>
#include "columnstoreversion.h"
#include "liboamcpp.h"
#include "configcpp.h"
#include "alarmmanager.h"
using namespace std;
using namespace oam;
using namespace config;
using namespace alarmmanager;
#include "helpers.h"
using namespace installer;
//pthread_mutex_t THREAD_LOCK;
typedef struct Instance_struct
{
std::string instanceName;
std::string moduleName;
std::string IPaddress;
} Instance;
typedef std::vector<Instance> InstanceList;
typedef struct Volume_struct
{
std::string volumeName;
std::string deviceName;
int dbrootID;
std::string moduleName;
} Volume;
typedef std::vector<Volume> VolumeList;
typedef struct ModuleIP_struct
{
std::string IPaddress;
std::string moduleName;
} ModuleIP;
typedef std::vector<ModuleIP> ModuleIPList;
typedef std::vector<std::string> PrivateIPList;
string getIPAddress(string instance);
void cleanupSystem(bool terminate = true);
void setSystemName();
void snmpAppCheck();
void setRootPassword();
void launchInstanceThread(ModuleIP moduleip);
int launchInstanceCount = 0;
void createVolumeThread(string module);
int createVolumeCount = 0;
int createdbrootid = 0;
int lid = 0;
int did = 1;
//unsigned getNumCores();
int numCores = 10; // default
// devices b-e saved for ephemeral storage
string UMdeviceName = "/dev/sdf";
string PMdeviceName = "/dev/sd";
string deviceLetter[] = {"g", "h", "i", "j", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "end"};
Config* sysConfig = Config::makeConfig();
string SystemSection = "SystemConfig";
string InstallSection = "Installation";
string ModuleSection = "SystemModuleConfig";
string installDir = "/usr/local/mariadb/columnstore";
InstanceList uminstancelist;
InstanceList pminstancelist;
VolumeList PMvolumelist;
VolumeList UMvolumelist;
string rootPassword = "Calpont1";
string AMIrootPassword = "Calpont1";
ModuleIPList elasticiplist;
ModuleIPList moduleiplist;
char* pcommand1 = 0;
string prompt1;
string NMSIPAddress = "0.0.0.0";
string systemName = "calpont-1";
string UserModuleInstanceType = oam::UnassignedName;
string UserModuleSecurityGroup = oam::UnassignedName;
int PMvolumeSize = 100;
int UMvolumeSize = 10;
string localInstance;
bool cleanupRunning = false;
string x509Cert = oam::UnassignedName;
string x509PriKey = oam::UnassignedName;
string region = "us-east-1";
string autoTagging = "y";
string elasticIPs = oam::UnassignedName;
string systemType = "";
string subnetID = oam::UnassignedName;
string VPCStartPrivateIP = oam::UnassignedName;
string localQuery = "n";
string MySQLRep = "n";
bool noPrompting;
string mysqlpw = " ";
bool PMEBS = true;
int main(int argc, char* argv[])
{
Oam oam;
string usePMEBS;
bool UMEBS = true;
string useUMEBS;
int dbrootPer = 1;
int umNumber = 1;
int pmNumber = 1;
int IserverTypeInstall;
string singleServerInstall = "2";
string postConfigureOutFile = "/root/postConfigure.log";
bool postConfigureLog = false;
bool postConfigureDebug = false;
string TotalUmMemory = oam::UnassignedName;
string NumBlocksPct = oam::UnassignedName;
bool postConfigureCleanup = false;
bool systemCleanup = false;
bool systemStop = false;
string existingPMInstances = oam::UnassignedName;
string existingUMInstances = oam::UnassignedName;
string UMprivateIPS = oam::UnassignedName;
string PMprivateIPS = oam::UnassignedName;
string instanceType;
string PMEBSFailoverSupport = "y";
string amazonConfigFile = "/root/amazonConfig.xml";
for ( int i = 1; i < argc; i++ )
{
if ( string("-h") == argv[i] || string("--help") == argv[i])
{
cout << endl;
cout << "This is the Amazon columnstore AMI System Configuration and Installation tool." << endl;
cout << "It will Configure and startup an Amazon columnstore System." << endl << endl;
cout << "It will read the system configuration settings from /root/amazonConfig.xml." << endl;
cout << "Or user can provide a different configuration file with the -c option." << endl;
cout << "Or if /root/amazonConfig.xml doesn't exist, then user will be prompted for settings." << endl;
cout << endl;
cout << "Usage: amazonInstaller -c 'config.xml' -h -l -v -pc -d -s" << endl;
cout << " -h Help" << endl;
cout << " -c system config file, default is '/root/amazonConfig.xml'" << endl;
cout << " -l logfile for postConfigure output to /root/postConfigure.log" << endl;
cout << " -v columnstore version" << endl;
cout << " -pc postConfigure failure System Cleanup, used to run System Cleanup if columnstore fails to install" << endl;
cout << " -d Delete Cluster, used to delete Instances and Volumes on a shutdowned system" << endl;
cout << " Require argument, include name of local Amazon Configure File '-c' option" << endl;
cout << " -s Stop Cluster, used to stop Instances on a shutdowned system" << endl;
exit (0);
}
else if ( string("-c") == argv[i] )
{
i++;
if (i >= argc )
{
cout << " ERROR: Config File not provided" << endl;
exit (1);
}
amazonConfigFile = argv[i];
//check if file exist
ifstream oldFile (amazonConfigFile.c_str());
if (!oldFile)
{
cout << "ERROR: Amazon Configure File (" + amazonConfigFile + ") doesn't exist, exiting" << endl;
exit (1);
}
}
else if ( string("-l") == argv[i] )
{
postConfigureLog = true;
}
else if ( string("-v") == argv[i] )
{
cout << "columnstore Version: " << columnstore_version << "-" << columnstore_release << endl;
exit (0);
}
else if ( string("-pc") == argv[i] )
{
postConfigureCleanup = true;
}
else if ( string("-d") == argv[i] )
{
systemCleanup = true;
}
else if ( string("-s") == argv[i] )
{
systemStop = true;
}
else if ( string("-t") == argv[i] )
{
i++;
if (i >= argc )
{
cout << " ERROR: Thread Count not provided" << endl;
exit (1);
}
string temp = argv[i];
numCores = atoi(temp.c_str());
}
}
//check if columnstore is up and running
if (oam.checkSystemRunning())
{
cout << endl << "columnstore is running, can't run AmazonInstaller while columnstore is running. Exiting.." << endl;
exit (0);
}
if ( systemCleanup || systemStop )
{
//check if config file exist
ifstream oldFile (amazonConfigFile.c_str());
if (!oldFile)
{
cout << "Amazon Configuration File (" << amazonConfigFile << ") doesn't exist, exiting..." << endl;
exit (1);
}
//read system paramaters from config file
Config* sysConfig = Config::makeConfig();
try
{
systemName = sysConfig->getConfig("SystemConfig", "SystemName");
}
catch (...) {}
if ( systemCleanup )
{
cout << endl << "**** WARNING - Deleting '" << systemName << "' cluster - WARNING ***** " << endl << endl;
cout << "You have selected the Option to perform a system cleanup, which will delete" << endl;
cout << "all of the Instances (excluding the local one) and all of the associated Volumes." << endl << endl;
}
else
{
cout << endl << "**** WARNING - Stopping '" << systemName << "' cluster - WARNING ***** " << endl << endl;
cout << "You have selected the Option to stop all the Instances in the cluster";
cout << " (excluding the local one)." << endl << endl;
}
while (true)
{
string ready = "n";
if ( systemCleanup )
prompt1 = "WARNING - You are about the delete '" + systemName + "' cluster. Are you sure you want to do this? [y,n] (n) > ";
else
prompt1 = "WARNING - You are about the stop the instances on '" + systemName + "' cluster. Are you sure you want to do this? [y,n] (n) > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) ready = pcommand1;
free(pcommand1);
pcommand1 = 0;
if (ready == "n")
exit(0);
}
if ( ready == "y" )
break;
cout << "Invalid Entry, please enter 'y' for yes or 'n' for no" << endl;
}
SystemModuleTypeConfig systemmoduletypeconfig;
try
{
oam.getSystemConfig(systemmoduletypeconfig);
for ( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++)
{
if ( systemmoduletypeconfig.moduletypeconfig[i].ModuleType.empty() )
// end of list
break;
int moduleCount = systemmoduletypeconfig.moduletypeconfig[i].ModuleCount;
if ( moduleCount == 0 )
// skip if no modules
continue;
string moduletype = systemmoduletypeconfig.moduletypeconfig[i].ModuleType;
DeviceNetworkList::iterator pt = systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.begin();
for ( ; pt != systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.end() ; pt++)
{
string modulename = (*pt).DeviceName;
string moduleID = modulename.substr(MAX_MODULE_TYPE_SIZE, MAX_MODULE_ID_SIZE);
HostConfigList::iterator pt1 = (*pt).hostConfigList.begin();
for ( ; pt1 != (*pt).hostConfigList.end() ; pt1++)
{
Instance instance;
instance.instanceName = (*pt1).HostName;
instance.moduleName = modulename;
if ( moduletype == "um")
{
uminstancelist.push_back(instance);
string UMStorageType = "internal";
{
try
{
oam.getSystemConfig("UMStorageType", UMStorageType);
}
catch (...) {}
}
if ( UMStorageType == "external" )
{
string volumeNameID = "UMVolumeName" + moduleID;
string volumeName = oam::UnassignedName;
try
{
oam.getSystemConfig( volumeNameID, volumeName);
}
catch (...)
{}
if ( volumeName.empty() || volumeName == oam::UnassignedName )
break;
else
{
Volume volume;
volume.volumeName = volumeName;
volume.moduleName = modulename;
UMvolumelist.push_back(volume);
}
}
}
else
pminstancelist.push_back(instance);
}
DeviceDBRootList::iterator pt3 = systemmoduletypeconfig.moduletypeconfig[i].ModuleDBRootList.begin();
for ( ; pt3 != systemmoduletypeconfig.moduletypeconfig[i].ModuleDBRootList.end() ; pt3++)
{
if ( (*pt3).DeviceID == atoi(moduleID.c_str()) )
{
DBRootConfigList::iterator pt2 = (*pt3).dbrootConfigList.begin();
for ( ; pt2 != (*pt3).dbrootConfigList.end() ;)
{
string DBRootStorageType = "internal";
{
try
{
oam.getSystemConfig("DBRootStorageType", DBRootStorageType);
}
catch (...) {}
}
if ( DBRootStorageType == "external" )
{
string volumeNameID = "PMVolumeName" + oam.itoa(*pt2);
string volumeName = oam::UnassignedName;
try
{
oam.getSystemConfig( volumeNameID, volumeName);
}
catch (...)
{}
if ( volumeName.empty() || volumeName == oam::UnassignedName )
break;
else
{
Volume volume;
volume.volumeName = volumeName;
volume.dbrootID = *pt2;
PMvolumelist.push_back(volume);
}
}
pt2++;
}
}
}
}
}
}
catch (exception& e)
{
cout << endl << "**** getModuleConfig Failed = " << e.what() << endl;
}
cleanupSystem(systemCleanup);
exit(0);
}
cout << endl;
cout << "This is the Amazon columnstore AMI System Configuration and Installation tool." << endl;
cout << "It will Configure and startup an Amazon columnstore System." << endl;
//check if columnstore is up and running
if (oam.checkSystemRunning())
{
cout << "columnstore is running, can't run amazonInstaller while columnstore is running. Exiting.." << endl;
exit (0);
}
//backup current Columnstore.xml
string configFile = MCSSYSCONFDIR + "/columnstore/Columnstore.xml";
string saveFile = MCSSYSCONFDIR + "/columnstore/Columnstore.xml.save";
string cmd = "rm -f " + saveFile;
system(cmd.c_str());
cmd = "cp " + configFile + " " + saveFile;
system(cmd.c_str());
//run pre-uninstall and post-install to start with a clean system
cmd = installDir + "/bin/pre-uninstall > /dev/null 2>&1";
system(cmd.c_str());
cmd = installDir + "/bin/post-uninstall > /dev/null 2>&1";
system(cmd.c_str());
//backup original Columnstore.xml if it doesn't exist
//if it does exist copy to Columnstore.xml
ifstream file (saveFile.c_str());
if (!file)
{
cmd = "cp " + configFile + " " + saveFile;
system(cmd.c_str());
}
else
{
unlink(configFile.c_str());
cmd = "cp " + saveFile + " " + configFile;
system(cmd.c_str());
}
//check if config file exist, if not, prompt from configuration settings
ifstream oldFile (amazonConfigFile.c_str());
if (!oldFile)
{
cout << endl << "===== Setup Amazon files =====" << endl << endl;
while (true)
{
cout << "For Amazon EC2 Instance installs, these files will need to be installed on" << endl;
cout << "on the local instance:" << endl << endl;
cout << " 1. X.509 Certificate" << endl;
cout << " 2. X.509 Private Key" << endl << endl;
while (true)
{
string ready = "y";
prompt1 = "Are these files installed and ready to continue [y,n] (y) > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) ready = pcommand1;
free(pcommand1);
pcommand1 = 0;
if (ready == "n")
{
cout << endl << "Please Install these files and re-run amazonInstaller. exiting..." << endl;
exit(0);
}
}
if ( ready == "y" )
break;
cout << "Invalid Entry, please enter 'y' for yes or 'n' for no" << endl;
}
try
{
x509Cert = sysConfig->getConfig(InstallSection, "AmazonX509Certificate");
x509PriKey = sysConfig->getConfig(InstallSection, "AmazonX509PrivateKey");
region = sysConfig->getConfig(InstallSection, "AmazonRegion");
}
catch (...)
{}
cout << endl;
while (true)
{
prompt1 = "Enter name with directory of the X.509 Certificate file (" + x509Cert + ") > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) x509Cert = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
ifstream File (x509Cert.c_str());
if (!File)
cout << "Error: file not found, please re-enter" << endl;
else
break;
}
while (true)
{
prompt1 = "Enter name with directory of the X.509 Private Key file (" + x509PriKey + ") > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) x509PriKey = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
ifstream File (x509PriKey.c_str());
if (!File)
cout << "Error: file not found, please re-enter" << endl;
else
break;
}
while (true)
{
prompt1 = "Enter the Amazon Region you are running in (" + region + ") > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) region = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
break;
}
break;
}
//set the x.509 file locations
try
{
sysConfig->setConfig(InstallSection, "AmazonX509Certificate", x509Cert);
sysConfig->setConfig(InstallSection, "AmazonX509PrivateKey", x509PriKey);
sysConfig->setConfig(InstallSection, "AmazonRegion", region);
}
catch (...)
{}
try
{
sysConfig->write();
}
catch (...)
{
cout << "ERROR: Failed trying to update columnstore System Configuration file" << endl;
exit(1);
}
cout << endl << "===== Setup System Configuration =====" << endl << endl;
//system Name
prompt1 = "Enter System Name (" + systemName + ") > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) systemName = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
cout << endl << "There are 2 options when configuring the System Module Type: separate and combined" << endl << endl;
cout << " 'separate' - User and Performance functionality on separate servers." << endl;
cout << " 'combined' - User and Performance functionality on the same server" << endl << endl;
string serverTypeInstall = "2";
while (true)
{
prompt1 = "Select the type of System Module Install [1=separate, 2=combined] (2) > ";
pcommand1 = readline(prompt1.c_str());
cout << endl;
if (pcommand1)
{
if (strlen(pcommand1) > 0) serverTypeInstall = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
if ( serverTypeInstall != "1" && serverTypeInstall != "2" )
{
cout << "Invalid Entry, please re-enter" << endl << endl;
continue;
}
IserverTypeInstall = atoi(serverTypeInstall.c_str());
break;
}
if (IserverTypeInstall == 1)
systemType = "separate";
else
systemType = "combined";
//verify and setup of modules count
switch ( IserverTypeInstall )
{
case (oam::INSTALL_NORMAL):
{
while (true)
{
umNumber = 1;
prompt1 = "Enter number of User Modules [1,1024] (" + oam.itoa(umNumber) + ") > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) umNumber = atoi(pcommand1);
free(pcommand1);
pcommand1 = 0;
}
if ( umNumber < 1 || umNumber > oam::MAX_MODULE )
{
cout << endl << "ERROR: Invalid Module Count '" + oam.itoa(umNumber) + "', please re-enter" << endl << endl;
continue;
}
break;
}
cout << endl;
//get exist um imstance list
prompt1 = "Enter List of Existing User Modules Instances (id1,id2,id3) or hit enter for none > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) existingPMInstances = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
instanceType = oam.getEC2LocalInstanceType();
if (instanceType.empty() || instanceType == "" || instanceType == "failed")
{
cout << endl << "ERROR: Failed to get Instance Type, double check Configuration settings. exiting..." << endl;
exit (1);
}
cout << endl;
//get UserModuleInstanceType
while (true)
{
prompt1 = "Enter User Module Instance Type or hit enter to default to current type (" + instanceType + ") > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) UserModuleInstanceType = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
}
cout << endl;
//get UserModuleSecurityGroup
while (true)
{
prompt1 = "Enter User Module Security Group or hit enter to default to current Security Group > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) UserModuleSecurityGroup = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
break;
}
cout << endl;
cout << endl;
//get UMEBS volume info
while (true)
{
string answer = "y";
prompt1 = "We recommend using EBS Volumes for User Module storage, you want to use EBS Volume? [y,n] (y) > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) answer = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
if ( answer == "n" )
{
UMEBS = false;
break;
}
useUMEBS = answer;
if ( answer == "y")
{
while (true)
{
prompt1 = "Default Volume size is 10gbs, change if you like [1,1024] (100) > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) UMvolumeSize = atoi(pcommand1);
free(pcommand1);
pcommand1 = 0;
}
if ( UMvolumeSize < 1 || UMvolumeSize > 1024 )
{
cout << endl << "ERROR: Invalid EBS Volume Size '" + oam.itoa(UMvolumeSize) + "', please re-enter" << endl << endl;
continue;
}
break;
}
break;
}
cout << "Invalid Entry, please enter 'y' for yes or 'n' for no" << endl;
}
break;
}
default:
break;
}
cout << endl;
//get number of pm
while (true)
{
pmNumber = 1;
prompt1 = "Enter number of Performance Modules [1,1024] (" + oam.itoa(pmNumber) + ") > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) pmNumber = atoi(pcommand1);
free(pcommand1);
pcommand1 = 0;
}
if ( pmNumber < 1 || pmNumber > oam::MAX_MODULE )
{
cout << endl << "ERROR: Invalid Module Count '" + oam.itoa(pmNumber) + "', please re-enter" << endl << endl;
continue;
}
break;
}
cout << endl;
//get exist pm imstance list
prompt1 = "Enter List of Existing Performance Modules Instances (id1,id2,id3) or hit enter for none > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) existingPMInstances = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
cout << endl;
//get EBS Volume info
while (true)
{
string answer = "y";
prompt1 = "We recommend using EBS Volumes for Performance Module storage, you want to use EBS Volumes? [y,n] (y) > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) answer = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
if ( answer == "n" )
{
PMEBS = false;
break;
}
usePMEBS = answer;
if ( answer == "y" )
{
while (true)
{
cout << "The default setting is 1 EBS Volume (dbroot) per Performance Module." << endl;
prompt1 = "How many EBS Volumes do you want to assign to each Performance Module (1) > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) dbrootPer = atoi(pcommand1);
free(pcommand1);
pcommand1 = 0;
}
if ( dbrootPer > 0 )
break;
cout << endl << "ERROR: Invalid EBS Volume Count per pm '" + oam.itoa(dbrootPer) + "', need at least 1, please re-enter" << endl << endl;
}
while (true)
{
prompt1 = "Default Volume size is 100gbs, change if you like [1,1024] (100) > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) PMvolumeSize = atoi(pcommand1);
free(pcommand1);
pcommand1 = 0;
}
if ( PMvolumeSize < 1 || PMvolumeSize > 1024 )
{
cout << endl << "ERROR: Invalid EBS Volume Size '" + oam.itoa(PMvolumeSize) + "', please re-enter" << endl << endl;
continue;
}
break;
}
break;
}
cout << "Invalid Entry, please enter 'y' for yes or 'n' for no" << endl;
}
cout << endl;
//get Elasitic UP list
prompt1 = "Enter List of Elastic IPs with Assigned ModuleName (x.x.x.x,um1,y.y.y.y,pm1) or hit enter for none > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) elasticIPs = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
cout << endl;
//get auto tagging
while (true)
{
string answer = "n";
prompt1 = "Instance and Volume Name Auto tagging is enabled, do you want to disable it? [y,n] (n) > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) answer = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
if ( answer == "n" )
{
autoTagging = "y";
break;
}
if ( answer == "y" )
{
autoTagging = "n";
break;
}
cout << "Invalid Entry, please enter 'y' for yes or 'n' for no" << endl;
}
cout << endl;
//get TotalUmMemory
prompt1 = "Enter TotalUmMemory size or hit enter to default standard size > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) TotalUmMemory = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
cout << endl;
//get NumBlocksPct
while (true)
{
prompt1 = "Enter NumBlocksPct size or hit enter to default standard size [1,100] > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) NumBlocksPct = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
if ( ( atoi(NumBlocksPct.c_str()) < 0 || atoi(NumBlocksPct.c_str()) > 100)
&& NumBlocksPct != oam::UnassignedName)
cout << "Invalid entry, please re-enter value 1-100" << endl;
else
break;
}
cout << endl;
//check snmp Apps disable option
snmpAppCheck();
//get root password
prompt1 = "Enter Root-Password used to access the Instances or hit enter to default to 'Calpont1' > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) rootPassword = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
cout << endl;
}
else
{
cout << "It will read the system configuration settings from " << amazonConfigFile << endl;
cout << endl;
//read system paramaters from config file
Config* amazonConfig = Config::makeConfig(amazonConfigFile);
try
{
x509Cert = amazonConfig->getConfig("SystemConfig", "x509CertificationFile");
}
catch (...)
{}
if ( x509Cert.empty() || x509Cert == oam::UnassignedName )
{
cout << "ERROR: x509CertificationFile not set, exiting" << endl;
exit (1);
}
ifstream File (x509Cert.c_str());
if (!File)
{
cout << "Error: x509CertificationFile not found, exiting" << endl;
exit (1);
}
try
{
x509PriKey = amazonConfig->getConfig("SystemConfig", "x509PrivateFile");
}
catch (...)
{}
if ( x509PriKey.empty() || x509PriKey == oam::UnassignedName )
{
cout << "ERROR: x509PrivateFile not set, exiting" << endl;
exit (1);
}
ifstream File1 (x509PriKey.c_str());
if (!File1)
{
cout << "Error: x509PrivateFile not found, exiting" << endl;
exit (1);
}
if ( x509PriKey == x509Cert )
{
cout << "Error: x509PrivateFile and x509CertificationFile are the same file name in the config file, exiting" << endl;
exit (1);
}
//standard config parmeters
try
{
systemName = amazonConfig->getConfig("SystemConfig", "SystemName");
systemType = amazonConfig->getConfig("SystemConfig", "SystemType");
elasticIPs = amazonConfig->getConfig("SystemConfig", "ElasticIPs");
umNumber = atoi(amazonConfig->getConfig("SystemConfig", "UserModuleCount").c_str());
useUMEBS = amazonConfig->getConfig("SystemConfig", "UseUMEBSVolumes");
UMvolumeSize = atoi(amazonConfig->getConfig("SystemConfig", "UMEBSVolumeSize").c_str());
pmNumber = atoi(amazonConfig->getConfig("SystemConfig", "PerformanceModuleCount").c_str());
dbrootPer = atoi(amazonConfig->getConfig("SystemConfig", "DBRootsPerPM").c_str());
usePMEBS = amazonConfig->getConfig("SystemConfig", "UsePMEBSVolumes");
PMvolumeSize = atoi(amazonConfig->getConfig("SystemConfig", "PMEBSVolumeSize").c_str());
NMSIPAddress = amazonConfig->getConfig("SystemConfig", "SNMPTrapIPAddr");
rootPassword = amazonConfig->getConfig("SystemConfig", "RootPassword");
UserModuleInstanceType = amazonConfig->getConfig("SystemConfig", "UserModuleInstanceType");
UserModuleSecurityGroup = amazonConfig->getConfig("SystemConfig", "UserModuleSecurityGroup");
TotalUmMemory = amazonConfig->getConfig("SystemConfig", "TotalUmMemory");
NumBlocksPct = amazonConfig->getConfig("SystemConfig", "NumBlocksPct");
existingPMInstances = amazonConfig->getConfig("SystemConfig", "PerformanceModuleInstances");
existingUMInstances = amazonConfig->getConfig("SystemConfig", "UserModuleInstances");
autoTagging = amazonConfig->getConfig("SystemConfig", "AutoTagging");
region = amazonConfig->getConfig("SystemConfig", "Region");
subnetID = amazonConfig->getConfig("SystemConfig", "SubNetID");
VPCStartPrivateIP = amazonConfig->getConfig("SystemConfig", "VPCStartPrivateIP");
UMprivateIPS = amazonConfig->getConfig("SystemConfig", "UserModulePrivateIP");
PMprivateIPS = amazonConfig->getConfig("SystemConfig", "PerformanceModulePrivateIP");
PMEBSFailoverSupport = amazonConfig->getConfig("SystemConfig", "PMEBSFailoverSupport");
}
catch (...)
{}
//hidden config paremeters
try
{
localQuery = amazonConfig->getConfig("SystemConfig", "LocalQuery");
}
catch (...)
{}
if ( localQuery.empty() )
localQuery = "n";
try
{
MySQLRep = amazonConfig->getConfig("SystemConfig", "MySQLRep");
}
catch (...)
{}
if ( MySQLRep.empty() )
MySQLRep = "n";
}
// validate config paramaters
if ( ( atoi(NumBlocksPct.c_str()) < 0 || atoi(NumBlocksPct.c_str()) > 100)
&& NumBlocksPct != oam::UnassignedName)
{
cout << "Invalid NumBlocksPct (1-100), exiting..." << endl;
exit (1);
}
if ( x509PriKey.find("/", 0) != 0 )
{
cout << "Error: x509PrivateFile '" + x509PriKey + "' missing directory name, exiting" << endl;
exit (1);
}
if ( x509Cert.find("/", 0) != 0 )
{
cout << "Error: x509CertificationFile '" + x509Cert + "' missing directory name, exiting" << endl;
exit (1);
}
if ( region == "eu-west-1" ||
region == "sa-east-1" ||
region == "us-east-1" ||
region == "ap-northeast-1" ||
region == "us-west-2" ||
region == "us-west-1" ||
region == "ap-southeast-1" )
{
try
{
sysConfig->setConfig(InstallSection, "AmazonRegion", region);
}
catch (...)
{
cout << endl << "ERROR: Problem setting AmazonRegion from the columnstore System Configuration file" << endl;
exit(1);
}
}
else
{
cout << endl << "ERROR: Invalid Region Name, run ec2-describe-regions to get list. exiting..." << endl;
exit (1);
}
//set the x.509 file locations
try
{
sysConfig->setConfig(InstallSection, "AmazonX509Certificate", x509Cert);
sysConfig->setConfig(InstallSection, "AmazonX509PrivateKey", x509PriKey);
}
catch (...)
{}
try
{
sysConfig->write();
}
catch (...)
{
cout << "ERROR: Failed trying to update columnstore System Configuration file" << endl;
exit(1);
}
//get Elastic IP to module assignments
if ( elasticIPs != oam::UnassignedName )
{
boost::char_separator<char> sep(",:");
boost::tokenizer< boost::char_separator<char> > tokens(elasticIPs, sep);
for ( boost::tokenizer< boost::char_separator<char> >::iterator it = tokens.begin();
it != tokens.end();
++it)
{
ModuleIP elasticip;
elasticip.IPaddress = *it;
++it;
elasticip.moduleName = *it;
elasticiplist.push_back(elasticip);
}
}
//get exist UM instance list, if there is one
vector <string> existinguminstance;
if ( systemType == "separate")
{
if ( existingUMInstances != oam::UnassignedName )
{
boost::char_separator<char> sep(",");
boost::tokenizer< boost::char_separator<char> > tokens(existingUMInstances, sep);
for ( boost::tokenizer< boost::char_separator<char> >::iterator it = tokens.begin();
it != tokens.end();
++it)
{
existinguminstance.push_back(*it);
}
}
}
else
umNumber = 0;
//get exist PM instance list, if there is one
vector <string> existingpminstance;
if ( existingPMInstances != oam::UnassignedName )
{
boost::char_separator<char> sep(",");
boost::tokenizer< boost::char_separator<char> > tokens(existingPMInstances, sep);
for ( boost::tokenizer< boost::char_separator<char> >::iterator it = tokens.begin();
it != tokens.end();
++it)
{
existingpminstance.push_back(*it);
}
}
//get Private IPs if VPC subNet configured
vector <string> umprivateip;
vector <string> pmprivateip;
if ( subnetID != oam::UnassignedName )
{
//set subnetID
try
{
sysConfig->setConfig(InstallSection, "AmazonSubNetID", subnetID);
}
catch (...)
{}
if ( VPCStartPrivateIP == "autoassign" )
{
for ( int um = 0 ; um < umNumber ; um++ )
{
umprivateip.push_back("autoassign");
}
for ( int pm = 0 ; pm < pmNumber ; pm++ )
{
pmprivateip.push_back("autoassign");
}
//set VPCNextPrivateIP
try
{
sysConfig->setConfig(InstallSection, "AmazonVPCNextPrivateIP", "autoassign");
}
catch (...)
{}
}
else
{
if ( VPCStartPrivateIP == oam::UnassignedName )
{
if ( UMprivateIPS == oam::UnassignedName )
{
cout << endl << "ERROR: Invalid UM Private IP Address List / VPCStartPrivateIP" << endl;
exit(1);
}
else
{
boost::char_separator<char> sep(",");
boost::tokenizer< boost::char_separator<char> > tokens(UMprivateIPS, sep);
for ( boost::tokenizer< boost::char_separator<char> >::iterator it = tokens.begin();
it != tokens.end();
++it)
{
if (!oam.isValidIP(*it))
{
cout << endl << "ERROR: Invalid UM Private IP Address: " << *it << endl;
exit(1);
}
umprivateip.push_back(*it);
}
if ( umNumber != (int) umprivateip.size() )
{
cout << endl << "ERROR: Number of UMs doesn't match number of UM Private IPs Provided" << endl;
exit(1);
}
}
if ( PMprivateIPS == oam::UnassignedName )
{
cout << endl << "ERROR: Invalid PM Private IP Address List / VPCStartPrivateIP" << endl;
exit(1);
}
else
{
boost::char_separator<char> sep(",");
boost::tokenizer< boost::char_separator<char> > tokens1(PMprivateIPS, sep);
for ( boost::tokenizer< boost::char_separator<char> >::iterator it = tokens1.begin();
it != tokens1.end();
++it)
{
if (!oam.isValidIP(*it))
{
cout << endl << "ERROR: Invalid PM Private IP Address: " << *it << endl;
exit(1);
}
pmprivateip.push_back(*it);
}
if ( pmNumber != (int) pmprivateip.size() )
{
cout << endl << "ERROR: Number of PMs doesn't match number of PM Private IPs Provided" << endl;
exit(1);
}
}
}
else
{
if (!oam.isValidIP(VPCStartPrivateIP))
{
cout << endl << "ERROR: Invalid Starting VPC Private IP Address: " << VPCStartPrivateIP << endl;
exit(1);
}
string VPCNextPrivateIP = VPCStartPrivateIP;
for ( int um = 0 ; um < umNumber ; um++ )
{
umprivateip.push_back(VPCNextPrivateIP);
try
{
VPCNextPrivateIP = oam.incrementIPAddress(VPCNextPrivateIP);
}
catch (...)
{
cout << endl << "ERROR: incrementIPAddress API error, check logs" << endl;
exit(1);
}
}
for ( int pm = 0 ; pm < pmNumber ; pm++ )
{
pmprivateip.push_back(VPCNextPrivateIP);
try
{
VPCNextPrivateIP = oam.incrementIPAddress(VPCNextPrivateIP);
}
catch (...)
{
cout << endl << "ERROR: incrementIPAddress API error, check logs" << endl;
exit(1);
}
}
//set VPCNextPrivateIP
try
{
sysConfig->setConfig(InstallSection, "AmazonVPCNextPrivateIP", VPCNextPrivateIP);
}
catch (...)
{}
}
}
}
//set AmazonPMFailover
try
{
sysConfig->setConfig(InstallSection, "AmazonPMFailover", PMEBSFailoverSupport);
}
catch (...)
{}
try
{
sysConfig->write();
}
catch (...)
{
cout << "ERROR: Failed trying to update columnstore System Configuration file" << endl;
exit(1);
}
//get local instance name (pm1)
localInstance = oam.getEC2LocalInstance();
if ( localInstance == "failed" || localInstance.empty() || localInstance == "")
{
cout << endl << "ERROR: Failed to get Instance ID, check configuration settings like region. exiting..." << endl;
exit (1);
}
instanceType = oam.getEC2LocalInstanceType();
if (instanceType.empty() || instanceType == "" || instanceType == "failed")
{
cout << endl << "ERROR: Failed to get Instance ID, check configuration settings like region. exiting..." << endl;
exit (1);
}
cout << "===== Setting up system '" + systemName + "' based on these settings ===== " << endl << endl;
cout << "columnstore Version = " << columnstore_version << "-" << columnstore_release << endl;
cout << "System Type = " << systemType << endl;
if ( subnetID != oam::UnassignedName )
{
cout << "SubNet ID = " << subnetID << endl;
if ( VPCStartPrivateIP == oam::UnassignedName )
{
if ( systemType == "separate" )
cout << "User Modules VPC Private IPs = " << UMprivateIPS << endl;
cout << "Performance Modules VPC Private IPs = " << PMprivateIPS << endl;
}
else
cout << "Starting VPC Private IP = " << VPCStartPrivateIP << endl;
}
if ( systemType == "separate" )
{
if ( UserModuleInstanceType == oam::UnassignedName )
cout << "Number of User Modules = " << umNumber << " (" + instanceType + ")" << endl;
else
cout << "Number of User Modules = " << umNumber << " (" + UserModuleInstanceType + ")" << endl;
if ( UserModuleSecurityGroup != oam::UnassignedName )
cout << "User Modules Instances Security Group = " << UserModuleSecurityGroup << endl;
if ( existingUMInstances != oam::UnassignedName )
cout << "Using User Modules Instances = " << existingUMInstances << endl;
cout << "Using EBS Volumes for User Module storage = " << useUMEBS << endl;
if ( useUMEBS == "y" )
cout << "User Module EBS Volume Size = " << UMvolumeSize << endl;
}
cout << "Number of Performance Modules = " << pmNumber << " (" + instanceType + ")" << endl;
if ( existingPMInstances != oam::UnassignedName )
cout << "Using Performance Modules Instances = " << existingPMInstances << endl;
if ( localQuery == "y" )
{
cout << "Local Query Feature = enabled" << endl;
if ( systemType == "combined" && localQuery == "y" )
{
cout << "NOTE: Local Query Feature is not valid on a 'combined' system, turning off feature" << endl;
localQuery == "n";
}
else
{
if ( MySQLRep == "n" )
{
cout << "NOTE: Local Query Feature is enabled and requires MySQL Replication, enabling MySQL Replication Feature" << endl;
MySQLRep = "y";
}
}
}
if ( MySQLRep == "y" )
cout << "MySQL Replication Feature = enabled" << endl;
cout << "Number of DBRoots per Performance Modules = " << dbrootPer << endl;
if ( systemType == "separate" )
{
cout << "Using EBS Volumes for Performance Module (DBRoot) storage = " << usePMEBS << endl;
if ( usePMEBS == "y" )
cout << "DBRoot EBS Volume Size = " << PMvolumeSize << endl;
}
else
{
cout << "Using EBS Volumes for Data storage = " << usePMEBS << endl;
if ( usePMEBS == "y" )
cout << "EBS Volume Size = " << PMvolumeSize << endl;
}
if ( elasticiplist.size() > 0 )
{
ModuleIPList::iterator list9 = elasticiplist.begin();
for (; list9 != elasticiplist.end() ; list9++)
{
cout << "Elastic IP Address " << (*list9).IPaddress << " assigned to " << (*list9).moduleName << endl;
}
}
cout << "PM EBSs Failover Support Enabled = " << PMEBSFailoverSupport << endl;
cout << "SNMP Trap Receiver IP Address = " << NMSIPAddress << endl;
if (autoTagging == "y" )
cout << "Instance and Volume Name Auto Tagging = enabled" << endl;
else
cout << "Instance and Volume Name Auto Tagging = disabled" << endl;
cout << "Amazon Region = " << region << endl;
//set calpont config settings
if ( TotalUmMemory != oam::UnassignedName )
{
cout << "TotalUmMemory = " << TotalUmMemory << endl;
try
{
sysConfig->setConfig("HashJoin", "TotalUmMemory", TotalUmMemory);
}
catch (...)
{
cout << endl << "ERROR: Problem setting SystemName from the columnstore System Configuration file" << endl;
exit(1);
}
}
if ( NumBlocksPct != oam::UnassignedName )
{
cout << "NumBlocksPct = " << NumBlocksPct << endl;
try
{
sysConfig->setConfig("DBBC", "NumBlocksPct", NumBlocksPct);
}
catch (...)
{
cout << endl << "ERROR: Problem setting SystemName from the columnstore System Configuration file" << endl;
exit(1);
}
}
if ( systemType == "separate" )
{
try
{
sysConfig->setConfig(InstallSection, "UMSecurityGroup", UserModuleSecurityGroup);
}
catch (...)
{
cout << "ERROR: Problem setting UMSecurityGroup from the columnstore System Configuration file" << endl;
exit(1);
}
try
{
sysConfig->setConfig(InstallSection, "UMInstanceType", UserModuleInstanceType);
}
catch (...)
{
cout << "ERROR: Problem setting InstanceType from the columnstore System Configuration file" << endl;
exit(1);
}
//verify and setup of modules count
if ( umNumber < 1 || umNumber > oam::MAX_MODULE )
{
cout << endl << "ERROR: Invalid User Module Count '" + oam.itoa(umNumber) + "', exiting" << endl;
exit (1);
}
}
try
{
sysConfig->setConfig(InstallSection, "PMInstanceType", instanceType);
}
catch (...)
{
cout << "ERROR: Problem setting InstanceType from the columnstore System Configuration file" << endl;
exit(1);
}
if ( usePMEBS == "y" )
{
PMEBS = true;
if ( systemType == "combined")
useUMEBS == "y";
}
else
PMEBS = false;
if ( useUMEBS == "y" )
UMEBS = true;
else
UMEBS = false;
try
{
sysConfig->setConfig(SystemSection, "SystemName", systemName);
sysConfig->setConfig(InstallSection, "AmazonAutoTagging", autoTagging);
}
catch (...)
{
cout << "ERROR: Problem setting SystemName from the columnstore System Configuration file" << endl;
exit(1);
}
if ( systemType == "separate" )
IserverTypeInstall = 1;
else if ( systemType == "combined" )
IserverTypeInstall = 2;
else
{
cout << "Error: SystemType is invalid (separare or combined only), exiting" << endl;
exit (1);
}
// set Server Type Installation Indicator
try
{
sysConfig->setConfig(InstallSection, "ServerTypeInstall", oam.itoa(IserverTypeInstall));
}
catch (...)
{}
// set root password
try
{
sysConfig->setConfig(InstallSection, "rpw", rootPassword);
}
catch (...)
{}
try
{
sysConfig->write();
}
catch (...)
{
cout << "ERROR: Failed trying to update columnstore System Configuration file" << endl;
exit(1);
}
//user module
try
{
sysConfig->setConfig(ModuleSection, "ModuleCount2", oam.itoa(umNumber));
}
catch (...)
{}
if ( pmNumber < 1 || pmNumber > oam::MAX_MODULE )
{
cout << endl << "ERROR: Invalid Performance Module Count '" + oam.itoa(pmNumber) + "', exiting" << endl;
exit (1);
}
//performance module
try
{
sysConfig->setConfig(ModuleSection, "ModuleCount3", oam.itoa(pmNumber));
}
catch (...)
{}
if ( dbrootPer < 1 )
{
cout << endl << "ERROR: Invalid DBRoot Count per pm '" + oam.itoa(dbrootPer) + "', exiting" << endl;
exit (1);
}
if (PMEBS)
{
if ( PMvolumeSize < 1 || PMvolumeSize > 1024 )
{
cout << endl << "ERROR: Invalid Performance Module EBS Volume Size '" + oam.itoa(PMvolumeSize) + "', exiting" << endl;
exit (1);
}
try
{
sysConfig->setConfig(InstallSection, "PMVolumeSize", oam.itoa(PMvolumeSize));
}
catch (...)
{}
}
if (UMEBS && systemType == "separate")
{
if ( UMvolumeSize < 1 || UMvolumeSize > 1024 )
{
cout << endl << "ERROR: Invalid User Module EBS Volume Size '" + oam.itoa(UMvolumeSize) + "', exiting" << endl;
exit (1);
}
try
{
sysConfig->setConfig(InstallSection, "UMVolumeSize", oam.itoa(UMvolumeSize));
}
catch (...)
{}
}
try
{
sysConfig->setConfig(SystemSection, "NMSIPAddress", NMSIPAddress);
}
catch (...)
{}
try
{
sysConfig->write();
}
catch (...)
{
cout << "ERROR: Failed trying to update columnstore System Configuration file" << endl;
cleanupSystem();
}
cout << endl << "===== Launch Instances =====" << endl << endl;
Instance instance;
instance.instanceName = localInstance;
instance.moduleName = "pm1";
instance.IPaddress = getIPAddress(localInstance);
pminstancelist.push_back(instance);
cout << "Local Instance for pm1: " + localInstance << endl;
if ( autoTagging == "y" )
{
cout << " Creating Instance Tag for pm1" << endl << endl;
string tagValue = systemName + "-pm1";
oam.createEC2tag( localInstance, "Name", tagValue );
}
if ( systemType == "separate" )
{
//launch um Instances
//check if using existing instances
int um = 1;
if ( !existinguminstance.empty() )
{
//assign um Instances
std::vector<std::string>::iterator list = existinguminstance.begin();
for (; list != existinguminstance.end() ; list++)
{
string module = "um" + oam.itoa(um);
cout << "Assigning Instance for " + module;
string instanceName = *list;
cout << ": " << instanceName << endl;
//check if Instance is running
getIPAddress(instanceName);
Instance instance;
instance.instanceName = instanceName;
instance.moduleName = module;
uminstancelist.push_back(instance);
um++;
if ( um > umNumber )
break;
}
}
//launch um Instances
std::vector<std::string>::iterator umprivatelist = umprivateip.begin();
for ( ; um < umNumber + 1 ; um ++ )
{
string module = "um" + oam.itoa(um);
ModuleIP moduleip;
moduleip.moduleName = module;
if ( umprivateip.size() == 0 )
moduleip.IPaddress = oam::UnassignedName;
else
{
moduleip.IPaddress = *umprivatelist;
umprivatelist++;
}
while (true)
{
if ( launchInstanceCount < numCores )
{
launchInstanceCount++;
pthread_t launchinstancethread;
int status = pthread_create (&launchinstancethread, NULL, (void* (*)(void*)) &launchInstanceThread, &moduleip);
if ( status != 0 )
{
cout << "launchInstanceThread failed for " + module << endl;
cleanupSystem();
}
sleep(1);
break;
}
else
sleep(10);
}
}
}
//check if using existing instances
int pm = 2;
if ( !existingpminstance.empty() )
{
//assign pm Instances
std::vector<std::string>::iterator list = existingpminstance.begin();
for (; list != existingpminstance.end() ; list++)
{
string module = "pm" + oam.itoa(pm);
cout << "Assigning Instance for " + module;
string instanceName = *list;
cout << ": " << instanceName << endl;
//check if Instance is running
getIPAddress(instanceName);
Instance instance;
instance.instanceName = instanceName;
instance.moduleName = module;
pminstancelist.push_back(instance);
pm++;
if ( pm > pmNumber )
break;
}
}
//launch pm Instances
std::vector<std::string>::iterator pmprivatelist = pmprivateip.begin();
for ( ; pm < pmNumber + 1 ; pm ++ )
{
string module = "pm" + oam.itoa(pm);
ModuleIP moduleip;
moduleip.moduleName = module;
if ( pmprivateip.size() == 0 )
moduleip.IPaddress = oam::UnassignedName;
else
{
moduleip.IPaddress = *pmprivatelist;
pmprivatelist++;
}
while (true)
{
if ( launchInstanceCount < numCores )
{
launchInstanceCount++;
pthread_t launchinstancethread;
int status = pthread_create (&launchinstancethread, NULL, (void* (*)(void*)) &launchInstanceThread, &moduleip);
if ( status != 0 )
{
cout << "launchInstanceThread failed for " + module << endl;
cleanupSystem();
}
sleep(1);
break;
}
else
sleep(10);
}
}
//set is a single instance install
bool ss = false;
if ( systemType == "combined" && pmNumber == 1 )
ss = true;
if (!ss)
{
//first wait until Launch Thread Count is at zero or hit timeout
int wait = 0;
while (true)
{
if ( launchInstanceCount == 0 )
break;
sleep(10);
wait++;
// give it 30 minutes to complete
if ( wait >= 1800 )
{
cout << "Timed out (30 minutes) waiting for Instances to be Launched" << endl;
cleanupSystem();
}
}
//setup new root password if needed
if ( rootPassword != AMIrootPassword)
setRootPassword();
}
else
cout << endl;
cout << endl;
//setup volumes, if needed
if ( PMEBS || UMEBS)
{
cout << "===== Create and Attach Volumes =====" << endl << endl;
if (UMEBS && systemType == "separate")
{
//create um volumes
for ( int vum = 1 ; vum < umNumber + 1 ; vum ++ )
{
string module = "um" + oam.itoa(vum);
while (true)
{
if ( createVolumeCount < numCores )
{
createVolumeCount++;
pthread_t createvolumethread;
int status = pthread_create (&createvolumethread, NULL, (void* (*)(void*)) &createVolumeThread, &module);
// createVolumeThread(module);
if ( status != 0 )
{
cout << "createVolumeThread failed for " + module << endl;
cleanupSystem();
}
sleep(5);
break;
}
else
sleep(10);
}
}
}
if ( PMEBS)
{
//create pm volumes
for ( int vpm = 1 ; vpm < pmNumber + 1 ; vpm ++ )
{
for ( int dbroot = 1 ; dbroot < dbrootPer + 1 ; dbroot++ )
{
string module = "pm" + oam.itoa(vpm);
while (true)
{
if ( createVolumeCount < numCores )
{
createVolumeCount++;
createdbrootid++;
pthread_t createvolumethread;
int status = pthread_create (&createvolumethread, NULL, (void* (*)(void*)) &createVolumeThread, &module);
// createVolumeThread(module);
if ( status != 0 )
{
cout << "createVolumeThread failed for " + module << endl;
cleanupSystem();
}
sleep(5);
break;
}
else
sleep(10);
}
}
}
}
//wait until Create Volume Count is at zero or hit timeout
int wait = 0;
while (true)
{
if ( createVolumeCount == 0 )
break;
sleep(10);
wait++;
// give it 2 hours to complete
if ( wait >= 720 )
{
cout << "Timed out (120 minutes) waiting for Volumes to be created" << endl;
cleanupSystem();
sleep(600000);
}
}
cout << endl;
}
cout << endl << "===== columnstore Configuration Setup and Installation =====" << endl << endl;
if ( systemType == "combined" )
{
cout << "----- Combined System Type - Setup and Install Calpont-MySQL Packages -----" << endl << endl;
//setup external link, if needed
if (UMEBS)
{
cmd = "mount " + installDir + "/data1 > /dev/null 2>&1";
system(cmd.c_str());
cmd = "mkdir -p " + installDir + "/data1/mysqldb > /dev/null 2>&1";
system(cmd.c_str());
cmd = "mkdir -p " + installDir + "/mysql > /dev/null 2>&1";
system(cmd.c_str());
cmd = "cd " + installDir + "/mysql/;ln -s " + installDir + "/data1/mysqldb db > /dev/null 2>&1";
system(cmd.c_str());
}
//install rpms
system("rpm -ivh /root/infinidb-mysql*rpm /root/infinidb-storage-engine*rpm");
cout << endl;
}
//
// update /root/Columnstore.xml
//
cout << "----- Updating columnstore Configuration File (Columnstore.xml) -----" << endl << endl;
//setup for multi-server install
try
{
sysConfig->setConfig(InstallSection, "SingleServerInstall", "n");
}
catch (...)
{}
//set for amazon cloud
string cloud = "amazon-ec2";
if ( subnetID != oam::UnassignedName )
cloud = "amazon-vpc";
try
{
sysConfig->setConfig(InstallSection, "Cloud", cloud);
}
catch (...)
{}
//elastic IP setup
if ( elasticiplist.size() > 0 )
{
try
{
sysConfig->setConfig(InstallSection, "AmazonElasticIPCount", oam.itoa(elasticiplist.size()));
}
catch (...)
{
cout << "ERROR: Problem setting AmazonElasticIPCount in the columnstore System Configuration file" << endl;
cleanupSystem();
}
int id = 1;
ModuleIPList::iterator list9 = elasticiplist.begin();
for (; list9 != elasticiplist.end() ; list9++)
{
string moduleName = (*list9).moduleName;
string IPaddress = (*list9).IPaddress;
string AmazonElasticModule = "AmazonElasticModule" + oam.itoa(id);
string AmazonElasticIPAddr = "AmazonElasticIPAddr" + oam.itoa(id);
//write volume and device name
try
{
sysConfig->setConfig(InstallSection, AmazonElasticModule, moduleName);
sysConfig->setConfig(InstallSection, AmazonElasticIPAddr, IPaddress);
}
catch (...)
{
cout << "ERROR: Problem setting Volume/Device Names in the columnstore System Configuration file" << endl;
cleanupSystem();
}
id++;
}
}
//system dbroot config
int systemDbrootCount = pmNumber * dbrootPer;
try
{
sysConfig->setConfig(SystemSection, "DBRootCount", oam.itoa(systemDbrootCount));
}
catch (...)
{
cout << "ERROR: Problem setting DBRoot Count in the columnstore System Configuration file" << endl;
cleanupSystem();
}
for ( int id = 1 ; id < systemDbrootCount + 1 ; id++ )
{
string dbrootPar = "DBRoot" + oam.itoa(id);
string dbrootLoc = installDir + "/data" + oam.itoa(id);
try
{
sysConfig->setConfig(SystemSection, dbrootPar, dbrootLoc);
}
catch (...)
{
cout << "ERROR: Problem setting DBRoot Count in the columnstore System Configuration file" << endl;
cleanupSystem();
}
}
//set module configuration
InstanceList::iterator list4 = uminstancelist.begin();
for (; list4 != uminstancelist.end() ; list4++)
{
string instance = (*list4).instanceName;
string module = (*list4).moduleName;
int moduleID = atoi(module.substr(MAX_MODULE_TYPE_SIZE, MAX_MODULE_ID_SIZE).c_str());
string IPAddress = (*list4).IPaddress;
string moduleHostNameParm = "ModuleHostName" + oam.itoa(moduleID) + "-1-2";
try
{
sysConfig->setConfig(ModuleSection, moduleHostNameParm, instance);
}
catch (...)
{
cout << "ERROR: Problem setting Host Name in the columnstore System Configuration file" << endl;
cleanupSystem();
}
string moduleIPAddrNameParm = "ModuleIPAddr" + oam.itoa(moduleID) + "-1-2";
try
{
sysConfig->setConfig(ModuleSection, moduleIPAddrNameParm, IPAddress);
}
catch (...)
{
cout << "ERROR: Problem setting IP address in the columnstore System Configuration file" << endl;
cleanupSystem();
}
}
InstanceList::iterator list5 = pminstancelist.begin();
for (; list5 != pminstancelist.end() ; list5++)
{
string instance = (*list5).instanceName;
string module = (*list5).moduleName;
int moduleID = atoi(module.substr(MAX_MODULE_TYPE_SIZE, MAX_MODULE_ID_SIZE).c_str());
string IPAddress = (*list5).IPaddress;
//cout << "IP Address for " << module << " " << IPAddress << endl;;
string moduleHostNameParm = "ModuleHostName" + oam.itoa(moduleID) + "-1-3";
try
{
sysConfig->setConfig(ModuleSection, moduleHostNameParm, instance);
}
catch (...)
{
cout << "ERROR: Problem setting Host Name in the columnstore System Configuration file" << endl;
cleanupSystem();
}
string moduleIPAddrNameParm = "ModuleIPAddr" + oam.itoa(moduleID) + "-1-3";
try
{
sysConfig->setConfig(ModuleSection, moduleIPAddrNameParm, IPAddress);
}
catch (...)
{
cout << "ERROR: Problem setting IP address in the columnstore System Configuration file" << endl;
cleanupSystem();
}
//DBRoots
string moduledbrootcount = "ModuleDBRootCount" + oam.itoa(moduleID) + "-3";
try
{
sysConfig->setConfig(ModuleSection, moduledbrootcount, oam.itoa(dbrootPer));
}
catch (...)
{
cout << "ERROR: Problem setting dbroot count in the columnstore System Configuration file" << endl;
cleanupSystem();
}
for ( int id = 1 ; id < dbrootPer + 1 ; id++ )
{
string moduledbrootid = "ModuleDBRootID" + oam.itoa(moduleID) + "-" + oam.itoa(id) + "-3";
int dbrootid;
if ( dbrootPer == 1 )
dbrootid = moduleID;
else
dbrootid = ((moduleID - 1) * dbrootPer) + id;
//cout << oam.itoa(moduleID) + " " + oam.itoa(id) + " " + oam.itoa(dbrootid) << endl;
try
{
sysConfig->setConfig(ModuleSection, moduledbrootid, oam.itoa(dbrootid));
}
catch (...)
{
cout << "ERROR: Problem setting DBRoot ID in the columnstore System Configuration file" << endl;
cleanupSystem();
}
}
}
//Config storage
if (UMEBS && systemType == "separate")
{
try
{
sysConfig->setConfig(InstallSection, "UMStorageType", "external");
}
catch (...)
{
cout << "ERROR: Problem setting UMStorageType in the columnstore System Configuration file" << endl;
cleanupSystem();
}
int id = 1;
VolumeList::iterator list6 = UMvolumelist.begin();
for (; list6 != UMvolumelist.end() ; list6++)
{
string volumeName = (*list6).volumeName;
string deviceName = (*list6).deviceName;
string volumeNameID = "UMVolumeName" + oam.itoa(id);
string deviceNameID = "UMVolumeDeviceName" + oam.itoa(id);
//write volume and device name
try
{
sysConfig->setConfig(InstallSection, volumeNameID, volumeName);
sysConfig->setConfig(InstallSection, deviceNameID, deviceName);
}
catch (...)
{
cout << "ERROR: Problem setting Volume/Device Names in the columnstore System Configuration file" << endl;
cleanupSystem();
}
id++;
}
}
if (PMEBS)
{
try
{
sysConfig->setConfig(InstallSection, "DBRootStorageType", "external");
}
catch (...)
{
cout << "ERROR: Problem setting DBRootStorageType in the columnstore System Configuration file" << endl;
cleanupSystem();
}
cmd = "mkdir -p " + installDir + "/local/etc/pm1 > /dev/null 2>&1";
system(cmd.c_str());
cmd = installDir + "/local/etc/pm1/fstab";
unlink(cmd.c_str());
cmd = "touch " + installDir + "/local/etc/pm1/fstab";
system(cmd.c_str());
cmd = "/etc/fstab.installerBackup";
unlink(cmd.c_str());
system("cp /etc/fstab /etc/fstab.installerBackup > /dev/null 2>&1");
int id = 1;
VolumeList::iterator list6 = PMvolumelist.begin();
for (; list6 != PMvolumelist.end() ; list6++)
{
string volumeName = (*list6).volumeName;
string deviceName = (*list6).deviceName;
string volumeNameID = "PMVolumeName" + oam.itoa(id);
string deviceNameID = "PMVolumeDeviceName" + oam.itoa(id);
//write volume and device name
try
{
sysConfig->setConfig(InstallSection, volumeNameID, volumeName);
sysConfig->setConfig(InstallSection, deviceNameID, deviceName);
}
catch (...)
{
cout << "ERROR: Problem setting Volume/Device Names in the columnstore System Configuration file" << endl;
cleanupSystem();
}
//update /etc/fstab with mount
string entry = deviceName + " " + installDir + "/data" + oam.itoa((*list6).dbrootID) + " ext2 noatime,nodiratime,noauto 0 0";
string cmd = "echo " + entry + " >> /etc/fstab";
system(cmd.c_str());
//use from addmodule later
cmd = "echo " + entry + " >> " + installDir + "/local/etc/pm1/fstab";
system(cmd.c_str());
id++;
}
}
try
{
sysConfig->write();
}
catch (...)
{
cout << "ERROR: Failed trying to update columnstore System Configuration file" << endl;
cleanupSystem();
}
//copy Columnstore.xml to Columnstore.xml.rpmsave for postConfigure no-prompt option
cmd = "rm -f " + MCSSYSCONFDIR + "/columnstore/Columnstore.xml.rpmsave";
system(cmd.c_str());
cmd = "cp " + MCSSYSCONFDIR + "/columnstore/Columnstore.xml " + MCSSYSCONFDIR + "/columnstore/Columnstore.xml.rpmsave";
int rtnCode = system(cmd.c_str());
if (WEXITSTATUS(rtnCode) != 0)
{
cout << "Error copying Columnstore.xml to Columnstore.xml.rpmsave" << endl;
cleanupSystem();
}
// run postConfigure with no-prompt option
cout << "----- Running the System Installer Script (postConfigure) -----" << endl;
string postConfigureCMD = installDir + "/bin/postConfigure -n -p " + rootPassword;
if ( postConfigureDebug )
postConfigureCMD = postConfigureCMD + " -d";
if ( localQuery == "y" )
postConfigureCMD = postConfigureCMD + " -lq";
if ( MySQLRep == "y" )
postConfigureCMD = postConfigureCMD + " -rep";
cout << endl << " Running command: " << postConfigureCMD << endl;
if ( postConfigureLog )
{
cout << "Outputting to log file " + postConfigureOutFile << ", please wait..." << endl;
string cmd = postConfigureCMD + " > " + postConfigureOutFile;
int ret = system(cmd.c_str());
if (WEXITSTATUS(ret) == 0 )
cout << "postConfigure Successfully Completed, system is ready to use" << endl << endl;
else
{
cout << "ERROR : postConfigure install error, check " << postConfigureOutFile << endl << endl;
if (postConfigureCleanup)
{
cout << "Running calpont-support script is capture system logs and other data" << endl << endl;
string cmd = installDir + "/bin/calpontSupport -p Calpont1 -hw -s -c -r -l";
system (cmd.c_str());
cleanupSystem();
}
}
}
else
{
int ret = system(postConfigureCMD.c_str());
if (WEXITSTATUS(ret) == 0 )
cout << "postConfigure Successfully Completed, system is ready to use" << endl << endl;
else
{
cout << endl << "ERROR : postConfigure install failure" << endl << endl;
if (postConfigureCleanup)
{
cout << "Running calpont-support script is capture system logs and other data" << endl << endl;
string cmd = installDir + "/bin/calpontSupport -p Calpont1 -hw -s -c -r -l";
system (cmd.c_str());
cleanupSystem();
}
}
}
}
string getIPAddress(string instance)
{
Oam oam;
string IPAddress = oam.getEC2InstanceIpAddress(instance);
if (IPAddress == "stopped" || IPAddress == "terminated")
{
cout << "ERROR: Instance " + instance + " not running, couldn't get IP Address" << endl << endl;
cleanupSystem();
}
return IPAddress;
}
void snmpAppCheck()
{
Oam oam;
cout << endl << "===== Setup the Network Management System (NMS) Server Configuration =====" << endl << endl;
cout << "This would be used to receive SNMP Traps from columnstore, like a Network Control Center" << endl;
cout << "Default to 0.0.0.0 to not enable snmptrap forwarding" << endl << endl;
prompt1 = "Enter IP Address(es) of NMS Server (0.0.0.0) > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) NMSIPAddress = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
return;
}
void setSystemName()
{
prompt1 = "Enter System Name (" + systemName + ") > ";
pcommand1 = readline(prompt1.c_str());
if (pcommand1)
{
if (strlen(pcommand1) > 0) systemName = pcommand1;
free(pcommand1);
pcommand1 = 0;
}
}
void setRootPassword()
{
Oam oam;
cout << endl << "--- Updating Root Password on all Instance(s) ---" << endl << endl;
InstanceList::iterator list1 = uminstancelist.begin();
for (; list1 != uminstancelist.end() ; list1++)
{
string instance = (*list1).instanceName;
string module = (*list1).moduleName;
//get IP Address of um instance
string ipAddress = oam.getEC2InstanceIpAddress(instance);
if (ipAddress == "stopped" || ipAddress == "terminated" )
{
cout << "ERROR: Instance " << instance << " failed to get private IP Address" << endl;
cleanupSystem();
}
string cmd = installDir + "/bin/remote_command.sh " + ipAddress + " " + AMIrootPassword + " '/root/updatePassword.sh " + rootPassword + "' > /dev/null 2>&1";
int rtnCode = system(cmd.c_str());
if (WEXITSTATUS(rtnCode) != 0)
{
cout << "ERROR: failed update of root password on " + module << endl;
cleanupSystem();
}
}
InstanceList::iterator list2 = pminstancelist.begin();
for (; list2 != pminstancelist.end() ; list2++)
{
string instance = (*list2).instanceName;
string module = (*list2).moduleName;
if ( module == "pm1" )
{
string cmd = "/root/updatePassword.sh " + rootPassword + " > /dev/null 2>&1";
int rtnCode = system(cmd.c_str());
if (WEXITSTATUS(rtnCode) != 0)
{
cout << "ERROR: failed update root of password on " + module << endl;
cleanupSystem();
}
continue;
}
//get IP Address of pm instance
string ipAddress = oam.getEC2InstanceIpAddress(instance);
if (ipAddress == "stopped" || ipAddress == "terminated" )
{
cout << "ERROR: Instance " << instance << " failed to get private IP Address" << endl;
cleanupSystem();
}
string cmd = installDir + "/bin/remote_command.sh " + ipAddress + " " + AMIrootPassword + " '/root/updatePassword.sh " + rootPassword + "' > /dev/null 2>&1";
int rtnCode = system(cmd.c_str());
if (WEXITSTATUS(rtnCode) != 0)
{
cout << "ERROR: failed update root of password on " + module << endl;
cleanupSystem();
}
}
}
void launchInstanceThread(ModuleIP moduleip)
{
Oam oam;
//get module info
string moduleName = moduleip.moduleName;
string IPAddress = moduleip.IPaddress;
//due to bad instances getting launched causing scp failures
//have retry login around fail scp command where a instance will be relaunched
int instanceRetry = 0;
for ( ; instanceRetry < 5 ; instanceRetry ++ )
{
if (cleanupRunning)
pthread_exit(0);
string instanceName;
if ( moduleName.find("um") == 0 )
instanceName = oam.launchEC2Instance(moduleName, IPAddress, UserModuleInstanceType, UserModuleSecurityGroup);
else
instanceName = oam.launchEC2Instance(moduleName, IPAddress);
if ( instanceName == "failed" )
{
cout << " *** Failed to Launch an Instance for " + moduleName << ", will retry up to 5 times" << endl;
continue;
}
cout << "Launched Instance for " << moduleName << ": " << instanceName << endl;
//give time for instance to startup
sleep(60);
cout << " SCP x.509 files to " + moduleName << endl;
string ipAddress = oam::UnassignedName;
bool pass = false;
for ( int retry = 0 ; retry < 60 ; retry++ )
{
if (cleanupRunning)
pthread_exit(0);
//get IP Address of pm instance
if ( ipAddress == oam::UnassignedName || ipAddress == "stopped" || ipAddress == "No-IPAddress" )
{
ipAddress = oam.getEC2InstanceIpAddress(instanceName);
if (ipAddress == "stopped" || ipAddress == "No-IPAddress" )
{
sleep(5);
continue;
}
}
string cmd = installDir + "/bin/remote_scp_put.sh " + ipAddress + " " + AMIrootPassword + " " + x509Cert + " > /tmp/scp.log_" + instanceName;
int rtnCode = system(cmd.c_str());
if (WEXITSTATUS(rtnCode) == 0)
{
pass = true;
break;
}
sleep(5);
}
if (!pass)
{
cout << " *** SCP Failed to Instance for " + moduleName << ", recreate a new instance" << endl;
cout << " *** Terminating Module (" + moduleName + ") Instance: " + instanceName << endl;
oam.terminateEC2Instance( instanceName );
continue;
}
pass = false;
for ( int retry = 0 ; retry < 60 ; retry++ )
{
if (cleanupRunning)
pthread_exit(0);
string cmd = installDir + "/bin/remote_scp_put.sh " + ipAddress + " " + AMIrootPassword + " " + x509PriKey + " > /tmp/scp.log_" + instanceName;
int rtnCode = system(cmd.c_str());
if (WEXITSTATUS(rtnCode) == 0)
{
pass = true;
break;
}
sleep(5);
}
if (!pass)
{
cout << " *** SCP Failed to Instance for " + moduleName << ", recreate a new instance" << endl;
cout << " *** Terminating Module (" + moduleName + ") Instance: " + instanceName << endl;
oam.terminateEC2Instance( instanceName );
continue;
}
Instance instance;
instance.instanceName = instanceName;
instance.moduleName = moduleName;
instance.IPaddress = ipAddress;
//cout << "IP Address for " << moduleName << " " << ipAddress << endl;
if ( moduleName.find("um") == 0 )
uminstancelist.push_back(instance);
else
pminstancelist.push_back(instance);
if ( autoTagging == "y" )
{
cout << " Creating Instance Tag for " << moduleName << endl;
string tagValue = systemName + "-" + moduleName;
oam.createEC2tag( instanceName, "Name", tagValue );
}
if ( elasticiplist.size() > 0 )
{
ModuleIPList::iterator list9 = elasticiplist.begin();
for (; list9 != elasticiplist.end() ; list9++)
{
if ( moduleName == (*list9).moduleName )
{
cout << " Assigning Elastic IP Address " << (*list9).IPaddress << " to " << (*list9).moduleName << endl;
try
{
oam.assignElasticIP(instanceName, (*list9).IPaddress);
}
catch (...)
{
cout << endl << "**** Assigning Elastic IP Address Failed : assignElasticIP API Error";
}
break;
}
}
}
break;
}
if ( instanceRetry >= 5 )
{
cout << " *** Failed to Successfully Launch Instance for " + moduleName << endl;
cleanupSystem();
pthread_exit(0);
}
launchInstanceCount--;
// exit thread
// return;
pthread_exit(0);
}
void createVolumeThread(string module)
{
Oam oam;
Volume volume;
//local copies
string moduleName = module;
int volumeSize;
string device;
string volumeName;
int dbrootid = 0;
string name;
if ( moduleName.find("um") == 0 )
{
device = UMdeviceName + moduleName.substr(MAX_MODULE_TYPE_SIZE, MAX_MODULE_ID_SIZE);
volumeSize = UMvolumeSize;
cout << "Creating Volume for module " << moduleName << endl;
name = moduleName;
}
else
{
//pm volume setup
dbrootid = createdbrootid;
device = PMdeviceName + deviceLetter[lid] + oam.itoa(did);
volumeSize = PMvolumeSize;
//bump id numbers
did++;
if ( did > 10 )
{
did = 1;
lid++;
if ( deviceLetter[lid] == "end" )
lid = 0;
}
cout << "Creating Volume for DBRoot#" << dbrootid << " on module " << moduleName << endl;
name = "DBRoot#" + oam.itoa(dbrootid);
}
//create volume
int retry = 0;
for ( ; retry < 5 ; retry++ )
{
if (cleanupRunning)
pthread_exit(0);
volumeName = oam.createEC2Volume(oam.itoa(volumeSize), name);
if ( volumeName == "failed" || volumeName.empty() )
cout << " *** ERROR: Failed to create a Volume for " << name << ", retry up to 5 times " << endl;
else
break;
}
if ( retry >= 5 )
{
cout << " *** ERROR: Failed to create a Volume for " << name << ", do cleanup" << endl;
cleanupSystem();
// exit (1);
pthread_exit(0);
}
// pthread_mutex_lock(&THREAD_LOCK);
volume.moduleName = moduleName;
volume.volumeName = volumeName;
volume.deviceName = device;
volume.dbrootID = dbrootid;
if ( moduleName.find("um") == 0 )
UMvolumelist.push_back(volume);
else
PMvolumelist.push_back(volume);
// pthread_mutex_unlock(&THREAD_LOCK);
cout << " Attach Volume and format : " << volumeName << ":" << device << " for " << name << endl;
//attach volumes to local instance
retry = 0;
for ( ; retry < 5 ; retry++ )
{
if (cleanupRunning)
pthread_exit(0);
if (!oam.attachEC2Volume(volumeName, device, localInstance))
{
cout << " *** ERROR: Volume " << volumeName << " failed to attach to: " << localInstance << ":" << name << ", retry up to 5 times " << endl;
oam.detachEC2Volume(volumeName);
}
else
break;
}
if ( retry >= 5 )
{
cout << " *** ERROR: Volume " << volumeName << " failed to attach to: " << localInstance << ":" << name << ", do cleanup " << endl;
cleanupSystem();
// exit (1);
pthread_exit(0);
}
//format attached volume
string cmd = "mkfs.ext2 -F " + device + " > /dev/null 2>&1";
system(cmd.c_str());
if (cleanupRunning)
pthread_exit(0);
//move volume if not assigned to local module (pm1)
if ( moduleName != "pm1" )
{
retry = 0;
for ( ; retry < 5 ; retry++ )
{
if (cleanupRunning)
pthread_exit(0);
if (!oam.detachEC2Volume(volumeName))
{
cout << "*** ERROR: Volume " << volumeName << " failed to detach from local instance, retry up to 5 times " << endl;
}
else
break;
}
if ( retry >= 5 )
{
cout << "*** ERROR: Volume " << volumeName << " failed to detach from local instance, do cleanup " << endl;
cleanupSystem();
// exit (1);
pthread_exit(0);
}
//attach to real instance
if ( moduleName.find("um") == 0 )
{
InstanceList::iterator list2 = uminstancelist.begin();
for (; list2 != uminstancelist.end() ; list2++)
{
if (cleanupRunning)
pthread_exit(0);
if ( moduleName == (*list2).moduleName )
{
//attach volumes to real instance
if (!oam.attachEC2Volume(volumeName, device, (*list2).instanceName))
{
cout << "ERROR: Volume " << volumeName << " failed to attach to: " << (*list2).instanceName << ":" << moduleName << endl;
cleanupSystem();
// exit (1);
pthread_exit(0);
}
}
}
}
else
{
//attach to real instance
InstanceList::iterator list2 = pminstancelist.begin();
for (; list2 != pminstancelist.end() ; list2++)
{
if (cleanupRunning)
pthread_exit(0);
if ( moduleName == (*list2).moduleName )
{
//attach volumes to real instance
retry = 0;
for ( ; retry < 5 ; retry++ )
{
if (!oam.attachEC2Volume(volumeName, device, (*list2).instanceName))
{
cout << "*** ERROR: Volume " << volumeName << " failed to attach to: " << (*list2).instanceName << ":" << moduleName << ", retry up to 5 times " << endl;
oam.detachEC2Volume(volumeName);
}
else
break;
}
if ( retry >= 5 )
{
cout << "*** ERROR: Volume " << volumeName << " failed to attach to: " << (*list2).instanceName << ":" << moduleName << ", do cleanup " << endl;
cleanupSystem();
// exit (1);
pthread_exit(0);
}
}
}
}
}
if ( autoTagging == "y" )
{
if ( moduleName.find("um") == 0 )
{
cout << " Creating Volume Tag for " << moduleName << endl;
string tagValue = systemName + "-" + moduleName;
oam.createEC2tag( volumeName, "Name", tagValue );
}
else
{
cout << " Creating Volume Tag for DBRoot#" << dbrootid << endl;
string tagValue = systemName + "-dbroot" + oam.itoa(dbrootid);
oam.createEC2tag( volumeName, "Name", tagValue );
}
}
createVolumeCount--;
// exit thread
// return;
pthread_exit(0);
}
/*
unsigned getNumCores()
{
ifstream cpuinfo("/proc/cpuinfo");
if (!cpuinfo.good())
return 2;
unsigned nc = 0;
string line;
getline(cpuinfo, line);
unsigned i = 0;
while (i < 10000 && cpuinfo.good() && !cpuinfo.eof())
{
string::size_type pos = line.find("processor",0);
if (pos != string::npos)
nc++;
getline(cpuinfo, line);
++i;
}
return nc;
}
*/
void cleanupSystem(bool terminate)
{
Oam oam;
if (cleanupRunning)
return;
cleanupRunning = true;
//get local module name
oamModuleInfo_t t;
string localModuleName = "pm1";
try
{
t = oam.getModuleInfo();
localModuleName = boost::get<0>(t);
}
catch (...) {}
if ( terminate )
{
cout << endl << "***** Performing System Cleanup *****" << endl << endl;
system("umount /usr/local/mariadb/columnstore/data* > /dev/null 2>&1");
//run pre-uninstall
string cmd = installDir + "/bin/pre-uninstall > /dev/null 2>&1";
system(cmd.c_str());
InstanceList::iterator list1 = uminstancelist.begin();
for (; list1 != uminstancelist.end() ; list1++)
{
string instance = (*list1).instanceName;
string module = (*list1).moduleName;
cout << "Terminating User Module (" + module + ") Instance: " + instance << endl;
oam.terminateEC2Instance( instance );
}
cout << endl;
InstanceList::iterator list2 = pminstancelist.begin();
for (; list2 != pminstancelist.end() ; list2++)
{
string instance = (*list2).instanceName;
string module = (*list2).moduleName;
if ( module == localModuleName )
continue;
cout << "Terminating Performance Module (" + module + ") Instance: " + instance << endl;
oam.terminateEC2Instance( instance );
}
}
else
{
cout << endl << "***** Performing Stopping System Instances *****" << endl << endl;
InstanceList::iterator list1 = uminstancelist.begin();
for (; list1 != uminstancelist.end() ; list1++)
{
string instance = (*list1).instanceName;
string module = (*list1).moduleName;
cout << "Stopping User Module (" + module + ") Instance: " + instance << endl;
oam.stopEC2Instance( instance );
}
cout << endl;
InstanceList::iterator list2 = pminstancelist.begin();
for (; list2 != pminstancelist.end() ; list2++)
{
string instance = (*list2).instanceName;
string module = (*list2).moduleName;
if ( module == localModuleName )
continue;
cout << "Stopping Performance Module (" + module + ") Instance: " + instance << endl;
oam.stopEC2Instance( instance );
}
cout << endl << "Instance Stoppage finished, exiting" << endl << endl;
exit (1);
}
// volumes
cout << endl;
VolumeList::iterator list3 = UMvolumelist.begin();
for (; list3 != UMvolumelist.end() ; list3++)
{
string volumeName = (*list3).volumeName;
string module = (*list3).moduleName;
cout << "Detaching and Deleting Volume (" + module + "): " + volumeName << endl;
oam.detachEC2Volume( volumeName );
oam.deleteEC2Volume( volumeName );
}
cout << endl;
VolumeList::iterator list4 = PMvolumelist.begin();
for (; list4 != PMvolumelist.end() ; list4++)
{
string volumeName = (*list4).volumeName;
int dbrootID = (*list4).dbrootID;
string device = (*list4).deviceName;
cout << "Detaching and Deleting (DBRoot#" + oam.itoa(dbrootID) + ") Volume: " + volumeName << endl;
//unmount pm1 disk
if ( (*list4).moduleName == "pm1" )
{
string cmd = "umount " + installDir + "/data" + oam.itoa(dbrootID) + " > /dev/null 2>&1";
system(cmd.c_str());
cmd = "rm -f " + device + " > /dev/null 2>&1";
system(cmd.c_str());
}
oam.detachEC2Volume( volumeName );
oam.deleteEC2Volume( volumeName );
}
system("rm -f /root/.ssh/known_hosts");
system("mv -f /etc/fstab.installerBackup /etc/fstab > /dev/null 2>&1");
if ( systemType == "combined" )
{
cout << "----- Combined System Type Uninstall Calpont-MySQL Packages -----" << endl << endl;
system("rpm -e infinidb-mysql infinidb-storage-engine");
}
cout << endl << "Cleanup finished, exiting" << endl << endl;
exit (1);
}