config abstraction changes added

This commit is contained in:
2023-03-22 09:43:40 +00:00
parent 88dddd0230
commit 69c0aa5cb1
14 changed files with 2015 additions and 1924 deletions

View File

@@ -1,64 +1,64 @@
package docker
import (
"bufio"
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/archive"
"github.com/docker/go-connections/nat"
"github.com/lithammer/shortuuid"
"github.com/phayes/freeport"
"io"
"io/ioutil"
"os/exec"
"time"
"bufio"
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/archive"
"github.com/docker/go-connections/nat"
"github.com/lithammer/shortuuid"
"github.com/phayes/freeport"
"io"
"io/ioutil"
"os/exec"
"time"
)
type DockerVM struct {
SSHUsername string `json:"SSHUsername"`
SSHPassword string `json:"SSHPassword"`
ID string `json:"ID"`
TagName string `json:"TagName"`
ImagePath string `json:"ImagePath"`
Ports Ports `json:"Ports"`
GPU string `json:"GPU"`
SSHUsername string `json:"SSHUsername"`
SSHPassword string `json:"SSHPassword"`
ID string `json:"ID"`
TagName string `json:"TagName"`
ImagePath string `json:"ImagePath"`
Ports Ports `json:"Ports"`
GPU string `json:"GPU"`
}
type DockerContainers struct {
DockerContainer []DockerContainer `json:"DockerContainer"`
DockerContainer []DockerContainer `json:"DockerContainer"`
}
type DockerContainer struct {
ContainerName string `json:"DockerContainerName"`
ContainerDescription string `json:"ContainerDescription"`
ContainerName string `json:"DockerContainerName"`
ContainerDescription string `json:"ContainerDescription"`
}
type Ports struct {
PortSet []Port `json:"Port"`
PortSet []Port `json:"Port"`
}
type Port struct {
PortName string `json:"PortName"`
InternalPort int `json:"InternalPort"`
Type string `json:"Type"`
ExternalPort int `json:"ExternalPort"`
IsUsed bool `json:"IsUsed"`
Description string `json:"Description"`
PortName string `json:"PortName"`
InternalPort int `json:"InternalPort"`
Type string `json:"Type"`
ExternalPort int `json:"ExternalPort"`
IsUsed bool `json:"IsUsed"`
Description string `json:"Description"`
}
type ErrorLine struct {
Error string `json:"error"`
ErrorDetail ErrorDetail `json:"errorDetail"`
Error string `json:"error"`
ErrorDetail ErrorDetail `json:"errorDetail"`
}
type ErrorDetail struct {
Message string `json:"message"`
Message string `json:"message"`
}
var dockerRegistryUserID = ""
@@ -66,137 +66,137 @@ var dockerRegistryUserID = ""
// BuildRunContainer Function is incharge to invoke building and running contianer and also allocating external
// ports
func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerVM, error) {
//Docker Struct Variable
var RespDocker *DockerVM = new(DockerVM)
//Docker Struct Variable
var RespDocker *DockerVM = new(DockerVM)
// Sets if GPU is selected or not
RespDocker.GPU = GPU
// Sets if GPU is selected or not
RespDocker.GPU = GPU
// Sets Free port to Struct
//RespDocker.SSHPort = Ports[0]
//RespDocker.VNCPort = Ports[1]
// Sets appropriate username and password to the
// variables in the struct
RespDocker.SSHUsername = "master"
RespDocker.SSHPassword = "password"
//RespDocker.VNCPassword = "vncpassword"
// Sets Free port to Struct
//RespDocker.SSHPort = Ports[0]
//RespDocker.VNCPort = Ports[1]
// Sets appropriate username and password to the
// variables in the struct
RespDocker.SSHUsername = "master"
RespDocker.SSHPassword = "password"
//RespDocker.VNCPassword = "vncpassword"
//Default parameters
RespDocker.TagName = "p2p-ubuntu"
// Get Path from config
config, err := config.ConfigInit(nil)
if err != nil {
return nil, err
}
RespDocker.ImagePath = config.DefaultDockerFile
//Default parameters
RespDocker.TagName = "p2p-ubuntu"
// Get Path from config
config, err := config.ConfigInit(nil, nil)
if err != nil {
return nil, err
}
RespDocker.ImagePath = config.DefaultDockerFile
// We are checking if the container name is not nil and not equal to the default one used
// which is docker-ubuntu-sshd
if ContainerName != "" && ContainerName != "docker-ubuntu-sshd" {
Containers, err := ViewAllContainers()
if err != nil {
return nil, err
}
// We are checking if the container name is not nil and not equal to the default one used
// which is docker-ubuntu-sshd
if ContainerName != "" && ContainerName != "docker-ubuntu-sshd" {
Containers, err := ViewAllContainers()
if err != nil {
return nil, err
}
for _, dockerContainer := range Containers.DockerContainer {
if dockerContainer.ContainerName == ContainerName {
RespDocker.ImagePath = config.DockerContainers + ContainerName + "/"
RespDocker.TagName = ContainerName
break
}
}
if RespDocker.ImagePath == config.DefaultDockerFile {
return nil, errors.New("Container " + ContainerName + " does not exist in the server")
}
}
for _, dockerContainer := range Containers.DockerContainer {
if dockerContainer.ContainerName == ContainerName {
RespDocker.ImagePath = config.DockerContainers + ContainerName + "/"
RespDocker.TagName = ContainerName
break
}
}
if RespDocker.ImagePath == config.DefaultDockerFile {
return nil, errors.New("Container " + ContainerName + " does not exist in the server")
}
}
PortsInformation, err := OpenPortsFile(RespDocker.ImagePath + "/ports.json")
if err != nil {
return nil, err
}
PortsInformation, err := OpenPortsFile(RespDocker.ImagePath + "/ports.json")
if err != nil {
return nil, err
}
// Number of perts we want to open + number of ports required inside the
// docker container
count := NumPorts + len(PortsInformation.PortSet)
// Creates number of ports
OpenPorts, err := freeport.GetFreePorts(count)
if err != nil {
return nil, err
}
// Allocate external ports to ports available in the ports.json file
for i := range PortsInformation.PortSet {
// Setting external ports
PortsInformation.PortSet[i].ExternalPort = OpenPorts[i]
PortsInformation.PortSet[i].IsUsed = true
}
//Length of Ports allocated from thr port file
portFileLength := len(PortsInformation.PortSet)
// Allocate New ports the user wants to generate
for i := 0; i < NumPorts; i++ {
var TempPort Port
TempPort.PortName = "AutoGen Port"
TempPort.Type = "tcp"
TempPort.InternalPort = OpenPorts[portFileLength+i]
TempPort.ExternalPort = OpenPorts[portFileLength+i]
TempPort.Description = "Auto generated TCP port"
TempPort.IsUsed = false
//Append temp port to port information
PortsInformation.PortSet = append(PortsInformation.PortSet, TempPort)
}
// Setting ports to the docker VM struct
RespDocker.Ports = *PortsInformation
// Number of perts we want to open + number of ports required inside the
// docker container
count := NumPorts + len(PortsInformation.PortSet)
// Creates number of ports
OpenPorts, err := freeport.GetFreePorts(count)
if err != nil {
return nil, err
}
// Allocate external ports to ports available in the ports.json file
for i := range PortsInformation.PortSet {
// Setting external ports
PortsInformation.PortSet[i].ExternalPort = OpenPorts[i]
PortsInformation.PortSet[i].IsUsed = true
}
//Length of Ports allocated from thr port file
portFileLength := len(PortsInformation.PortSet)
// Allocate New ports the user wants to generate
for i := 0; i < NumPorts; i++ {
var TempPort Port
TempPort.PortName = "AutoGen Port"
TempPort.Type = "tcp"
TempPort.InternalPort = OpenPorts[portFileLength+i]
TempPort.ExternalPort = OpenPorts[portFileLength+i]
TempPort.Description = "Auto generated TCP port"
TempPort.IsUsed = false
//Append temp port to port information
PortsInformation.PortSet = append(PortsInformation.PortSet, TempPort)
}
// Setting ports to the docker VM struct
RespDocker.Ports = *PortsInformation
// Gets docker information from env variables
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return nil, err
}
// Gets docker information from env variables
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return nil, err
}
// Builds docker image
err = RespDocker.imageBuild(cli)
if err != nil {
return nil, err
}
// Builds docker image
err = RespDocker.imageBuild(cli)
if err != nil {
return nil, err
}
// Runs docker contianer
err = RespDocker.runContainer(cli)
// Runs docker contianer
err = RespDocker.runContainer(cli)
if err != nil {
return nil, err
}
if err != nil {
return nil, err
}
return RespDocker, nil
return RespDocker, nil
}
// Builds docker image (TODO: relative path for Dockerfile deploy)
func (d *DockerVM) imageBuild(dockerClient *client.Client) error {
ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
//defer cancel()
ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
//defer cancel()
tar, err := archive.TarWithOptions(d.ImagePath, &archive.TarOptions{})
if err != nil {
return err
}
tar, err := archive.TarWithOptions(d.ImagePath, &archive.TarOptions{})
if err != nil {
return err
}
opts := types.ImageBuildOptions{
Dockerfile: "Dockerfile",
Tags: []string{d.TagName},
Remove: true,
}
res, err := dockerClient.ImageBuild(ctx, tar, opts)
if err != nil {
return err
}
opts := types.ImageBuildOptions{
Dockerfile: "Dockerfile",
Tags: []string{d.TagName},
Remove: true,
}
res, err := dockerClient.ImageBuild(ctx, tar, opts)
if err != nil {
return err
}
defer res.Body.Close()
defer res.Body.Close()
err = print(res.Body)
if err != nil {
return err
}
err = print(res.Body)
if err != nil {
return err
}
return nil
return nil
}
// Starts container and assigns port numbers
@@ -205,200 +205,200 @@ func (d *DockerVM) imageBuild(dockerClient *client.Client) error {
// -p 3443:6901 -p 3453:22 -p 3434:3434 -p 3245:3245 -v=/opt/data:/data
// p2p-ubuntu /start > /dev/null
func (d *DockerVM) runContainer(dockerClient *client.Client) error {
ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
// 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
// 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{}{},
}
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),
// },
//},
}
// 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.PortSet {
// Parameters "tcp or udp", external port
Port, err := nat.NewPort(d.Ports.PortSet[i].Type, fmt.Sprint(d.Ports.PortSet[i].InternalPort))
if err != nil {
return err
}
for i := range d.Ports.PortSet {
// Parameters "tcp or udp", external port
Port, err := nat.NewPort(d.Ports.PortSet[i].Type, fmt.Sprint(d.Ports.PortSet[i].InternalPort))
if err != nil {
return err
}
// Exposed Ports
ExposedPort[Port] = struct{}{}
// Exposed Ports
ExposedPort[Port] = struct{}{}
PortForwarding[Port] = []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: fmt.Sprint(d.Ports.PortSet[i].ExternalPort),
},
}
}
PortForwarding[Port] = []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: fmt.Sprint(d.Ports.PortSet[i].ExternalPort),
},
}
}
config := &container.Config{
Image: d.TagName,
Entrypoint: []string{"/start"},
Volumes: map[string]struct{}{"/opt/data:/data": {}},
ExposedPorts: ExposedPort,
}
hostConfig := &container.HostConfig{
PortBindings: PortForwarding,
}
config := &container.Config{
Image: d.TagName,
Entrypoint: []string{"/start"},
Volumes: map[string]struct{}{"/opt/data:/data": {}},
ExposedPorts: ExposedPort,
}
hostConfig := &container.HostConfig{
PortBindings: PortForwarding,
}
res, err := dockerClient.ContainerCreate(ctx, config, hostConfig,
nil, nil, "")
res, err := dockerClient.ContainerCreate(ctx, config, hostConfig,
nil, nil, "")
// Set response ID
d.ID = res.ID
// Set response ID
d.ID = res.ID
if err != nil {
return err
}
if err != nil {
return err
}
err = dockerClient.ContainerStart(ctx, res.ID, types.ContainerStartOptions{})
err = dockerClient.ContainerStart(ctx, res.ID, types.ContainerStartOptions{})
if err != nil {
return err
}
} else {
// Generate Random ID
id := shortuuid.New()
d.ID = id
if err != nil {
return err
}
} else {
// Generate Random ID
id := shortuuid.New()
d.ID = id
var cmd bytes.Buffer
cmd.WriteString("docker run -d=true --name=" + id + " --restart=always --gpus all ")
for i := range d.Ports.PortSet {
cmd.WriteString("-p " + fmt.Sprint(d.Ports.PortSet[i].ExternalPort) + ":" + fmt.Sprint(d.Ports.PortSet[i].InternalPort) + " ")
}
cmd.WriteString("-v=/opt/data:/data " + d.TagName + " /start > /dev/null")
//"-v=/opt/data:/data p2p-ubuntu /start > /dev/null"
cmdStr := cmd.String()
_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
if err != nil {
return err
}
}
return nil
var cmd bytes.Buffer
cmd.WriteString("docker run -d=true --name=" + id + " --restart=always --gpus all ")
for i := range d.Ports.PortSet {
cmd.WriteString("-p " + fmt.Sprint(d.Ports.PortSet[i].ExternalPort) + ":" + fmt.Sprint(d.Ports.PortSet[i].InternalPort) + " ")
}
cmd.WriteString("-v=/opt/data:/data " + d.TagName + " /start > /dev/null")
//"-v=/opt/data:/data p2p-ubuntu /start > /dev/null"
cmdStr := cmd.String()
_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
if err != nil {
return err
}
}
return nil
}
// StopAndRemoveContainer
// Stop and remove a container
// Reference (https://gist.github.com/frikky/e2efcea6c733ea8d8d015b7fe8a91bf6)
func StopAndRemoveContainer(containername string) error {
ctx := context.Background()
ctx := context.Background()
// Gets docker information from env variables
client, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return err
}
// Gets docker information from env variables
client, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return err
}
if err = client.ContainerStop(ctx, containername, nil); err != nil {
return err
}
if err = client.ContainerStop(ctx, containername, nil); err != nil {
return err
}
removeOptions := types.ContainerRemoveOptions{
RemoveVolumes: true,
Force: true,
}
removeOptions := types.ContainerRemoveOptions{
RemoveVolumes: true,
Force: true,
}
if err = client.ContainerRemove(ctx, containername, removeOptions); err != nil {
return err
}
if err = client.ContainerRemove(ctx, containername, removeOptions); err != nil {
return err
}
return nil
return nil
}
// ViewAllContainers returns all containers runnable and which can be built
func ViewAllContainers() (*DockerContainers, error) {
// Traverse the deploy path as per given in the config file
config, err := config.ConfigInit(nil)
if err != nil {
return nil, err
}
// Traverse the deploy path as per given in the config file
config, err := config.ConfigInit(nil, nil)
if err != nil {
return nil, err
}
folders, err := ioutil.ReadDir(config.DockerContainers)
if err != nil {
return nil, err
}
folders, err := ioutil.ReadDir(config.DockerContainers)
if err != nil {
return nil, err
}
//Declare variable DockerContainers of type struct
var Containers *DockerContainers = new(DockerContainers)
//Declare variable DockerContainers of type struct
var Containers *DockerContainers = new(DockerContainers)
for _, f := range folders {
if f.IsDir() {
//Declare variable DockerContainer of type struct
var Container DockerContainer
for _, f := range folders {
if f.IsDir() {
//Declare variable DockerContainer of type struct
var Container DockerContainer
// Setting container name to deploy name
Container.ContainerName = f.Name()
// Getting Description from file description.txt
Description, err := ioutil.ReadFile(config.DockerContainers + "/" + Container.ContainerName + "/description.txt")
// if we os.Open returns an error then handle it
if err != nil {
return nil, err
}
// Setting container name to deploy name
Container.ContainerName = f.Name()
// Getting Description from file description.txt
Description, err := ioutil.ReadFile(config.DockerContainers + "/" + Container.ContainerName + "/description.txt")
// if we os.Open returns an error then handle it
if err != nil {
return nil, err
}
// Get Description from description.txt
Container.ContainerDescription = string(Description)
// Get Description from description.txt
Container.ContainerDescription = string(Description)
Containers.DockerContainer = append(Containers.DockerContainer, Container)
}
}
Containers.DockerContainer = append(Containers.DockerContainer, Container)
}
}
return Containers, nil
return Containers, nil
}
func print(rd io.Reader) error {
var lastLine string
var lastLine string
scanner := bufio.NewScanner(rd)
for scanner.Scan() {
lastLine = scanner.Text()
}
scanner := bufio.NewScanner(rd)
for scanner.Scan() {
lastLine = scanner.Text()
}
errLine := &ErrorLine{}
json.Unmarshal([]byte(lastLine), errLine)
if errLine.Error != "" {
return errors.New(errLine.Error)
}
errLine := &ErrorLine{}
json.Unmarshal([]byte(lastLine), errLine)
if errLine.Error != "" {
return errors.New(errLine.Error)
}
if err := scanner.Err(); err != nil {
return err
}
if err := scanner.Err(); err != nil {
return err
}
return nil
return nil
}
func OpenPortsFile(filename string) (*Ports, error) {
buf, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
buf, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
c := &Ports{}
err = json.Unmarshal(buf, c)
if err != nil {
return nil, fmt.Errorf("in file %q: %v", filename, err)
}
c := &Ports{}
err = json.Unmarshal(buf, c)
if err != nil {
return nil, fmt.Errorf("in file %q: %v", filename, err)
}
return c, nil
return c, nil
}

