From f319a34841c315b5eb531e4145e5389bee71df9b Mon Sep 17 00:00:00 2001 From: frb Date: Wed, 22 Jul 2015 12:58:14 +0200 Subject: [PATCH 1/8] ADD some cluster-related parameters --- cosmos-gui/conf/cosmos-gui.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cosmos-gui/conf/cosmos-gui.json b/cosmos-gui/conf/cosmos-gui.json index 4893b41..2619b6f 100644 --- a/cosmos-gui/conf/cosmos-gui.json +++ b/cosmos-gui/conf/cosmos-gui.json @@ -2,6 +2,18 @@ "gui": { "port": 80 }, + "clusters": { + "storage": { + "endpoint": "dev-fiwr-httpfs-01.hi.inet", + "user": "fiware-portal", + "private_key": "/Users/frb/devel/fiware/private-key.pem" + }, + "computing": { + "endpoint": "dev-fiwr-...", + "user": "fiware-portal", + "private_key": "/Users/frb/devel/fiware/private-key.pem" + } + }, "hdfs": { "quota": 5, "superuser": "hdfs" From ba7f495fdc56bcf0ab926d3f9b6c576afaa57706 Mon Sep 17 00:00:00 2001 From: frb Date: Wed, 22 Jul 2015 12:59:42 +0200 Subject: [PATCH 2/8] MODIFY how the commands are run by the GUI, now it is over ssh --- cosmos-gui/src/app.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/cosmos-gui/src/app.js b/cosmos-gui/src/app.js index 4cfd653..c3065a8 100644 --- a/cosmos-gui/src/app.js +++ b/cosmos-gui/src/app.js @@ -69,6 +69,12 @@ var response_type = config.oauth2.response_type; var callbackURL = config.oauth2.callbackURL; var hdfsQuota = config.hdfs.quota; var hdfsSuperuser = config.hdfs.superuser; +var scPrivKey = config.clusters.storage.endpoint; +var scUser = config.clusters.storage.user; +var scEndpoint = config.clusters.storage.private_key; +var ccPrivKey = config.clusters.computing.endpoint; +var scUser = config.clusters.computing.user; +var ccEndpoint = config.clusters.computing.private_key; // Creates oauth library object with the config data var oa = new OAuth2(client_id, @@ -142,46 +148,46 @@ app.post('/new_account', function(req, res) { if (password1 === password2) { mysqlDriver.addUser(idm_username, username, password1, function(error, result) { if (error) { - res.boom.badData('There was some error when adding information in the database for user ' + username, error); + res.boom.badData('There was some error when adding information in the database for user '+ username, error); return; } // if - cmdRunner.run('bash', ['-c', 'useradd ' + username], function(error, result) { + cmdRunner.run('bash', ['-c', 'echo "useradd ' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { if (error) { res.boom.badData('There was an error while adding the Unix user ' + username, error); return; } // if console.log('Successful command executed: \'bash -c useradd ' + username + '\''); - cmdRunner.run('bash', ['-c', 'echo ' + password1 + ' | passwd ' + username + ' --stdin'], function(error, result) { + cmdRunner.run('bash', ['-c', 'echo "echo ' + password1 + ' | passwd ' + username + ' --stdin' + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { if (error) { res.boom.badData('There was an error while setting the password for user ' + username, error); return; } // if console.log('Successful command executed: \'bash -c echo ' + password1 + ' | passwd ' + username + ' --stdin\''); - cmdRunner.run('bash', ['-c', 'sudo -u ' + hdfsSuperuser + ' hadoop fs -mkdir /user/' + username], function(error, result) { + cmdRunner.run('bash', ['-c', 'echo "sudo -u ' + hdfsSuperuser + ' hadoop fs -mkdir /user/' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { if (error) { res.boom.badData('There was an error while creating the HDFS folder for user ' + username, error); return; } // if console.log('Successful command executed: \'bash -c sudo -u ' + hdfsSuperuser + ' hadoop fs -mkdir /user/' + username + '\''); - cmdRunner.run('bash', ['-c', 'sudo -u ' + hdfsSuperuser + ' hadoop fs -chown -R ' + username + ':' + username + ' /user/' + username], function(error, result) { + cmdRunner.run('bash', ['-c', 'echo "sudo -u ' + hdfsSuperuser + ' hadoop fs -chown -R ' + username + ':' + username + ' /user/' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { if (error) { res.boom.badData('There was an error while changing the ownership of /user/' + username, error); return; } // if console.log('Successful command executed: \'bash -c sudo -u ' + hdfsSuperuser + ' hadoop fs -chown -R ' + username + ':' + username + ' /user/' + username + '\''); - cmdRunner.run('bash', ['-c', 'sudo -u ' + hdfsSuperuser + ' hadoop fs -chmod -R 740 /user/' + username], function(error, result) { + cmdRunner.run('bash', ['-c', 'echo "sudo -u ' + hdfsSuperuser + ' hadoop fs -chmod -R 740 /user/' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { if (error) { res.boom.badData('There was an error while changing the permissions to /user/' + username, error); return; } // if console.log('Successful command executed: \'bash -c sudo -u ' + hdfsSuperuser + ' hadoop fs -chmod -R 740 /user/' + username + '\''); - cmdRunner.run('bash', ['-c', 'sudo -u ' + hdfsSuperuser + ' hadoop dfsadmin -setSpaceQuota ' + hdfsQuota + 'g /user/' + username], function(error, result) { + cmdRunner.run('bash', ['-c', 'echo "sudo -u ' + hdfsSuperuser + ' hadoop dfsadmin -setSpaceQuota ' + hdfsQuota + 'g /user/' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { if (error) { res.boom.badData('There was an error while setting the quota to /user/' + username, error); return; From 99be59cabe668bfdea1cb1a2db638b2dff3a9a56 Mon Sep 17 00:00:00 2001 From: frb Date: Thu, 23 Jul 2015 08:46:57 +0200 Subject: [PATCH 3/8] UPDATE CHANGES_NEXT_RELEASE --- CHANGES_NEXT_RELEASE | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index 545fa71..cc474c6 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -3,3 +3,4 @@ - [cosmos] [HARDENING] Add initial content to the general README (#1) - [cosmos-gui] [HARDENING] Set 740 permissions to new created accounts (#17) - [cosmos-gui] [HARDENING] Add the HDFS superuser as a configuration parameter (#20) +- [cosmos-gui] [HARDENING] Run administration commands remotely through ssh (#23) From 8ed2b47b9020e0a0425f9f6bdcb0bc44fe579e5a Mon Sep 17 00:00:00 2001 From: frb Date: Thu, 23 Jul 2015 08:47:23 +0200 Subject: [PATCH 4/8] ADD cluster-related parameters to the README --- cosmos-gui/README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cosmos-gui/README.md b/cosmos-gui/README.md index f4dbe14..0757e4c 100644 --- a/cosmos-gui/README.md +++ b/cosmos-gui/README.md @@ -135,10 +135,19 @@ To be done. [Top](#top) ##Configuration -cosmos-gui is configured through `conf/cosmos-gui.json`. There you will find a JSON document with four main *sections*: +cosmos-gui is configured through `conf/cosmos-gui.json`. There you will find a JSON document with five main *sections*: * **gui**: * **port**: specifies the listening port for the application. By default it is 80, but can be changed if such a port is being used in your deployment. +* **clusters**: + * **storage** + * **endpoint**: IP address or FQDN of the Namenode/HttpFS server of the storage cluster. + * **user**: Unix user within the Namenode/HttpFS server having sudo permissions. + * **private_key**: user's private key used to ssh into the Namenode/HttpFS server. + * **computing** + * **endpoint**: IP address or FQDN of the Namenode/HttpFS server of the computing cluster. + * **user**: Unix user within the Namenode/HttpFS server having sudo permissions. + * **private_key**: user's private key used to ssh into the Namenode/HttpFS server. * **hdfs**: * **quota**: measured in gigabytes, defines the size of the HDFS space assigned to each Cosmos user. * **superuser**: HDFS superuser, typically `hdfs`. From 5855dd3b9562d1a7029fa317e8a5f1e7c2367f93 Mon Sep 17 00:00:00 2001 From: frb Date: Thu, 23 Jul 2015 08:49:11 +0200 Subject: [PATCH 5/8] ADD cluster parameters to the configuration file --- cosmos-gui/conf/cosmos-gui.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cosmos-gui/conf/cosmos-gui.json b/cosmos-gui/conf/cosmos-gui.json index 2619b6f..9744034 100644 --- a/cosmos-gui/conf/cosmos-gui.json +++ b/cosmos-gui/conf/cosmos-gui.json @@ -4,14 +4,14 @@ }, "clusters": { "storage": { - "endpoint": "dev-fiwr-httpfs-01.hi.inet", - "user": "fiware-portal", - "private_key": "/Users/frb/devel/fiware/private-key.pem" + "endpoint": "", + "user": "", + "private_key": "" }, "computing": { - "endpoint": "dev-fiwr-...", - "user": "fiware-portal", - "private_key": "/Users/frb/devel/fiware/private-key.pem" + "endpoint": "", + "user": "", + "private_key": "" } }, "hdfs": { @@ -19,10 +19,10 @@ "superuser": "hdfs" }, "oauth2": { - "idmURL": "", + "idmURL": "https://account.lab.fiware.org", "client_id": "", "client_secret": "", - "callbackURL": "http://localhost:80/auth", + "callbackURL": "", "response_type": "code" }, "mysql": { From b9e5b0c9e3de90671d3bed52eb72134c63466d8a Mon Sep 17 00:00:00 2001 From: frb Date: Thu, 23 Jul 2015 08:49:40 +0200 Subject: [PATCH 6/8] MODIFY how the administration commands are run, now ssh is used --- cosmos-gui/src/app.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/cosmos-gui/src/app.js b/cosmos-gui/src/app.js index c3065a8..e37226e 100644 --- a/cosmos-gui/src/app.js +++ b/cosmos-gui/src/app.js @@ -69,12 +69,12 @@ var response_type = config.oauth2.response_type; var callbackURL = config.oauth2.callbackURL; var hdfsQuota = config.hdfs.quota; var hdfsSuperuser = config.hdfs.superuser; -var scPrivKey = config.clusters.storage.endpoint; +var scPrivKey = config.clusters.storage.private_key; var scUser = config.clusters.storage.user; -var scEndpoint = config.clusters.storage.private_key; -var ccPrivKey = config.clusters.computing.endpoint; -var scUser = config.clusters.computing.user; -var ccEndpoint = config.clusters.computing.private_key; +var scEndpoint = config.clusters.storage.endpoint; +var ccPrivKey = config.clusters.computing.private_key; +var ccUser = config.clusters.computing.user; +var ccEndpoint = config.clusters.computing.endpoint; // Creates oauth library object with the config data var oa = new OAuth2(client_id, @@ -152,48 +152,48 @@ app.post('/new_account', function(req, res) { return; } // if - cmdRunner.run('bash', ['-c', 'echo "useradd ' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { + cmdRunner.run('bash', ['-c', 'echo "sudo useradd ' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { if (error) { res.boom.badData('There was an error while adding the Unix user ' + username, error); return; } // if - console.log('Successful command executed: \'bash -c useradd ' + username + '\''); - cmdRunner.run('bash', ['-c', 'echo "echo ' + password1 + ' | passwd ' + username + ' --stdin' + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { + console.log('Successful command executed: \'bash -c echo "sudo useradd ' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint + '\''); + cmdRunner.run('bash', ['-c', 'echo "echo ' + password1 + ' | sudo passwd ' + username + ' --stdin' + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { if (error) { res.boom.badData('There was an error while setting the password for user ' + username, error); return; } // if - console.log('Successful command executed: \'bash -c echo ' + password1 + ' | passwd ' + username + ' --stdin\''); + console.log('Successful command executed: \'bash -c echo "echo ' + password1 + ' | sudo passwd ' + username + ' --stdin' + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint + '\''); cmdRunner.run('bash', ['-c', 'echo "sudo -u ' + hdfsSuperuser + ' hadoop fs -mkdir /user/' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { if (error) { res.boom.badData('There was an error while creating the HDFS folder for user ' + username, error); return; } // if - console.log('Successful command executed: \'bash -c sudo -u ' + hdfsSuperuser + ' hadoop fs -mkdir /user/' + username + '\''); + console.log('Successful command executed: \'bash -c echo "sudo -u ' + hdfsSuperuser + ' hadoop fs -mkdir /user/' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint + '\''); cmdRunner.run('bash', ['-c', 'echo "sudo -u ' + hdfsSuperuser + ' hadoop fs -chown -R ' + username + ':' + username + ' /user/' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { if (error) { res.boom.badData('There was an error while changing the ownership of /user/' + username, error); return; } // if - console.log('Successful command executed: \'bash -c sudo -u ' + hdfsSuperuser + ' hadoop fs -chown -R ' + username + ':' + username + ' /user/' + username + '\''); + console.log('Successful command executed: \'bash -c echo "sudo -u ' + hdfsSuperuser + ' hadoop fs -chown -R ' + username + ':' + username + ' /user/' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint + '\''); cmdRunner.run('bash', ['-c', 'echo "sudo -u ' + hdfsSuperuser + ' hadoop fs -chmod -R 740 /user/' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { if (error) { res.boom.badData('There was an error while changing the permissions to /user/' + username, error); return; } // if - console.log('Successful command executed: \'bash -c sudo -u ' + hdfsSuperuser + ' hadoop fs -chmod -R 740 /user/' + username + '\''); + console.log('Successful command executed: \'bash -c echo "sudo -u ' + hdfsSuperuser + ' hadoop fs -chmod -R 740 /user/' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint + '\''); cmdRunner.run('bash', ['-c', 'echo "sudo -u ' + hdfsSuperuser + ' hadoop dfsadmin -setSpaceQuota ' + hdfsQuota + 'g /user/' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint], function(error, result) { if (error) { res.boom.badData('There was an error while setting the quota to /user/' + username, error); return; } // if - console.log('Successful command executed: \'bash -c sudo -u ' + hdfsSuperuser + ' hadoop dfsadmin -setSpaceQuota ' + hdfsQuota + 'g /user/' + username + '\''); + console.log('Successful command executed: \'bash -c echo "sudo -u ' + hdfsSuperuser + ' hadoop dfsadmin -setSpaceQuota ' + hdfsQuota + 'g /user/' + username + '" | ssh -i ' + scPrivKey + ' ' + scUser + '@' + scEndpoint + '\''); res.redirect('/'); }) }) From 59c09622b992d9129dbd743b6ad1b7c67f390e41 Mon Sep 17 00:00:00 2001 From: frb Date: Thu, 23 Jul 2015 08:49:59 +0200 Subject: [PATCH 7/8] UPDATE style.css --- cosmos-gui/public/stylesheets/style.css | 41 ++++++++++++++----------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/cosmos-gui/public/stylesheets/style.css b/cosmos-gui/public/stylesheets/style.css index e96ce44..35cb2a4 100644 --- a/cosmos-gui/public/stylesheets/style.css +++ b/cosmos-gui/public/stylesheets/style.css @@ -105,38 +105,28 @@ a img { */ body { font-family: 'Georgia'; - background-color: #faf9f0; + background-color: #fff; color: #444; } header { - font-family: 'Quicksand'; - padding: 50px 10px; - color: #fff; - font-size: 25px; text-align: center; -/* - * Note the use of the `main-color` - * variable and the `darken` function - */ - background-color: #fa5b4d; - border-bottom: 1px solid #df1806; - text-shadow: 0px -1px 0px #df1806; + background-color: #fff; } .container { - width: 500px; + width: 700px; margin: 50px auto; overflow: hidden; } .main-content { float: left; - width: 300px; + width: 400px; } .main-content p { margin-bottom: 20px; } .sidebar { float: left; - width: 200px; + width: 300px; } .sidebar .widget { /* @@ -148,7 +138,7 @@ header { border-radius: 3px; border: 1px solid #ccc; margin-left: 20px; - background-color: #faf9f0; + background-color: #fff; -webkit-box-shadow: inset 0px 0px 0px 3px rgba(255,255,255,0.8), 0px 3px 0px -2px rgba(0,0,0,0.1); box-shadow: inset 0px 0px 0px 3px rgba(255,255,255,0.8), 0px 3px 0px -2px rgba(0,0,0,0.1); } @@ -170,9 +160,24 @@ p { line-height: 1.8; } footer { - width: 500px; - margin: 50px auto; + margin: 20px auto; border-top: 1px dotted #ccc; padding-top: 5px; font-size: 13px; + text-align: center; + bottom: 0; + position: absolute; + width: 100%; +} +#submit { + background-color: #ccc; + padding: 5px; + margin: 10px; +} +#submit2 { + background-color: #ccc; + padding: 5px; +} +#password { + width: 400px; } From 67b44ca9a498beeead3239911b1ade1a1eaef32c Mon Sep 17 00:00:00 2001 From: frb Date: Thu, 23 Jul 2015 10:01:40 +0200 Subject: [PATCH 8/8] ADD how to add RSA key fringerprints to the known_hosts file --- cosmos-gui/README.md | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/cosmos-gui/README.md b/cosmos-gui/README.md index 0757e4c..fd13bed 100644 --- a/cosmos-gui/README.md +++ b/cosmos-gui/README.md @@ -16,14 +16,14 @@ * [Contact](#contact) ##What is cosmos-gui -This is one of the pieces of the called "Cosmos ecosystem". Cosmos is the code name for a [Hadoop](http://hadoop.apache.org/)-based solution to FIWARE's BigData Analysis Generic Enabler; such a solution is based on the split of storage and computing: +This is one of the pieces of the named "Cosmos Ecosystem". Within such an ecosystem there is a [Hadoop](http://hadoop.apache.org/)-based implementation of FIWARE's BigData Analysis Generic Enabler; such a solution is based on the split of storage and computing capabilities: * A only-[HDFS](https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/HdfsUserGuide.html) cluster for permanently storing the user data. * Depending on the available resources and the goals pursued by your deployment, there are two flavours for the computing side: * Another Hadoop cluster, shared among all the users, addressing data processing and only allowing for temporal storage. * A [Sahara](https://wiki.openstack.org/wiki/Sahara)-based platform for on-demand private temporal Hadoop clusters. -As seen, the storage cluster is always shared, thus a provisioning procedure is require in order to create specific Unix users and HDFS user spaces; this is also know as creating a Cosmos account. This procedure is automated by this cosmos-gui, a Node.js application rendering a set of web pages mainly in charge of guiding the user through this provisioning step. +As seen, the storage cluster is always shared, and depending on the chosen flavour, the computing cluster is shared as well. Thus a provisioning procedure is require in order to create specific Unix users and HDFS user spaces within both clusters; this is also know as creating a Cosmos account. This procedure is automated by this cosmos-gui, a Node.js application rendering a set of web pages mainly in charge of guiding the user through this provisioning step. In addition, the cosmos-gui can be used as a centralized dashboard where a user can explore its HDFS space and run [predefined MapReduce](https://github.com/telefonicaid/fiware-tidoop/tree/develop/tidoop-mr-lib-api) jobs, once his/her Cosmos account has been provisioned. @@ -35,7 +35,9 @@ This is a software written in JavaScript, specifically suited for [Node.js](http [Top](#top) ###Prerequisites -This GUI has no sense if there is no [Hadoop](http://hadoop.apache.org/)-based storage cluster to be managed. +This GUI has no sense if there is no storage and computing clusters to be managed. + +A couple of sudoer users, one within the storage cluster and another one wihtin the computing clusters, are required. Through these users the cosmos-gui will remotely run certain administration commands such as new users creation, HDFS userspaces provision, etc. The access through these sudoer users will be authenticated by means of private keys. The Cosmos users management is done by means of a [MySQL](https://www.mysql.com/) database, thus install it in the same node the GUI runs, or a remote but accessible machine. @@ -46,20 +48,27 @@ Of course, common Unix tools such as `git` and `curl` are needed. [Top](#top) ###Installating the GUI -cosmos-gui must be installed in a machine being part of the storage cluster to be managed. This can be done in the Namenode, or in a dedicated node for services related to the cluster, such as HttpFS. +cosmos-gui must be installed in a machine having ssh access both to the storage and computing clusters the GUI is going to manage. This ssh access may be limited to the Namenode (or Namenodes, if HA is enabled) of each cluster, and it is necessary since certain administration commands are remotely run through ssh. + +Start by creating, if not yet created, a Unix user named `cosmos-gui`; it is needed for installing and running the application. You can only do this as root, or as another sudoer user: -Once logged into the node, start by creating, if not yet created, a sudoer Unix user named `cosmos`; it is needed for installing and running the application. You can only do this as root, or as another sudoer user: + $ sudo useradd cosmos-gui + $ sudo passwd cosmos-gui + +Now, change to the new fresh `cosmos-gui` user: - $ sudo useradd cosmos sudo # if the 'sudo' group is within /etc/sudoers - $ sudo useradd cosmos # if the 'sudo' group is not within /etc/sudoers - $ sudo passwd cosmos + $ su - cosmos-gui -If the `sudo` group is not within `/etc/sudoers` you can add such a group or add specifically the `cosmos` user, as you want. This is done by invoking the `sudo visudo` command. +Before continuing, remember to add the RSA key fingerprints of the Namenodes accessed by the GUI. This fingerprints are automatically added to `/home/cosmos-gui/.ssh/known_hosts` if you try a ssh access to the Namenodes for the first time. + + $ ssh somesudoeruser@my.storage.namenode.com + The authenticity of host 'my.storage.namenode.com (192.168.12.1)' can't be established. + RSA key fingerprint is 96:c4:0b:8c:09:ce:d4:09:91:a2:b2:9c:40:71:9b:c6. + Are you sure you want to continue connecting (yes/no)? yes + Warning: Permanently added 'my.storage.namenode.com,192.168.12.1' (RSA) to the list of known hosts. -Now, change to the new fresh `cosmos` user: +Please observe `somesudoeruser` is the (ficticious) sudoer user required for the storage cluster, as stated in the [Prerequisites](#prerequisites) section. Do the same for the computing cluster. - $ su - cosmos - Then, clone the Cosmos repository somewhere of your ownership: $ git clone https://github.com/telefonicaid/fiware-cosmos.git