renommage majuscules qd public et debut env service

This commit is contained in:
eleonore12345 2024-08-12 15:29:28 +02:00
parent bfc872dab8
commit 04e1e1b964
12 changed files with 151 additions and 103 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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;
};

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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

View File

@ -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;