View File

@@ -1,226 +1,226 @@
package server
import (
"encoding/json"
"fmt"
"github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
"github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/Akilan1999/p2p-rendering-computation/p2p"
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
"github.com/gin-gonic/gin"
"io/ioutil"
"net/http"
"strconv"
"time"
"encoding/json"
"fmt"
"github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
"github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/Akilan1999/p2p-rendering-computation/p2p"
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
"github.com/gin-gonic/gin"
"io/ioutil"
"net/http"
"strconv"
"time"
)
func Server() (*gin.Engine, error) {
r := gin.Default()
r := gin.Default()
//Get Server port based on the config file
config, err := config.ConfigInit(nil)
if err != nil {
return nil, err
}
//Get Server port based on the config file
config, err := config.ConfigInit(nil, nil)
if err != nil {
return nil, err
}
// update IPTable with new port and ip address and update ip table
var ProxyIpAddr p2p.IpAddress
var lowestLatencyIpAddress p2p.IpAddress
// update IPTable with new port and ip address and update ip table
var ProxyIpAddr p2p.IpAddress
var lowestLatencyIpAddress p2p.IpAddress
// Gets default information of the server
r.GET("/server_info", func(c *gin.Context) {
c.JSON(http.StatusOK, ServerInfo())
})
// Gets default information of the server
r.GET("/server_info", func(c *gin.Context) {
c.JSON(http.StatusOK, ServerInfo())
})
// Speed test with 50 mbps
r.GET("/50", func(c *gin.Context) {
// Get Path from config
c.File(config.SpeedTestFile)
})
// Speed test with 50 mbps
r.GET("/50", func(c *gin.Context) {
// Get Path from config
c.File(config.SpeedTestFile)
})
// Route build to do a speed test
r.GET("/upload", func(c *gin.Context) {
file, _ := c.FormFile("file")
// Route build to do a speed test
r.GET("/upload", func(c *gin.Context) {
file, _ := c.FormFile("file")
// Upload the file to specific dst.
// c.SaveUploadedFile(file, dst)
// Upload the file to specific dst.
// c.SaveUploadedFile(file, dst)
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
})
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
})
//Gets Ip Table from server node
r.POST("/IpTable", func(c *gin.Context) {
// Getting IPV4 address of client
var ClientHost p2p.IpAddress
//Gets Ip Table from server node
r.POST("/IpTable", func(c *gin.Context) {
// Getting IPV4 address of client
var ClientHost p2p.IpAddress
if p2p.Ip4or6(c.ClientIP()) == "version 6" {
ClientHost.Ipv6 = c.ClientIP()
} else {
ClientHost.Ipv4 = c.ClientIP()
}
if p2p.Ip4or6(c.ClientIP()) == "version 6" {
ClientHost.Ipv6 = c.ClientIP()
} else {
ClientHost.Ipv4 = c.ClientIP()
}
// Variable to store IP table information
var IPTable p2p.IpAddresses
// Variable to store IP table information
var IPTable p2p.IpAddresses
// Receive file from POST request
body, err := c.FormFile("json")
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Receive file from POST request
body, err := c.FormFile("json")
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Open file
open, err := body.Open()
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Open file
open, err := body.Open()
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Open received file
file, err := ioutil.ReadAll(open)
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Open received file
file, err := ioutil.ReadAll(open)
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
json.Unmarshal(file, &IPTable)
json.Unmarshal(file, &IPTable)
//Add Client IP address to IPTable struct
IPTable.IpAddress = append(IPTable.IpAddress, ClientHost)
//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 {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Runs speed test to return only servers in the IP table pingable
err = IPTable.SpeedTestUpdatedIPTable()
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Reads IP addresses from ip table
IpAddresses, err := p2p.ReadIpTable()
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Reads IP addresses from ip table
IpAddresses, err := p2p.ReadIpTable()
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
c.JSON(http.StatusOK, IpAddresses)
})
c.JSON(http.StatusOK, IpAddresses)
})
// Starts docker container in server
r.GET("/startcontainer", func(c *gin.Context) {
// Get Number of ports to open and whether to use GPU or not
Ports := c.DefaultQuery("ports", "0")
GPU := c.DefaultQuery("GPU", "false")
ContainerName := c.DefaultQuery("ContainerName", "")
var PortsInt int
// Starts docker container in server
r.GET("/startcontainer", func(c *gin.Context) {
// Get Number of ports to open and whether to use GPU or not
Ports := c.DefaultQuery("ports", "0")
GPU := c.DefaultQuery("GPU", "false")
ContainerName := c.DefaultQuery("ContainerName", "")
var PortsInt int
// Convert Get Request value to int
fmt.Sscanf(Ports, "%d", &PortsInt)
// Convert Get Request value to int
fmt.Sscanf(Ports, "%d", &PortsInt)
// Creates container and returns-back result to
// access container
resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName)
// Creates container and returns-back result to
// access container
resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName)
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
// Ensures that FRP is triggered only if a proxy address is provided
if ProxyIpAddr.Ipv4 != "" && c.Request.Host != "localhost:"+config.ServerPort && c.Request.Host != "0.0.0.0:"+config.ServerPort {
resp, err = frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, lowestLatencyIpAddress.ServerPort, resp)
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
fmt.Println(resp)
}
// Ensures that FRP is triggered only if a proxy address is provided
if ProxyIpAddr.Ipv4 != "" && c.Request.Host != "localhost:"+config.ServerPort && c.Request.Host != "0.0.0.0:"+config.ServerPort {
resp, err = frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, lowestLatencyIpAddress.ServerPort, resp)
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
fmt.Println(resp)
}
c.JSON(http.StatusOK, resp)
})
c.JSON(http.StatusOK, resp)
})
//Remove container
r.GET("/RemoveContainer", func(c *gin.Context) {
ID := c.DefaultQuery("id", "0")
if err := docker.StopAndRemoveContainer(ID); err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.String(http.StatusOK, "success")
})
//Remove container
r.GET("/RemoveContainer", func(c *gin.Context) {
ID := c.DefaultQuery("id", "0")
if err := docker.StopAndRemoveContainer(ID); err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.String(http.StatusOK, "success")
})
//Show images available
r.GET("/ShowImages", func(c *gin.Context) {
resp, err := docker.ViewAllContainers()
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.JSON(http.StatusOK, resp)
})
//Show images available
r.GET("/ShowImages", func(c *gin.Context) {
resp, err := docker.ViewAllContainers()
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.JSON(http.StatusOK, resp)
})
// Request for port no from Server with address
r.GET("/FRPPort", func(c *gin.Context) {
port, err := frp.StartFRPProxyFromRandom()
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
// Request for port no from Server with address
r.GET("/FRPPort", func(c *gin.Context) {
port, err := frp.StartFRPProxyFromRandom()
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.String(http.StatusOK, strconv.Itoa(port))
})
c.String(http.StatusOK, strconv.Itoa(port))
})
// If there is a proxy port specified
// then starts the FRP server
//if config.FRPServerPort != "0" {
// go frp.StartFRPProxyFromRandom()
//}
// If there is a proxy port specified
// then starts the FRP server
//if config.FRPServerPort != "0" {
// go frp.StartFRPProxyFromRandom()
//}
// TODO check if IPV6 or Proxy port is specified
// if not update current entry as proxy address
// with appropriate port on IP Table
if config.BehindNAT == "True" {
table, err := p2p.ReadIpTable()
if err != nil {
return nil, err
}
// TODO check if IPV6 or Proxy port is specified
// if not update current entry as proxy address
// with appropriate port on IP Table
if config.BehindNAT == "True" {
table, err := p2p.ReadIpTable()
if err != nil {
return nil, err
}
var lowestLatency int64
// random large number
lowestLatency = 10000000
var lowestLatency int64
// random large number
lowestLatency = 10000000
for i, _ := range table.IpAddress {
// Checks if the ping is the lowest and if the following node is acting as a proxy
//if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" {
if table.IpAddress[i].Latency.Milliseconds() < lowestLatency {
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
lowestLatencyIpAddress = table.IpAddress[i]
}
}
for i, _ := range table.IpAddress {
// Checks if the ping is the lowest and if the following node is acting as a proxy
//if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" {
if table.IpAddress[i].Latency.Milliseconds() < lowestLatency {
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
lowestLatencyIpAddress = table.IpAddress[i]
}
}
// If there is an identified node
if lowestLatency != 10000000 {
serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort)
if err != nil {
return nil, err
}
// Create 3 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, config.ServerPort)
if err != nil {
return nil, err
}
// If there is an identified node
if lowestLatency != 10000000 {
serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort)
if err != nil {
return nil, err
}
// Create 3 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, config.ServerPort)
if err != nil {
return nil, err
}
// updating with the current proxy address
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
ProxyIpAddr.ServerPort = proxyPort
ProxyIpAddr.Name = config.MachineName
ProxyIpAddr.NAT = "False"
ProxyIpAddr.EscapeImplementation = "FRP"
// updating with the current proxy address
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
ProxyIpAddr.ServerPort = proxyPort
ProxyIpAddr.Name = config.MachineName
ProxyIpAddr.NAT = "False"
ProxyIpAddr.EscapeImplementation = "FRP"
// append the following to the ip table
table.IpAddress = append(table.IpAddress, ProxyIpAddr)
// write information back to the IP Table
table.WriteIpTable()
// update ip table
go clientIPTable.UpdateIpTableListClient()
}
// append the following to the ip table
table.IpAddress = append(table.IpAddress, ProxyIpAddr)
// write information back to the IP Table
table.WriteIpTable()
// update ip table
go clientIPTable.UpdateIpTableListClient()
}
}
}
// Run gin server on the specified port
go r.Run(":" + config.ServerPort)
// Run gin server on the specified port
go r.Run(":" + config.ServerPort)
return r, nil
return r, nil
}