Merge branch 'master' of github.com:Akilan1999/p2p-redering-computation into withdocs

This commit is contained in:
2021-04-15 14:00:08 +04:00
9 changed files with 206 additions and 78 deletions

View File

@@ -3,6 +3,8 @@ package client
import (
"bytes"
"encoding/json"
"fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p"
"io"
"io/ioutil"
@@ -12,17 +14,34 @@ import (
"path/filepath"
)
// Does the following to update it's IP table
type IP struct {
Query string
}
// UpdateIpTable Does the following to update it's IP table
func UpdateIpTable(IpAddress string) error {
resp, err := SendPostRequest("http://"+IpAddress+":8088/IpTable",
"/etc/p2p-rendering/ip_table.json",
"json")
config, err := config.ConfigInit()
if err != nil {
return err
}
client := http.Client{}
resp, err := UploadMultipartFile(client,"http://"+IpAddress+":8088/IpTable","json",config.IPTable)
if err != nil {
return err
}
//resp, err := SendPostRequest("http://"+IpAddress+":8088/IpTable",
// config.IPTable,
// "json")
//
//if err != nil {
// return err
//}
var ipStruct p2p.IpAddresses
json.Unmarshal(resp, &ipStruct)
@@ -36,7 +55,7 @@ func UpdateIpTable(IpAddress string) error {
return nil
}
//updates IP tables (Default 3 hops) based on server information available
// UpdateIpTableListClient updates IP tables (Default 3 hops) based on server information available
//on the ip tables
func UpdateIpTableListClient() error {
// Ensure that the IP Table has Node pingable
@@ -49,7 +68,7 @@ func UpdateIpTableListClient() error {
// duplication
Addresses, err := p2p.ReadIpTable()
DoNotRead := Addresses
var DoNotRead p2p.IpAddresses
// Run loop 3 times
for i := 0; i < 3; i++ {
@@ -59,11 +78,25 @@ func UpdateIpTableListClient() error {
return err
}
// Appending current machine public IP address as should not be there in IP Table
var PublicIP p2p.IpAddress
ip, err := CurrentPublicIP()
if err != nil {
return err
}
PublicIP.Ipv4 = ip
DoNotRead.IpAddress = append(DoNotRead.IpAddress, PublicIP)
// Updates IP table based on server IP table
for j := range Addresses.IpAddress {
// Check if IP addresses is there in the struct DoNotRead
Exists := false
if PublicIP.Ipv4 == Addresses.IpAddress[j].Ipv4 {
Exists = true
}
// Check if IP addresses is there in the struct DoNotRead
for k := range DoNotRead.IpAddress {
if DoNotRead.IpAddress[k].Ipv4 == Addresses.IpAddress[j].Ipv4 {
Exists = true
@@ -75,7 +108,6 @@ func UpdateIpTableListClient() error {
if Exists {
continue
}
err = UpdateIpTable(Addresses.IpAddress[j].Ipv4)
if err != nil {
return err
@@ -89,7 +121,8 @@ func UpdateIpTableListClient() error {
return nil
}
// Sends a file as a POST request.
// SendPostRequest Sends a file as a
//POST request.
// Reference (https://stackoverflow.com/questions/51234464/upload-a-file-with-post-request-golang)
func SendPostRequest (url string, filename string, filetype string) ([]byte,error) {
file, err := os.Open(filename)
@@ -132,4 +165,76 @@ func SendPostRequest (url string, filename string, filetype string) ([]byte,erro
}
return content, nil
}
func UploadMultipartFile(client http.Client, uri, key, path string) ([]byte, error) {
body, writer := io.Pipe()
req, err := http.NewRequest(http.MethodPost, uri, body)
if err != nil {
return nil, err
}
mwriter := multipart.NewWriter(writer)
req.Header.Add("Content-Type", mwriter.FormDataContentType())
errchan := make(chan error)
go func() {
defer close(errchan)
defer writer.Close()
defer mwriter.Close()
w, err := mwriter.CreateFormFile(key, path)
if err != nil {
errchan <- err
return
}
in, err := os.Open(path)
if err != nil {
errchan <- err
return
}
defer in.Close()
if written, err := io.Copy(w, in); err != nil {
errchan <- fmt.Errorf("error copying %s (%d bytes written): %v", path, written, err)
return
}
if err := mwriter.Close(); err != nil {
errchan <- err
return
}
}()
resp, err := client.Do(req)
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return content, nil
}
// CurrentPublicIP Get Current Public IP address
func CurrentPublicIP() (string,error) {
req, err := http.Get("http://ip-api.com/json/")
if err != nil {
return "",err
}
defer req.Body.Close()
body, err := ioutil.ReadAll(req.Body)
if err != nil {
return "",err
}
var ip IP
json.Unmarshal(body, &ip)
return ip.Query, nil
}

View File

@@ -16,7 +16,7 @@ var CliAction = func(ctx *cli.Context) error {
}
//Listing servers and also updates IP tables (Default 3 hops)
if ListServers {
if UpdateServerList {
err := client.UpdateIpTableListClient()
if err != nil {
@@ -26,6 +26,10 @@ var CliAction = func(ctx *cli.Context) error {
p2p.PrintIpTable()
}
if ServerList {
p2p.PrintIpTable()
}
// Function called to stop and remove server from Docker
if RemoveVM != "" && ID != "" {
err := client.RemoveContianer(RemoveVM,ID)
@@ -38,7 +42,6 @@ var CliAction = func(ctx *cli.Context) error {
if CreateVM != "" {
var PortsInt int
PortsInt = 0
if Ports != "" {
// Convert Get Request value to int

View File

@@ -6,14 +6,15 @@ import (
// Variables declared for CLI
var (
CreateVM string
Ports string
Mode string
RemoveVM string
ID string
Specs string
GPU bool
ListServers bool
CreateVM string
Ports string
Mode string
RemoveVM string
ID string
Specs string
GPU bool
UpdateServerList bool
ServerList bool
)
var AppConfigFlags = []cli.Flag{
@@ -25,11 +26,17 @@ var AppConfigFlags = []cli.Flag{
EnvVars: []string{"P2P_MODE"},
Destination: &Mode,
},
&cli.BoolFlag{
Name: "UpdateServerList",
Usage: "Update List of Server available based on servers iptables",
EnvVars: []string{"UPDATE_SERVER_LIST"},
Destination: &UpdateServerList,
},
&cli.BoolFlag{
Name: "ListServers",
Usage: "List servers which can render tasks",
EnvVars: []string{"LIST_SERVERS"},
Destination: &ListServers,
Destination: &ServerList,
},
&cli.StringFlag{
Name: "CreateVM",
@@ -53,7 +60,7 @@ var AppConfigFlags = []cli.Flag{
Name: "Ports",
Usage: "Number of ports to open for the Docker Container",
EnvVars: []string{"NUM_PORTS"},
Destination: &ID,
Destination: &Ports,
},
&cli.BoolFlag{
Name: "GPU",

Binary file not shown.

View File

@@ -1,10 +1,16 @@
{
"ip_address": [
{
"ipv4": "localhost",
"latency": 14981051,
"download": 8142.122540206258,
"upload": 3578.766512629995
"ipv4": "145.40.90.151",
"latency": 144024138,
"download": 6.124989686501195,
"upload": 3863.649528583081
},
{
"ipv4": "86.99.70.106",
"latency": 7972645,
"download": 87.32677875720803,
"upload": 6006.624976985241
}
]
}

View File

@@ -22,15 +22,14 @@ type IpAddress struct {
Upload float64 `json:"upload"`
}
// Read data from Ip tables from json file
// ReadIpTable Read data from Ip tables from json file
func ReadIpTable()(*IpAddresses ,error){
// Get Path from config
config, err := config.ConfigInit()
if err != nil {
return nil,err
}
jsonFile, err := os.Open(config.SpeedTestFile)
jsonFile, err := os.Open(config.IPTable)
// if we os.Open returns an error then handle it
if err != nil {
return nil,err
@@ -53,7 +52,7 @@ func ReadIpTable()(*IpAddresses ,error){
return &ipAddresses, nil
}
// Write to IP table json file
// WriteIpTable Write to IP table json file
func (i *IpAddresses) WriteIpTable() error {
file, err := json.MarshalIndent(i, "", " ")
if err != nil {
@@ -66,7 +65,7 @@ func (i *IpAddresses) WriteIpTable() error {
return err
}
err = ioutil.WriteFile(config.SpeedTestFile, file, 0644)
err = ioutil.WriteFile(config.IPTable, file, 0644)
if err != nil {
return err
}
@@ -74,7 +73,7 @@ func (i *IpAddresses) WriteIpTable() error {
return nil
}
// Print Ip table data for Cli
// PrintIpTable Print Ip table data for Cli
func PrintIpTable() error {
table, err := ReadIpTable()

View File

@@ -1,6 +1,6 @@
package p2p
// Runs a speed test and does updates IP tables accordingly
// SpeedTest Runs a speed test and does updates IP tables accordingly
func (ip *IpAddresses)SpeedTest() error{
for i, _ := range ip.IpAddress {
@@ -8,7 +8,7 @@ func (ip *IpAddresses)SpeedTest() error{
err := ip.IpAddress[i].PingTest()
if err != nil {
// Remove IP address of element not pingable
ip.IpAddress = append(ip.IpAddress[:i], ip.IpAddress[i+1:]...)
ip.IpAddress = remove(ip.IpAddress,i)
// Proceed to next element in the array
continue
}
@@ -33,7 +33,7 @@ func (ip *IpAddresses)SpeedTest() error{
return nil
}
// Called when ip tables from client/server is also passed on
// SpeedTestUpdatedIPTable Called when ip tables from client/server is also passed on
func (ip *IpAddresses)SpeedTestUpdatedIPTable() error{
targets, err := ReadIpTable()
if err != nil {
@@ -71,7 +71,7 @@ func (ip *IpAddresses)SpeedTestUpdatedIPTable() error{
return nil
}
// Runs speed test in iptables locally only
// LocalSpeedTestIpTable Runs speed test in iptables locally only
func LocalSpeedTestIpTable() error {
targets, err := ReadIpTable()
if err != nil {
@@ -86,3 +86,8 @@ func LocalSpeedTestIpTable() error {
return nil
}
// Helper function to remove element from an array of a struct
func remove(s []IpAddress, i int) []IpAddress {
s[len(s)-1], s[i] = s[i], s[len(s)-1]
return s[:len(s)-1]
}

View File

@@ -145,52 +145,53 @@ func (d *DockerVM)imageBuild(dockerClient *client.Client) error {
func (d *DockerVM)runContainer(dockerClient *client.Client) error{
ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
//Exposed ports for docker config file
var ExposedPort nat.PortSet
ExposedPort = nat.PortSet{
"22/tcp": struct{}{},
"6901/tcp": struct{}{},
}
// Port forwarding for VNC and SSH ports
PortForwarding := nat.PortMap{
"22/tcp": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: fmt.Sprint(d.SSHPort),
},
},
"6901/tcp": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: fmt.Sprint(d.VNCPort),
},
},
}
for i := range d.Ports {
Port, err := nat.NewPort("tcp",fmt.Sprint(d.Ports[i]))
if err != nil {
return err
}
// Exposed Ports
ExposedPort[Port] = struct{}{}
PortForwarding[Port] = []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: fmt.Sprint(d.Ports[i]),
},
}
}
// The first mode runs using the Docker Api. As the API supports using
// CPU and uses a shell script for GPU call because till this point of
// implementation docker api does not support the flag "--gpu all"
if d.GPU != "true" {
//Exposed ports for docker config file
var ExposedPort nat.PortSet
ExposedPort = nat.PortSet{
"22/tcp": struct{}{},
"6901/tcp": struct{}{},
}
// Port forwarding for VNC and SSH ports
PortForwarding := nat.PortMap{
"22/tcp": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: fmt.Sprint(d.SSHPort),
},
},
"6901/tcp": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: fmt.Sprint(d.VNCPort),
},
},
}
for i := range d.Ports {
Port, err := nat.NewPort("tcp",fmt.Sprint(d.Ports[i]))
if err != nil {
return err
}
// Exposed Ports
ExposedPort[Port] = struct{}{}
PortForwarding[Port] = []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: fmt.Sprint(d.Ports[i]),
},
}
}
config := &container.Config{
Image: d.TagName,
Entrypoint: []string{"/dockerstartup/vnc_startup.sh", "/start"},

View File

@@ -44,10 +44,9 @@ func Server() error{
// Getting IPV4 address of client
var ClientHost p2p.IpAddress
ClientHost.Ipv4 = c.ClientIP()
// Variable to store IP table information
var IPTable p2p.IpAddresses
//Add Client IP address to IPTable struct
IPTable.IpAddress = append(IPTable.IpAddress, ClientHost)
// Receive file from POST request
body, err := c.FormFile("json")
@@ -69,6 +68,9 @@ func Server() error{
json.Unmarshal(file,&IPTable)
//Add Client IP address to IPTable struct
IPTable.IpAddress = append(IPTable.IpAddress, ClientHost)
// Runs speed test to return only servers in the IP table pingable
err = IPTable.SpeedTestUpdatedIPTable()
if err != nil {