From 04e1e1b964527253391fc09810a99e92146694c0 Mon Sep 17 00:00:00 2001 From: eleonore12345 Date: Mon, 12 Aug 2024 15:29:28 +0200 Subject: [PATCH] renommage majuscules qd public et debut env service --- src/BashManager.cpp | 5 ++- src/BashManager.h | 4 +-- src/BashModule.cpp | 8 ++--- src/BashModule.h | 8 ++--- src/DockerModule.cpp | 76 +++++++++++++++++++++--------------------- src/DockerModule.h | 11 ++++--- src/Module.h | 8 ++--- src/Service.cpp | 8 ++--- src/Service.h | 6 ++-- src/Services.cpp | 30 ++++++++++------- src/Services.h | 12 +++---- src/main.cpp | 78 ++++++++++++++++++++++++++++++++------------ 12 files changed, 151 insertions(+), 103 deletions(-) diff --git a/src/BashManager.cpp b/src/BashManager.cpp index 1c10ea8..50933b7 100644 --- a/src/BashManager.cpp +++ b/src/BashManager.cpp @@ -5,9 +5,8 @@ #include #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 diff --git a/src/BashManager.h b/src/BashManager.h index e7d1fa3..e265a09 100644 --- a/src/BashManager.h +++ b/src/BashManager.h @@ -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 \ No newline at end of file diff --git a/src/BashModule.cpp b/src/BashModule.cpp index 808991c..7c0f68c 100644 --- a/src/BashModule.cpp +++ b/src/BashModule.cpp @@ -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; } diff --git a/src/BashModule.h b/src/BashModule.h index 61d1b46..54e755d 100644 --- a/src/BashModule.h +++ b/src/BashModule.h @@ -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); diff --git a/src/DockerModule.cpp b/src/DockerModule.cpp index dbb475b..9e01c97 100644 --- a/src/DockerModule.cpp +++ b/src/DockerModule.cpp @@ -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; } diff --git a/src/DockerModule.h b/src/DockerModule.h index 944b2f0..ccd6e3d 100644 --- a/src/DockerModule.h +++ b/src/DockerModule.h @@ -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 \ No newline at end of file diff --git a/src/Module.h b/src/Module.h index 2510fc1..dbd002b 100644 --- a/src/Module.h +++ b/src/Module.h @@ -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; }; diff --git a/src/Service.cpp b/src/Service.cpp index 520536f..8151350 100644 --- a/src/Service.cpp +++ b/src/Service.cpp @@ -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 Service::getServers() const +list Service::GetServers() const { return servers; } @@ -23,7 +23,7 @@ list 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; diff --git a/src/Service.h b/src/Service.h index ad082ec..9329ce9 100644 --- a/src/Service.h +++ b/src/Service.h @@ -15,9 +15,9 @@ class Service { public: Service(int aUserID, string aUsername, list aServers):userID(aUserID),username(aUsername),servers(aServers){} ~Service(){} - int getUserID () const; - string getUsername() const; - list getServers() const; + int GetUserID () const; + string GetUsername() const; + list GetServers() const; bool operator == (const Service & service) const; friend ostream & operator<<(ostream & out, const Service & s); private: diff --git a/src/Services.cpp b/src/Services.cpp index 74750b8..9eb73c8 100644 --- a/src/Services.cpp +++ b/src/Services.cpp @@ -8,49 +8,50 @@ #include #include #include "Services.h" +#include "BashManager.h" //constructor -Services::Services(string ServicesCSV) +Services::Services() { - services=readServicesFromCSV(ServicesCSV); + services=readServicesFromCSV(); } //destructor Services::~Services(){} //public methods -vector Services::getServices()const +vector 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 Services::findByServer(string aServer) const +list Services::FindByServer(string aServer) const { //this method may disappear. Serves development purposes for now. list 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 Services::findByServer(string aServer) const } //private methods -vector Services::readServicesFromCSV (string CSV) const +vector Services::readServicesFromCSV () const { //this method extracts the list of uid|username|servers from the services.csv file - //and returns them in a vector , with Service a structure defined in the header vector 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; diff --git a/src/Services.h b/src/Services.h index 0d21a23..410048f 100644 --- a/src/Services.h +++ b/src/Services.h @@ -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 getServices() const; - const Service * findByUsername(string aUsername) const; - const Service * findByID(int aUserID) const; - list findByServer(string aServer) const; + Services(); + vector GetServices() const; + const Service * FindByUsername(string aUsername) const; + const Service * FindByID(int aUserID) const; + list FindByServer(string aServer) const; ~Services(); private: - vector readServicesFromCSV (string CSV) const; + vector readServicesFromCSV () const; vector services; }; #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 78a681a..4146edf 100644 --- a/src/main.cpp +++ b/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/" <