renommage majuscules qd public et debut env service
This commit is contained in:
parent
bfc872dab8
commit
04e1e1b964
@ -5,9 +5,8 @@
|
||||
#include <iostream>
|
||||
#include "BashManager.h"
|
||||
|
||||
int BashManager::execute(string command)
|
||||
int BashManager::Execute(string command)
|
||||
{
|
||||
cout << "command is " << command << endl;
|
||||
FILE * p = popen(command.c_str(),"r");
|
||||
if( p == NULL)
|
||||
{
|
||||
@ -18,7 +17,7 @@ int BashManager::execute(string command)
|
||||
return 0;
|
||||
}
|
||||
|
||||
string BashManager::executeAndReadResult(string command)
|
||||
string BashManager::ExecuteAndReadResult(string command)
|
||||
{
|
||||
string result="";
|
||||
char lineBuffer [4095]={0}; //4095 is the maximum length of a shell line
|
||||
|
@ -12,8 +12,8 @@ using namespace std;
|
||||
class BashManager
|
||||
{
|
||||
public:
|
||||
static string executeAndReadResult(string command);
|
||||
static int execute(string command);
|
||||
static string ExecuteAndReadResult(string command);
|
||||
static int Execute(string command);
|
||||
};
|
||||
|
||||
#endif
|
@ -116,12 +116,12 @@ int BashModule::executeScriptAs(string serviceUsername, string script)
|
||||
}
|
||||
|
||||
//public methods
|
||||
int BashModule::prepare()
|
||||
int BashModule::Prepare()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BashModule::deploy (string serviceUsername)
|
||||
int BashModule::Deploy (string serviceUsername)
|
||||
{
|
||||
string deployScript="./services/"+serviceUsername+"/deploy.sh"; //to be executed as current user
|
||||
string deployAsScript="./services/"+serviceUsername+"/deploy_user.sh"; //to be executed as the user corresponding to the service
|
||||
@ -136,7 +136,7 @@ int BashModule::deploy (string serviceUsername)
|
||||
}
|
||||
|
||||
|
||||
int BashModule::remove (string serviceUsername)
|
||||
int BashModule::Remove (string serviceUsername)
|
||||
{
|
||||
string removeScript="./services/"+serviceUsername+"/undeploy_user.sh";
|
||||
if (executeScript(serviceUsername,removeScript)!=0){
|
||||
@ -146,7 +146,7 @@ int BashModule::remove (string serviceUsername)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BashModule::clean()
|
||||
int BashModule::Clean()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,10 +12,10 @@ class BashModule : public Module
|
||||
public:
|
||||
BashModule();
|
||||
~BashModule(){} //inline
|
||||
int prepare ();
|
||||
int deploy (string serviceUsername);
|
||||
int remove(string serviceUsername);
|
||||
int clean ();
|
||||
int Prepare ();
|
||||
int Deploy (string serviceUsername);
|
||||
int Remove(string serviceUsername);
|
||||
int Clean ();
|
||||
private:
|
||||
int executeScript(string serviceUsername,string script);
|
||||
int executeScriptAs(string serviceUsername,string script);
|
||||
|
@ -11,43 +11,15 @@ DockerModule::DockerModule()
|
||||
{
|
||||
name="Docker";
|
||||
}
|
||||
//public methods
|
||||
int DockerModule::prepare()
|
||||
|
||||
//private methods
|
||||
|
||||
int DockerModule::removeContainersCreatedByDockerCompose()
|
||||
{
|
||||
return BashManager::execute("systemctl start docker docker.socket");
|
||||
return BashManager::Execute("docker-compose down --rmi all --remove-orphans");
|
||||
}
|
||||
|
||||
int DockerModule::deploy (string serviceUsername)
|
||||
{
|
||||
cout << "docker module deploy" << endl;
|
||||
//test if there is a docker-compose.yml or docker-compose.yaml
|
||||
string docker_compose="./services/"+serviceUsername+"/docker-compose.yml";
|
||||
if(!(filesystem::exists(docker_compose))){
|
||||
docker_compose="./services/"+serviceUsername+"/docker-compose.yaml";
|
||||
if(!(filesystem::exists(docker_compose))){
|
||||
cout << "No docker-compose for this service." << endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
//pulling images
|
||||
int pulling =BashManager::execute("docker-compose pull")==0;
|
||||
if(pulling==0){
|
||||
//starting service
|
||||
int starting=BashManager::execute("docker-compose up -d --remove-orphans");
|
||||
}else{
|
||||
cerr << "Error in "<< name << "deploying "<< serviceUsername << endl;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int removeContainersCreatedByDockerCompose()
|
||||
{
|
||||
return BashManager::execute("docker-compose down --rmi all --remove-orphans");
|
||||
}
|
||||
|
||||
int removeContainersWithServiceName(string serviceName)
|
||||
int DockerModule::removeContainersWithServiceName(string serviceName)
|
||||
{
|
||||
//constructing the name of the docker container from the name of the service by replacing . with _
|
||||
size_t pos=serviceName.find('.');
|
||||
@ -62,11 +34,41 @@ int removeContainersWithServiceName(string serviceName)
|
||||
[ -z \"$container\" ] && continue || true ; \
|
||||
docker rm \"$container\" ; \
|
||||
done <<< \"$(docker ps | grep '" + dockerService + "' | cut -d ' ' -f 1)\"";
|
||||
return BashManager::execute(cmd);
|
||||
return BashManager::Execute(cmd);
|
||||
}
|
||||
}
|
||||
//public methods
|
||||
int DockerModule::Prepare()
|
||||
{
|
||||
return BashManager::Execute("systemctl start docker docker.socket");
|
||||
}
|
||||
|
||||
int DockerModule::remove (string serviceUsername)
|
||||
int DockerModule::Deploy (string serviceUsername)
|
||||
{
|
||||
cout << "docker module deploy" << endl;
|
||||
//test if there is a docker-compose.yml or docker-compose.yaml
|
||||
string docker_compose="./services/"+serviceUsername+"/docker-compose.yml";
|
||||
if(!(filesystem::exists(docker_compose))){
|
||||
docker_compose="./services/"+serviceUsername+"/docker-compose.yaml";
|
||||
if(!(filesystem::exists(docker_compose))){
|
||||
cout << "No docker-compose for this service." << endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
//pulling images
|
||||
int pulling =BashManager::Execute("docker-compose pull")==0;
|
||||
if(pulling==0){
|
||||
//starting service
|
||||
int starting=BashManager::Execute("docker-compose up -d --remove-orphans");
|
||||
}else{
|
||||
cerr << "Error in "<< name << "deploying "<< serviceUsername << endl;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int DockerModule::Remove (string serviceUsername)
|
||||
{
|
||||
//remove unwanted containers
|
||||
removeContainersCreatedByDockerCompose();
|
||||
@ -74,7 +76,7 @@ int DockerModule::remove (string serviceUsername)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DockerModule::clean()
|
||||
int DockerModule::Clean()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,9 +12,12 @@ class DockerModule : public Module
|
||||
public:
|
||||
DockerModule();//inline
|
||||
~DockerModule(){} //inline
|
||||
int prepare ();
|
||||
int deploy (string serviceUsername);
|
||||
int remove(string serviceUsername);
|
||||
int clean ();
|
||||
int Prepare ();
|
||||
int Deploy (string serviceUsername);
|
||||
int Remove(string serviceUsername);
|
||||
int Clean ();
|
||||
private:
|
||||
int removeContainersCreatedByDockerCompose();
|
||||
int removeContainersWithServiceName (string serviceUsename);
|
||||
};
|
||||
#endif
|
@ -14,10 +14,10 @@ class Module
|
||||
Module(){};
|
||||
//=0 means pure virtual method, making Module a pure virtual class
|
||||
virtual ~Module()=0; //make protected to ensure it is not used externally?
|
||||
virtual int prepare ()=0;
|
||||
virtual int deploy (string serviceUsername)=0;
|
||||
virtual int remove(string serviceUsername)=0;
|
||||
virtual int clean ()=0;
|
||||
virtual int Prepare ()=0;
|
||||
virtual int Deploy (string serviceUsername)=0;
|
||||
virtual int Remove(string serviceUsername)=0;
|
||||
virtual int Clean ()=0;
|
||||
friend ostream & operator<< (ostream & out, const Module & m);
|
||||
string name;
|
||||
};
|
||||
|
@ -7,15 +7,15 @@
|
||||
//constructor and destructor defined inline
|
||||
|
||||
//public methods
|
||||
int Service::getUserID () const
|
||||
int Service::GetUserID () const
|
||||
{
|
||||
return userID;
|
||||
}
|
||||
string Service::getUsername() const
|
||||
string Service::GetUsername() const
|
||||
{
|
||||
return username;
|
||||
}
|
||||
list<string> Service::getServers() const
|
||||
list<string> Service::GetServers() const
|
||||
{
|
||||
return servers;
|
||||
}
|
||||
@ -23,7 +23,7 @@ list<string> Service::getServers() const
|
||||
//operator == override
|
||||
bool Service::operator == (const Service & service) const
|
||||
{
|
||||
if (service.getServers()==servers && service.getUserID()==userID && service.getUsername()==username){
|
||||
if (service.GetServers()==servers && service.GetUserID()==userID && service.GetUsername()==username){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
|
@ -15,9 +15,9 @@ class Service {
|
||||
public:
|
||||
Service(int aUserID, string aUsername, list <string> aServers):userID(aUserID),username(aUsername),servers(aServers){}
|
||||
~Service(){}
|
||||
int getUserID () const;
|
||||
string getUsername() const;
|
||||
list<string> getServers() const;
|
||||
int GetUserID () const;
|
||||
string GetUsername() const;
|
||||
list<string> GetServers() const;
|
||||
bool operator == (const Service & service) const;
|
||||
friend ostream & operator<<(ostream & out, const Service & s);
|
||||
private:
|
||||
|
@ -8,49 +8,50 @@
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include "Services.h"
|
||||
#include "BashManager.h"
|
||||
|
||||
//constructor
|
||||
Services::Services(string ServicesCSV)
|
||||
Services::Services()
|
||||
{
|
||||
services=readServicesFromCSV(ServicesCSV);
|
||||
services=readServicesFromCSV();
|
||||
}
|
||||
//destructor
|
||||
Services::~Services(){}
|
||||
|
||||
//public methods
|
||||
vector<Service> Services::getServices()const
|
||||
vector<Service> Services::GetServices()const
|
||||
{
|
||||
return services;
|
||||
}
|
||||
|
||||
const Service* Services::findByUsername(string aUsername) const
|
||||
const Service* Services::FindByUsername(string aUsername) const
|
||||
{
|
||||
//this method may disappear. Serves development purposes for now.
|
||||
for (const Service & service : services){
|
||||
if (service.getUsername().compare(aUsername)==0){
|
||||
if (service.GetUsername().compare(aUsername)==0){
|
||||
return &service;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Service * Services::findByID(int aUserID) const
|
||||
const Service * Services::FindByID(int aUserID) const
|
||||
{
|
||||
//this method may disappear. Serves development purposes for now.
|
||||
for (const Service & service : services){
|
||||
if (service.getUserID()==aUserID){
|
||||
if (service.GetUserID()==aUserID){
|
||||
return &service;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
list<const Service*> Services::findByServer(string aServer) const
|
||||
list<const Service*> Services::FindByServer(string aServer) const
|
||||
{
|
||||
//this method may disappear. Serves development purposes for now.
|
||||
list<const Service*> result;
|
||||
for (const Service & service : services){
|
||||
for (string server : service.getServers()){
|
||||
for (string server : service.GetServers()){
|
||||
if(server.compare(aServer)==0){
|
||||
result.push_back(&service);
|
||||
}
|
||||
@ -60,17 +61,22 @@ list<const Service*> Services::findByServer(string aServer) const
|
||||
}
|
||||
|
||||
//private methods
|
||||
vector <Service> Services::readServicesFromCSV (string CSV) const
|
||||
vector <Service> Services::readServicesFromCSV () const
|
||||
{
|
||||
//this method extracts the list of uid|username|servers from the services.csv file
|
||||
//and returns them in a vector <Service>, with Service a structure defined in the header
|
||||
vector <Service> result;
|
||||
char * CSV = getenv("servicefile"); //service file is an environment variable
|
||||
// Check if the environment variable is set
|
||||
if (CSV==nullptr) {
|
||||
cerr << "Error when trying to read services.csv. Environment variable servicefiles is not set." << endl;
|
||||
return result;
|
||||
}
|
||||
ifstream streamServices(CSV);
|
||||
if (!streamServices){
|
||||
cout << "Invalid services.csv file." << endl;
|
||||
}else{
|
||||
string line;
|
||||
string tmpUserID=""; //used before converting to int
|
||||
string tmpUserID; //used before converting to int
|
||||
int userID;
|
||||
string username;
|
||||
string server;
|
||||
|
@ -18,14 +18,14 @@ class Services
|
||||
//extracts the list of uid|username|service from the services.csv file
|
||||
{
|
||||
public:
|
||||
Services(string servicesCSV="../src/services.csv");
|
||||
vector<Service> getServices() const;
|
||||
const Service * findByUsername(string aUsername) const;
|
||||
const Service * findByID(int aUserID) const;
|
||||
list<const Service*> findByServer(string aServer) const;
|
||||
Services();
|
||||
vector<Service> GetServices() const;
|
||||
const Service * FindByUsername(string aUsername) const;
|
||||
const Service * FindByID(int aUserID) const;
|
||||
list<const Service*> FindByServer(string aServer) const;
|
||||
~Services();
|
||||
private:
|
||||
vector <Service> readServicesFromCSV (string CSV) const;
|
||||
vector <Service> readServicesFromCSV () const;
|
||||
vector <Service> services;
|
||||
};
|
||||
#endif
|
78
src/main.cpp
78
src/main.cpp
@ -24,7 +24,7 @@ int isServiceOnServer(string serviceUsername)
|
||||
//it looks into the /etc/hosts file thanks to a pipe to a separate bash process
|
||||
{
|
||||
string cmd ="getent hosts " +serviceUsername;
|
||||
string result = BashManager::executeAndReadResult(cmd);
|
||||
string result = BashManager::ExecuteAndReadResult(cmd);
|
||||
if(result.find("::1")!=string::npos){ //if result contains "::1" which is the notation for loopback in IpV6
|
||||
cout << "service on server" << endl;
|
||||
return 0;
|
||||
@ -39,19 +39,19 @@ int createUser(string serviceUsername)
|
||||
//this method creates a Unix user dedicated to the service
|
||||
//get the User ID from servers.csv
|
||||
int uidStart=2000; //so that the uids do not overlap with existing uids
|
||||
Services services = Services("./services/services.csv");
|
||||
const Service * service = services.findByUsername(serviceUsername);
|
||||
int uid = (*service).getUserID()+uidStart;
|
||||
Services services = Services();
|
||||
const Service * service = services.FindByUsername(serviceUsername);
|
||||
int uid = (*service).GetUserID()+uidStart;
|
||||
//test if user already exists
|
||||
string cmd = "id -u "+serviceUsername;
|
||||
string res = BashManager::executeAndReadResult (cmd);
|
||||
string res = BashManager::ExecuteAndReadResult (cmd);
|
||||
if(res==to_string(uid)){
|
||||
cout << "user already existed" << endl;
|
||||
return 0;
|
||||
}
|
||||
//create user
|
||||
string cmd2 ="useradd -u " + to_string(uid) + " " + serviceUsername + "&& usermod -s /sbin/nologin "+ serviceUsername; //no direct login
|
||||
string res2 = BashManager::executeAndReadResult(cmd2);
|
||||
string res2 = BashManager::ExecuteAndReadResult(cmd2);
|
||||
if (res2 != ""){
|
||||
cerr << "Error when executing the bash command to create a user specific to the service." << endl;
|
||||
cerr << res2 << endl;
|
||||
@ -62,9 +62,23 @@ int createUser(string serviceUsername)
|
||||
|
||||
int createEnvService(string serviceUsername)
|
||||
{
|
||||
Services services;
|
||||
//create directories
|
||||
//filesystem::create_directories()
|
||||
string http_dir="/srv/http/"+serviceUsername;
|
||||
string data_dir="/data/"+serviceUsername;
|
||||
string secret_dir="/data/secrets/"+serviceUsername;
|
||||
string docker_dir="/services/"+serviceUsername;
|
||||
string jc_service=serviceUsername;
|
||||
string home="/data/"+serviceUsername;
|
||||
string net="172.29."+services.FindByUsername(serviceUsername)->GetUserID();
|
||||
/*
|
||||
"HTTP_DIR='/srv/http/$service'" "$dir/.env"
|
||||
|
||||
cert="$(findcert.sh "$service")" || true
|
||||
if [ -n "$cert" ] ; then
|
||||
line_in_file "JC_CERT='$cert'" "$dir/.env"
|
||||
fi*/
|
||||
|
||||
/*
|
||||
run mkdir -p "$DATA_DIR" "$HTTP_DIR"
|
||||
@ -86,29 +100,39 @@ int removeEnvService()
|
||||
|
||||
int createEnv()
|
||||
{
|
||||
//this method writes environment variables in a file and sets them for every bash call
|
||||
string proxyDir="etc/nginx";
|
||||
string nginx_conf_path=proxyDir+"/sites-enabled";
|
||||
string new_nginx_conf_path=proxyDir+"/new-sites-enabled";
|
||||
string dns_certs_path="/data/dnscerts.jean-cloud.org/certs/live";
|
||||
string http_certs_path="/etc/letsencrypt/live";
|
||||
string dummy_cert_path=http_certs_path+"/dummy";
|
||||
string servicefile="./services/services.csv";
|
||||
string services_uid_start="2000";
|
||||
|
||||
//create a file accessible outside the C++ program
|
||||
ofstream outfile ("/etc/jeancloud.env");
|
||||
outfile << "proxy_dir=" << proxyDir << endl;
|
||||
outfile << "nginx_conf_path=" << proxyDir << "/sites-enabled/" <<endl;
|
||||
outfile << "new_nginx_conf_path=" << proxyDir << "/new-sites-enabled" << endl;
|
||||
outfile << "nginx_conf_path=" << nginx_conf_path << endl;
|
||||
outfile << "new_nginx_conf_path=" << new_nginx_conf_path << endl;
|
||||
outfile << "dns_certs_path=" << dns_certs_path << endl;
|
||||
outfile << "http_certs_path=" << http_certs_path << endl;
|
||||
outfile << "dummy_cert_path=" << http_certs_path << "/dummy" <<endl;
|
||||
outfile << "servicefile=/services/services.csv";
|
||||
outfile << "services_uid_start=2000" << endl;
|
||||
outfile << "dummy_cert_path=" << dummy_cert_path << endl;
|
||||
outfile << "servicefile=" << servicefile << endl;
|
||||
outfile << "services_uid_start=" << services_uid_start << endl;
|
||||
outfile.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int deployAll()
|
||||
{
|
||||
//this method deploys all the services that are on this server
|
||||
cout << "deploying all" <<endl;
|
||||
createEnv();
|
||||
//for each service deploy service
|
||||
//setting the environment variables for all the shell commands called in this C++ programm
|
||||
setenv("proxy_dir",proxyDir.c_str(),1);
|
||||
setenv("nginx_conf_path",nginx_conf_path.c_str(),1);
|
||||
setenv("new_nginx_conf_path",new_nginx_conf_path.c_str(),1);
|
||||
setenv("dns_certs_path",dns_certs_path.c_str(),1);
|
||||
setenv("http_certs_path",http_certs_path.c_str(),1);
|
||||
setenv("dummy_cert_path",dummy_cert_path.c_str(),1);
|
||||
setenv("servicefile",servicefile.c_str(),1);
|
||||
setenv("services_uid_start",services_uid_start.c_str(),1);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -126,7 +150,7 @@ int deployService(string serviceUsername){
|
||||
//call to the deploy functionality of all modules
|
||||
//the modules themselves determine their course of action depending on the service
|
||||
for(Module * mod_ptr : modules){
|
||||
int modResult = (*mod_ptr).deploy(serviceUsername);
|
||||
int modResult = (*mod_ptr).Deploy(serviceUsername);
|
||||
if (modResult!=0){
|
||||
cerr << "Error in " << (*mod_ptr) << " when deploying " << serviceUsername << endl;
|
||||
}
|
||||
@ -138,6 +162,20 @@ int deployService(string serviceUsername){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int deployAll()
|
||||
{
|
||||
//this method deploys all the services that are on this server
|
||||
cout << "deploying all" <<endl;
|
||||
createEnv();
|
||||
//initializing modules
|
||||
Services services = Services();
|
||||
for (Service service : services.GetServices()){
|
||||
deployService(service.GetUsername());
|
||||
}
|
||||
//for each service deploy service
|
||||
return 0;
|
||||
}
|
||||
|
||||
int removeAll()
|
||||
{
|
||||
cout << "removing all"<<endl;
|
||||
|
Loading…
Reference in New Issue
Block a user