Diseño procedimental¶
En este apartado se referencian los algoritmos implementados en el sistema que son considerados de mayor relevancia.
Envío del comando de creación¶
extern "C" int createdirectory(const char* home, int uid, int gid, const char* address_host){
rapidjson::Value Command(rapidjson::kStringType);
Command.SetString("Create-Home");
writer.AddMember("Command", Command, allocator);
char aux[BUFFSIZE];
int len = sprintf(aux, "%s,%d,%d", home, uid, gid);
char aux2[len];
strcpy(aux2, aux);
rapidjson::Value Params(rapidjson::kStringType);
Params.SetString(aux2,len);
writer.AddMember("Params", Params, allocator);
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> salida(buffer);
writer.Accept(salida);
SSL_write(ssl, data_arr, sizeof(data_arr));
char buf_recv[500];
len = SSL_read(ssl, buf_recv, sizeof(buf_recv));
extern "C" int create_polo_directories(const char* home, int uid, int gid){
std::vector<Node> nodes;
Marco marco(TIMEOUT);
marco.request_for(nodes, "polousers");
for (unsigned int i = 0; i < nodes.size(); i++)
{
createdirectory(home, uid, gid, nodes[i].getAddress().c_str());
}
return 0;
}
Recepción del comando de creación¶
def dataReceived(self, data):
"""
Process a new stream of information
:param bytes data: The stream of information
"""
data_dict = json.loads(data.decode('utf-8'))
#The parameters must be separated by commas
params = data_dict["Params"].split(',',3)
if data_dict["Command"] == "Create-Home":
"""The response is acknowledged as soon as possible in order
to avoid a long waiting time in the requesting node
"""
self.transport.write(json.dumps({"OK":0}).encode('utf-8'))
logging.debug("I shall now create the directory %s for %d %d with the utmost pleasure" % (params[0], int(params[1]), int(params[2])))
retval = self.create_homedir(params[0], int(params[1]), int(params[2]))
logging.debug(os.path.join(params[0], 'apache-tomcat-7.0.62'))
if os.path.exists(os.path.join(params[0], 'apache-tomcat-7.0.62')):
logging.debug("I shall now configure Tomcat")
try:
self.configure_tomcat(os.path.join(params[0], 'apache-tomcat-7.0.62'), int(params[1]))
except Exception as e:
logging.debug(e)
#self.transport.write(json.dumps({"Error":str(e)}).encode('utf-8'))
if retval == 0:
logging.debug("Created")
if retval == 1:
logging.debug("The directory was not created because it already exists")
else:
# Wrong command
self.transport.write(json.dumps({"Error":1}).encode('utf-8'))
def create_homedir(self, name, uid, gid):
"""
Creates the home directory, setting the appropriate permissions
:param str name: The path of the directory
:param int uid: The uid of the owner
:param int gid: The gid of the owner's main group
"""
if os.path.exists(name):
logging.info("The directory %s already exists.", name)
return 1
try:
shutil.copytree(skeldir, name)
except OSError as e:
if e.errno == errno.ENOTDIR:
shutil.copy(src, name)
else:
logging.error("Directory not copied. Error %s" % e)
return 2
try:
for root, dirs, files in os.walk(name):
for d in dirs: os.chown(os.path.join(root, d), uid, gid)
for f in files: os.chown(os.path.join(root, f), uid, gid)
except Exception as e:
logging.error("Something went wrong during chown. %s" % e)
return 2
try:
os.chown(name, uid, gid)
except OSError as e:
logging.error("Ownership could not be set: %s", e)
return 2
try:
os.chmod(name, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
except OSError as e:
logging.error("Permission could not be set: %s", e)
return 0
return 0
Configuración de Tomcat¶
def configure_tomcat(self, directory, uid):
"""
Configures the local instance of Tomcat to work with a set of ports dedicated to the user.
Tomcat uses the following ports:
- 8080: The main port where services listen for connections. It is replaced by uid + 10000
- 8005: The shutdown port. It is replaced by uid + 20000
:param str directory: The path of the Tomcat installation
:param int uid: The uid of the user, which determines the number of the port
"""
if not isinstance(uid, six.integer_types):
error = None
try:
uid = int(uid, 10)
except ValueError:
error = True
if error:
raise Exception("Wrong uid value")
server_xml = os.path.join(directory, 'conf/server.xml')
logging.debug(server_xml)
if not os.path.isfile(server_xml):
raise Exception("Not found!")
error = None
try:
tree = ET.parse(server_xml)
except Exception:
error = True
if error:
raise Exception("Error on parsing")
root = tree.getroot()
root.attrib["port"] = str(uid+conf.STOP_PORT_INCREMENT)
ajp = root.find("./Service[@name='Catalina']/Connector[@protocol='AJP/1.3']")
http = root.find("./Service[@name='Catalina']/Connector[@protocol='HTTP/1.1']")
if http is None or ajp is None:
raise Exception("Necessary tags elements not found in XML")
http.attrib["port"] = str(uid)
ajp.attrib["port"] = str(uid+conf.MAIN_PORT_INCREMENT)
tree.write(server_xml)