did basic conversion to org mode for the docs folder
This commit is contained in:
35
Docs/Abstractions.md.org
Normal file
35
Docs/Abstractions.md.org
Normal file
@@ -0,0 +1,35 @@
|
||||
* Abstractions
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: abstractions
|
||||
:END:
|
||||
| [[file:Installation.md][◀ Previous]] | [[file:Implementation.md][Next ▶]] |
|
||||
|--------------------------------------+------------------------------------|
|
||||
|
||||
The Abstractions package consists of black-boxed functions for P2PRC.
|
||||
|
||||
** Functions
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: functions
|
||||
:END:
|
||||
- =Init(<Project name>)=: Initializes P2PRC with all the needed
|
||||
configurations.
|
||||
- =Start()=: Starts p2prc as a server and makes it possible to extend by
|
||||
adding other routes and functionality to P2PRC.
|
||||
- =MapPort(<port no>)=: On the local machine the port you want to export
|
||||
to world.
|
||||
- =StartContainer(<ip address>)=: The machine on the p2p network where
|
||||
you want to spin up a docker container.
|
||||
- =RemoveContainer(<ip address>,<container id>)=: Terminate container
|
||||
based on the IP address and container name.
|
||||
- =GetSpecs(<ip address>)=: Get specs of a machine on the network based
|
||||
on the IP address.
|
||||
- =ViewIPTable()=: View the IP table which about nodes in the network.
|
||||
- =UpdateIPTable()=: Force update IP table to learn about new nodes
|
||||
faster.
|
||||
|
||||
--------------
|
||||
|
||||
*** Next Chapter: [[file:Implementation.md][Implementation]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: next-chapter-implementation
|
||||
:END:
|
||||
180
Docs/Bindings.md.org
Normal file
180
Docs/Bindings.md.org
Normal file
@@ -0,0 +1,180 @@
|
||||
* Language Bindings
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: language-bindings
|
||||
:END:
|
||||
[[https://en.wikipedia.org/wiki/Language_binding][Language bindings]]
|
||||
refers to wrappers to bridge 2 programming languages. This is used in
|
||||
P2PRC to extend calling P2PRC functions in other programming languages.
|
||||
Currently this is done by generating =.so= and =.h= from the Go
|
||||
compiler.
|
||||
|
||||
** How to build shared object files
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: how-to-build-shared-object-files
|
||||
:END:
|
||||
**** The easier way
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: the-easier-way
|
||||
:END:
|
||||
#+begin_src sh
|
||||
# Run
|
||||
make sharedObjects
|
||||
#+end_src
|
||||
|
||||
**** Or the direct way
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: or-the-direct-way
|
||||
:END:
|
||||
#+begin_src sh
|
||||
# Run
|
||||
cd Bindings && go build -buildmode=c-shared -o p2prc.so
|
||||
#+end_src
|
||||
|
||||
**** If successfully built:
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: if-successfully-built
|
||||
:END:
|
||||
#+begin_src sh
|
||||
# Enter into the Bindings directory
|
||||
cd Bindings
|
||||
# List files
|
||||
ls
|
||||
# Find files
|
||||
p2prc.h p2prc.so
|
||||
#+end_src
|
||||
|
||||
** Workings under the hood
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: workings-under-the-hood
|
||||
:END:
|
||||
Below are a sample set of commands to open the bindings implementation.
|
||||
|
||||
#+begin_example
|
||||
# run
|
||||
cd Bindings/
|
||||
# list files
|
||||
ls
|
||||
# search for file
|
||||
Client.go
|
||||
#+end_example
|
||||
|
||||
*** In Client go
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: in-client-go
|
||||
:END:
|
||||
There a few things to notice which are different from your standard Go
|
||||
programs:
|
||||
|
||||
**** 1. We import "C" which means [[https://pkg.go.dev/cmd/cgo][Cgo]] is required.
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: we-import-c-which-means-cgo-is-required.
|
||||
:END:
|
||||
#+begin_src go
|
||||
import "C"
|
||||
#+end_src
|
||||
|
||||
**** 2. All functions which are required to be called from other programming languages have comment such as.
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: all-functions-which-are-required-to-be-called-from-other-programming-languages-have-comment-such-as.
|
||||
:END:
|
||||
#+begin_src go
|
||||
//export <function name>
|
||||
|
||||
// ------------ Example ----------------
|
||||
// The function below allows to externally
|
||||
// to call the P2PRC function to start containers
|
||||
// in a specific node in the know list of nodes
|
||||
// in the p2p network.
|
||||
// Note: the comment "//export StartContainer".
|
||||
|
||||
//export StartContainer
|
||||
func StartContainer(IP string) (output *C.char) {
|
||||
container, err := client.StartContainer(IP, 0, false, "", "")
|
||||
if err != nil {
|
||||
return C.CString(err.Error())
|
||||
}
|
||||
return ConvertStructToJSONString(container)
|
||||
}
|
||||
#+end_src
|
||||
|
||||
**** 3. While looking through the file (If 2 files are compared it is pretty trivial to notice a common structure).
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: while-looking-through-the-file-if-2-files-are-compared-it-is-pretty-trivial-to-notice-a-common-structure.
|
||||
:END:
|
||||
#+begin_src go
|
||||
// --------- Example ------------
|
||||
|
||||
//export StartContainer
|
||||
func StartContainer(IP string) (output *C.char) {
|
||||
container, err := client.StartContainer(IP, 0, false, "", "")
|
||||
if err != nil {
|
||||
return C.CString(err.Error())
|
||||
}
|
||||
return ConvertStructToJSONString(container)
|
||||
}
|
||||
|
||||
//export ViewPlugin
|
||||
func ViewPlugin() (output *C.char) {
|
||||
plugins, err := plugin.DetectPlugins()
|
||||
if err != nil {
|
||||
return C.CString(err.Error())
|
||||
}
|
||||
return ConvertStructToJSONString(plugins)
|
||||
}
|
||||
#+end_src
|
||||
|
||||
**** It is easy to notice that:
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: it-is-easy-to-notice-that
|
||||
:END:
|
||||
- =ConvertStructToJSONString(<go object>)=: This is a helper function
|
||||
that convert a go object to JSON string initially and converts it to
|
||||
=CString=.
|
||||
- =(output *C.char)=: This is the return type for most of the functions.
|
||||
|
||||
**** A Pseudo code to refer to the common function implementation shape could be represented as:
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: a-pseudo-code-to-refer-to-the-common-function-implementation-shape-could-be-represented-as
|
||||
:END:
|
||||
#+begin_example
|
||||
func <Function name> (output *C.char) {
|
||||
<response>,<error> := <P2PRC function name>(<parameters if needed>)
|
||||
if <error> != nil {
|
||||
return C.CString(<error>.Error())
|
||||
}
|
||||
return ConvertStructToJSONString(<response>)
|
||||
}
|
||||
#+end_example
|
||||
|
||||
** Current languages supported
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: current-languages-supported
|
||||
:END:
|
||||
- Python
|
||||
|
||||
*** Build sample python program
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: build-sample-python-program
|
||||
:END:
|
||||
The easier way
|
||||
|
||||
#+begin_src sh
|
||||
# Run
|
||||
make python
|
||||
# Expected ouput
|
||||
Output is in the Directory Bindings/python/export/
|
||||
# Run
|
||||
cd Bindings/python/export/
|
||||
# list files
|
||||
ls
|
||||
# Expected output
|
||||
SharedObjects/ p2prc.py
|
||||
#+end_src
|
||||
|
||||
Above shows a generated folder which consists of a folder called
|
||||
"SharedObjects/" which consists of =p2prc.so= and =p2prc.h= files.
|
||||
=p2prc.py= refers to a sample python script calling P2PRC go functions.
|
||||
To start an any project to extend P2PRC with python, This generated
|
||||
folder can copied and created as a new git repo for P2PRC extensions
|
||||
scripted or used a reference point as proof of concept that P2PRC can be
|
||||
called from other programming languages.
|
||||
24
Docs/CliImplementation.md.org
Normal file
24
Docs/CliImplementation.md.org
Normal file
@@ -0,0 +1,24 @@
|
||||
* Cli module
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: cli-module
|
||||
:END:
|
||||
The Cli (i.e Command Line Interface) is the only one in which the user
|
||||
can directly interact with the modules in the project. The objective
|
||||
when building the Cli was to have the least amount of commands as
|
||||
possible. The cli was built using the library called urfave cli v2 .
|
||||
They were 2 major files created named as flags.go and actions.go. ###
|
||||
Flags.go The flags .go file is responsible to create the appropriate
|
||||
flags for the cli. There are 2 types of flags called boolean and string.
|
||||
Each of the flags outputs are assigned to a variable to be handled. The
|
||||
flags can also detect environment variables set. This feature is useful
|
||||
because if the user wants to call certain flags in a repeated sequence
|
||||
it only has to be initialized once.
|
||||
|
||||
*** Actions.go
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: actions.go
|
||||
:END:
|
||||
The actions.go file is implemented to call the appropriate functions
|
||||
when the flags are called. It interacts directly with the modules in the
|
||||
project. Action.go checks if variables are not empty string or the
|
||||
boolean value is true.
|
||||
33
Docs/Client.md.org
Normal file
33
Docs/Client.md.org
Normal file
@@ -0,0 +1,33 @@
|
||||
* Client Module
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: client-module
|
||||
:END:
|
||||
This module is incharge of communicating with the server and receiving
|
||||
the appropriate information back from the server.
|
||||
|
||||
** Functions of the Client Module
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: functions-of-the-client-module
|
||||
:END:
|
||||
|
||||
#+begin_html
|
||||
<!-- - [Interact with the Server Api](#functions-of-the-client-module) -->
|
||||
#+end_html
|
||||
|
||||
- [[#decision-maker-on-how-the-ip-table-is-created-or-updated][Decision
|
||||
maker on how the ip table is created or updated]]
|
||||
|
||||
** Decision maker on how the IP table is created or updated
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: decision-maker-on-how-the-ip-table-is-created-or-updated
|
||||
:END:
|
||||
- Does a local speedtest to verify and see if the server IP's in the IP
|
||||
table are pingable.
|
||||
- Tries to ping the servers IP Table addresses.
|
||||
- If it's pingable then it's added as a new entry in the IP table.
|
||||
- The following steps occurs in the clients IP table.
|
||||
- To ensure that the same servers are not being called to update the IP
|
||||
table. There is a temporary list of IP address which have already been
|
||||
called in relation to updating the IP table.
|
||||
- Based on the current implementation there will 3 hops done to update
|
||||
the IP table.
|
||||
15
Docs/ClientArchitecture.md.org
Normal file
15
Docs/ClientArchitecture.md.org
Normal file
@@ -0,0 +1,15 @@
|
||||
* Client Module Architecture
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: client-module-architecture
|
||||
:END:
|
||||
The Client Module interacts with the P2P module and Server Module. It is
|
||||
responsible for interacting with the server module and appropriately
|
||||
updating the IP table on the client side. It connects to the server
|
||||
using the server's REST Apis. It is also the primary decision maker on
|
||||
how the IP table is updated is on the client side. This is because each
|
||||
user can have requirements like how many number of hops they would want
|
||||
to do to update their IP table. Hops is the number of times the client
|
||||
is going to download the IP table from different servers ,once it gets
|
||||
the IP tables from the previous servers.
|
||||
|
||||
[[file:images/NumOfHops.png]] [[file:images/clientmoduleArch.png]]
|
||||
135
Docs/ClientImplementation.md.org
Normal file
135
Docs/ClientImplementation.md.org
Normal file
@@ -0,0 +1,135 @@
|
||||
* Client Module Implementation
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: client-module-implementation
|
||||
:END:
|
||||
The Client Module interacts with the P2P module and Server Module. It is
|
||||
responsible for interacting with the server module and appropriately
|
||||
updating the IP table on the client side. It connects to the server
|
||||
using the server's REST Apis. It is also the primary decision maker on
|
||||
how the IP table is updated is on the client side. This is because each
|
||||
user can have requirements like how many number of hops they would want
|
||||
to do to update their IP table. Hops is the number of times the client
|
||||
is going to download the IP table from different servers ,once it gets
|
||||
the IP tables from the previous servers.
|
||||
|
||||
[[file:images/NumOfHops.png]] [[file:images/clientmoduleArch.png]]
|
||||
|
||||
** Topics
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: topics
|
||||
:END:
|
||||
1. [[#updating-the-IP-table][Updating the IP table]]
|
||||
2. [[#reading-server-specifications][Reading server specifications]]
|
||||
3. [[#Client-creating-and-removing-container][Client creating and
|
||||
removing container]]
|
||||
4. [[#Tracking-Containers][Tracking Containers]]
|
||||
5. [[#Grouping-Containers][Grouping Containers]]
|
||||
|
||||
This section focuses in depth on how the client module works. The client
|
||||
module is incharge of communicating with different servers based on the
|
||||
IP addresses provided to the user. The IP addresses are derived from
|
||||
peer to peer modules. The objective here is how the client module
|
||||
interacts with peer to peer module and server module.
|
||||
|
||||
*** Updating the IP table
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: updating-the-ip-table
|
||||
:END:
|
||||
The client module calls the peer to peer module to get the local IP
|
||||
table initially, Based on the servers IP addresses available it calls
|
||||
the speedtest function from the peer to peer module to update IP
|
||||
addresses with information such as latencies, download and upload
|
||||
speeds. Once this is done the client module does a Rest Api call to the
|
||||
server to download its IP Table. Once the hops are done it writes the
|
||||
appropriate results to the Local IP table. Once this is done it prints
|
||||
out the results. To derive parameters such as current the public IP
|
||||
address the url "http://ip-api.com/json/" was called. This url returns
|
||||
json response of the current public IP address. This feature will be
|
||||
used in the future to ensure that the user's current IP address will not
|
||||
be used for a speed test. Clients IP table is updated to the server
|
||||
using a form of type multipart.
|
||||
|
||||
*** Reading server specifications
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: reading-server-specifications
|
||||
:END:
|
||||
The client module calls the route /server_specs and reads the json
|
||||
response. If the json response was successful then it just calls the
|
||||
pretty print function which just prints the json output in the terminal.
|
||||
|
||||
*** Client creating and removing container
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: client-creating-and-removing-container
|
||||
:END:
|
||||
The client module uses the servers Rest apis to create and delete
|
||||
containers. To create a container the client requires 3 parameters being
|
||||
the server ip address, the number of the ports the user wants to open
|
||||
and if the user wants it connected to the GPU or not. The 3 parameters
|
||||
are sent as a GET request to the server and the server responds with a
|
||||
json file which has information such as the container ID, ports open ,
|
||||
SSH username, SSH password, VNC username and VNC password. At the moment
|
||||
the username and password are hard coded from the server side for both
|
||||
SSH and VNC. To remove a container the client module only requires the
|
||||
server IP address and the container ID. The client prints the response
|
||||
from the server Rest api.
|
||||
|
||||
*** Tracking Containers
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: tracking-containers
|
||||
:END:
|
||||
Clients create docker images in multiple machines. This means if the
|
||||
client (i.e user) has many containers created there needs to be a way to
|
||||
track them. To track containers there is a file called
|
||||
=trackcontainers.json= which tracks all the containers running. The
|
||||
snippet below show a sample structure of file =trackcontainer.json=.
|
||||
|
||||
#+begin_example
|
||||
{
|
||||
"TrackContainer": [
|
||||
{
|
||||
"ID": "<ID>",
|
||||
"Container": {<docker.DockerVM struct>},
|
||||
"IpAddress": "<IP Address>"
|
||||
}
|
||||
]
|
||||
}
|
||||
#+end_example
|
||||
|
||||
The default path to the container tracker is
|
||||
=client/trackcontainers/trackcontainers.json=.
|
||||
|
||||
*** Grouping Containers
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: grouping-containers
|
||||
:END:
|
||||
When starting a set container possibility to be able to group them. The
|
||||
benefit this would be that when executing plugins the group ID would be
|
||||
enough to execute plugin in a set of containers. This provides the
|
||||
possibility to execute repetitive tasks in containers in a single cli
|
||||
command. To store groups there is a file called
|
||||
=grouptrackcontainer.json= which tracks all the groups currently present
|
||||
set by the client. The snippet below show a sample structure of file
|
||||
=grouptrackcontainer.json=.
|
||||
|
||||
#+begin_example
|
||||
{
|
||||
"Groups": [
|
||||
{
|
||||
"ID": "grp<Random UUID>",
|
||||
"TrackContainer": [{client.TrackContainers struct}]
|
||||
}
|
||||
]
|
||||
}
|
||||
#+end_example
|
||||
|
||||
The default path to the container tracker is
|
||||
=client/trackcontainers/grouptrackcontainer.json=.
|
||||
|
||||
#+begin_quote
|
||||
[!NOTE] The group id will be auto-generated and will have its own prefix
|
||||
in the start which will mostly be =grp<UUID>=.\\
|
||||
When a container is removed using the command.
|
||||
=p2prc --rm <IP Address> --id <Container id>=. It will be automatically
|
||||
deleted from the groups it exists in.
|
||||
|
||||
#+end_quote
|
||||
35
Docs/ConfigImplementation.md.org
Normal file
35
Docs/ConfigImplementation.md.org
Normal file
@@ -0,0 +1,35 @@
|
||||
* Config Implementation
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: config-implementation
|
||||
:END:
|
||||
The configuration module is responsible to store basic information of
|
||||
absolute paths of files being called in the Go code. In a full-fledged
|
||||
Cli the configuration file can be found in the directory /etc/ and from
|
||||
there points to location such as where the IP table file is located. In
|
||||
the future implementation the config file will have information such as
|
||||
number of hops and other parameters to tweak and to improve the
|
||||
effectiveness of the peer to peer network. The configuration module was
|
||||
implemented using the library Viper. The Viper library automates
|
||||
features such as searching in default paths to find out if the
|
||||
configuration file is present. If the configuration file is not present
|
||||
in the default paths then it auto generates the configuration file. The
|
||||
configurations file can be in any format. In this project the
|
||||
configuration file was generated using JSON format.
|
||||
|
||||
#+begin_src json
|
||||
{
|
||||
"MachineName": "pc-74-120.customer.ask4.lan",
|
||||
"IPTable": "/Users/akilan/Documents/p2p-rendering-computation/p2p/iptable/ip_table.json",
|
||||
"DockerContainers": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/",
|
||||
"DefaultDockerFile": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/docker-ubuntu-sshd/",
|
||||
"SpeedTestFile": "/Users/akilan/Documents/p2p-rendering-computation/p2p/50.bin",
|
||||
"IPV6Address": "",
|
||||
"PluginPath": "/Users/akilan/Documents/p2p-rendering-computation/plugin/deploy",
|
||||
"TrackContainersPath": "/Users/akilan/Documents/p2p-rendering-computation/client/trackcontainers/trackcontainers.json",
|
||||
"ServerPort": "8088",
|
||||
"GroupTrackContainersPath": "/Users/akilan/Documents/p2p-rendering-computation/client/trackcontainers/grouptrackcontainers.json",
|
||||
"FRPServerPort": "True",
|
||||
"BehindNAT": "True",
|
||||
"CustomConfig": null
|
||||
}
|
||||
#+end_src
|
||||
26
Docs/DesignArchtectureIntro.md.org
Normal file
26
Docs/DesignArchtectureIntro.md.org
Normal file
@@ -0,0 +1,26 @@
|
||||
* Design Architecture
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: design-architecture
|
||||
:END:
|
||||
This chapter focuses on architecture of the dissertation. The objective
|
||||
would be to have a good understanding on the purpose of each module and
|
||||
how they interact with each other. The design architecture was inspired
|
||||
and based on the linux kernel design. The project is segmented into
|
||||
various modules. Each module is responsible for certain tasks in the
|
||||
project. The modules are highly dependent on each other hence the entire
|
||||
codebase can be considered as a huge monolithic chuck which acts as its
|
||||
own library. The following sub topics below talk about the main modules
|
||||
and how they function with appropriate diagrams.
|
||||
|
||||
*** 1. [[file:ClientArchitecture.md][Client Module]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: client-module
|
||||
:END:
|
||||
*** 2. [[file:P2PArchitecture.md][P2P Module]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: p2p-module
|
||||
:END:
|
||||
*** 3. [[file:ServerArchitecture.md][Server Module]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: server-module
|
||||
:END:
|
||||
5
Docs/DomainNameMappingsImplementation.md.org
Normal file
5
Docs/DomainNameMappingsImplementation.md.org
Normal file
@@ -0,0 +1,5 @@
|
||||
* Domain name mappings
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: domain-name-mappings
|
||||
:END:
|
||||
This
|
||||
66
Docs/Implementation.md.org
Normal file
66
Docs/Implementation.md.org
Normal file
@@ -0,0 +1,66 @@
|
||||
* Implementation
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: implementation
|
||||
:END:
|
||||
| [[file:Introduction.md][◀ Previous]] | [[file:README.md][Back to TOC]] |
|
||||
|--------------------------------------+---------------------------------|
|
||||
|
||||
This chapter describes how the project was built. It talks in depth of
|
||||
the implementation performed to give a better understanding of the
|
||||
project.
|
||||
|
||||
** Programming langauge used
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: programming-langauge-used
|
||||
:END:
|
||||
The programming language used for this project was
|
||||
[[https://go.dev/][Golang]]. The reason Go lang was chosen was because
|
||||
it is a compiled language. The entire codebase is just a single binary
|
||||
file. When distributing to other linux distributing the only requirement
|
||||
would be the binary file to run the code. It is easy to write
|
||||
independant modules and be monolithic at the sametime using Go. Using
|
||||
Go.mod makes it very easy to handle external libraries and modularise
|
||||
code. The go.mod name for the project is
|
||||
[[https://git.sr.ht/~akilan1999/p2p-rendering-computation][git.sr.ht/~akilan1999/p2p-rendering-computation]].
|
||||
|
||||
-
|
||||
** [[file:CliImplementation.md][Cli Module]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: cli-module
|
||||
:END:
|
||||
|
||||
-
|
||||
** [[file:ConfigImplementation.md][Config Module]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: config-module
|
||||
:END:
|
||||
|
||||
-
|
||||
** [[file:ServerImplementation.md][Server Module]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: server-module
|
||||
:END:
|
||||
|
||||
-
|
||||
** [[file:ClientImplementation.md][Client Module]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: client-module
|
||||
:END:
|
||||
|
||||
-
|
||||
** [[file:P2PImplementation.md][P2P Module]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: p2p-module
|
||||
:END:
|
||||
|
||||
-
|
||||
** [[file:PluginImplementation.md][Plugin Module]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: plugin-module
|
||||
:END:
|
||||
|
||||
-
|
||||
** [[file:GenerateImplementation.md][Generate Module]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: generate-module
|
||||
:END:
|
||||
361
Docs/Installation.md.org
Normal file
361
Docs/Installation.md.org
Normal file
@@ -0,0 +1,361 @@
|
||||
* Installation
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: installation
|
||||
:END:
|
||||
| [[file:Introduction.md][◀ Previous]] | [[file:Abstractions.md][Next ▶]] |
|
||||
|--------------------------------------+----------------------------------|
|
||||
|
||||
Over here we will cover the basic steps to get the server and client
|
||||
side running.
|
||||
|
||||
** Latest release install
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: latest-release-install
|
||||
:END:
|
||||
https://github.com/Akilan1999/p2p-rendering-computation/releases
|
||||
|
||||
** Install from Github master branch
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: install-from-github-master-branch
|
||||
:END:
|
||||
*** Install Go lang
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: install-go-lang
|
||||
:END:
|
||||
The entire the implementation of this project is done using Go lang.
|
||||
Thus, we need go lang to compile to code to a binary file.
|
||||
[[https://golang.org/doc/install][Instructions to install Go lang]]
|
||||
|
||||
*** Install Docker
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: install-docker
|
||||
:END:
|
||||
In this project the choice of virtualization is Docker due to it's wide
|
||||
usage in the developer community. In the server module we use the Docker
|
||||
Go API to create and interact with the containers.
|
||||
|
||||
[[https://docs.docker.com/get-docker/][Instructions to install docker]]
|
||||
|
||||
[[https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker][Instructions
|
||||
to install docker GPU]]
|
||||
|
||||
#+begin_example
|
||||
// Do ensure that the docker command does not need sudo to run
|
||||
sudo chmod 666 /var/run/docker.sock
|
||||
#+end_example
|
||||
|
||||
*** Build Project and install project
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: build-project-and-install-project
|
||||
:END:
|
||||
To set up the internal dependencies and build the entire go code into a
|
||||
single binary
|
||||
|
||||
#+begin_example
|
||||
make install
|
||||
#+end_example
|
||||
|
||||
**** For Windows
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: for-windows
|
||||
:END:
|
||||
To set up P2PRC on Windows, simply run this batch file. *Make sure you
|
||||
are not in admin mode when running this.*
|
||||
|
||||
#+begin_example
|
||||
.\install.bat
|
||||
#+end_example
|
||||
|
||||
*** Add appropriate paths to =.bashrc=
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: add-appropriate-paths-to-.bashrc
|
||||
:END:
|
||||
#+begin_example
|
||||
export P2PRC=/<PATH>/p2p-rendering-computation
|
||||
export PATH=/<PATH>/p2p-rendering-computation:${PATH}
|
||||
#+end_example
|
||||
|
||||
*** Set up configuration file
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: set-up-configuration-file
|
||||
:END:
|
||||
#+begin_example
|
||||
make configfile
|
||||
#+end_example
|
||||
|
||||
Open the config file =config.json= and add the IPv6 address if you have
|
||||
one.
|
||||
|
||||
*** Test if binary works
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: test-if-binary-works
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --help
|
||||
#+end_example
|
||||
|
||||
**** Output:
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: output
|
||||
:END:
|
||||
#+begin_example
|
||||
NAME:
|
||||
p2p-rendering-computation - p2p cli application to create and access VMs in other servers
|
||||
|
||||
USAGE:
|
||||
p2prc [global options] command [command options] [arguments...]
|
||||
|
||||
VERSION:
|
||||
<version no>
|
||||
|
||||
COMMANDS:
|
||||
help, h Shows a list of commands or help for one command
|
||||
|
||||
GLOBAL OPTIONS:
|
||||
--Server, -s Starts server (default: false) [$SERVER]
|
||||
--UpdateServerList, --us Update List of Server available based on servers iptables (default: false) [$UPDATE_SERVER_LIST]
|
||||
--ListServers, --ls List servers which can render tasks (default: false) [$LIST_SERVERS]
|
||||
--AddServer value, --as value Adds server IP address to iptables [$ADD_SERVER]
|
||||
--ViewImages value, --vi value View images available on the server IP address [$VIEW_IMAGES]
|
||||
--CreateVM value, --touch value Creates Docker container on the selected server [$CREATE_VM]
|
||||
--ContainerName value, --cn value Specifying the container run on the server side [$CONTAINER_NAME]
|
||||
--RemoveVM value, --rm value Stop and Remove Docker container (IP:port) accompanied by container ID via --ID or --id [$REMOVE_VM]
|
||||
--ID value, --id value Docker Container ID [$ID]
|
||||
--Ports value, -p value Number of ports to open for the Docker Container [$NUM_PORTS]
|
||||
--GPU, --gpu Create Docker Containers to access GPU (default: false) [$USE_GPU]
|
||||
--Specification value, --specs value Specs of the server node [$SPECS]
|
||||
--SetDefaultConfig, --dc Sets a default configuration file (default: false) [$SET_DEFAULT_CONFIG]
|
||||
--NetworkInterfaces, --ni Shows the network interface in your computer (default: false) [$NETWORK_INTERFACE]
|
||||
--ViewPlugins, --vp Shows plugins available to be executed (default: false) [$VIEW_PLUGIN]
|
||||
--TrackedContainers, --tc View (currently running) containers which have been created from the client side (default: false) [$TRACKED_CONTAINERS]
|
||||
--ExecutePlugin value, --plugin value Plugin which needs to be executed [$EXECUTE_PLUGIN]
|
||||
--CreateGroup, --cgroup Creates a new group (default: false) [$CREATE_GROUP]
|
||||
--Group value, --group value group flag with argument group ID [$GROUP]
|
||||
--Groups, --groups View all groups (default: false) [$GROUPS]
|
||||
--RemoveContainerGroup, --rmcgroup Remove specific container in the group (default: false) [$REMOVE_CONTAINER_GROUP]
|
||||
--RemoveGroup value, --rmgroup value Removes the entire group [$REMOVE_GROUP]
|
||||
--Generate value, --gen value Generates a new copy of P2PRC which can be modified based on your needs [$GENERATE]
|
||||
--ModuleName value, --mod value New go project module name [$MODULENAME]
|
||||
--PullPlugin value, --pp value Pulls plugin from git repos [$PULLPLUGIN]
|
||||
--RemovePlugin value, --rp value Removes plugin [$REMOVEPLUGIN]
|
||||
--help, -h show help (default: false)
|
||||
--version, -v print the version (default: false)
|
||||
#+end_example
|
||||
|
||||
--------------
|
||||
|
||||
* Using basic commands
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: using-basic-commands
|
||||
:END:
|
||||
*** Start as a server
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: start-as-a-server
|
||||
:END:
|
||||
Do ensure you have Docker installed for this
|
||||
|
||||
#+begin_example
|
||||
p2prc -s
|
||||
#+end_example
|
||||
|
||||
*** View server Specification
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: view-server-specification
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --specs=<ip address>
|
||||
#+end_example
|
||||
|
||||
*** Run container
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: run-container
|
||||
:END:
|
||||
use the =--gpu= if you know the other machine has a gpu.
|
||||
|
||||
#+begin_example
|
||||
p2prc --touch=<server ip address> -p <number of ports> --gpu
|
||||
#+end_example
|
||||
|
||||
*** Remove container
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: remove-container
|
||||
:END:
|
||||
The docker id is present in the output where you create a container
|
||||
|
||||
#+begin_example
|
||||
p2prc --rm=<server ip address> --id=<docker container id>
|
||||
#+end_example
|
||||
|
||||
*** Adding servers to ip table
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: adding-servers-to-ip-table
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --as=<server ip address you want to add>
|
||||
#+end_example
|
||||
|
||||
*** Update ip table
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: update-ip-table
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --us
|
||||
#+end_example
|
||||
|
||||
*** List Servers
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: list-servers
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --ls
|
||||
#+end_example
|
||||
|
||||
*** View Network interfaces
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: view-network-interfaces
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --ni
|
||||
#+end_example
|
||||
|
||||
*** Viewing Containers created Client side
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: viewing-containers-created-client-side
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --tc
|
||||
#+end_example
|
||||
|
||||
[[file:ClientImplementation.md#tracking-containers][read more on
|
||||
tracking containers]]
|
||||
|
||||
*** Running plugin
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: running-plugin
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --plugin <plugin name> --id <container id or group id>
|
||||
#+end_example
|
||||
|
||||
*** Create group
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: create-group
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --cgroup
|
||||
#+end_example
|
||||
|
||||
*** Add container to group
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: add-container-to-group
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --group <group id> --id <container id>
|
||||
#+end_example
|
||||
|
||||
*** View groups
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: view-groups
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --groups
|
||||
#+end_example
|
||||
|
||||
*** View specific group
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: view-specific-group
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --group <group id>
|
||||
#+end_example
|
||||
|
||||
*** Delete container from group
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: delete-container-from-group
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --rmcgroup --group <group id> --id <container id>
|
||||
#+end_example
|
||||
|
||||
*** Delete entire group
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: delete-entire-group
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --rmgroup <group id>
|
||||
#+end_example
|
||||
|
||||
[[file:ClientImplementation.md#Grouping-Containers][read more on
|
||||
grouping containers]] ### Extending usecase of P2PRC (Requires a go
|
||||
compiler to run)
|
||||
|
||||
#+begin_example
|
||||
p2prc --gen <project name> --mod <go module name>
|
||||
#+end_example
|
||||
|
||||
[[file:GenerateImplementation.md][read more about the generate module]]
|
||||
|
||||
*** Pulling plugin from a remote repo
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: pulling-plugin-from-a-remote-repo
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --pp <repo link>
|
||||
#+end_example
|
||||
|
||||
*** Deleting plugin from the plugin directory
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: deleting-plugin-from-the-plugin-directory
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --rp <plugin name>
|
||||
#+end_example
|
||||
|
||||
*** Added custom metadata about the current node
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: added-custom-metadata-about-the-current-node
|
||||
:END:
|
||||
#+begin_example
|
||||
p2prc --amd "custom metadata"
|
||||
#+end_example
|
||||
|
||||
--------------
|
||||
|
||||
* Using Plugins
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: using-plugins
|
||||
:END:
|
||||
This feature is still Under Development:
|
||||
[[file:PluginImplementation.md][Read more on the implementation]]
|
||||
|
||||
**** Dependencies
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: dependencies
|
||||
:END:
|
||||
- Ansible:
|
||||
- Debian/ubuntu: =sudo apt install ansible=
|
||||
- Others:
|
||||
[[https://ansible-tips-and-tricks.readthedocs.io/en/latest/ansible/install/][Installation
|
||||
link]]
|
||||
|
||||
**** Run Test Cases
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: run-test-cases
|
||||
:END:
|
||||
- Generate Test Case Ansible file
|
||||
- =make testcases=
|
||||
- Enter inside plugin directory and run tests.
|
||||
|
||||
#+begin_quote
|
||||
[!NOTE] That docker needs to installed and needs to run without sudo.
|
||||
Refer the section [[#install-docker][Install Docker]]. - =cd plugin= -
|
||||
=go test .=
|
||||
|
||||
#+end_quote
|
||||
|
||||
--------------
|
||||
|
||||
*** Next Chapter: [[file:Abstractions.md][Abstractions]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: next-chapter-abstractions
|
||||
:END:
|
||||
48
Docs/Introduction.md.org
Normal file
48
Docs/Introduction.md.org
Normal file
@@ -0,0 +1,48 @@
|
||||
* Chapter 1: Introduction
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: chapter-1-introduction
|
||||
:END:
|
||||
| [[file:README.md][◀ Back to TOC]] | [[file:Installation.md][Next ▶]] |
|
||||
|-----------------------------------+----------------------------------|
|
||||
|
||||
** Abstract
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: abstract
|
||||
:END:
|
||||
This project focuses on creating a framework on running heavy tasks that
|
||||
a regular computer cannot run easily such as graphically demanding video
|
||||
games, rendering 3D animations , protein folding simulations. In this
|
||||
project the major focus will not be on the financial incentive part. A
|
||||
peer to peer network will be created to help run tasks decentrally,
|
||||
increasing bandwidth for running tasks. To ensure the tasks in the peer
|
||||
to peer network do not corrupt the server 0S (Operating System), they
|
||||
will be executed in a virtual environment in the server.
|
||||
|
||||
The main aim of this project was to create a custom peer to peer
|
||||
network. The user acting as the client has total flexibility on how to
|
||||
batch the tasks and the user acting as the server has complete
|
||||
flexibility on tracking the container's usages and killing the
|
||||
containers at any point of time.
|
||||
|
||||
** Motivation
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: motivation
|
||||
:END:
|
||||
Many of the users rely on our PC / Laptop or servers that belong to a
|
||||
server farm to run heavy tasks and with the demand of high creativity
|
||||
requires higher computing power. Buying a powerful computer every few
|
||||
years to run a bunch of heavy tasks which are not executed as frequently
|
||||
to reap the benefits can be inefficient utilization of hardware. On the
|
||||
other end, renting servers to run these heavy tasks can be really
|
||||
useful. Ethically speaking this is leading to monopolisation of
|
||||
computing power similar to what is happening in the web server area. By
|
||||
using peer to peer principles it is possible to remove the
|
||||
monopolisation factor and increase the bandwidth between the client and
|
||||
server.
|
||||
|
||||
--------------
|
||||
|
||||
*** Next Chapter: [[file:Installation.md][Installation]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: next-chapter-installation
|
||||
:END:
|
||||
50
Docs/NAT-Traveral.md.org
Normal file
50
Docs/NAT-Traveral.md.org
Normal file
@@ -0,0 +1,50 @@
|
||||
* NAT Traversal
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: nat-traversal
|
||||
:END:
|
||||
P2PRC currently supports TURN for NAT traversal.
|
||||
|
||||
** TURN
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: turn
|
||||
:END:
|
||||
The current TURN implementation used is FRP. The TURN server is also
|
||||
required when a P2PRC node is acting as a Server. The TURN server is
|
||||
determined based on the Node with the least amount of latency based on
|
||||
the Nodes available on the IPTable. Once a TURN server is determined
|
||||
there are 2 actions performed. The first one is =/FRPPort= to the TURN
|
||||
server to receive a port which is used to generate the external port
|
||||
from the TURN server. The flow below describes the workflow.
|
||||
|
||||
*** Client mode
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: client-mode
|
||||
:END:
|
||||
- Call =/FRPPort=
|
||||
|
||||
#+begin_example
|
||||
http://<turn server ip>:<server port no>/FRPport
|
||||
#+end_example
|
||||
|
||||
- Call the TURN server in the following manner. The following is a
|
||||
sample code snippet below.
|
||||
|
||||
#+begin_src go
|
||||
import (
|
||||
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
serverPort, err := frp.GetFRPServerPort("http://" + <lowestLatencyIpAddress.Ipv4> + ":" + lowestLatencyIpAddress.ServerPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Create 1 second delay to allow FRP server to start
|
||||
time.Sleep(1 * time.Second)
|
||||
// Starts FRP as a client with
|
||||
proxyPort, err := frp.StartFRPClientForServer(<lowestLatencyIpAddress.Ipv4>, serverPort, <the port you want to expose externally>)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
#+end_src
|
||||
136
Docs/P2P-testing.md.org
Normal file
136
Docs/P2P-testing.md.org
Normal file
@@ -0,0 +1,136 @@
|
||||
* Testing P2P network
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: testing-p2p-network
|
||||
:END:
|
||||
The objective would be to test the p2p network, and the effectiveness of
|
||||
updating the ip tables. The objective of would be to give the impression
|
||||
to the client and server of a Zero configuration setting. For testing
|
||||
there will be a test network set. In the testing scenario all will be
|
||||
client and server because the IP table does not store clients IP
|
||||
addresses. At current number of hopes would be 3 as default.
|
||||
|
||||
*** Test Network Scenario 1
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: test-network-scenario-1
|
||||
:END:
|
||||
The test network consists of 5 nodes acting as a client and server. The
|
||||
objective would be to have the entire IP table Updated in each node with
|
||||
interacting with only 1 node once. Each node has knowledge of one node
|
||||
only.
|
||||
|
||||
[[https://user-images.githubusercontent.com/31743758/115069627-e4aa8c80-9f04-11eb-8402-706a3407f0e8.png]]
|
||||
Fig 1.0 Visual Representation of testnet scenario 1
|
||||
|
||||
**** Result
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: result
|
||||
:END:
|
||||
All nodes except node 1 where able to have information of IP addresses
|
||||
in the test net. This was due to the reason of 3 hops set as default.
|
||||
Node 1 had in it's IP table IP addresses of Node 2, Node 3, Node 4. Once
|
||||
the number of hops was set to 4 objective of the test was acheived.
|
||||
|
||||
*** Test Network Scenario 2
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: test-network-scenario-2
|
||||
:END:
|
||||
The second test network has a scenario of a single peer which all the
|
||||
other nodes connect too. The scenario being when the other nodes connect
|
||||
to the single server they download information about nodes that have
|
||||
connected to the server node before.
|
||||
|
||||
*** Testing Broadcast Module
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: testing-broadcast-module
|
||||
:END:
|
||||
For testing the broadcast module 2 types of servers will be tested. One
|
||||
with a CPU only , another one with a CPU and GPU. The expected result
|
||||
being that the appropriate results are visible.
|
||||
|
||||
**** Results (CPU and GPU):
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: results-cpu-and-gpu
|
||||
:END:
|
||||
#+begin_example
|
||||
{
|
||||
"Hostname": "akilan-Lenovo-IdeaPad-Y510P",
|
||||
"Platform": "ubuntu",
|
||||
"CPU": "Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz",
|
||||
"RAM": 7872,
|
||||
"Disk": 937367,
|
||||
"GPU": {
|
||||
"DriveVersion": "390.141",
|
||||
"Gpu": {
|
||||
"GpuName": "GeForce GT 755M",
|
||||
"BiosVersion": "80.07.A8.00.0F",
|
||||
"FanSpeed": "N/A",
|
||||
"Utilization": {
|
||||
"GpuUsage": "N/A",
|
||||
"MemoryUsage": "N/A"
|
||||
},
|
||||
"Temperature": {
|
||||
"GpuTemp": "66 C"
|
||||
},
|
||||
"Clock": {
|
||||
"GpuClock": "N/A",
|
||||
"GpuMemClock": "N/A"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#+end_example
|
||||
|
||||
At the moment of the current implementation v1.0. Nvidia GPU are only
|
||||
compatible. As the Go code calls the command =nvidia-smi= to get
|
||||
information about the GPU available.
|
||||
|
||||
**** Results (CPU only)
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: results-cpu-only
|
||||
:END:
|
||||
#+begin_example
|
||||
{
|
||||
"Hostname": "sv-t1.small.x86-01",
|
||||
"Platform": "ubuntu",
|
||||
"CPU": "Intel(R) Atom(TM) CPU C2750 @ 2.40GHz",
|
||||
"RAM": 7944,
|
||||
"Disk": 138793,
|
||||
"GPU": null
|
||||
}
|
||||
#+end_example
|
||||
|
||||
As the =nvidia-smi= interface was not detected it only broadcasts the
|
||||
CPU specs available.
|
||||
|
||||
*** SpeedTests
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: speedtests
|
||||
:END:
|
||||
The speed test has 3 parameters which are Ping , upload and download.
|
||||
The tests check if the results returned are approximately correct. The
|
||||
ping at the moment returns the correct result. The upload and download
|
||||
returned are inccorect at the moment, This is due incorrect
|
||||
implementation in for timer and will be patched in future versions.
|
||||
|
||||
*** Unit tests
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: unit-tests
|
||||
:END:
|
||||
All functions implemented on the P2P module returns type error. The
|
||||
units test call certain functions and check if the functions return an
|
||||
error or not. This proved sufficient as the point of the units tests was
|
||||
code coverage to check if certain functions return an error.
|
||||
|
||||
**** Functions tested
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: functions-tested
|
||||
:END:
|
||||
This sections talks about the function called and represents code
|
||||
coverage.
|
||||
|
||||
1. =TestServer_SpeedTest=: Function called LocalSpeedTestIpTable()
|
||||
2. =TestReadIpTable=: Function called ReadIpTable()
|
||||
|
||||
The P2P module has a 100% code coverage in unit tests as both the unit
|
||||
tests call directly or call within the function all the functions used
|
||||
in the P2P module.
|
||||
45
Docs/P2P.md.org
Normal file
45
Docs/P2P.md.org
Normal file
@@ -0,0 +1,45 @@
|
||||
* P2P (Peer to Peer module)
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: p2p-peer-to-peer-module
|
||||
:END:
|
||||
In this repository the P2P module has been designed from sratch at the
|
||||
point of this implementation.
|
||||
[[https://pkg.go.dev/git.sr.ht/~akilan1999/p2p-rendering-computation@v0.0.0-20210404191839-6a046babcb02/p2p][More
|
||||
about function implementation]]
|
||||
|
||||
** Terminology
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: terminology
|
||||
:END:
|
||||
1. IPTable: Refers to a json file which stores information about the
|
||||
current servers avaliable with the speedtest results ran from the
|
||||
Node that triggered it.
|
||||
|
||||
#+begin_example
|
||||
{
|
||||
"ip_address": [
|
||||
{
|
||||
"ipv4": "localhost",
|
||||
"latency": 14981051,
|
||||
"download": 8142.122540206258,
|
||||
"upload": 3578.766512629995,
|
||||
}
|
||||
]
|
||||
}
|
||||
#+end_example
|
||||
|
||||
** Responsibility
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: responsibility
|
||||
:END:
|
||||
- To ensure the IP table has nodes which are pingable
|
||||
- Taking to nodes behind NAT. [[file:NAT-Traversal][More about the
|
||||
implementation]]...
|
||||
|
||||
#+begin_quote
|
||||
[!NOTE] If you are running in server mode it is recommended to use
|
||||
[[https://routerguide.net/when-and-how-to-setup-dmz-host-for-home-use/][DMZ]]
|
||||
to bypass the
|
||||
[[https://en.wikipedia.org/wiki/Network_address_translation][NAT]].
|
||||
|
||||
#+end_quote
|
||||
16
Docs/P2PArchitecture.md.org
Normal file
16
Docs/P2PArchitecture.md.org
Normal file
@@ -0,0 +1,16 @@
|
||||
* P2P Module Architecture
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: p2p-module-architecture
|
||||
:END:
|
||||
The P2P module (i.e Peer to Peer Module) is responsible for storing the
|
||||
IP table and interacting with the IP table. In the following
|
||||
implementation of the P2P module ,the IP table stores information about
|
||||
servers available in the network. The other functionality the P2P module
|
||||
takes care of is doing the appropriate speed tests to the servers in the
|
||||
IP table. This is for informing the users about nodes which are close by
|
||||
and nodes which have quicker uploads and downloads speeds. The module is
|
||||
responsible to ensure that there are no duplicate server IPs in the IP
|
||||
table and to remove all server IPs which are not pingable.
|
||||
|
||||
#+caption: UML diagram of P2P module
|
||||
[[file:images/p2pmoduleArch.png]]
|
||||
111
Docs/P2PImplementation.md.org
Normal file
111
Docs/P2PImplementation.md.org
Normal file
@@ -0,0 +1,111 @@
|
||||
* P2P Module Implementation
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: p2p-module-implementation
|
||||
:END:
|
||||
The P2P module (i.e Peer to Peer Module) is responsible for storing the
|
||||
IP table and interacting with the IP table. In the following
|
||||
implementation of the P2P module ,the IP table stores information about
|
||||
servers available in the network. The other functionality the P2P module
|
||||
takes care of is doing the appropriate speed tests to the servers in the
|
||||
IP table. This is for informing the users about nodes which are close by
|
||||
and nodes which have quicker uploads and downloads speeds. The module is
|
||||
responsible to ensure that there are no duplicate server IPs in the IP
|
||||
table and to remove all server IPs which are not pingable.
|
||||
|
||||
#+caption: UML diagram of P2P module
|
||||
[[file:images/p2pmoduleArch.png]]
|
||||
|
||||
The peer to peer implementation was built from scratch. This is because
|
||||
other peer to peer libraries were on the implementation of the
|
||||
Distributed hash table. At the current moment all those heavy features
|
||||
are not needed because the objective is to search and list all possible
|
||||
servers available. The limitation being that to be a part of the network
|
||||
the user has to know at least 1 server. The advantage of building from
|
||||
scratch makes the module super light and possibility for custom
|
||||
functions and structs. The sub topics below will mention the
|
||||
implementations of each functionality in depth.
|
||||
|
||||
** IP Table
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: ip-table
|
||||
:END:
|
||||
The ip table file is a json as the format with a list of servers ip
|
||||
addresses, latencies, downloads and uploads speeds. The functions
|
||||
implemented include read file, write file and remove duplicate IP
|
||||
addresses. The remove duplicate IP address function exists because
|
||||
sometimes servers IP tables can have the same ip addresses as what the
|
||||
client has. The path of the IP table json file is received from the
|
||||
configuration module.
|
||||
|
||||
#+begin_src json
|
||||
{
|
||||
"ip_address": [
|
||||
{
|
||||
"ipv4": "<ipv4 address>",
|
||||
"latency": "<latency>",
|
||||
"download": "<download>",
|
||||
"upload": "<upload>"
|
||||
"port no": "<server port no>",
|
||||
}
|
||||
]
|
||||
}
|
||||
#+end_src
|
||||
|
||||
*** Latency
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: latency
|
||||
:END:
|
||||
The latency is measured in milliseconds. The route /server_info is
|
||||
called from the server and time it takes to provide a json response is
|
||||
recorded.
|
||||
|
||||
** NAT Traversal
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: nat-traversal
|
||||
:END:
|
||||
P2PRC currently supports TURN for NAT traversal.
|
||||
|
||||
** TURN
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: turn
|
||||
:END:
|
||||
The current TURN implementation used is FRP. The TURN server is also
|
||||
required when a P2PRC node is acting as a Server. The TURN server is
|
||||
determined based on the Node with the least amount of latency based on
|
||||
the Nodes available on the IPTable. Once a TURN server is determined
|
||||
there are 2 actions performed. The first one is =/FRPPort= to the TURN
|
||||
server to receive a port which is used to generate the external port
|
||||
from the TURN server. The flow below describes the workflow.
|
||||
|
||||
*** Client mode
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: client-mode
|
||||
:END:
|
||||
- Call =/FRPPort=
|
||||
|
||||
#+begin_example
|
||||
http://<turn server ip>:<server port no>/FRPport
|
||||
#+end_example
|
||||
|
||||
- Call the TURN server in the following manner. The following is a
|
||||
sample code snippet below.
|
||||
|
||||
#+begin_src go
|
||||
import (
|
||||
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
serverPort, err := frp.GetFRPServerPort("http://" + <lowestLatencyIpAddress.Ipv4> + ":" + lowestLatencyIpAddress.ServerPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Create 1 second delay to allow FRP server to start
|
||||
time.Sleep(1 * time.Second)
|
||||
// Starts FRP as a client with
|
||||
proxyPort, err := frp.StartFRPClientForServer(<lowestLatencyIpAddress.Ipv4>, serverPort, <the port you want to expose externally>)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
#+end_src
|
||||
213
Docs/PluginImplementation.md.org
Normal file
213
Docs/PluginImplementation.md.org
Normal file
@@ -0,0 +1,213 @@
|
||||
* Plugin Module Implementation
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: plugin-module-implementation
|
||||
:END:
|
||||
** Topics
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: topics
|
||||
:END:
|
||||
1. [[#introduction][Introduciton]]
|
||||
2. [[#site-File-Template][Site.yml]]
|
||||
3. [[#hosts-file][Host]]
|
||||
4. [[#description-file][Description]]
|
||||
5. [[#automatic-port-allocations][Automatic port allocations]]
|
||||
6. [[#sample-plugins-implemented][Sample plugins implemented]]
|
||||
|
||||
** Introduction
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: introduction
|
||||
:END:
|
||||
The plugin module is designed to ensure clients can execute instructions
|
||||
in a declarative manner across different containers created. This means
|
||||
the user (i.e client) needs to write the instruction only once, and
|
||||
these instructions can be executed across different nodes in a
|
||||
repetitive manner.
|
||||
|
||||
In the scenario of this project Ansibles will be used as the way the
|
||||
users can create these instructions.
|
||||
|
||||
- [[file:Installation.md#Using-Plugins][Setup instruction]]
|
||||
|
||||
The plugin module introduces a new path to the config file known as
|
||||
pluginpath. This path by defaults points to =${P2PRC}/plugin/deploy=.
|
||||
Any file/folder inside =plugin/deploy= is part of the .gitginore.
|
||||
Plugins are detected by folder names inside the =plugin/deploy=.
|
||||
|
||||
#+begin_example
|
||||
plugin
|
||||
|___ Deploy
|
||||
|___<plugin name>
|
||||
|___ site.yml
|
||||
|___ hosts
|
||||
|___ ports.json
|
||||
|___ description.txt
|
||||
.
|
||||
.
|
||||
.
|
||||
n: n number of plugins possible
|
||||
#+end_example
|
||||
|
||||
** Site File Template
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: site-file-template
|
||||
:END:
|
||||
The site file is also known as the Ansible playbook and is incharge of
|
||||
executing instructions in a declarative manner. The below example
|
||||
specifies how to make one.
|
||||
|
||||
#+begin_example
|
||||
- hosts: all
|
||||
|
||||
tasks:
|
||||
- name: <task name>
|
||||
<ansible task>
|
||||
debug:
|
||||
msg: <debug message>
|
||||
#+end_example
|
||||
|
||||
Read more about ansible tasks:
|
||||
https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html#about-playbooks
|
||||
|
||||
** Hosts file
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: hosts-file
|
||||
:END:
|
||||
hosts file is also known as the inventory file. This file consists of
|
||||
all the information required to connect to other nodes to execute
|
||||
Ansible instructions. In this project this file needs to be set in a
|
||||
certain configuration because the go code or binary will populate this
|
||||
file automatically with the appropriate information required to connect
|
||||
to local or remote containers.
|
||||
|
||||
#+begin_quote
|
||||
[!NOTE] Add as exactly specified below:
|
||||
|
||||
#+begin_example
|
||||
all:
|
||||
vars:
|
||||
ansible_python_interpreter: /usr/bin/python3 // Path to your python 3 interpreter
|
||||
main:
|
||||
hosts:
|
||||
host1:
|
||||
// Note: These values will be automatically overwritten
|
||||
// by the Go functions
|
||||
ansible_host: 0.0.0.0
|
||||
ansible_port: 39269
|
||||
ansible_user: master
|
||||
ansible_ssh_pass: password
|
||||
ansible_sudo_pass: password
|
||||
#+end_example
|
||||
|
||||
#+end_quote
|
||||
|
||||
** Ports.json
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: ports.json
|
||||
:END:
|
||||
The =ports.json= file is intended to mention the number of ports
|
||||
required by the plugin.
|
||||
|
||||
#+begin_example
|
||||
{
|
||||
"NumOfPorts": <number of ports>
|
||||
}
|
||||
#+end_example
|
||||
|
||||
** Description file
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: description-file
|
||||
:END:
|
||||
This is a simple text file used to describe what the module does. When
|
||||
the client is looking at various commands via the ClI. The description
|
||||
is displayed along-side the plugin name.
|
||||
|
||||
Ex: When the flag =--ViewPlugins= or =--vp= is called
|
||||
|
||||
#+begin_example
|
||||
{
|
||||
"PluginsDetected": [
|
||||
{
|
||||
"FolderName": "<name of the plugin>",
|
||||
"PluginDescription": "<description of the plugin>"
|
||||
}
|
||||
]
|
||||
}
|
||||
#+end_example
|
||||
|
||||
** Automatic port allocations
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: automatic-port-allocations
|
||||
:END:
|
||||
P2PRC would be in-charge to set to the ports to various TCP ports
|
||||
opened. Due to this implementation the plugin being executed is copied
|
||||
to the tmp directory with a unique UUID.
|
||||
|
||||
#+begin_example
|
||||
Command: ls /tmp
|
||||
output: Semantic <UUID>_<Plugin Name>
|
||||
2e6d76c4-0ed1-4b55-9385-79a58d4f0492_p2prc-vscode-browser
|
||||
7b631e08-62ee-4c1c-a2a4-c05857b9aa7d_p2prc-vscode-browser
|
||||
#+end_example
|
||||
|
||||
Once the copy of the plugin is added to the /tmp directory the site.yml
|
||||
file inside the appropriate yaml is modified with the appropriate ports
|
||||
assigned to the container.
|
||||
|
||||
*** Ex:
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: ex
|
||||
:END:
|
||||
1. Create container called c1 with an automatic generated TCP port 3313
|
||||
(external) - 3313 (internal)
|
||||
2. Assumption of plugin p1 exists. p1 has one server which needs to be
|
||||
mapped to a free open TCP port in container c1. Below shows an
|
||||
implementation of a sample site.yml file.
|
||||
|
||||
#+begin_example
|
||||
---
|
||||
- hosts: all
|
||||
tasks:
|
||||
- name: start vscode code server
|
||||
shell: sh server.sh 0.0.0.0:{{index . 0}}
|
||||
#+end_example
|
||||
|
||||
Notice there is the following {{index . 0}}. {{index . 0}} does not
|
||||
belong to Ansible but rather is a way to mention where to add the
|
||||
external free port of the container. We use the golang
|
||||
[[https://pkg.go.dev/text/template][template library]] to parse and
|
||||
populate the site.yml with the appropriate open ports. An array of ints
|
||||
which consists of open free ports are sent to the site.yml. 0 in
|
||||
{{index . 0}} refers to the index in the int array passed on.
|
||||
|
||||
After the port is automatically it's ready to run !
|
||||
|
||||
#+begin_example
|
||||
---
|
||||
- hosts: all
|
||||
tasks:
|
||||
- name: start vscode code server
|
||||
shell: sh server.sh 0.0.0.0:3313
|
||||
#+end_example
|
||||
|
||||
*** Sample plugins implemented:
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sample-plugins-implemented
|
||||
:END:
|
||||
- [[https://github.com/Akilan1999/p2prc-vscode-browser][VSCode Plugin]]
|
||||
|
||||
** Pull Plugins
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: pull-plugins
|
||||
:END:
|
||||
The following allows us to pull plugins from a remote git repository and
|
||||
store them in the default plugins directory. The implementation uses a
|
||||
Go git library to pull the git repo and automatically save it as a
|
||||
folder in the plugin path.
|
||||
|
||||
** Delete Plugins
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: delete-plugins
|
||||
:END:
|
||||
We delete the plugin folder based on the plugin name provided as an
|
||||
argument on the cli command. Once the folder is deleted, the plugin
|
||||
manager automatically knows that the plugin does not exist anymore.
|
||||
18
Docs/README.md.org
Normal file
18
Docs/README.md.org
Normal file
@@ -0,0 +1,18 @@
|
||||
* Table of contents
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: table-of-contents
|
||||
:END:
|
||||
1. [[file:Introduction.md][Introduction]]
|
||||
2. [[file:Installation.md][Installation]]
|
||||
3. [[file:Abstractions.md][Abstractions]]
|
||||
4. [[file:Implementation.md][Implementation]]
|
||||
1. [[file:ClientImplementation.md][Client Module]]
|
||||
2. [[file:P2PImplementation.md][P2P Module]]
|
||||
3. [[file:ServerImplementation.md][Server Module]]
|
||||
4. [[file:ConfigImplementation.md][Config Module]]
|
||||
5. [[file:CliImplementation.md][Cli Module]]
|
||||
6. [[file:PluginImplementation.md][Plugin Module]]
|
||||
7. [[file:Bindings.md][Language bindings]]
|
||||
8. [[file:Bindings.md][Domain name mappings]]
|
||||
5. Language bindings
|
||||
1. [[file:haskell/][Haskell]]
|
||||
14
Docs/ServerArchitecture.md.org
Normal file
14
Docs/ServerArchitecture.md.org
Normal file
@@ -0,0 +1,14 @@
|
||||
* Server Module Architecture
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: server-module-architecture
|
||||
:END:
|
||||
The server module takes care of setting and removing the virtualization
|
||||
environment (i.e containers) for accessing and doing the appropriate
|
||||
computation. It also interacts with the peer to peer module to update
|
||||
the IP table on the server side. The server module accesses information
|
||||
regarding CPU and GPU specifications of the machine running the server
|
||||
module. To do Speed tests the server has routes which allows it to
|
||||
upload and download a 50mb.
|
||||
|
||||
#+caption: UML diagram of server module
|
||||
[[file:images/servermoduleArch.png]]
|
||||
278
Docs/ServerImplementation.md.org
Normal file
278
Docs/ServerImplementation.md.org
Normal file
@@ -0,0 +1,278 @@
|
||||
* Server Module Implementation
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: server-module-implementation
|
||||
:END:
|
||||
This section focuses on an in-depth understanding of the server module
|
||||
implementation. To understand the architecture of the server module
|
||||
refer. The server module can be split into various sections. Each
|
||||
section will provide information on how a certain feature works.
|
||||
|
||||
The server module takes care of setting and removing the virtualization
|
||||
environment (i.e containers) for accessing and doing the appropriate
|
||||
computation. It also interacts with the peer to peer module to update
|
||||
the IP table on the server side. The server module accesses information
|
||||
regarding CPU and GPU specifications of the machine running the server
|
||||
module. To do Speed tests the server has routes which allows it to
|
||||
upload and download a 50mb.
|
||||
|
||||
#+caption: UML diagram of server module
|
||||
[[file:images/servermoduleArch.png]]
|
||||
|
||||
** Web framework
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: web-framework
|
||||
:END:
|
||||
The web framework used for the server module is called Gin. The reason
|
||||
Gin was chosen is due to its wide use and strong documentation available
|
||||
on the official github repository. The default port used is 8088. For
|
||||
version 1.0 of the project ,the server needs to keep port 8088 open to
|
||||
ensure that other clients and servers can detect it. The possible
|
||||
requests available are GET and POST for this implementation. The
|
||||
possible responses are either a string or json response or a file. In
|
||||
the majority of routes a string response refers to an error when calling
|
||||
the following routes. The following sub topics below will talk about the
|
||||
route implemented:
|
||||
|
||||
*** /server_info
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: server_info
|
||||
:END:
|
||||
This route is responsible to get information about the specifications of
|
||||
the server. The response of this route is in json if the call was
|
||||
successful.
|
||||
|
||||
*** /50
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: section
|
||||
:END:
|
||||
This route is responsible for returning a randomly generated 50mb file.
|
||||
This is used to calculate the download speed from the p2p module.
|
||||
|
||||
*** /IpTable
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: iptable
|
||||
:END:
|
||||
This route is a POST request that is responsible to update the server IP
|
||||
table based on the IP table the client provides. Once the server gets
|
||||
the IP table it checks if the client is also a server. This is done by
|
||||
calling the url http://:8088/server_info. If the server_info route from
|
||||
the client responds back with computer specifications of the client.
|
||||
Then the server initially appends the clients IP to the struct. After
|
||||
that the IP table received from the client is uploaded to the struct.
|
||||
Once this is done the server passes the struct to the peer to peer
|
||||
module function. The peer to peer module function will return the back
|
||||
with the new struct with the valid server nodes. The server responds
|
||||
back to the new struct as a json format. If a string is present in the
|
||||
response then there is probably an error on the server side.
|
||||
|
||||
*** /startcontainer
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: startcontainer
|
||||
:END:
|
||||
This route takes in a GET request with the number of TCP ports to open
|
||||
and checks whether the docker container should be hooked to the GPU or
|
||||
not. This route talks to the docker module implemented as a sub module
|
||||
in the server module. More information on the docker module in section
|
||||
5.4.3. This route calls docker the module to start the container for the
|
||||
client. The docker module returns back a struct. This struct is returned
|
||||
back to the client as the json response. This struct consists of
|
||||
information such as docker id, ports numbers open , information
|
||||
regarding SSH and VNC connections to the docker container created when
|
||||
the client created this request.
|
||||
|
||||
*** /RemoveContainer
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: removecontainer
|
||||
:END:
|
||||
This route takes in a GET request as the container ID. Based on the
|
||||
container ID provided ,it calls the docker module which deletes the
|
||||
container. If the deletion is successful it returns back a string which
|
||||
says success.
|
||||
|
||||
** Server information/ Specification
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: server-information-specification
|
||||
:END:
|
||||
This section provides information on how the server specifications are
|
||||
read. There are 2 major implementations. The first implementation
|
||||
mentions how basic information such as RAM usage, CPU specification are
|
||||
detected and the second implementation mentions how the GPU drivers are
|
||||
detected and information is extracted. The client has to assume that the
|
||||
server is using default docker settings in terms of CPU cycles and other
|
||||
parameters.
|
||||
|
||||
*** Basic Information
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: basic-information
|
||||
:END:
|
||||
The file name for these functions is called gopsutil.go. This codebase
|
||||
uses the library gopsutil. Gopsutil has various packages or modules
|
||||
within the library which have functions implemented to get system
|
||||
information. The following information is stored in a struct and the
|
||||
function returns that struct.
|
||||
|
||||
#+begin_src go
|
||||
type SysInfo struct {
|
||||
Hostname string `bson:hostname`
|
||||
Platform string `bson:platform`
|
||||
CPU string `bson:cpu`
|
||||
RAM uint64 `bson:ram`
|
||||
Disk uint64 `bson:disk`
|
||||
GPU *Query `xml: GpuInfo`
|
||||
}
|
||||
#+end_src
|
||||
|
||||
*** GPU Information
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: gpu-information
|
||||
:END:
|
||||
The file name for these functions is called GPU.go. This codebase checks
|
||||
if the Nvidia driver exists and returns the driver information. To do
|
||||
this a shell command called nvidia-smi is executed. This shell command
|
||||
is executed with a --xml as flag to ensure that the output is in the XML
|
||||
format. If there is an output as a xml format, that means there is an
|
||||
nvidia driver installed, and the function just reads the output and
|
||||
stores it to the struct and returns the GPU information.
|
||||
|
||||
#+begin_src go
|
||||
|
||||
type Query struct {
|
||||
DriveVersion string `xml:"driver_version"`
|
||||
Gpu Gpu `xml:"gpu"`
|
||||
}
|
||||
|
||||
type Gpu struct{
|
||||
GpuName string `xml:"product_name"`
|
||||
BiosVersion string `xml:"vbios_version"`
|
||||
FanSpeed string `xml:"fan_speed"`
|
||||
Utilization GpuUtilization `xml:"utilization"`
|
||||
Temperature GpuTemperature `xml:"temperature"`
|
||||
Clock GpuClock `xml:"clocks"`
|
||||
}
|
||||
|
||||
type GpuUtilization struct {
|
||||
GpuUsage string `xml:"gpu_util"`
|
||||
MemoryUsage string `xml:"memory_util"`
|
||||
}
|
||||
|
||||
type GpuTemperature struct {
|
||||
GpuTemp string `xml:"gpu_temp"`
|
||||
}
|
||||
|
||||
type GpuClock struct {
|
||||
GpuClock string `xml:"graphics_clock"`
|
||||
GpuMemClock string `xml:"mem_clock"`
|
||||
}
|
||||
#+end_src
|
||||
|
||||
** Docker Module
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: docker-module
|
||||
:END:
|
||||
This section provides information on how the server module interacts
|
||||
with the docker containers. The server calls 2 routes which either
|
||||
creates or removes the docker container. Docker has a huge advantage
|
||||
because it takes less than 20 seconds to spin up a new container once
|
||||
it's built and executed at least once. For docker operations a separate
|
||||
module/package has been created. The following subtopics will provide
|
||||
more information on how this package works.
|
||||
|
||||
*** Docker Api
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: docker-api
|
||||
:END:
|
||||
For this the api has been taken from the official docker repository. To
|
||||
be more specific it is the client module in the official docker
|
||||
repository. Docker was built using Go. During this project Docker
|
||||
functions could be directly called from the docker repository. The
|
||||
Docker api initially ensures that it can detect the docker environment
|
||||
variables. Once detected, it can execute various functions from the
|
||||
docker client module. The reason the docker api was selected was to
|
||||
detect and handle errors better.
|
||||
|
||||
*** Docker Image
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: docker-image
|
||||
:END:
|
||||
The docker image used to spin up the containers is called
|
||||
ConSol/docker-headless-vnc-container. The following container was
|
||||
modified to open SSH ports for an SSH connection. The following docker
|
||||
image runs ubuntu 16. The reason this image was chosen as a default is
|
||||
because if the client wants to access the container in the form of a
|
||||
desktop environment. This image would allow the client to do so from
|
||||
just a browser.
|
||||
|
||||
*** Build container
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: build-container
|
||||
:END:
|
||||
This function pulls the docker image locally and builds the image.
|
||||
Initially there is a timeout function to ensure that building the image
|
||||
does not take too long to build. The next phase would be based on the
|
||||
path to get the DockerFile. The tag name of the container is set as
|
||||
p2p-ubuntu as default. Once the following is set then the docker build
|
||||
command is executed.
|
||||
|
||||
*** Run container
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: run-container
|
||||
:END:
|
||||
After building the container it needs to be executed for the user to
|
||||
access the container and do certain operations. The docker
|
||||
package/module has a function to do this. The function takes in the
|
||||
docker environment as a parameter and also the docker struct. The docker
|
||||
struct has information such as the TCP ports which are supposed to be
|
||||
open and whether the docker container should have the GPU hooked to it
|
||||
or not. Based on the appropriate information provided ,the docker image
|
||||
gets started. The Image gets started by interacting with the docker
|
||||
client modules. When hooking the GPU the docker run command is called
|
||||
from the shell. This is because the docker Api does not support the GPU
|
||||
module yet. When the container is executed for the first time it takes
|
||||
more than 10 minutes to build. From the second time onwards it takes
|
||||
only 10 seconds to run.
|
||||
|
||||
*** Stop and remove container
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: stop-and-remove-container
|
||||
:END:
|
||||
This implementation here ensures that the docker is stopped, and the
|
||||
container is removed. This is to ensure it does not utilize server
|
||||
resources when it is not being used, or the task that is intended to be
|
||||
executed is complete. To run this function all that is needed is the
|
||||
docker container ID. If the function is successful it returns a string
|
||||
that says success.
|
||||
|
||||
*** Ports json file
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: ports-json-file
|
||||
:END:
|
||||
This file will help map internal ports inside a container to external
|
||||
ports inside a container. A common example would be the SSH port which
|
||||
is port 22 inside the docker container and is mapped to random TCP port
|
||||
outside container so that any external machines can directly connect
|
||||
into the container. The below representation mentions of where the
|
||||
ports.json file is located and also the format of that file.
|
||||
|
||||
#+begin_example
|
||||
|_ <Container name>
|
||||
|_ Dockerfile
|
||||
|_ description.txt
|
||||
|_ ports.json // The ports file
|
||||
#+end_example
|
||||
|
||||
Format of the ports.json file
|
||||
|
||||
#+begin_example
|
||||
{
|
||||
"Port": [
|
||||
{
|
||||
"PortName": "<Port name>",
|
||||
"InternalPort": <internal port>,
|
||||
"Type": "<tcp/udp>",
|
||||
"ExternalPort": <external port>,
|
||||
"IsUsed": "<boolean value (i.e true or false)>",
|
||||
"Description": "<description about the port>"
|
||||
}, ... n
|
||||
]
|
||||
}
|
||||
#+end_example
|
||||
Reference in New Issue
Block a user