Merge pull request #97 from Akilan1999/approprirate-abstractions

Appropriate abstractions
This commit is contained in:
Akilan Selvacoumar
2023-06-07 23:49:39 +01:00
committed by GitHub
27 changed files with 2316 additions and 2228 deletions

View File

@@ -1,6 +1,6 @@
# Abstractions # Abstractions
The Abstractions package consists of blackboxed functions for P2PRC. The Abstractions package consists of black-boxed functions for P2PRC.
## Functions ## Functions
- ```Init(<Project name>)```: Initialises P2PRC with all the needed configurations. - ```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. - ```Start()```: Starts p2prc as a server and makes it possible to extend by adding other routes and functionality to P2PRC.

View File

@@ -35,6 +35,3 @@ func main() {
} }
``` ```
// todo diagram representation of the interaction with
nodes spawned in the p2p network.

View File

@@ -1,27 +1,27 @@
package abstractions package abstractions
import ( import (
"github.com/Akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/Akilan1999/p2p-rendering-computation/config/generate" "github.com/Akilan1999/p2p-rendering-computation/config/generate"
"github.com/Akilan1999/p2p-rendering-computation/server" "github.com/Akilan1999/p2p-rendering-computation/server"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
// Init Initialises p2prc // Init Initialises p2prc
func Init(name string) (config *config.Config, err error) { func Init(name string, customConfig interface{}) (config *config.Config, err error) {
// set the config file with default paths // set the config file with default paths
config, err = generate.SetDefaults(name, false) config, err = generate.SetDefaults(name, false, customConfig, false)
if err != nil { if err != nil {
return return
} }
return return
} }
// Start p2prc in a server mode // Start p2prc in a server mode
func Start() (*gin.Engine, error) { func Start() (*gin.Engine, error) {
engine, err := server.Server() engine, err := server.Server()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return engine, nil return engine, nil
} }

View File

@@ -1,310 +1,310 @@
package client package client
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/Akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/google/uuid" "github.com/google/uuid"
"io/ioutil" "io/ioutil"
"os" "os"
) )
// Groups Data Structure type // Groups Data Structure type
type Groups struct { type Groups struct {
GroupList []*Group `json:"Groups"` GroupList []*Group `json:"Groups"`
} }
// Group Information about a single group // Group Information about a single group
type Group struct { type Group struct {
ID string `json:"ID"` ID string `json:"ID"`
TrackContainerList []*TrackContainer `json:"TrackContainer"` TrackContainerList []*TrackContainer `json:"TrackContainer"`
// Sneaky as required only when removing the element // Sneaky as required only when removing the element
// Set when GetGroup function is called // Set when GetGroup function is called
index int index int
} }
// CreateGroup Creates a new group to add a set of track containers // CreateGroup Creates a new group to add a set of track containers
func CreateGroup() (*Group, error) { func CreateGroup() (*Group, error) {
// Creating variable of type new group // Creating variable of type new group
var NewGroup Group var NewGroup Group
// Generate new UUID for group ID // Generate new UUID for group ID
id := uuid.New() id := uuid.New()
// Add new group id and prepend with the string "grp" // Add new group id and prepend with the string "grp"
// The reason this is done is to differentiate between a // The reason this is done is to differentiate between a
// group ID and docker container ID // group ID and docker container ID
NewGroup.ID = "grp" + id.String() NewGroup.ID = "grp" + id.String()
// Adding the new group to the // Adding the new group to the
// GroupTrackContainer File // GroupTrackContainer File
err := NewGroup.AddGroupToFile() err := NewGroup.AddGroupToFile()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &NewGroup, nil return &NewGroup, nil
} }
// RemoveGroup Removes group based on the group ID provided // RemoveGroup Removes group based on the group ID provided
func RemoveGroup(GroupID string) error { func RemoveGroup(GroupID string) error {
// Read group information from the // Read group information from the
//grouptrackcontainer json file //grouptrackcontainer json file
groups, err := ReadGroup() groups, err := ReadGroup()
if err != nil { if err != nil {
return err return err
} }
// Gets Group struct based on group ID // Gets Group struct based on group ID
// provided // provided
group, err := GetGroup(GroupID) group, err := GetGroup(GroupID)
if err != nil { if err != nil {
return err return err
} }
// Remove Group struct from the groups variable // Remove Group struct from the groups variable
groups.GroupList = append(groups.GroupList[:group.index], groups.GroupList[group.index+1:]...) groups.GroupList = append(groups.GroupList[:group.index], groups.GroupList[group.index+1:]...)
// Write new groups to the grouptrackcontainer json file // Write new groups to the grouptrackcontainer json file
err = groups.WriteGroup() err = groups.WriteGroup()
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// AddContainerToGroup Adds container information to the Group based on the Group ID // AddContainerToGroup Adds container information to the Group based on the Group ID
func AddContainerToGroup(ContainerID string, GroupID string) (*Group, error) { func AddContainerToGroup(ContainerID string, GroupID string) (*Group, error) {
// Gets container information based on container ID provided // Gets container information based on container ID provided
containerInfo, err := GetContainerInformation(ContainerID) containerInfo, err := GetContainerInformation(ContainerID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Gets group information based on the group ID provided // Gets group information based on the group ID provided
group, err := GetGroup(GroupID) group, err := GetGroup(GroupID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Adds container information the group // Adds container information the group
group.AddContainer(containerInfo) group.AddContainer(containerInfo)
// Get Groups information from reading the grouptrackcontainer.json file // Get Groups information from reading the grouptrackcontainer.json file
groups, err := ReadGroup() groups, err := ReadGroup()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Updating specific element in the group list with the added container // Updating specific element in the group list with the added container
groups.GroupList[group.index] = group groups.GroupList[group.index] = group
// Write groups information on the grouptrackcontainer.json file // Write groups information on the grouptrackcontainer.json file
err = groups.WriteGroup() err = groups.WriteGroup()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return group, nil return group, nil
} }
// RemoveContainerGroup Remove Container from the group ID specified // RemoveContainerGroup Remove Container from the group ID specified
func RemoveContainerGroup(ContainerID string, GroupID string) (*Group, error) { func RemoveContainerGroup(ContainerID string, GroupID string) (*Group, error) {
// Get container information based on container ID provided // Get container information based on container ID provided
containerInfo, err := GetContainerInformation(ContainerID) containerInfo, err := GetContainerInformation(ContainerID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Gets group information based on the group ID provided // Gets group information based on the group ID provided
group, err := GetGroup(GroupID) group, err := GetGroup(GroupID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Remove container from the appropriate group // Remove container from the appropriate group
err = group.RemoveContainerGroup(containerInfo) err = group.RemoveContainerGroup(containerInfo)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Get Groups information from reading the grouptrackcontainer.json file // Get Groups information from reading the grouptrackcontainer.json file
groups, err := ReadGroup() groups, err := ReadGroup()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Updating specific element in the group list with the remove container // Updating specific element in the group list with the remove container
groups.GroupList[group.index] = group groups.GroupList[group.index] = group
// Write groups information on the grouptrackcontainer.json file // Write groups information on the grouptrackcontainer.json file
err = groups.WriteGroup() err = groups.WriteGroup()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return group, nil return group, nil
} }
// RemoveContainerGroups Remove Container from groups (i.e which ever groups has information // RemoveContainerGroups Remove Container from groups (i.e which ever groups has information
// about that container). This is mostly called when a container is deleted or removed from // about that container). This is mostly called when a container is deleted or removed from
// the tracked container list // the tracked container list
func RemoveContainerGroups(ContainerID string) error { func RemoveContainerGroups(ContainerID string) error {
// Get container information based on container ID provided // Get container information based on container ID provided
containerInfo, err := GetContainerInformation(ContainerID) containerInfo, err := GetContainerInformation(ContainerID)
if err != nil { if err != nil {
return err return err
} }
// Get Groups information from reading the grouptrackcontainer.json file // Get Groups information from reading the grouptrackcontainer.json file
groups, err := ReadGroup() groups, err := ReadGroup()
if err != nil { if err != nil {
return err return err
} }
// Removes container information from all groups it is found in // Removes container information from all groups it is found in
err = groups.RemoveContainerGroups(containerInfo) err = groups.RemoveContainerGroups(containerInfo)
if err != nil { if err != nil {
return err return err
} }
// Write groups information on the grouptrackcontainer.json file // Write groups information on the grouptrackcontainer.json file
err = groups.WriteGroup() err = groups.WriteGroup()
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// GetGroup Gets group information based on // GetGroup Gets group information based on
// group id provided // group id provided
func GetGroup(GroupID string) (*Group, error) { func GetGroup(GroupID string) (*Group, error) {
// Read group information from the // Read group information from the
//grouptrackcontainer json file //grouptrackcontainer json file
groups, err := ReadGroup() groups, err := ReadGroup()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Iterate through the set of groups and // Iterate through the set of groups and
// if the group ID matches then return it // if the group ID matches then return it
for i, group := range groups.GroupList { for i, group := range groups.GroupList {
if group.ID == GroupID { if group.ID == GroupID {
group.index = i group.index = i
return group, nil return group, nil
} }
} }
return nil, errors.New("Group not found. ") return nil, errors.New("Group not found. ")
} }
// AddGroupToFile Adds Group struct to the GroupTrackContainer File // AddGroupToFile Adds Group struct to the GroupTrackContainer File
func (grp *Group) AddGroupToFile() error { func (grp *Group) AddGroupToFile() error {
// Gets all group information from the // Gets all group information from the
// GroupTrackContainer JSON file // GroupTrackContainer JSON file
groups, err := ReadGroup() groups, err := ReadGroup()
if err != nil { if err != nil {
return err return err
} }
// Appending the newly created group // Appending the newly created group
groups.GroupList = append(groups.GroupList, grp) groups.GroupList = append(groups.GroupList, grp)
// Writing Group information to the GroupTrackContainer // Writing Group information to the GroupTrackContainer
// JSON file // JSON file
err = groups.WriteGroup() err = groups.WriteGroup()
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// ReadGroup Function reads grouptrackcontainers.json and converts // ReadGroup Function reads grouptrackcontainers.json and converts
// result to Groups // result to Groups
func ReadGroup() (*Groups, error) { func ReadGroup() (*Groups, error) {
// Get Path from config // Get Path from config
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
jsonFile, err := os.Open(config.GroupTrackContainersPath) jsonFile, err := os.Open(config.GroupTrackContainersPath)
// if we os.Open returns an error then handle it // if we os.Open returns an error then handle it
if err != nil { if err != nil {
return nil, err return nil, err
} }
// defer the closing of our jsonFile so that we can parse it later on // defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close() defer jsonFile.Close()
// read our opened xmlFile as a byte array. // read our opened xmlFile as a byte array.
byteValue, _ := ioutil.ReadAll(jsonFile) byteValue, _ := ioutil.ReadAll(jsonFile)
// we initialize our Users array // we initialize our Users array
var groups Groups var groups Groups
// we unmarshal our byteArray which contains our // we unmarshal our byteArray which contains our
// jsonFile's content into 'users' which we defined above // jsonFile's content into 'users' which we defined above
json.Unmarshal(byteValue, &groups) json.Unmarshal(byteValue, &groups)
return &groups, nil return &groups, nil
} }
// WriteGroup Function to write type Groups to the grouptrackcontainers.json file // WriteGroup Function to write type Groups to the grouptrackcontainers.json file
func (grp *Groups) WriteGroup() error { func (grp *Groups) WriteGroup() error {
file, err := json.MarshalIndent(grp, "", " ") file, err := json.MarshalIndent(grp, "", " ")
if err != nil { if err != nil {
return err return err
} }
// Get Path from config // Get Path from config
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return err return err
} }
// Writes to the appropriate file // Writes to the appropriate file
err = ioutil.WriteFile(config.GroupTrackContainersPath, file, 0644) err = ioutil.WriteFile(config.GroupTrackContainersPath, file, 0644)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// AddContainer Adds a container to the Tracked container list of the group // AddContainer Adds a container to the Tracked container list of the group
func (grp *Group) AddContainer(Container *TrackContainer) error { func (grp *Group) AddContainer(Container *TrackContainer) error {
grp.TrackContainerList = append(grp.TrackContainerList, Container) grp.TrackContainerList = append(grp.TrackContainerList, Container)
return nil return nil
} }
// RemoveContainerGroup Removes container information from the group // RemoveContainerGroup Removes container information from the group
func (grp *Group) RemoveContainerGroup(Container *TrackContainer) error { func (grp *Group) RemoveContainerGroup(Container *TrackContainer) error {
// Iterating through all container in the Group of Tracked Container // Iterating through all container in the Group of Tracked Container
for i, container := range grp.TrackContainerList { for i, container := range grp.TrackContainerList {
// If the container ID matches then remove the container from the group // If the container ID matches then remove the container from the group
if container.Id == Container.Id { if container.Id == Container.Id {
grp.TrackContainerList = append(grp.TrackContainerList[:i], grp.TrackContainerList[i+1:]...) grp.TrackContainerList = append(grp.TrackContainerList[:i], grp.TrackContainerList[i+1:]...)
} }
} }
return nil return nil
} }
// RemoveContainerGroups removes container found in all groups // RemoveContainerGroups removes container found in all groups
func (grp *Groups) RemoveContainerGroups(Container *TrackContainer) error { func (grp *Groups) RemoveContainerGroups(Container *TrackContainer) error {
// Iterating through all groups // Iterating through all groups
for i, group := range grp.GroupList { for i, group := range grp.GroupList {
// Removes the container in the following group // Removes the container in the following group
// if it exists // if it exists
err := group.RemoveContainerGroup(Container) err := group.RemoveContainerGroup(Container)
if err != nil { if err != nil {
return err return err
} }
// Set group information to list groups // Set group information to list groups
grp.GroupList[i] = group grp.GroupList[i] = group
} }
return nil return nil
} }
// ModifyContainerGroups Modifies container information is all groups // ModifyContainerGroups Modifies container information is all groups
// available // available
func (TC *TrackContainer) ModifyContainerGroups() error { func (TC *TrackContainer) ModifyContainerGroups() error {
group, err := ReadGroup() group, err := ReadGroup()
if err != nil { if err != nil {
return err return err
} }
// Iterate though all groups and modify the container // Iterate though all groups and modify the container
// information in groups where the modified container // information in groups where the modified container
// ID matches // ID matches
for i, _ := range group.GroupList { for i, _ := range group.GroupList {
// Checking in each group if the modified container ID exists // Checking in each group if the modified container ID exists
for j, _ := range group.GroupList[i].TrackContainerList { for j, _ := range group.GroupList[i].TrackContainerList {
// If there is match then change them // If there is match then change them
if group.GroupList[i].TrackContainerList[j].Id == TC.Id { if group.GroupList[i].TrackContainerList[j].Id == TC.Id {
group.GroupList[i].TrackContainerList[j] = TC group.GroupList[i].TrackContainerList[j] = TC
} }
} }
} }
// Write modified result to the Groups track container JSON file // Write modified result to the Groups track container JSON file
err = group.WriteGroup() err = group.WriteGroup()
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }

View File

@@ -1,149 +1,149 @@
package client package client
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/Akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/Akilan1999/p2p-rendering-computation/server/docker" "github.com/Akilan1999/p2p-rendering-computation/server/docker"
"io/ioutil" "io/ioutil"
"os" "os"
) )
// TrackContainers This struct stores arrays of current containers running // TrackContainers This struct stores arrays of current containers running
type TrackContainers struct { type TrackContainers struct {
TrackContainerList []TrackContainer `json:"TrackContainer"` TrackContainerList []TrackContainer `json:"TrackContainer"`
} }
// TrackContainer Stores information of current containers // TrackContainer Stores information of current containers
type TrackContainer struct { type TrackContainer struct {
Id string `json:"ID"` Id string `json:"ID"`
Container *docker.DockerVM `json:"Container"` Container *docker.DockerVM `json:"Container"`
IpAddress string `json:"IpAddress"` IpAddress string `json:"IpAddress"`
} }
// AddTrackContainer Adds new container which has been added to the track container // AddTrackContainer Adds new container which has been added to the track container
func AddTrackContainer(d *docker.DockerVM, ipAddress string) error { func AddTrackContainer(d *docker.DockerVM, ipAddress string) error {
// Checking if pointer d is null // Checking if pointer d is null
if d == nil { if d == nil {
return errors.New("d is nil") return errors.New("d is nil")
} }
//Get config information to derive paths for track containers json file //Get config information to derive paths for track containers json file
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return err return err
} }
// Getting information about the file trackcontainers.json file // Getting information about the file trackcontainers.json file
stat, err := os.Stat(config.TrackContainersPath) stat, err := os.Stat(config.TrackContainersPath)
if err != nil { if err != nil {
return err return err
} }
// Initialize variable for TrackContainers // Initialize variable for TrackContainers
var trackContainers TrackContainers var trackContainers TrackContainers
// If the trackcontainers.json file is not empty then // If the trackcontainers.json file is not empty then
// Read from that file // Read from that file
if stat.Size() != 0 { if stat.Size() != 0 {
// Reads tracked container file // Reads tracked container file
trackContainersFile, err := ReadTrackContainers(config.TrackContainersPath) trackContainersFile, err := ReadTrackContainers(config.TrackContainersPath)
if err != nil { if err != nil {
return err return err
} }
trackContainers = *trackContainersFile trackContainers = *trackContainersFile
} }
// Initialize new variable with type struct TrackContainers and // Initialize new variable with type struct TrackContainers and
// add container struct and ip address // add container struct and ip address
var trackContainer TrackContainer var trackContainer TrackContainer
trackContainer.Id = d.ID trackContainer.Id = d.ID
trackContainer.Container = d trackContainer.Container = d
trackContainer.IpAddress = ipAddress trackContainer.IpAddress = ipAddress
// Adds new container as passed in the parameter to the struct // Adds new container as passed in the parameter to the struct
if &trackContainer == nil { if &trackContainer == nil {
return errors.New("trackContainer variable is nil") return errors.New("trackContainer variable is nil")
} }
trackContainers.TrackContainerList = append(trackContainers.TrackContainerList, trackContainer) trackContainers.TrackContainerList = append(trackContainers.TrackContainerList, trackContainer)
// write modified information to the tracked json file // write modified information to the tracked json file
data, err := json.MarshalIndent(trackContainers, "", "\t") data, err := json.MarshalIndent(trackContainers, "", "\t")
if err != nil { if err != nil {
return err return err
} }
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777) err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// RemoveTrackedContainer This function removos tracked container from the trackcontainer JSON file // RemoveTrackedContainer This function removos tracked container from the trackcontainer JSON file
func RemoveTrackedContainer(id string) error { func RemoveTrackedContainer(id string) error {
//Get config information to derive paths for track containers json file //Get config information to derive paths for track containers json file
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return err return err
} }
// Getting tracked container struct // Getting tracked container struct
trackedContainers, err := ReadTrackContainers(config.TrackContainersPath) trackedContainers, err := ReadTrackContainers(config.TrackContainersPath)
// Storing index of element to remove // Storing index of element to remove
var removeElement int var removeElement int
removeElement = -1 removeElement = -1
for i := range trackedContainers.TrackContainerList { for i := range trackedContainers.TrackContainerList {
if trackedContainers.TrackContainerList[i].Id == id { if trackedContainers.TrackContainerList[i].Id == id {
removeElement = i removeElement = i
break break
} }
} }
// Checks if the element to be removed has been detected // Checks if the element to be removed has been detected
if removeElement == -1 { if removeElement == -1 {
return errors.New("Container ID not found in the tracked list") return errors.New("Container ID not found in the tracked list")
} }
// Remove the detected element from the struct // Remove the detected element from the struct
trackedContainers.TrackContainerList = append(trackedContainers.TrackContainerList[:removeElement], trackedContainers.TrackContainerList[removeElement+1:]...) trackedContainers.TrackContainerList = append(trackedContainers.TrackContainerList[:removeElement], trackedContainers.TrackContainerList[removeElement+1:]...)
// write modified information to the tracked json file // write modified information to the tracked json file
data, err := json.MarshalIndent(trackedContainers, "", "\t") data, err := json.MarshalIndent(trackedContainers, "", "\t")
if err != nil { if err != nil {
return err return err
} }
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777) err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// ViewTrackedContainers View Containers currently tracked // ViewTrackedContainers View Containers currently tracked
func ViewTrackedContainers() (error, *TrackContainers) { func ViewTrackedContainers() (error, *TrackContainers) {
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return err, nil return err, nil
} }
trackedContianers, err := ReadTrackContainers(config.TrackContainersPath) trackedContianers, err := ReadTrackContainers(config.TrackContainersPath)
if err != nil { if err != nil {
return err, nil return err, nil
} }
return nil, trackedContianers return nil, trackedContianers
} }
// ReadTrackContainers Reads containers which are currently tracked // ReadTrackContainers Reads containers which are currently tracked
func ReadTrackContainers(filename string) (*TrackContainers, error) { func ReadTrackContainers(filename string) (*TrackContainers, error) {
buf, err := ioutil.ReadFile(filename) buf, err := ioutil.ReadFile(filename)
if err != nil { if err != nil {
return nil, err return nil, err
} }
c := &TrackContainers{} c := &TrackContainers{}
err = json.Unmarshal(buf, c) err = json.Unmarshal(buf, c)
if err != nil { if err != nil {
return nil, fmt.Errorf("in file %q: %v", filename, err) return nil, fmt.Errorf("in file %q: %v", filename, err)
} }
return c, nil return c, nil
} }
//func ModifyTrackContainers() //func ModifyTrackContainers()
@@ -151,70 +151,70 @@ func ReadTrackContainers(filename string) (*TrackContainers, error) {
// GetContainerInformation gets information about container based on // GetContainerInformation gets information about container based on
// container ID provided // container ID provided
func GetContainerInformation(ID string) (*TrackContainer, error) { func GetContainerInformation(ID string) (*TrackContainer, error) {
// Getting the current containers // Getting the current containers
err, CurrentContainers := ViewTrackedContainers() err, CurrentContainers := ViewTrackedContainers()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Iterating through all tracked containers to get the container information // Iterating through all tracked containers to get the container information
// of the ID passed through the function parameter // of the ID passed through the function parameter
for _, container := range CurrentContainers.TrackContainerList { for _, container := range CurrentContainers.TrackContainerList {
if container.Container.ID == ID { if container.Container.ID == ID {
return &container, nil return &container, nil
} }
} }
return nil, errors.New("Container not found. ") return nil, errors.New("Container not found. ")
} }
// ModifyContainerInformation Modifies information inside the container // ModifyContainerInformation Modifies information inside the container
func (TC *TrackContainer) ModifyContainerInformation() error { func (TC *TrackContainer) ModifyContainerInformation() error {
// Gets all the information of tracker containers // Gets all the information of tracker containers
err, t := ViewTrackedContainers() err, t := ViewTrackedContainers()
if err != nil { if err != nil {
return err return err
} }
// Find the element where the containers match and // Find the element where the containers match and
// change them // change them
for i, container := range t.TrackContainerList { for i, container := range t.TrackContainerList {
if TC.Id == container.Id { if TC.Id == container.Id {
t.TrackContainerList[i] = *TC t.TrackContainerList[i] = *TC
break break
} }
} }
// Write the modified information to the file // Write the modified information to the file
// write modified information to the tracked json file // write modified information to the tracked json file
err = t.WriteContainers() err = t.WriteContainers()
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// WriteContainers Write information back to the config file // WriteContainers Write information back to the config file
func (TC *TrackContainers) WriteContainers() error { func (TC *TrackContainers) WriteContainers() error {
// Initialize config file // Initialize config file
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
// write modified information to the tracked json file // write modified information to the tracked json file
data, err := json.MarshalIndent(TC, "", "\t") data, err := json.MarshalIndent(TC, "", "\t")
if err != nil { if err != nil {
return err return err
} }
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777) err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// CheckID Checks if the ID belongs to a group or a single container // CheckID Checks if the ID belongs to a group or a single container
func CheckID(ID string) (string, error) { func CheckID(ID string) (string, error) {
// For group checks if the 1st characters is "grp" // For group checks if the 1st characters is "grp"
if ID[0:3] == "grp" { if ID[0:3] == "grp" {
return "group", nil return "group", nil
} else { } else {
return "container", nil return "container", nil
} }
return "", nil return "", nil
} }

View File

@@ -1,16 +1,16 @@
package clientIPTable package clientIPTable
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/Akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/Akilan1999/p2p-rendering-computation/p2p" "github.com/Akilan1999/p2p-rendering-computation/p2p"
"io" "io"
"io/ioutil" "io/ioutil"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"os" "os"
"sync" "sync"
) )
var mu sync.Mutex var mu sync.Mutex
@@ -18,136 +18,136 @@ var mu sync.Mutex
// UpdateIpTable Does the following to update it's IP table // UpdateIpTable Does the following to update it's IP table
func UpdateIpTable(IpAddress string, serverPort string, wg *sync.WaitGroup) error { func UpdateIpTable(IpAddress string, serverPort string, wg *sync.WaitGroup) error {
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return err return err
} }
client := http.Client{} client := http.Client{}
var resp []byte var resp []byte
version := p2p.Ip4or6(IpAddress) version := p2p.Ip4or6(IpAddress)
if version == "version 6" { if version == "version 6" {
resp, err = UploadMultipartFile(client, "http://["+IpAddress+"]:"+serverPort+"/IpTable", "json", config.IPTable) resp, err = UploadMultipartFile(client, "http://["+IpAddress+"]:"+serverPort+"/IpTable", "json", config.IPTable)
if err != nil { if err != nil {
return err return err
} }
} else { } else {
resp, err = UploadMultipartFile(client, "http://"+IpAddress+":"+serverPort+"/IpTable", "json", config.IPTable) resp, err = UploadMultipartFile(client, "http://"+IpAddress+":"+serverPort+"/IpTable", "json", config.IPTable)
if err != nil { if err != nil {
return err return err
} }
} }
if resp == nil { if resp == nil {
return nil return nil
} }
//resp, err := SendPostRequest("http://"+IpAddress+":8088/IpTable", //resp, err := SendPostRequest("http://"+IpAddress+":8088/IpTable",
// config.IPTable, // config.IPTable,
// "json") // "json")
// //
//if err != nil { //if err != nil {
// return err // return err
//} //}
var ipStruct p2p.IpAddresses var ipStruct p2p.IpAddresses
json.Unmarshal(resp, &ipStruct) json.Unmarshal(resp, &ipStruct)
// Updates IP table based on information provided // Updates IP table based on information provided
// by the server // by the server
if len(ipStruct.IpAddress) > 0 { if len(ipStruct.IpAddress) > 0 {
err = ipStruct.SpeedTestUpdatedIPTable() err = ipStruct.SpeedTestUpdatedIPTable()
if err != nil { if err != nil {
return err return err
} }
} }
err = ipStruct.WriteIpTable() err = ipStruct.WriteIpTable()
if err != nil { if err != nil {
return err return err
} }
wg.Done() wg.Done()
return nil return nil
} }
// UpdateIpTableListClient 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 // on the ip tables
func UpdateIpTableListClient() error { func UpdateIpTableListClient() error {
// Get config information // Get config information
Config, err := config.ConfigInit(nil) Config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return err return err
} }
// Ensure that the IP Table has Node pingable // Ensure that the IP Table has Node pingable
err = p2p.LocalSpeedTestIpTable() err = p2p.LocalSpeedTestIpTable()
if err != nil { if err != nil {
return err return err
} }
// IP addresses to not append to struct due to // IP addresses to not append to struct due to
// duplication // duplication
Addresses, err := p2p.ReadIpTable() Addresses, err := p2p.ReadIpTable()
var DoNotRead p2p.IpAddresses var DoNotRead p2p.IpAddresses
currentIPV4, err := p2p.CurrentPublicIP() currentIPV4, err := p2p.CurrentPublicIP()
if err != nil { if err != nil {
return err return err
} }
var w sync.WaitGroup var w sync.WaitGroup
// Run loop 2 times // Run loop 2 times
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
// Gets information from IP table // Gets information from IP table
Addresses, err = p2p.ReadIpTable() Addresses, err = p2p.ReadIpTable()
if err != nil { if err != nil {
return err return err
} }
//DoNotRead.IpAddress = append(DoNotRead.IpAddress, PublicIP) //DoNotRead.IpAddress = append(DoNotRead.IpAddress, PublicIP)
// Updates IP table based on server IP table // Updates IP table based on server IP table
for j := range Addresses.IpAddress { for j := range Addresses.IpAddress {
Exists := false Exists := false
// If the address is local then add to the local list // If the address is local then add to the local list
if currentIPV4 == Addresses.IpAddress[j].Ipv4 && Addresses.IpAddress[j].ServerPort == Config.ServerPort { if currentIPV4 == Addresses.IpAddress[j].Ipv4 && Addresses.IpAddress[j].ServerPort == Config.ServerPort {
Exists = true Exists = true
} }
// Check if IP addresses is there in the struct DoNotRead // Check if IP addresses is there in the struct DoNotRead
for k := range DoNotRead.IpAddress { for k := range DoNotRead.IpAddress {
if (DoNotRead.IpAddress[k].Ipv4 == Addresses.IpAddress[j].Ipv4 && DoNotRead.IpAddress[k].ServerPort == Addresses.IpAddress[j].ServerPort) || (DoNotRead.IpAddress[k].Ipv6 != "" && Addresses.IpAddress[j].Ipv6 == DoNotRead.IpAddress[k].Ipv6) { if (DoNotRead.IpAddress[k].Ipv4 == Addresses.IpAddress[j].Ipv4 && DoNotRead.IpAddress[k].ServerPort == Addresses.IpAddress[j].ServerPort) || (DoNotRead.IpAddress[k].Ipv6 != "" && Addresses.IpAddress[j].Ipv6 == DoNotRead.IpAddress[k].Ipv6) {
Exists = true Exists = true
break break
} }
} }
// If the struct exists then continues // If the struct exists then continues
if Exists { if Exists {
continue continue
} }
w.Add(1) w.Add(1)
if Addresses.IpAddress[j].Ipv6 != "" { if Addresses.IpAddress[j].Ipv6 != "" {
go UpdateIpTable(Addresses.IpAddress[j].Ipv6, Addresses.IpAddress[j].ServerPort, &w) go UpdateIpTable(Addresses.IpAddress[j].Ipv6, Addresses.IpAddress[j].ServerPort, &w)
} else if Addresses.IpAddress[j].Ipv4 != currentIPV4 { } else if Addresses.IpAddress[j].Ipv4 != currentIPV4 {
go UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort, &w) go UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort, &w)
} }
w.Wait() w.Wait()
//Appends server1 IP address to variable DoNotRead //Appends server1 IP address to variable DoNotRead
DoNotRead.IpAddress = append(DoNotRead.IpAddress, Addresses.IpAddress[j]) DoNotRead.IpAddress = append(DoNotRead.IpAddress, Addresses.IpAddress[j])
} }
} }
return nil return nil
} }
// SendPostRequest Sends a file as a // SendPostRequest Sends a file as a
@@ -197,58 +197,58 @@ func UpdateIpTableListClient() error {
//} //}
func UploadMultipartFile(client http.Client, uri, key, path string) ([]byte, error) { func UploadMultipartFile(client http.Client, uri, key, path string) ([]byte, error) {
body, writer := io.Pipe() body, writer := io.Pipe()
req, err := http.NewRequest(http.MethodPost, uri, body) req, err := http.NewRequest(http.MethodPost, uri, body)
if err != nil { if err != nil {
return nil, err return nil, err
} }
mwriter := multipart.NewWriter(writer) mwriter := multipart.NewWriter(writer)
req.Header.Add("Content-Type", mwriter.FormDataContentType()) req.Header.Add("Content-Type", mwriter.FormDataContentType())
errchan := make(chan error) errchan := make(chan error)
go func() { go func() {
defer close(errchan) defer close(errchan)
defer writer.Close() defer writer.Close()
defer mwriter.Close() defer mwriter.Close()
w, err := mwriter.CreateFormFile(key, path) w, err := mwriter.CreateFormFile(key, path)
if err != nil { if err != nil {
errchan <- err errchan <- err
return return
} }
in, err := os.Open(path) in, err := os.Open(path)
if err != nil { if err != nil {
errchan <- err errchan <- err
return return
} }
defer in.Close() defer in.Close()
if written, err := io.Copy(w, in); err != nil { if written, err := io.Copy(w, in); err != nil {
errchan <- fmt.Errorf("error copying %s (%d bytes written): %v", path, written, err) errchan <- fmt.Errorf("error copying %s (%d bytes written): %v", path, written, err)
return return
} }
if err := mwriter.Close(); err != nil { if err := mwriter.Close(); err != nil {
errchan <- err errchan <- err
return return
} }
}() }()
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
content, err := ioutil.ReadAll(resp.Body) content, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return content, nil return content, nil
} }

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1 @@
{}

View File

@@ -17,11 +17,10 @@ var CliAction = func(ctx *cli.Context) error {
if err != nil { if err != nil {
fmt.Print(err) fmt.Print(err)
} }
//server.Rpc()
for { for {
} }
//server.Rpc()
} }
//Listing servers and also updates IP tables (Default 3 hops) //Listing servers and also updates IP tables (Default 3 hops)
@@ -96,10 +95,14 @@ var CliAction = func(ctx *cli.Context) error {
} }
// Function called to stop and remove server from Docker // Function called to stop and remove server from Docker
if RemoveVM != "" && ID != "" { if RemoveVM != "" {
err := client.RemoveContianer(RemoveVM, ID) if ID == "" {
if err != nil { fmt.Println("provide container ID via --ID or --id")
fmt.Print(err) } else {
err := client.RemoveContianer(RemoveVM, ID)
if err != nil {
fmt.Print(err)
}
} }
} }
@@ -135,7 +138,7 @@ var CliAction = func(ctx *cli.Context) error {
//Sets default paths to the config file //Sets default paths to the config file
if SetDefaultConfig { if SetDefaultConfig {
_, err := generate.SetDefaults("P2PRC", false) _, err := generate.SetDefaults("P2PRC", false, nil, false)
if err != nil { if err != nil {
fmt.Print(err) fmt.Print(err)
} }
@@ -182,7 +185,7 @@ var CliAction = func(ctx *cli.Context) error {
fmt.Println("Success") fmt.Println("Success")
} }
} else { } else {
fmt.Println("provide container ID") fmt.Println("provide container ID via --ID or --id")
} }
} }

View File

@@ -92,7 +92,7 @@ var AppConfigFlags = []cli.Flag{
&cli.StringFlag{ &cli.StringFlag{
Name: "RemoveVM", Name: "RemoveVM",
Aliases: []string{"rm"}, Aliases: []string{"rm"},
Usage: "Stop and Remove Docker container", Usage: "Stop and Remove Docker container (IP:port) accompanied by container ID via --ID or --id",
EnvVars: []string{"REMOVE_VM"}, EnvVars: []string{"REMOVE_VM"},
Destination: &RemoveVM, Destination: &RemoveVM,
}, },
@@ -148,7 +148,7 @@ var AppConfigFlags = []cli.Flag{
&cli.BoolFlag{ &cli.BoolFlag{
Name: "TrackedContainers", Name: "TrackedContainers",
Aliases: []string{"tc"}, Aliases: []string{"tc"},
Usage: "View containers which have " + Usage: "View (currently running) containers which have " +
"been created from the client side ", "been created from the client side ",
EnvVars: []string{"TRACKED_CONTAINERS"}, EnvVars: []string{"TRACKED_CONTAINERS"},
Destination: &TrackedContainers, Destination: &TrackedContainers,

View File

@@ -1,7 +1,8 @@
package config package config
import ( import (
"github.com/spf13/viper" "encoding/json"
"io/ioutil"
"os" "os"
) )
@@ -28,6 +29,7 @@ type Config struct {
GroupTrackContainersPath string GroupTrackContainersPath string
FRPServerPort string FRPServerPort string
BehindNAT string BehindNAT string
CustomConfig interface{}
//NetworkInterface string //NetworkInterface string
//NetworkInterfaceIPV6Index int //NetworkInterfaceIPV6Index int
} }
@@ -41,6 +43,9 @@ func GetPathP2PRC(Envname string) (string, error) {
} }
} }
curDir := os.Getenv(defaultEnvName) curDir := os.Getenv(defaultEnvName)
if curDir == "" {
return curDir, nil
}
return curDir + "/", nil return curDir + "/", nil
} }
@@ -59,45 +64,93 @@ func GetEnvName() string {
} }
// ConfigInit Pass environment name as an optional parameter // ConfigInit Pass environment name as an optional parameter
func ConfigInit(defaultsParameter map[string]interface{}, envNameOptional ...string) (*Config, error) { func ConfigInit(defaultsParameter map[string]interface{}, CustomConfig interface{}, envNameOptional ...string) (*Config, error) {
if len(envNameOptional) > 0 { if len(envNameOptional) > 0 {
defaultEnvName = envNameOptional[0] defaultEnvName = envNameOptional[0]
} }
//
////Setting current directory to default path
//defaultPath, err := GetPathP2PRC(defaultEnvName)
//if err != nil {
// return nil, err
//}
////Paths to search for config file
//configPaths = append(configPaths, defaultPath)
//
////Add all possible configurations paths
//for _, v := range configPaths {
// viper.AddConfigPath(v)
//}
//
////Read config file
//if err := viper.ReadInConfig(); err != nil {
// // If the error thrown is config file not found
// //Sets default configuration to viper
// for k, v := range defaults {
// viper.SetDefault(k, v)
// }
// viper.SetConfigName(configName)
// viper.SetConfigFile(configFile)
// viper.SetConfigType(configType)
//
// if err = viper.WriteConfig(); err != nil {
// return nil, err
// }
//}
//
//// Adds configuration to the struct
//var config Config
//if err := viper.Unmarshal(&config); err != nil {
// return nil, err
//}
//
//return &config, nil
//Setting current directory to default path
defaultPath, err := GetPathP2PRC(defaultEnvName) defaultPath, err := GetPathP2PRC(defaultEnvName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
//Paths to search for config file
configPaths = append(configPaths, defaultPath)
//Add all possible configurations paths // Open our jsonFile
for _, v := range configPaths { jsonFile, err := os.Open(defaultPath + configFile)
viper.AddConfigPath(v) // if we os.Open returns an error then handle it
if err != nil {
return nil, err
} }
//Read config file // defer the closing of our jsonFile so that we can parse it later on
if err := viper.ReadInConfig(); err != nil { defer jsonFile.Close()
// If the error thrown is config file not found
//Sets default configuration to viper
for k, v := range defaults {
viper.SetDefault(k, v)
}
viper.SetConfigName(configName)
viper.SetConfigFile(configFile)
viper.SetConfigType(configType)
if err = viper.WriteConfig(); err != nil { byteValue, _ := ioutil.ReadAll(jsonFile)
var config Config
json.Unmarshal(byteValue, &config)
if CustomConfig != nil {
// Convert Custom Config to byte
customConfigByte, err := json.Marshal(config.CustomConfig)
if err != nil {
return nil, err return nil, err
} }
}
// Adds configuration to the struct // Again map the byte to the CustomConfig interface
var config Config json.Unmarshal(customConfigByte, &CustomConfig)
if err := viper.Unmarshal(&config); err != nil {
return nil, err
} }
return &config, nil return &config, nil
} }
func (c *Config) WriteConfig() error {
//Getting Current Directory from environment variable
//curDir := os.Getenv("REMOTEGAMING")
defaultPath, err := GetPathP2PRC(defaultEnvName)
if err != nil {
return err
}
file, _ := json.MarshalIndent(c, "", " ")
_ = ioutil.WriteFile(defaultPath+"config.json", file, 0644)
return nil
}

View File

@@ -1,28 +1,28 @@
package config package generate
import ( import (
"fmt" "fmt"
"github.com/Akilan1999/p2p-rendering-computation/config/generate" "github.com/Akilan1999/p2p-rendering-computation/config"
"os" "os"
"testing" "testing"
) )
func TestConfigInit(t *testing.T) { // func TestConfigInit(t *testing.T) {
_, err := ConfigInit(nil) // _, err := config.ConfigInit(nil)
if err != nil { // if err != nil {
t.Error(err) // t.Error(err)
} // }
} // }
func TestSetDefaults(t *testing.T) { // func TestSetDefaults(t *testing.T) {
_, err := generate.SetDefaults("", false) // _, err := SetDefaults("", false)
if err != nil { // if err != nil {
t.Error(err) // t.Error(err)
} // }
} // }
func TestGetCurrentPath(t *testing.T) { func TestGetCurrentPath(t *testing.T) {
path, err := generate.GetCurrentPath() path, err := GetCurrentPath()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Error(err) t.Error(err)
@@ -31,7 +31,7 @@ func TestGetCurrentPath(t *testing.T) {
} }
func TestGetPathP2PRC(t *testing.T) { func TestGetPathP2PRC(t *testing.T) {
path, err := GetPathP2PRC("") path, err := config.GetPathP2PRC("")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Error(err) t.Error(err)
@@ -48,14 +48,14 @@ func TestSetEnvName(t *testing.T) {
} }
// Sets the environment variable as the default to read // Sets the environment variable as the default to read
// for P2PRC // for P2PRC
err = SetEnvName("TEST") err = config.SetEnvName("TEST")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Error(err) t.Error(err)
} }
// Checks if the output for the default read is "lol" // Checks if the output for the default read is "lol"
path, err := GetPathP2PRC("") path, err := config.GetPathP2PRC("")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Error(err) t.Error(err)

View File

@@ -37,7 +37,7 @@ func GetCurrentPath() (string, error) {
// SetDefaults This function to be called only during a // SetDefaults This function to be called only during a
// make install // make install
func SetDefaults(envName string, forceDefault bool, ConfigUpdate ...*config.Config) (*config.Config, error) { func SetDefaults(envName string, forceDefault bool, CustomConfig interface{}, NoBoilerPlate bool, ConfigUpdate ...*config.Config) (*config.Config, error) {
//Setting current directory to default path //Setting current directory to default path
defaultPath, err := GetCurrentPath() defaultPath, err := GetCurrentPath()
if err != nil { if err != nil {
@@ -68,38 +68,31 @@ func SetDefaults(envName string, forceDefault bool, ConfigUpdate ...*config.Conf
// return err // return err
//} //}
var Defaults config.Config
if len(ConfigUpdate) == 0 { if len(ConfigUpdate) == 0 {
//Setting default paths for the config file //Setting default paths for the config file
defaults["IPTable"] = defaultPath + "p2p/iptable/ip_table.json" Defaults.IPTable = defaultPath + "p2p/iptable/ip_table.json"
defaults["DefaultDockerFile"] = defaultPath + "server/docker/containers/docker-ubuntu-sshd/" Defaults.DefaultDockerFile = defaultPath + "server/docker/containers/docker-ubuntu-sshd/"
defaults["DockerContainers"] = defaultPath + "server/docker/containers/" Defaults.DockerContainers = defaultPath + "server/docker/containers/"
defaults["SpeedTestFile"] = defaultPath + "p2p/50.bin" Defaults.SpeedTestFile = defaultPath + "p2p/50.bin"
defaults["IPV6Address"] = "" Defaults.IPV6Address = ""
defaults["PluginPath"] = defaultPath + "plugin/deploy" Defaults.PluginPath = defaultPath + "plugin/deploy"
defaults["TrackContainersPath"] = defaultPath + "client/trackcontainers/trackcontainers.json" Defaults.TrackContainersPath = defaultPath + "client/trackcontainers/trackcontainers.json"
defaults["GroupTrackContainersPath"] = defaultPath + "client/trackcontainers/grouptrackcontainers.json" Defaults.GroupTrackContainersPath = defaultPath + "client/trackcontainers/grouptrackcontainers.json"
defaults["ServerPort"] = "8088" Defaults.ServerPort = "8088"
defaults["FRPServerPort"] = "0" Defaults.FRPServerPort = "True"
defaults["BehindNAT"] = "True" Defaults.CustomConfig = CustomConfig
Defaults.BehindNAT = "True"
// Random name generator // Random name generator
hostname, err := os.Hostname() hostname, err := os.Hostname()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defaults["MachineName"] = hostname Defaults.MachineName = hostname
} else { } else {
defaults["IPTable"] = ConfigUpdate[0].IPTable Defaults = *ConfigUpdate[0]
defaults["DefaultDockerFile"] = ConfigUpdate[0].DefaultDockerFile
defaults["DockerContainers"] = ConfigUpdate[0].DockerContainers
defaults["SpeedTestFile"] = ConfigUpdate[0].SpeedTestFile
defaults["IPV6Address"] = ConfigUpdate[0].IPV6Address
defaults["PluginPath"] = ConfigUpdate[0].PluginPath
defaults["TrackContainersPath"] = ConfigUpdate[0].TrackContainersPath
defaults["GroupTrackContainersPath"] = ConfigUpdate[0].GroupTrackContainersPath
defaults["ServerPort"] = ConfigUpdate[0].ServerPort
defaults["FRPServerPort"] = ConfigUpdate[0].FRPServerPort
defaults["BehindNAT"] = ConfigUpdate[0].BehindNAT
} }
//defaults["NetworkInterface"] = "wlp0s20f3" //defaults["NetworkInterface"] = "wlp0s20f3"
@@ -108,22 +101,31 @@ func SetDefaults(envName string, forceDefault bool, ConfigUpdate ...*config.Conf
//Paths to search for config file //Paths to search for config file
configPaths = append(configPaths, defaultPath) configPaths = append(configPaths, defaultPath)
if fileExists(defaultPath + "config.json") && forceDefault { if fileExists(defaultPath+"config.json") && forceDefault {
err := os.Remove(defaultPath + "config.json") err := os.Remove(defaultPath + "config.json")
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
//Calling configuration file // write defaults to the config file
Config, err := config.ConfigInit(defaults, envName) err = Defaults.WriteConfig()
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = GenerateFiles() //Calling configuration file
Config, err := config.ConfigInit(defaults, nil, envName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !NoBoilerPlate {
err = GenerateFiles()
if err != nil {
return nil, err
}
}
return Config, nil return Config, nil
} }

View File

@@ -1,164 +1,163 @@
package generate package generate
import ( import (
"github.com/Akilan1999/p2p-rendering-computation/p2p" "github.com/Akilan1999/p2p-rendering-computation/p2p"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"os" "os"
) )
// GenerateFiles Generates all the files needed to setup P2PRC // GenerateFiles Generates all the files needed to setup P2PRC
func GenerateFiles(rootNodes ...p2p.IpAddress) (err error) { func GenerateFiles(rootNodes ...p2p.IpAddress) (err error) {
err = GenerateIPTableFile(rootNodes) err = GenerateIPTableFile(rootNodes)
err = GenerateDockerFiles() err = GenerateDockerFiles()
err = GeneratePluginDirectory() err = GeneratePluginDirectory()
err = GenerateClientTrackContainers() err = GenerateClientTrackContainers()
return return
} }
// GenerateIPTableFile Generates the IPTable file with the appropirate root node // GenerateIPTableFile Generates the IPTable file with the appropirate root node
func GenerateIPTableFile(rootNodes []p2p.IpAddress) (err error) { func GenerateIPTableFile(rootNodes []p2p.IpAddress) (err error) {
var rootnodes p2p.IpAddresses var rootnodes p2p.IpAddresses
var rootnode p2p.IpAddress var rootnode p2p.IpAddress
err = CreateIPTableFolderStructure() err = CreateIPTableFolderStructure()
if err != nil { if err != nil {
return err return err
} }
// If root node addresses are not provided as optional parameters // If root node addresses are not provided as optional parameters
if len(rootNodes) <= 0 { if len(rootNodes) <= 0 {
rootnode.Name = "Node1" rootnode.Name = "Node1"
rootnode.ServerPort = "8088" rootnode.ServerPort = "8088"
rootnode.NAT = "False" rootnode.NAT = "False"
rootnode.Ipv4 = "64.227.168.102" rootnode.Ipv4 = "64.227.168.102"
rootnodes.IpAddress = append(rootnodes.IpAddress, rootnode) rootnodes.IpAddress = append(rootnodes.IpAddress, rootnode)
} else { } else {
// if root nodes are provided then override them as the optional parameter // if root nodes are provided then override them as the optional parameter
for i := range rootNodes { for i := range rootNodes {
rootnodes.IpAddress = append(rootnodes.IpAddress, rootNodes[i]) rootnodes.IpAddress = append(rootnodes.IpAddress, rootNodes[i])
} }
} }
err = rootnodes.WriteIpTable() err = rootnodes.WriteIpTable()
return return
} }
// CreateIPTableFolderStructure Create folder structure for IPTable // CreateIPTableFolderStructure Create folder structure for IPTable
func CreateIPTableFolderStructure() (err error) { func CreateIPTableFolderStructure() (err error) {
path, err := GetCurrentPath() path, err := GetCurrentPath()
if err != nil { if err != nil {
return err return err
} }
if _, err = os.Stat(path + "p2p"); os.IsNotExist(err) { if _, err = os.Stat(path + "p2p"); os.IsNotExist(err) {
if err = os.Mkdir(path+"p2p", os.ModePerm); err != nil { if err = os.Mkdir(path+"p2p", os.ModePerm); err != nil {
return err return err
} }
if _, err = os.Stat(path + "p2p/iptable"); os.IsNotExist(err) { }
if err = os.Mkdir(path+"p2p/iptable", os.ModePerm); err != nil { if _, err = os.Stat(path + "p2p/iptable"); os.IsNotExist(err) {
return err if err = os.Mkdir(path+"p2p/iptable", os.ModePerm); err != nil {
} return err
} }
if _, err = os.Stat(path + "p2p/iptable/ip_table.json"); os.IsNotExist(err) { }
_, err = os.Create(path + "p2p/iptable/ip_table.json") if _, err = os.Stat(path + "p2p/iptable/ip_table.json"); os.IsNotExist(err) {
if err != nil { _, err = os.Create(path + "p2p/iptable/ip_table.json")
return err if err != nil {
} return err
} }
}
} return
return
} }
// GenerateDockerFiles Generate default docker files // GenerateDockerFiles Generate default docker files
func GenerateDockerFiles() (err error) { func GenerateDockerFiles() (err error) {
path, err := GetCurrentPath() path, err := GetCurrentPath()
if err != nil { if err != nil {
return err return err
} }
if _, err = os.Stat(path + "server"); os.IsNotExist(err) { if _, err = os.Stat(path + "server"); os.IsNotExist(err) {
if err = os.Mkdir(path+"server", os.ModePerm); err != nil { if err = os.Mkdir(path+"server", os.ModePerm); err != nil {
return err return err
} }
if _, err = os.Stat(path + "server/docker"); os.IsNotExist(err) { if _, err = os.Stat(path + "server/docker"); os.IsNotExist(err) {
if err = os.Mkdir(path+"server/docker", os.ModePerm); err != nil { if err = os.Mkdir(path+"server/docker", os.ModePerm); err != nil {
return err return err
} }
} }
if _, err = os.Stat(path + "server/docker/containers"); os.IsNotExist(err) { if _, err = os.Stat(path + "server/docker/containers"); os.IsNotExist(err) {
if err = os.Mkdir(path+"server/docker/containers", os.ModePerm); err != nil { if err = os.Mkdir(path+"server/docker/containers", os.ModePerm); err != nil {
return err return err
} }
} }
if _, err = os.Stat(path + "server/docker/containers"); os.IsNotExist(err) { if _, err = os.Stat(path + "server/docker/containers"); os.IsNotExist(err) {
if err = os.Mkdir(path+"server/docker/containers", os.ModePerm); err != nil { if err = os.Mkdir(path+"server/docker/containers", os.ModePerm); err != nil {
return err return err
} }
} }
if _, err = os.Stat(path + "server/docker/containers/docker-ubuntu-sshd"); os.IsNotExist(err) { if _, err = os.Stat(path + "server/docker/containers/docker-ubuntu-sshd"); os.IsNotExist(err) {
if err = os.Mkdir(path+"server/docker/containers/docker-ubuntu-sshd", os.ModePerm); err != nil { if err = os.Mkdir(path+"server/docker/containers/docker-ubuntu-sshd", os.ModePerm); err != nil {
return err return err
} }
} }
} }
// Clone base docker image // Clone base docker image
_, err = git.PlainClone(path+"server/docker/containers/docker-ubuntu-sshd", false, &git.CloneOptions{ _, err = git.PlainClone(path+"server/docker/containers/docker-ubuntu-sshd", false, &git.CloneOptions{
URL: "https://github.com/Akilan1999/docker-ubuntu-sshd", URL: "https://github.com/Akilan1999/docker-ubuntu-sshd",
Progress: os.Stdout, Progress: os.Stdout,
}) })
if err != nil { if err != nil {
return err return err
} }
return return
} }
// GeneratePluginDirectory Generates plugin directory structure // GeneratePluginDirectory Generates plugin directory structure
func GeneratePluginDirectory() (err error) { func GeneratePluginDirectory() (err error) {
path, err := GetCurrentPath() path, err := GetCurrentPath()
if err != nil { if err != nil {
return err return err
} }
if _, err = os.Stat(path + "plugin"); os.IsNotExist(err) { if _, err = os.Stat(path + "plugin"); os.IsNotExist(err) {
if err = os.Mkdir(path+"plugin", os.ModePerm); err != nil { if err = os.Mkdir(path+"plugin", os.ModePerm); err != nil {
return err return err
} }
if _, err = os.Stat(path + "plugin/deploy"); os.IsNotExist(err) { if _, err = os.Stat(path + "plugin/deploy"); os.IsNotExist(err) {
if err = os.Mkdir(path+"plugin/deploy", os.ModePerm); err != nil { if err = os.Mkdir(path+"plugin/deploy", os.ModePerm); err != nil {
return err return err
} }
} }
} }
return return
} }
func GenerateClientTrackContainers() (err error) { func GenerateClientTrackContainers() (err error) {
path, err := GetCurrentPath() path, err := GetCurrentPath()
if err != nil { if err != nil {
return err return err
} }
if _, err = os.Stat(path + "client"); os.IsNotExist(err) { if _, err = os.Stat(path + "client"); os.IsNotExist(err) {
if err = os.Mkdir(path+"client", os.ModePerm); err != nil { if err = os.Mkdir(path+"client", os.ModePerm); err != nil {
return err return err
} }
if _, err = os.Stat(path + "client/trackcontainers.json"); os.IsNotExist(err) { if _, err = os.Stat(path + "client/trackcontainers.json"); os.IsNotExist(err) {
_, err = os.Create(path + "client/trackcontainers.json") _, err = os.Create(path + "client/trackcontainers.json")
if err != nil { if err != nil {
return err return err
} }
} }
if _, err = os.Stat(path + "client/grouptrackcontainers.json"); os.IsNotExist(err) { if _, err = os.Stat(path + "client/grouptrackcontainers.json"); os.IsNotExist(err) {
_, err = os.Create(path + "client/grouptrackcontainers.json") _, err = os.Create(path + "client/grouptrackcontainers.json")
if err != nil { if err != nil {
return err return err
} }
} }
} }
return return
} }

View File

@@ -0,0 +1,35 @@
package generate
import (
"fmt"
"github.com/Akilan1999/p2p-rendering-computation/config"
"testing"
)
type CustomConfig struct {
Test string
}
// Test case to generate defaults with custom data-structure
func TestSetDefaults(t *testing.T) {
setDefaults, err := SetDefaults("", true, &CustomConfig{Test: "lol"}, true)
if err != nil {
fmt.Println(err)
t.Fail()
return
}
fmt.Println(setDefaults)
var c CustomConfig
_, err = config.ConfigInit(nil, &c)
if err != nil {
fmt.Println(err)
t.Fail()
return
}
fmt.Println(c)
}

3
go.mod
View File

@@ -12,7 +12,6 @@ require (
github.com/gin-gonic/gin v1.6.3 github.com/gin-gonic/gin v1.6.3
github.com/go-git/go-git/v5 v5.4.2 github.com/go-git/go-git/v5 v5.4.2
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e
github.com/lithammer/shortuuid v3.0.0+incompatible github.com/lithammer/shortuuid v3.0.0+incompatible
github.com/moby/sys/mount v0.2.0 // indirect github.com/moby/sys/mount v0.2.0 // indirect
github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf // indirect github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf // indirect
@@ -20,11 +19,9 @@ require (
github.com/otiai10/copy v1.6.0 github.com/otiai10/copy v1.6.0
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
github.com/shirou/gopsutil/v3 v3.22.10 github.com/shirou/gopsutil/v3 v3.22.10
github.com/spf13/viper v1.7.0
github.com/urfave/cli/v2 v2.3.0 github.com/urfave/cli/v2 v2.3.0
gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40 // indirect gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40 // indirect
gitlab.com/NebulousLabs/go-upnp v0.0.0-20181011194642-3a71999ed0d3 gitlab.com/NebulousLabs/go-upnp v0.0.0-20181011194642-3a71999ed0d3
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
gotest.tools/v3 v3.0.3 // indirect gotest.tools/v3 v3.0.3 // indirect
) )

15
go.sum
View File

@@ -65,7 +65,6 @@ github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28= github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
@@ -285,7 +284,6 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjr
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
@@ -451,8 +449,6 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e h1:XmA6L9IPRdUr28a+SK/oMchGgQy159wvzXA5tJ7l+40=
github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e/go.mod h1:AFIo+02s+12CEg8Gzz9kzhCbmbq6JcKNrhHffCGA9z4=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
@@ -486,7 +482,6 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
@@ -558,7 +553,6 @@ github.com/lithammer/shortuuid v3.0.0+incompatible/go.mod h1:FR74pbAuElzOUuenUHT
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -589,7 +583,6 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
@@ -674,7 +667,6 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9
github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E= github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E=
github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
@@ -770,24 +762,19 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -807,7 +794,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
@@ -941,7 +927,6 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

View File

@@ -1,10 +1,11 @@
package main package main
import ( import (
"github.com/Akilan1999/p2p-rendering-computation/cmd"
"github.com/urfave/cli/v2"
"log" "log"
"os" "os"
"github.com/Akilan1999/p2p-rendering-computation/cmd"
"github.com/urfave/cli/v2"
) )
// VERSION specifies the version of the platform // VERSION specifies the version of the platform

View File

@@ -1,165 +1,178 @@
package frp package frp
import ( import (
"fmt" "github.com/Akilan1999/p2p-rendering-computation/server/docker"
"github.com/Akilan1999/p2p-rendering-computation/server/docker" "github.com/fatedier/frp/client"
"github.com/fatedier/frp/client" "github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config" "math/rand"
"github.com/phayes/freeport" "strconv"
"math/rand" "time"
"strconv" "github.com/phayes/freeport"
"time"
) )
// Client This struct stores // Client This struct stores
// client information with server // client information with server
// proxy connected // proxy connected
type Client struct { type Client struct {
Name string Name string
Server *Server Server *Server
ClientMappings []ClientMapping ClientMappings []ClientMapping
} }
// ClientMapping Stores client mapping ports // ClientMapping Stores client mapping ports
// to proxy server // to proxy server
type ClientMapping struct { type ClientMapping struct {
LocalIP string LocalIP string
LocalPort int LocalPort int
RemotePort int RemotePort int
} }
// StartFRPClientForServer Starts Server using FRP server // StartFRPClientForServer Starts Server using FRP server
// returns back a port // returns back a port
func StartFRPClientForServer(ipaddress string, port string, localport string) (string, error) { // remote port is a custom external port a user would want
// Setup server information // to open. This under the assumption the user knows the
var s Server // exact port available in server doing the TURN connection.
s.address = ipaddress func StartFRPClientForServer(ipaddress string, port string, localport string, remoteport string) (string, error) {
// convert port to int // Setup server information
portInt, err := strconv.Atoi(port) var s Server
if err != nil { s.address = ipaddress
return "", err // convert port to int
} portInt, err := strconv.Atoi(port)
s.port = portInt if err != nil {
return "", err
}
s.port = portInt
// Setup client information // Setup client information
var c Client var c Client
c.Name = "ServerPort" c.Name = "ServerPort"
c.Server = &s c.Server = &s
// converts localport to int // converts localport to int
portInt, err = strconv.Atoi(localport) portInt, err = strconv.Atoi(localport)
if err != nil { if err != nil {
return "", err return "", err
} }
//random port var OpenPorts []int
//randPort := rangeIn(10000, 99999) // if the remote port is
OpenPorts, err := freeport.GetFreePorts(1) // not empty then set the remote port to that.
if err != nil { if remoteport != "" {
return "", err // converts localport to int
} portIntRemote, err := strconv.Atoi(remoteport)
c.ClientMappings = []ClientMapping{ if err != nil {
{ return "", err
LocalIP: "localhost", }
LocalPort: portInt, OpenPorts = append(OpenPorts, portIntRemote)
RemotePort: OpenPorts[0], } else {
}, //random port
} //randPort := rangeIn(10000, 99999)
OpenPorts, err = freeport.GetFreePorts(1)
if err != nil {
return "", err
}
}
c.ClientMappings = []ClientMapping{
{
LocalIP: "localhost",
LocalPort: portInt,
RemotePort: OpenPorts[0],
},
}
// Start client server // Start client server
go c.StartFRPClient() go c.StartFRPClient()
return strconv.Itoa(OpenPorts[0]), nil return strconv.Itoa(OpenPorts[0]), nil
} }
func StartFRPCDockerContainer(ipaddress string, port string, Docker *docker.DockerVM) (*docker.DockerVM, error) { func StartFRPCDockerContainer(ipaddress string, port string, Docker *docker.DockerVM) (*docker.DockerVM, error) {
// setting new docker variable // setting new docker variable
//var DockerFRP docker.DockerVM //var DockerFRP docker.DockerVM
//DockerFRP = *Docker //DockerFRP = *Docker
//DockerFRP.Ports.PortSet = []docker.Port{} //DockerFRP.Ports.PortSet = []docker.Port{}
// Setup server information // Setup server information
var s Server var s Server
s.address = ipaddress s.address = ipaddress
// convert port to int // convert port to int
portInt, err := strconv.Atoi(port) portInt, err := strconv.Atoi(port)
if err != nil { if err != nil {
return nil, err return nil, err
} }
s.port = portInt s.port = portInt
// Setup client information // Setup client information
var c Client var c Client
c.Name = "ServerPort" c.Name = "ServerPort"
c.Server = &s c.Server = &s
// set client mapping // set client mapping
//var clientMappings []ClientMapping //var clientMappings []ClientMapping
fmt.Println(len(Docker.Ports.PortSet)) for i, _ := range Docker.Ports.PortSet {
for i, _ := range Docker.Ports.PortSet { portMap := Docker.Ports.PortSet[i].ExternalPort
portMap := Docker.Ports.PortSet[i].ExternalPort
serverPort, err := GetFRPServerPort("http://" + ipaddress + ":" + port) serverPort, err := GetFRPServerPort("http://" + ipaddress + ":" + port)
if err != nil { if err != nil {
return nil, err return nil, err
} }
//delay to allow the FRP server to start //delay to allow the FRP server to start
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
proxyPort, err := StartFRPClientForServer(ipaddress, serverPort, strconv.Itoa(portMap)) proxyPort, err := StartFRPClientForServer(ipaddress, serverPort, strconv.Itoa(portMap), "")
if err != nil { if err != nil {
return nil, err return nil, err
} }
portInt, err = strconv.Atoi(proxyPort) portInt, err = strconv.Atoi(proxyPort)
if err != nil { if err != nil {
return nil, err return nil, err
} }
Docker.Ports.PortSet[i].ExternalPort = portInt Docker.Ports.PortSet[i].ExternalPort = portInt
} }
return Docker, nil return Docker, nil
} }
// StartFRPClient Starts FRP client // StartFRPClient Starts FRP client
func (c *Client) StartFRPClient() error { func (c *Client) StartFRPClient() error {
cfg := config.GetDefaultClientConf() cfg := config.GetDefaultClientConf()
var proxyConfs map[string]config.ProxyConf var proxyConfs map[string]config.ProxyConf
var visitorCfgs map[string]config.VisitorConf var visitorCfgs map[string]config.VisitorConf
proxyConfs = make(map[string]config.ProxyConf) proxyConfs = make(map[string]config.ProxyConf)
cfg.ServerAddr = c.Server.address cfg.ServerAddr = c.Server.address
cfg.ServerPort = c.Server.port cfg.ServerPort = c.Server.port
for i, _ := range c.ClientMappings { for i, _ := range c.ClientMappings {
var tcpcnf config.TCPProxyConf var tcpcnf config.TCPProxyConf
tcpcnf.LocalIP = c.ClientMappings[i].LocalIP tcpcnf.LocalIP = c.ClientMappings[i].LocalIP
tcpcnf.LocalPort = c.ClientMappings[i].LocalPort tcpcnf.LocalPort = c.ClientMappings[i].LocalPort
tcpcnf.RemotePort = c.ClientMappings[i].RemotePort tcpcnf.RemotePort = c.ClientMappings[i].RemotePort
proxyConfs[tcpcnf.ProxyName] = &tcpcnf proxyConfs[tcpcnf.ProxyName] = &tcpcnf
} }
cli, err := client.NewService(cfg, proxyConfs, visitorCfgs, "") cli, err := client.NewService(cfg, proxyConfs, visitorCfgs, "")
if err != nil { if err != nil {
return err return err
} }
cli.Run() cli.Run()
return nil return nil
} }
// helper function to generate random // helper function to generate random
// number in a certain range // number in a certain range
func rangeIn(low, hi int) int { func rangeIn(low, hi int) int {
return low + rand.Intn(hi-low) return low + rand.Intn(hi-low)
} }

View File

@@ -6,8 +6,8 @@
"IPV6": "", "IPV6": "",
"Latency": 0, "Latency": 0,
"ServerPort": "8088", "ServerPort": "8088",
"NAT": "False", "NAT": "False",
"EscapeImplementation": "None" "EscapeImplementation": "None"
} }
] ]
} }

View File

@@ -1,256 +1,257 @@
package p2p package p2p
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/Akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"io/ioutil" "io/ioutil"
"net" "net"
"net/http" "net/http"
"os" "os"
"time" "time"
) )
// Get IP table Data // Get IP table Data
type IpAddresses struct { type IpAddresses struct {
IpAddress []IpAddress `json:"ip_address"` IpAddress []IpAddress `json:"ip_address"`
} }
type IpAddress struct { type IpAddress struct {
Name string `json:"Name"` Name string `json:"Name"`
Ipv4 string `json:"IPV4"` Ipv4 string `json:"IPV4"`
Ipv6 string `json:"IPV6"` Ipv6 string `json:"IPV6"`
Latency time.Duration `json:"Latency"` Latency time.Duration `json:"Latency"`
Download float64 `json:"Download"` Download float64 `json:"Download"`
Upload float64 `json:"Upload"` Upload float64 `json:"Upload"`
ServerPort string `json:"ServerPort"` ServerPort string `json:"ServerPort"`
NAT string `json:"NAT"` NAT string `json:"NAT"`
EscapeImplementation string `json:"EscapeImplementation"` EscapeImplementation string `json:"EscapeImplementation"`
CustomInformation []byte
} }
type IP struct { type IP struct {
Query string Query string
} }
// ReadIpTable Read data from Ip tables from json file // ReadIpTable Read data from Ip tables from json file
func ReadIpTable() (*IpAddresses, error) { func ReadIpTable() (*IpAddresses, error) {
// Get Path from config // Get Path from config
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
jsonFile, err := os.Open(config.IPTable) jsonFile, err := os.Open(config.IPTable)
// if we os.Open returns an error then handle it // if we os.Open returns an error then handle it
if err != nil { if err != nil {
return nil, err return nil, err
} }
// defer the closing of our jsonFile so that we can parse it later on // defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close() defer jsonFile.Close()
// read our opened xmlFile as a byte array. // read our opened xmlFile as a byte array.
byteValue, _ := ioutil.ReadAll(jsonFile) byteValue, _ := ioutil.ReadAll(jsonFile)
// we initialize our Users array // we initialize our Users array
var ipAddresses IpAddresses var ipAddresses IpAddresses
// we unmarshal our byteArray which contains our // we unmarshal our byteArray which contains our
// jsonFile's content into 'users' which we defined above // jsonFile's content into 'users' which we defined above
json.Unmarshal(byteValue, &ipAddresses) json.Unmarshal(byteValue, &ipAddresses)
var PublicIP IpAddress var PublicIP IpAddress
ipv6, err := GetCurrentIPV6() ipv6, err := GetCurrentIPV6()
if err != nil { if err != nil {
return nil, err return nil, err
} }
ip, err := CurrentPublicIP() ip, err := CurrentPublicIP()
if err != nil { if err != nil {
return nil, err return nil, err
} }
PublicIP.Ipv4 = ip PublicIP.Ipv4 = ip
PublicIP.Ipv6 = ipv6 PublicIP.Ipv6 = ipv6
PublicIP.ServerPort = config.ServerPort PublicIP.ServerPort = config.ServerPort
PublicIP.Name = config.MachineName PublicIP.Name = config.MachineName
PublicIP.NAT = config.BehindNAT PublicIP.NAT = config.BehindNAT
PublicIP.EscapeImplementation = "None" PublicIP.EscapeImplementation = "None"
// Updates current machine IP address to the IP table // Updates current machine IP address to the IP table
ipAddresses.IpAddress = append(ipAddresses.IpAddress, PublicIP) ipAddresses.IpAddress = append(ipAddresses.IpAddress, PublicIP)
//before writing to iptable ensures the duplicates are removed //before writing to iptable ensures the duplicates are removed
if err = ipAddresses.RemoveDuplicates(); err != nil { if err = ipAddresses.RemoveDuplicates(); err != nil {
return nil, err return nil, err
} }
return &ipAddresses, nil return &ipAddresses, nil
} }
// WriteIpTable Write to IP table json file // WriteIpTable Write to IP table json file
func (i *IpAddresses) WriteIpTable() error { func (i *IpAddresses) WriteIpTable() error {
//before writing to iptable ensures the duplicates are removed //before writing to iptable ensures the duplicates are removed
if err := i.RemoveDuplicates(); err != nil { if err := i.RemoveDuplicates(); err != nil {
return err return err
} }
file, err := json.MarshalIndent(i, "", " ") file, err := json.MarshalIndent(i, "", " ")
if err != nil { if err != nil {
return err return err
} }
// Get Path from config // Get Path from config
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return err return err
} }
err = ioutil.WriteFile(config.IPTable, file, 0644) err = ioutil.WriteFile(config.IPTable, file, 0644)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// PrintIpTable Print Ip table data for Cli // PrintIpTable Print Ip table data for Cli
func PrintIpTable() error { func PrintIpTable() error {
table, err := ReadIpTable() table, err := ReadIpTable()
if err != nil { if err != nil {
return err return err
} }
for i := 0; i < len(table.IpAddress); i++ { for i := 0; i < len(table.IpAddress); i++ {
fmt.Printf("\nMachine Name: %s\nIP Address: %s\nIPV6: %s\nLatency: %s\nServerPort: %s\nbehindNAT: %s\nEscapeImplementation: %s\n-----------"+ fmt.Printf("\nMachine Name: %s\nIP Address: %s\nIPV6: %s\nLatency: %s\nServerPort: %s\nbehindNAT: %s\nEscapeImplementation: %s\n-----------"+
"-----------------\n", table.IpAddress[i].Name, table.IpAddress[i].Ipv4, table.IpAddress[i].Ipv6, "-----------------\n", table.IpAddress[i].Name, table.IpAddress[i].Ipv4, table.IpAddress[i].Ipv6,
table.IpAddress[i].Latency, table.IpAddress[i].ServerPort, table.IpAddress[i].NAT, table.IpAddress[i].EscapeImplementation) table.IpAddress[i].Latency, table.IpAddress[i].ServerPort, table.IpAddress[i].NAT, table.IpAddress[i].EscapeImplementation)
} }
//PrettyPrint(table) //PrettyPrint(table)
return nil return nil
} }
// RemoveDuplicates This is a temporary fix current functions failing to remove // RemoveDuplicates This is a temporary fix current functions failing to remove
// Duplicate IP addresses from local IP table // Duplicate IP addresses from local IP table
func (table *IpAddresses) RemoveDuplicates() error { func (table *IpAddresses) RemoveDuplicates() error {
var NoDuplicates IpAddresses var NoDuplicates IpAddresses
for i, _ := range table.IpAddress { for i, _ := range table.IpAddress {
Exists := false Exists := false
for k := range NoDuplicates.IpAddress { for k := range NoDuplicates.IpAddress {
// Statements checked for // Statements checked for
// - duplicate IPV4 addresses [<IPV4>:<Port No>] // - duplicate IPV4 addresses [<IPV4>:<Port No>]
// - duplicate IPV6 addresses [<IPV6>] // - duplicate IPV6 addresses [<IPV6>]
// - Node is behind NAT and no escape implementation provided // - Node is behind NAT and no escape implementation provided
if (NoDuplicates.IpAddress[k].Ipv4 != "" && NoDuplicates.IpAddress[k].Ipv4 == table.IpAddress[i].Ipv4 && if (NoDuplicates.IpAddress[k].Ipv4 != "" && NoDuplicates.IpAddress[k].Ipv4 == table.IpAddress[i].Ipv4 &&
NoDuplicates.IpAddress[k].ServerPort == table.IpAddress[i].ServerPort) || NoDuplicates.IpAddress[k].ServerPort == table.IpAddress[i].ServerPort) ||
(NoDuplicates.IpAddress[k].Ipv6 != "" && NoDuplicates.IpAddress[k].Ipv6 == table.IpAddress[i].Ipv6) { (NoDuplicates.IpAddress[k].Ipv6 != "" && NoDuplicates.IpAddress[k].Ipv6 == table.IpAddress[i].Ipv6) {
Exists = true Exists = true
break break
} }
} }
if table.IpAddress[i].NAT == "True" && table.IpAddress[i].EscapeImplementation == "None" { if table.IpAddress[i].NAT == "True" && table.IpAddress[i].EscapeImplementation == "None" {
Exists = true Exists = true
} }
if Exists { if Exists {
continue continue
} }
NoDuplicates.IpAddress = append(NoDuplicates.IpAddress, table.IpAddress[i]) NoDuplicates.IpAddress = append(NoDuplicates.IpAddress, table.IpAddress[i])
} }
table.IpAddress = NoDuplicates.IpAddress table.IpAddress = NoDuplicates.IpAddress
return nil return nil
} }
// CurrentPublicIP Get Current Public IP address // CurrentPublicIP Get Current Public IP address
func CurrentPublicIP() (string, error) { func CurrentPublicIP() (string, error) {
req, err := http.Get("http://ip-api.com/json/") req, err := http.Get("http://ip-api.com/json/")
if err != nil { if err != nil {
return "", err return "", err
} }
defer req.Body.Close() defer req.Body.Close()
body, err := ioutil.ReadAll(req.Body) body, err := ioutil.ReadAll(req.Body)
if err != nil { if err != nil {
return "", err return "", err
} }
var ip IP var ip IP
json.Unmarshal(body, &ip) json.Unmarshal(body, &ip)
return ip.Query, nil return ip.Query, nil
} }
// GetCurrentIPV6 gets the current IPV6 address based on the interface // GetCurrentIPV6 gets the current IPV6 address based on the interface
// specified in the config file // specified in the config file
func GetCurrentIPV6() (string, error) { func GetCurrentIPV6() (string, error) {
Config, err := config.ConfigInit(nil) Config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return "", err return "", err
} }
// Fix in future release // Fix in future release
//byNameInterface, err := net.InterfaceByName(Config.NetworkInterface) //byNameInterface, err := net.InterfaceByName(Config.NetworkInterface)
//if err != nil { //if err != nil {
// return "",err // return "",err
//} //}
//addresses, err := byNameInterface.Addrs() //addresses, err := byNameInterface.Addrs()
//if err != nil { //if err != nil {
// return "",err // return "",err
//} //}
//if addresses[1].String() == "" { //if addresses[1].String() == "" {
// return "",errors.New("IPV6 address not detected") // return "",errors.New("IPV6 address not detected")
//} //}
//IP,_,err := net.ParseCIDR(addresses[Config.NetworkInterfaceIPV6Index].String()) //IP,_,err := net.ParseCIDR(addresses[Config.NetworkInterfaceIPV6Index].String())
//if err != nil { //if err != nil {
// return "",err // return "",err
//} //}
return Config.IPV6Address, nil return Config.IPV6Address, nil
} }
// ViewNetworkInterface This function is created to view the network interfaces available // ViewNetworkInterface This function is created to view the network interfaces available
func ViewNetworkInterface() error { func ViewNetworkInterface() error {
ifaces, err := net.Interfaces() ifaces, err := net.Interfaces()
if err != nil { if err != nil {
return err return err
} }
for _, i := range ifaces { for _, i := range ifaces {
addrs, err := i.Addrs() addrs, err := i.Addrs()
if err != nil { if err != nil {
return err return err
} }
for index, a := range addrs { for index, a := range addrs {
switch v := a.(type) { switch v := a.(type) {
case *net.IPAddr: case *net.IPAddr:
fmt.Printf("(%v) %v : %s (%s)\n", index, i.Name, v, v.IP.DefaultMask()) fmt.Printf("(%v) %v : %s (%s)\n", index, i.Name, v, v.IP.DefaultMask())
case *net.IPNet: case *net.IPNet:
fmt.Printf("(%v) %v : %s \n", index, i.Name, v) fmt.Printf("(%v) %v : %s \n", index, i.Name, v)
} }
} }
} }
return nil return nil
} }
// Ip4or6 Helper function to check if the IP address is IPV4 or // Ip4or6 Helper function to check if the IP address is IPV4 or
// IPV6 (https://socketloop.com/tutorials/golang-check-if-ip-address-is-version-4-or-6) // IPV6 (https://socketloop.com/tutorials/golang-check-if-ip-address-is-version-4-or-6)
func Ip4or6(s string) string { func Ip4or6(s string) string {
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
switch s[i] { switch s[i] {
case '.': case '.':
return "version 4" return "version 4"
case ':': case ':':
return "version 6" return "version 6"
} }
} }
return "version 6" return "version 6"
} }

View File

@@ -1,16 +1,16 @@
package p2p package p2p
import ( import (
"bytes" "bytes"
"errors" "errors"
"github.com/Akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"io" "io"
"io/ioutil" "io/ioutil"
"log" "log"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"os" "os"
"time" "time"
) )
// var dlSizes = [...]int{350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000} // var dlSizes = [...]int{350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000}
@@ -80,100 +80,100 @@ var httpclient = http.Client{}
// Download Speed // Download Speed
func (s *IpAddress) DownloadSpeed() error { func (s *IpAddress) DownloadSpeed() error {
start := time.Now() start := time.Now()
resp, err := httpclient.Get("http://" + s.Ipv4 + ":8088/50") resp, err := httpclient.Get("http://" + s.Ipv4 + ":8088/50")
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close() defer resp.Body.Close()
ioutil.ReadAll(resp.Body) ioutil.ReadAll(resp.Body)
t := time.Since(start) t := time.Since(start)
//fmt.Println(s.Seconds()) //fmt.Println(s.Seconds())
// size * time (seconds) // size * time (seconds)
s.Download = (50 / t.Seconds()) * 8 s.Download = (50 / t.Seconds()) * 8
return nil return nil
} }
func (s *IpAddress) UploadSpeed() error { func (s *IpAddress) UploadSpeed() error {
start := time.Now() start := time.Now()
// Get upload file path from config file // Get upload file path from config file
// Get Path from config // Get Path from config
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return err return err
} }
b, w := createMultipartFormData("file", config.SpeedTestFile) b, w := createMultipartFormData("file", config.SpeedTestFile)
req, err := http.NewRequest("GET", "http://"+s.Ipv4+":"+s.ServerPort+"/upload", &b) req, err := http.NewRequest("GET", "http://"+s.Ipv4+":"+s.ServerPort+"/upload", &b)
if err != nil { if err != nil {
return err return err
} }
// Don't forget to set the content type, this will contain the boundary. // Don't forget to set the content type, this will contain the boundary.
req.Header.Set("Content-Type", w.FormDataContentType()) req.Header.Set("Content-Type", w.FormDataContentType())
defer req.Body.Close() defer req.Body.Close()
ioutil.ReadAll(req.Body) ioutil.ReadAll(req.Body)
t := time.Since(start) t := time.Since(start)
//fmt.Println(s.Seconds()) //fmt.Println(s.Seconds())
// size * time (seconds) // size * time (seconds)
s.Upload = (50 / t.Seconds()) * 8 s.Upload = (50 / t.Seconds()) * 8
return nil return nil
} }
// Upload helper function for uploading // Upload helper function for uploading
// (https://stackoverflow.com/questions/20205796/post-data-using-the-content-type-multipart-form-data // (https://stackoverflow.com/questions/20205796/post-data-using-the-content-type-multipart-form-data
func createMultipartFormData(fieldName, fileName string) (bytes.Buffer, *multipart.Writer) { func createMultipartFormData(fieldName, fileName string) (bytes.Buffer, *multipart.Writer) {
var b bytes.Buffer var b bytes.Buffer
var err error var err error
w := multipart.NewWriter(&b) w := multipart.NewWriter(&b)
var fw io.Writer var fw io.Writer
file := mustOpen(fileName) file := mustOpen(fileName)
if fw, err = w.CreateFormFile(fieldName, file.Name()); err != nil { if fw, err = w.CreateFormFile(fieldName, file.Name()); err != nil {
log.Fatalf("Error creating writer: %v", err) log.Fatalf("Error creating writer: %v", err)
} }
if _, err = io.Copy(fw, file); err != nil { if _, err = io.Copy(fw, file); err != nil {
log.Fatalf("Error with io.Copy: %v", err) log.Fatalf("Error with io.Copy: %v", err)
//t.Errorf("Error with io.Copy: %v", err) //t.Errorf("Error with io.Copy: %v", err)
} }
w.Close() w.Close()
return b, w return b, w
} }
func mustOpen(f string) *os.File { func mustOpen(f string) *os.File {
r, err := os.Open(f) r, err := os.Open(f)
if err != nil { if err != nil {
log.Fatalf("Error with mustOpen: %v", err) log.Fatalf("Error with mustOpen: %v", err)
} }
return r return r
} }
// PingTest executes test to measure latency // PingTest executes test to measure latency
func (s *IpAddress) PingTest() error { func (s *IpAddress) PingTest() error {
//pingURL := strings.Split(s.URL, "/upload")[0] + "/latency.txt" //pingURL := strings.Split(s.URL, "/upload")[0] + "/latency.txt"
var pingURL string var pingURL string
if s.Ipv6 != "" { if s.Ipv6 != "" {
pingURL = "http://[" + s.Ipv6 + "]:" + s.ServerPort + "/server_info" pingURL = "http://[" + s.Ipv6 + "]:" + s.ServerPort + "/server_info"
s.Ipv4 = "" s.Ipv4 = ""
} else { } else {
pingURL = "http://" + s.Ipv4 + ":" + s.ServerPort + "/server_info" pingURL = "http://" + s.Ipv4 + ":" + s.ServerPort + "/server_info"
} }
l := time.Duration(100000000000) // 10sec l := time.Duration(100000000000) // 10sec
for i := 0; i < 3; i++ { for i := 0; i < 3; i++ {
sTime := time.Now() sTime := time.Now()
resp, err := http.Get(pingURL) resp, err := http.Get(pingURL)
fTime := time.Now() fTime := time.Now()
if err != nil || resp.StatusCode != 200 { if err != nil || resp.StatusCode != 200 {
return errors.New("Node not found") return errors.New("Node not found")
} }
if fTime.Sub(sTime) < l { if fTime.Sub(sTime) < l {
l = fTime.Sub(sTime) l = fTime.Sub(sTime)
} }
resp.Body.Close() resp.Body.Close()
} }
s.Latency = time.Duration(int64(l.Nanoseconds() / 2)) s.Latency = time.Duration(int64(l.Nanoseconds() / 2))
return nil return nil
} }

View File

@@ -1,64 +1,64 @@
package plugin package plugin
import ( import (
"github.com/Akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"net/url" "net/url"
"os" "os"
"strings" "strings"
) )
// DownloadPlugin This functions downloads package from // DownloadPlugin This functions downloads package from
// a git repo. // a git repo.
func DownloadPlugin(pluginurl string) error { func DownloadPlugin(pluginurl string) error {
// paring plugin url // paring plugin url
u, err := url.Parse(pluginurl) u, err := url.Parse(pluginurl)
if err != nil { if err != nil {
return err return err
} }
path := u.Path path := u.Path
// Trim first character of the string // Trim first character of the string
path = path[1:] path = path[1:]
// trim last element of the string // trim last element of the string
path = path[:len(path)-1] path = path[:len(path)-1]
// Replaces / with _ // Replaces / with _
folder := strings.Replace(path, "/", "_", -1) folder := strings.Replace(path, "/", "_", -1)
// Reads plugin path from the config path // Reads plugin path from the config path
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return err return err
} }
// clones a repo and stores it at the plugin directory // clones a repo and stores it at the plugin directory
_, err = git.PlainClone(config.PluginPath+"/"+folder, false, &git.CloneOptions{ _, err = git.PlainClone(config.PluginPath+"/"+folder, false, &git.CloneOptions{
URL: pluginurl, URL: pluginurl,
Progress: os.Stdout, Progress: os.Stdout,
}) })
// returns error if raised // returns error if raised
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// DeletePlugin The following function deletes a plugin based on // DeletePlugin The following function deletes a plugin based on
// the plugin name provided. // the plugin name provided.
func DeletePlugin(pluginname string) error { func DeletePlugin(pluginname string) error {
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return err return err
} }
plugin, err := SearchPlugin(pluginname) plugin, err := SearchPlugin(pluginname)
if err != nil { if err != nil {
return err return err
} }
// Delete the directory holding the plugin // Delete the directory holding the plugin
err = os.RemoveAll(config.PluginPath + "/" + plugin.FolderName) err = os.RemoveAll(config.PluginPath + "/" + plugin.FolderName)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }

View File

@@ -1,362 +1,362 @@
package plugin package plugin
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/Akilan1999/p2p-rendering-computation/client" "github.com/Akilan1999/p2p-rendering-computation/client"
"github.com/Akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/google/uuid" "github.com/google/uuid"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
"io/ioutil" "io/ioutil"
"net" "net"
"os" "os"
"strconv" "strconv"
"text/template" "text/template"
"github.com/apenella/go-ansible/pkg/execute" "github.com/apenella/go-ansible/pkg/execute"
"github.com/apenella/go-ansible/pkg/options" "github.com/apenella/go-ansible/pkg/options"
"github.com/apenella/go-ansible/pkg/playbook" "github.com/apenella/go-ansible/pkg/playbook"
"github.com/apenella/go-ansible/pkg/stdoutcallback/results" "github.com/apenella/go-ansible/pkg/stdoutcallback/results"
"github.com/otiai10/copy" "github.com/otiai10/copy"
) )
// Plugins Array of all plugins detected // Plugins Array of all plugins detected
type Plugins struct { type Plugins struct {
PluginsDetected []*Plugin PluginsDetected []*Plugin
} }
// Plugin Information about the plugins available // Plugin Information about the plugins available
type Plugin struct { type Plugin struct {
FolderName string FolderName string
PluginDescription string PluginDescription string
path string path string
Execute []*ExecuteIP Execute []*ExecuteIP
NumOfPorts int NumOfPorts int
} }
// ExecuteIP IP Address to execute Ansible instruction // ExecuteIP IP Address to execute Ansible instruction
type ExecuteIP struct { type ExecuteIP struct {
ContainerID string ContainerID string
IPAddress string IPAddress string
SSHPortNo string SSHPortNo string
Success bool Success bool
} }
// Host Struct for ansible host // Host Struct for ansible host
// Generated from https://zhwt.github.io/yaml-to-go/ // Generated from https://zhwt.github.io/yaml-to-go/
type Host struct { type Host struct {
All struct { All struct {
Vars struct { Vars struct {
AnsiblePythonInterpreter string `yaml:"ansible_python_interpreter"` AnsiblePythonInterpreter string `yaml:"ansible_python_interpreter"`
} `yaml:"vars"` } `yaml:"vars"`
} `yaml:"all"` } `yaml:"all"`
Main struct { Main struct {
Hosts struct { Hosts struct {
Host1 struct { Host1 struct {
AnsibleHost string `yaml:"ansible_host"` AnsibleHost string `yaml:"ansible_host"`
AnsiblePort int `yaml:"ansible_port"` AnsiblePort int `yaml:"ansible_port"`
AnsibleUser string `yaml:"ansible_user"` AnsibleUser string `yaml:"ansible_user"`
AnsibleSSHPass string `yaml:"ansible_ssh_pass"` AnsibleSSHPass string `yaml:"ansible_ssh_pass"`
AnsibleSudoPass string `yaml:"ansible_sudo_pass"` AnsibleSudoPass string `yaml:"ansible_sudo_pass"`
} `yaml:"host1"` } `yaml:"host1"`
} `yaml:"hosts"` } `yaml:"hosts"`
} `yaml:"main"` } `yaml:"main"`
} }
// DetectPlugins Detects all the plugins available // DetectPlugins Detects all the plugins available
func DetectPlugins() (*Plugins, error) { func DetectPlugins() (*Plugins, error) {
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
folders, err := ioutil.ReadDir(config.PluginPath) folders, err := ioutil.ReadDir(config.PluginPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var plugins *Plugins = new(Plugins) var plugins *Plugins = new(Plugins)
for _, f := range folders { for _, f := range folders {
if f.IsDir() { if f.IsDir() {
//Declare variable plugin of type Plugin //Declare variable plugin of type Plugin
var plugin Plugin var plugin Plugin
// Setting name of folder to plugin // Setting name of folder to plugin
plugin.FolderName = f.Name() plugin.FolderName = f.Name()
// Getting Description from file description.txt // Getting Description from file description.txt
Description, err := ioutil.ReadFile(config.PluginPath + "/" + plugin.FolderName + "/description.txt") Description, err := ioutil.ReadFile(config.PluginPath + "/" + plugin.FolderName + "/description.txt")
// if we os.Open returns an error then handle it // if we os.Open returns an error then handle it
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Get Description from description.txt // Get Description from description.txt
plugin.PluginDescription = string(Description) plugin.PluginDescription = string(Description)
// Set plugin path // Set plugin path
plugin.path = config.PluginPath + "/" + plugin.FolderName plugin.path = config.PluginPath + "/" + plugin.FolderName
plugins.PluginsDetected = append(plugins.PluginsDetected, &plugin) plugins.PluginsDetected = append(plugins.PluginsDetected, &plugin)
// Get the number of ports the plugin needs // Get the number of ports the plugin needs
err = plugin.NumPorts() err = plugin.NumPorts()
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
} }
return plugins, nil return plugins, nil
} }
// SearchPlugin Detects plugin information based on the // SearchPlugin Detects plugin information based on the
// name provided on the parameter // name provided on the parameter
func SearchPlugin(pluginname string) (*Plugin, error) { func SearchPlugin(pluginname string) (*Plugin, error) {
plugins, err := DetectPlugins() plugins, err := DetectPlugins()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// loop ot find the plugin name that matches // loop ot find the plugin name that matches
for _, plugin := range plugins.PluginsDetected { for _, plugin := range plugins.PluginsDetected {
if pluginname == plugin.FolderName { if pluginname == plugin.FolderName {
return plugin, nil return plugin, nil
} }
} }
return nil, errors.New("plugin not detected") return nil, errors.New("plugin not detected")
} }
// RunPlugin Executes plugins based on the plugin name provided // RunPlugin Executes plugins based on the plugin name provided
func RunPlugin(pluginName string, IPAddresses []*ExecuteIP) (*Plugin, error) { func RunPlugin(pluginName string, IPAddresses []*ExecuteIP) (*Plugin, error) {
plugins, err := DetectPlugins() plugins, err := DetectPlugins()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Variable to store struct information about the plugin // Variable to store struct information about the plugin
var plugindetected *Plugin var plugindetected *Plugin
for _, plugin := range plugins.PluginsDetected { for _, plugin := range plugins.PluginsDetected {
if plugin.FolderName == pluginName { if plugin.FolderName == pluginName {
plugindetected = plugin plugindetected = plugin
plugindetected.Execute = IPAddresses plugindetected.Execute = IPAddresses
// Get Execute plugin path from config file // Get Execute plugin path from config file
config, err := config.ConfigInit(nil) config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
plugindetected.path = config.PluginPath plugindetected.path = config.PluginPath
break break
} }
} }
if plugindetected == nil { if plugindetected == nil {
return nil, errors.New("Plugin not detected") return nil, errors.New("Plugin not detected")
} }
// Create copy of the plugin the tmp directory // Create copy of the plugin the tmp directory
// To ensure we execute the plugin from there // To ensure we execute the plugin from there
err = plugindetected.CopyToTmpPlugin() err = plugindetected.CopyToTmpPlugin()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Executing the plugin // Executing the plugin
err = plugindetected.ExecutePlugin() err = plugindetected.ExecutePlugin()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return plugindetected, nil return plugindetected, nil
} }
// ExecutePlugin Function to execute plugins that are called // ExecutePlugin Function to execute plugins that are called
func (p *Plugin) ExecutePlugin() error { func (p *Plugin) ExecutePlugin() error {
// Run ip address to execute ansible inside // Run ip address to execute ansible inside
for _, execute := range p.Execute { for _, execute := range p.Execute {
// Modify ansible hosts before executing // Modify ansible hosts before executing
err := execute.ModifyHost(p) err := execute.ModifyHost(p)
if err != nil { if err != nil {
return err return err
} }
// sets the ports to the plugin folder // sets the ports to the plugin folder
err = p.AutoSetPorts(execute.ContainerID) err = p.AutoSetPorts(execute.ContainerID)
if err != nil { if err != nil {
return err return err
} }
err = execute.RunAnsible(p) err = execute.RunAnsible(p)
if err != nil { if err != nil {
return err return err
} }
// If ran successfully then change success flag to true // If ran successfully then change success flag to true
execute.Success = true execute.Success = true
} }
return nil return nil
} }
// RunAnsible Executes based on credentials on the struct // RunAnsible Executes based on credentials on the struct
func (e *ExecuteIP) RunAnsible(p *Plugin) error { func (e *ExecuteIP) RunAnsible(p *Plugin) error {
ansiblePlaybookConnectionOptions := &options.AnsibleConnectionOptions{ ansiblePlaybookConnectionOptions := &options.AnsibleConnectionOptions{
User: "master", User: "master",
} }
ansiblePlaybookOptions := &playbook.AnsiblePlaybookOptions{ ansiblePlaybookOptions := &playbook.AnsiblePlaybookOptions{
Inventory: p.path + "/" + p.FolderName + "/hosts", Inventory: p.path + "/" + p.FolderName + "/hosts",
ExtraVars: map[string]interface{}{"ansible_ssh_common_args": "-o StrictHostKeyChecking=no"}, ExtraVars: map[string]interface{}{"ansible_ssh_common_args": "-o StrictHostKeyChecking=no"},
} }
ansiblePlaybookPrivilegeEscalationOptions := &options.AnsiblePrivilegeEscalationOptions{ ansiblePlaybookPrivilegeEscalationOptions := &options.AnsiblePrivilegeEscalationOptions{
Become: true, Become: true,
} }
playbook := &playbook.AnsiblePlaybookCmd{ playbook := &playbook.AnsiblePlaybookCmd{
Playbooks: []string{p.path + "/" + p.FolderName + "/site.yml"}, Playbooks: []string{p.path + "/" + p.FolderName + "/site.yml"},
ConnectionOptions: ansiblePlaybookConnectionOptions, ConnectionOptions: ansiblePlaybookConnectionOptions,
PrivilegeEscalationOptions: ansiblePlaybookPrivilegeEscalationOptions, PrivilegeEscalationOptions: ansiblePlaybookPrivilegeEscalationOptions,
Options: ansiblePlaybookOptions, Options: ansiblePlaybookOptions,
Exec: execute.NewDefaultExecute( Exec: execute.NewDefaultExecute(
execute.WithTransformers( execute.WithTransformers(
results.Prepend("success"), results.Prepend("success"),
), ),
), ),
} }
err := playbook.Run(context.TODO()) err := playbook.Run(context.TODO())
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// ModifyHost adds IP address , port no to the config file // ModifyHost adds IP address , port no to the config file
func (e *ExecuteIP) ModifyHost(p *Plugin) error { func (e *ExecuteIP) ModifyHost(p *Plugin) error {
host, err := ReadHost(p.path + "/" + p.FolderName + "/hosts") host, err := ReadHost(p.path + "/" + p.FolderName + "/hosts")
if err != nil { if err != nil {
return err return err
} }
// Setting ansible host // Setting ansible host
host.Main.Hosts.Host1.AnsibleHost = e.IPAddress host.Main.Hosts.Host1.AnsibleHost = e.IPAddress
// Setting SSH port no // Setting SSH port no
host.Main.Hosts.Host1.AnsiblePort, err = strconv.Atoi(e.SSHPortNo) host.Main.Hosts.Host1.AnsiblePort, err = strconv.Atoi(e.SSHPortNo)
if err != nil { if err != nil {
return err return err
} }
// Setting SSH user name // Setting SSH user name
host.Main.Hosts.Host1.AnsibleUser = "master" host.Main.Hosts.Host1.AnsibleUser = "master"
// Setting SSH password // Setting SSH password
host.Main.Hosts.Host1.AnsibleSSHPass = "password" host.Main.Hosts.Host1.AnsibleSSHPass = "password"
// Setting SSH sudo password // Setting SSH sudo password
host.Main.Hosts.Host1.AnsibleSudoPass = "password" host.Main.Hosts.Host1.AnsibleSudoPass = "password"
// write modified information to the hosts yaml file // write modified information to the hosts yaml file
data, err := yaml.Marshal(host) data, err := yaml.Marshal(host)
if err != nil { if err != nil {
return err return err
} }
err = ioutil.WriteFile(p.path+"/"+p.FolderName+"/hosts", data, 0777) err = ioutil.WriteFile(p.path+"/"+p.FolderName+"/hosts", data, 0777)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// ReadHost Reads host file and adds // ReadHost Reads host file and adds
func ReadHost(filename string) (*Host, error) { func ReadHost(filename string) (*Host, error) {
buf, err := ioutil.ReadFile(filename) buf, err := ioutil.ReadFile(filename)
if err != nil { if err != nil {
return nil, err return nil, err
} }
c := &Host{} c := &Host{}
err = yaml.Unmarshal(buf, c) err = yaml.Unmarshal(buf, c)
if err != nil { if err != nil {
return nil, fmt.Errorf("in file %q: %v", filename, err) return nil, fmt.Errorf("in file %q: %v", filename, err)
} }
return c, nil return c, nil
} }
// RunPluginContainer Runs ansible plugin based on plugin name and container name which // RunPluginContainer Runs ansible plugin based on plugin name and container name which
// is derived from the tracked containers file // is derived from the tracked containers file
// We pass in the group ID as a parameter because when we modify the ports taken // We pass in the group ID as a parameter because when we modify the ports taken
func RunPluginContainer(PluginName string, ContainerID string) error { func RunPluginContainer(PluginName string, ContainerID string) error {
// Gets container information based on container ID // Gets container information based on container ID
ContainerInformation, err := client.GetContainerInformation(ContainerID) ContainerInformation, err := client.GetContainerInformation(ContainerID)
if err != nil { if err != nil {
return err return err
} }
// Setting Up IP's for which the plugins will be executed // Setting Up IP's for which the plugins will be executed
var ExecuteIPs []*ExecuteIP var ExecuteIPs []*ExecuteIP
var ExecuteIP ExecuteIP var ExecuteIP ExecuteIP
// Getting port no of SSH port // Getting port no of SSH port
for _, port := range ContainerInformation.Container.Ports.PortSet { for _, port := range ContainerInformation.Container.Ports.PortSet {
if port.PortName == "SSH" { if port.PortName == "SSH" {
ExecuteIP.SSHPortNo = fmt.Sprint(port.ExternalPort) ExecuteIP.SSHPortNo = fmt.Sprint(port.ExternalPort)
break break
} }
} }
// Handle error if SSH port is not provided // Handle error if SSH port is not provided
if ExecuteIP.SSHPortNo == "" { if ExecuteIP.SSHPortNo == "" {
return errors.New("SSH port not found") return errors.New("SSH port not found")
} }
// Split the port no from ip address since current the IP address // Split the port no from ip address since current the IP address
// field is populated as // field is populated as
// <ip address>:<port no> // <ip address>:<port no>
host, _, err := net.SplitHostPort(ContainerInformation.IpAddress) host, _, err := net.SplitHostPort(ContainerInformation.IpAddress)
if err != nil { if err != nil {
return err return err
} }
// IP address of the container // IP address of the container
ExecuteIP.IPAddress = host ExecuteIP.IPAddress = host
// Set container ID to ExecutorIP // Set container ID to ExecutorIP
ExecuteIP.ContainerID = ContainerInformation.Id ExecuteIP.ContainerID = ContainerInformation.Id
// Append IP to list of executor IP // Append IP to list of executor IP
ExecuteIPs = append(ExecuteIPs, &ExecuteIP) ExecuteIPs = append(ExecuteIPs, &ExecuteIP)
// Run plugin to execute plugin // Run plugin to execute plugin
_, err = RunPlugin(PluginName, ExecuteIPs) _, err = RunPlugin(PluginName, ExecuteIPs)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// CheckRunPlugin Checks if the ID belongs to the group or container // CheckRunPlugin Checks if the ID belongs to the group or container
// calls the plugin function the appropriate amount of times // calls the plugin function the appropriate amount of times
func CheckRunPlugin(PluginName string, ID string) error { func CheckRunPlugin(PluginName string, ID string) error {
// Check if the ID belongs to the group or container ID // Check if the ID belongs to the group or container ID
id, err := client.CheckID(ID) id, err := client.CheckID(ID)
if err != nil { if err != nil {
return err return err
} }
// When the ID belongs to a group // When the ID belongs to a group
if id == "group" { if id == "group" {
// gets the group information // gets the group information
group, err := client.GetGroup(ID) group, err := client.GetGroup(ID)
if err != nil { if err != nil {
return err return err
} }
// Iterate through each container information in the group // Iterate through each container information in the group
// and run the plugin in each of them // and run the plugin in each of them
for _, container := range group.TrackContainerList { for _, container := range group.TrackContainerList {
// runs plugin for each container // runs plugin for each container
err := RunPluginContainer(PluginName, container.Id) err := RunPluginContainer(PluginName, container.Id)
if err != nil { if err != nil {
return err return err
} }
} }
} else { // This means the following ID is a container ID } else { // This means the following ID is a container ID
err := RunPluginContainer(PluginName, ID) err := RunPluginContainer(PluginName, ID)
if err != nil { if err != nil {
return err return err
} }
} }
return nil return nil
} }
// CopyToTmpPlugin This function would ensure that we create a copy of the // CopyToTmpPlugin This function would ensure that we create a copy of the
@@ -364,101 +364,101 @@ func CheckRunPlugin(PluginName string, ID string) error {
// from there. This due to the reason of automating port allocation // from there. This due to the reason of automating port allocation
// when running plugins // when running plugins
func (p *Plugin) CopyToTmpPlugin() error { func (p *Plugin) CopyToTmpPlugin() error {
// generate rand to UUID this is debug the ansible file if needed // generate rand to UUID this is debug the ansible file if needed
id := uuid.New() id := uuid.New()
// copies the plugin to the tmp directory // copies the plugin to the tmp directory
err := copy.Copy(p.path+"/"+p.FolderName, "/tmp/"+id.String()+"_"+p.FolderName) err := copy.Copy(p.path+"/"+p.FolderName, "/tmp/"+id.String()+"_"+p.FolderName)
if err != nil { if err != nil {
return err return err
} }
// Set the plugin execution to the tmp location // Set the plugin execution to the tmp location
p.path = "/tmp" p.path = "/tmp"
p.FolderName = id.String() + "_" + p.FolderName p.FolderName = id.String() + "_" + p.FolderName
return nil return nil
} }
// AutoSetPorts Automatically maps free ports to site.yml file // AutoSetPorts Automatically maps free ports to site.yml file
func (p *Plugin) AutoSetPorts(containerID string) error { func (p *Plugin) AutoSetPorts(containerID string) error {
container, err := client.GetContainerInformation(containerID) container, err := client.GetContainerInformation(containerID)
if err != nil { if err != nil {
return err return err
} }
// variable that would have a list of ports // variable that would have a list of ports
// to be allocated to the plugin system // to be allocated to the plugin system
var ports []int var ports []int
// Counted that increments when a port is taken // Counted that increments when a port is taken
PortTaken := 0 PortTaken := 0
// setting all external ports available in an array // setting all external ports available in an array
for i, port := range container.Container.Ports.PortSet { for i, port := range container.Container.Ports.PortSet {
if port.IsUsed == false { if port.IsUsed == false {
// Ensuring we break outside the loop once the ports // Ensuring we break outside the loop once the ports
// are set. // are set.
if PortTaken >= p.NumOfPorts { if PortTaken >= p.NumOfPorts {
break break
} }
// Setting the following port flag to true // Setting the following port flag to true
container.Container.Ports.PortSet[i].IsUsed = true container.Container.Ports.PortSet[i].IsUsed = true
// Incrementing the variable PortTaken // Incrementing the variable PortTaken
PortTaken++ PortTaken++
// Maps to internal since // Maps to internal since
// Inside the machine // Inside the machine
// internal port -> (maps) same internal port // internal port -> (maps) same internal port
// TURN (i.e FRP) based approach (internal port -> maps to different external port) // TURN (i.e FRP) based approach (internal port -> maps to different external port)
ports = append(ports, port.InternalPort) ports = append(ports, port.InternalPort)
} }
} }
// parses the site.yml file in the tmp directory // parses the site.yml file in the tmp directory
t, err := template.ParseFiles(p.path + "/" + p.FolderName + "/site.yml") t, err := template.ParseFiles(p.path + "/" + p.FolderName + "/site.yml")
if err != nil { if err != nil {
return err return err
} }
// opens the output file // opens the output file
f, err := os.Create(p.path + "/" + p.FolderName + "/site.yml") f, err := os.Create(p.path + "/" + p.FolderName + "/site.yml")
if err != nil { if err != nil {
return err return err
} }
// sends the ports to the site.yml file to populate them // sends the ports to the site.yml file to populate them
err = t.Execute(f, ports) err = t.Execute(f, ports)
if err != nil { if err != nil {
return err return err
} }
// Once the following is done set port to taken // Once the following is done set port to taken
// n tracked container list // n tracked container list
err = container.ModifyContainerInformation() err = container.ModifyContainerInformation()
if err != nil { if err != nil {
return err return err
} }
// Once the following is done set port to taken // Once the following is done set port to taken
// I(Groups) // I(Groups)
err = container.ModifyContainerGroups() err = container.ModifyContainerGroups()
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// NumPorts Gets the Number the ports the // NumPorts Gets the Number the ports the
// plugin requires // plugin requires
func (p *Plugin) NumPorts() error { func (p *Plugin) NumPorts() error {
jsonFile, err := os.Open(p.path + "/ports.json") jsonFile, err := os.Open(p.path + "/ports.json")
// if we os.Open returns an error then handle it // if we os.Open returns an error then handle it
if err != nil { if err != nil {
return err return err
} }
// defer the closing of our jsonFile so that we can parse it later on // defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close() defer jsonFile.Close()
// read our opened xmlFile as a byte array. // read our opened xmlFile as a byte array.
byteValue, _ := ioutil.ReadAll(jsonFile) byteValue, _ := ioutil.ReadAll(jsonFile)
// we unmarshal our byteArray which contains our // we unmarshal our byteArray which contains our
// jsonFile's content into 'users' which we defined above // jsonFile's content into 'users' which we defined above
json.Unmarshal(byteValue, &p) json.Unmarshal(byteValue, &p)
return nil return nil
} }

View File

@@ -1,257 +1,257 @@
package plugin package plugin
import ( import (
"fmt" "fmt"
"github.com/Akilan1999/p2p-rendering-computation/client" "github.com/Akilan1999/p2p-rendering-computation/client"
"github.com/Akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/Akilan1999/p2p-rendering-computation/server/docker" "github.com/Akilan1999/p2p-rendering-computation/server/docker"
"net" "net"
"strconv" "strconv"
"testing" "testing"
) )
// Test if the dummy plugin added is detected // Test if the dummy plugin added is detected
func TestDetectPlugins(t *testing.T) { func TestDetectPlugins(t *testing.T) {
_, err := DetectPlugins() _, err := DetectPlugins()
if err != nil { if err != nil {
t.Fail() t.Fail()
} }
} }
// Test ensures that the ansible are executed inside local containers // Test ensures that the ansible are executed inside local containers
func TestRunPlugin(t *testing.T) { func TestRunPlugin(t *testing.T) {
var testips []*ExecuteIP var testips []*ExecuteIP
var testip1, testip2 ExecuteIP var testip1, testip2 ExecuteIP
// Create docker container and get SSH port // Create docker container and get SSH port
container1, err := docker.BuildRunContainer(0, "false", "") container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
//Test IP 1 configuration //Test IP 1 configuration
testip1.IPAddress = "0.0.0.0" testip1.IPAddress = "0.0.0.0"
testip1.SSHPortNo = strconv.Itoa(container1.Ports.PortSet[0].ExternalPort) testip1.SSHPortNo = strconv.Itoa(container1.Ports.PortSet[0].ExternalPort)
// Create docker container and get SSH port // Create docker container and get SSH port
container2, err := docker.BuildRunContainer(0, "false", "") container2, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
//Test IP 2 configuration //Test IP 2 configuration
testip2.IPAddress = "0.0.0.0" testip2.IPAddress = "0.0.0.0"
testip2.SSHPortNo = strconv.Itoa(container2.Ports.PortSet[0].ExternalPort) testip2.SSHPortNo = strconv.Itoa(container2.Ports.PortSet[0].ExternalPort)
testips = append(testips, &testip1) testips = append(testips, &testip1)
testips = append(testips, &testip2) testips = append(testips, &testip2)
_, err = RunPlugin("TestAnsible", testips) _, err = RunPlugin("TestAnsible", testips)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Removing container1 after Ansible is executed // Removing container1 after Ansible is executed
err = docker.StopAndRemoveContainer(container1.ID) err = docker.StopAndRemoveContainer(container1.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
err = docker.StopAndRemoveContainer(container2.ID) err = docker.StopAndRemoveContainer(container2.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
} }
// Test to ensure that the ansible host file is modified to // Test to ensure that the ansible host file is modified to
// the appropriate IP // the appropriate IP
func TestExecuteIP_ModifyHost(t *testing.T) { func TestExecuteIP_ModifyHost(t *testing.T) {
var plugin Plugin var plugin Plugin
var testip ExecuteIP var testip ExecuteIP
// Get plugin path from config file // Get plugin path from config file
Config, err := config.ConfigInit(nil) Config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
//Set plugin name //Set plugin name
plugin.FolderName = "TestAnsible" plugin.FolderName = "TestAnsible"
plugin.path = Config.PluginPath plugin.path = Config.PluginPath
//Test IP 1 configuration //Test IP 1 configuration
testip.IPAddress = "0.0.0.0" testip.IPAddress = "0.0.0.0"
testip.SSHPortNo = "41289" testip.SSHPortNo = "41289"
err = testip.ModifyHost(&plugin) err = testip.ModifyHost(&plugin)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
} }
// Test to ensure the cli function runs as intended and executes // Test to ensure the cli function runs as intended and executes
// the test ansible script // the test ansible script
func TestRunPluginContainer(t *testing.T) { func TestRunPluginContainer(t *testing.T) {
// Create docker container and get SSH port // Create docker container and get SSH port
container1, err := docker.BuildRunContainer(0, "false", "") container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Ensuring created container is the added to the tracked list // Ensuring created container is the added to the tracked list
err = client.AddTrackContainer(container1, "0.0.0.0") err = client.AddTrackContainer(container1, "0.0.0.0")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Running test Ansible script // Running test Ansible script
err = RunPluginContainer("TestAnsible", container1.ID) err = RunPluginContainer("TestAnsible", container1.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Removes container information from the tracker IP addresses // Removes container information from the tracker IP addresses
err = client.RemoveTrackedContainer(container1.ID) err = client.RemoveTrackedContainer(container1.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Removing container1 after Ansible is executed // Removing container1 after Ansible is executed
err = docker.StopAndRemoveContainer(container1.ID) err = docker.StopAndRemoveContainer(container1.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
} }
// Testing the function can plugin can run with // Testing the function can plugin can run with
// group ID and container ID // group ID and container ID
func TestCheckRunPlugin(t *testing.T) { func TestCheckRunPlugin(t *testing.T) {
// Create docker container and get SSH port // Create docker container and get SSH port
container1, err := docker.BuildRunContainer(0, "false", "") container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Create docker container and get SSH port // Create docker container and get SSH port
container2, err := docker.BuildRunContainer(0, "false", "") container2, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Ensuring created container1 is the added to the tracked list // Ensuring created container1 is the added to the tracked list
err = client.AddTrackContainer(container1, "0.0.0.0") err = client.AddTrackContainer(container1, "0.0.0.0")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Ensuring created container2 is the added to the tracked list // Ensuring created container2 is the added to the tracked list
err = client.AddTrackContainer(container2, "0.0.0.0") err = client.AddTrackContainer(container2, "0.0.0.0")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Create group to add created containers // Create group to add created containers
group, err := client.CreateGroup() group, err := client.CreateGroup()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Add container 1 to the group // Add container 1 to the group
_, err = client.AddContainerToGroup(container1.ID, group.ID) _, err = client.AddContainerToGroup(container1.ID, group.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Add container 2 to the group // Add container 2 to the group
_, err = client.AddContainerToGroup(container2.ID, group.ID) _, err = client.AddContainerToGroup(container2.ID, group.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// -------------------------- Main test cases ------------------------------- // -------------------------- Main test cases -------------------------------
// Checking function against container ID // Checking function against container ID
err = CheckRunPlugin("TestAnsible", container1.ID) err = CheckRunPlugin("TestAnsible", container1.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Checking function against group ID // Checking function against group ID
err = CheckRunPlugin("TestAnsible", group.ID) err = CheckRunPlugin("TestAnsible", group.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Remove created group // Remove created group
err = client.RemoveGroup(group.ID) err = client.RemoveGroup(group.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Removes container1 information from the tracker IP addresses // Removes container1 information from the tracker IP addresses
err = client.RemoveTrackedContainer(container1.ID) err = client.RemoveTrackedContainer(container1.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Removing container1 after Ansible is executed // Removing container1 after Ansible is executed
err = docker.StopAndRemoveContainer(container1.ID) err = docker.StopAndRemoveContainer(container1.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Removes container2 information from the tracker IP addresses // Removes container2 information from the tracker IP addresses
err = client.RemoveTrackedContainer(container2.ID) err = client.RemoveTrackedContainer(container2.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Removing container2 after Ansible is executed // Removing container2 after Ansible is executed
err = docker.StopAndRemoveContainer(container2.ID) err = docker.StopAndRemoveContainer(container2.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
} }
func TestDownloadPlugin(t *testing.T) { func TestDownloadPlugin(t *testing.T) {
err := DownloadPlugin("https://github.com/Akilan1999/laplace/") err := DownloadPlugin("https://github.com/Akilan1999/laplace/")
if err != nil { if err != nil {
} }
} }
// Simple test case implemented to the test if // Simple test case implemented to the test if
// the port no can be extracted from the IP address. // the port no can be extracted from the IP address.
func TestParseIP(t *testing.T) { func TestParseIP(t *testing.T) {
host, port, err := net.SplitHostPort("12.34.23.13:5432") host, port, err := net.SplitHostPort("12.34.23.13:5432")
if err != nil { if err != nil {
fmt.Printf("Error: %v\n", err) fmt.Printf("Error: %v\n", err)
} else { } else {
fmt.Printf("Host: %s\nPort: %s\n", host, port) fmt.Printf("Host: %s\nPort: %s\n", host, port)
} }
} }

View File

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

View File

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