33 Commits

Author SHA1 Message Date
Akilan Selvacoumar
5ac033403f Merge pull request #97 from Akilan1999/approprirate-abstractions
Appropriate abstractions
2023-06-07 23:49:39 +01:00
d52aca3d14 fixed spelling mistakes 2023-06-07 23:49:15 +01:00
05c9f52e6d added improved docs for P2PRC abstractions 2023-06-07 23:42:56 +01:00
732b31fafa go fmt the entire project and added possbility to start a server with a TURN connection with a custom remote connection 2023-04-22 12:43:22 +01:00
5edf1f801b added default ip address for ip table 2023-04-22 11:24:04 +01:00
4e025bdc70 changed back root ip address 2023-04-14 10:57:58 +01:00
3bcba8a3e2 fixed iptable directory changes 2023-04-14 10:54:24 +01:00
Akilan Selvacoumar
97d10918b1 Merge pull request #95 from farhansolodev/approprirate-abstractions
few small fixes
2023-04-03 21:21:30 +01:00
farhansolodev
d3181d272e revert paths 2023-04-04 00:17:52 +04:00
Farhan Alvi
0550a35df1 Update ip_table.json 2023-04-03 22:55:16 +04:00
farhansolodev
7984f72db1 better wording 2023-04-03 22:50:11 +04:00
farhansolodev
806b499e72 more explicit --rm instructions + erroring out if no --id provided 2023-04-03 22:48:57 +04:00
farhansolodev
cf1e7c6d6f wrong container json file paths 2023-04-03 21:05:57 +04:00
farhansolodev
86aaba23c4 hardcoded default path incorrect 2023-04-03 06:17:19 +04:00
farhansolodev
53bef115b0 fix cyclic dependancy + duplicate test 2023-04-03 06:16:29 +04:00
farhansolodev
fbbb23c13a dead code 2023-04-03 06:15:56 +04:00
farhansolodev
f0496f8184 ran go mod tidy right after cloning 2023-04-03 06:15:45 +04:00
69c0aa5cb1 config abstraction changes added 2023-03-22 09:43:40 +00:00
Akilan Selvacoumar
88dddd0230 Merge pull request #94 from Akilan1999/documentation-NAT-tarversal
Documentation nat tarversal
2023-03-22 07:03:41 +00:00
c9f007a652 base MD file added for NAT traversal 2023-03-22 07:03:04 +00:00
3b70ff5879 pushed changes for base NAT traversal changes 2023-03-14 17:31:50 +00:00
Akilan Selvacoumar
6161b0afa3 Merge pull request #93 from Akilan1999/abstracted-functions
modified server specs to return type ServerSpec instead of interface.
2023-02-24 22:42:31 +00:00
4268b5a637 modified server specs 2023-02-24 22:36:16 +00:00
Akilan Selvacoumar
60a00cbb57 Merge pull request #92 from Akilan1999/abstracted-functions
changes to configuration
2023-02-24 02:54:10 +00:00
35b9e7ea33 changes to configuration 2023-02-24 02:53:30 +00:00
Akilan Selvacoumar
e965adf798 Merge pull request #91 from Akilan1999/flexible-server
Flexible server
2023-02-22 23:12:28 +00:00
1428d324b1 modified README file 2023-02-22 23:10:09 +00:00
c646a1389e added other abstractions documentation to P2PRC 2023-02-22 23:08:11 +00:00
be9de346e5 removed duplicate docker folder 2023-02-22 17:13:51 +00:00
73e62ba0fa docker files 2023-02-22 17:10:14 +00:00
60500620db added base abstraction functions 2023-02-22 03:15:49 +00:00
4dac4234ad added config flixble system 2023-02-22 02:46:11 +00:00
c7a665fdc8 added new module 2023-02-14 20:33:30 +00:00
62 changed files with 2918 additions and 3682 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

11
.gitignore vendored
View File

@@ -11,23 +11,16 @@ config.json
#ignore generated iptables #ignore generated iptables
p2p/iptable/ p2p/iptable/
!p2p/iptable/.gitkeep
#ignore plugins added #ignore plugins added
plugin/deploy/ plugin/deploy/
!plugin/deploy/.gitkeep
#ignore track container file #ignore track container file
client/trackcontainers/ client/trackcontainers/
!client/trackcontainers/.gitkeep
# Test generated files # Test generated files
generate/p2prctest generate/p2prctest
!generate/p2prctest/.gitkeep
generate/Test generate/Test
!generate/Test/.gitkeep
#ignore windows exe files #ignore windows exe files
*.exe *.exe
dist/ dist/
#MACOS .idea file # ignore docker image files
.DS_Store server/docker/containers/
.gitkeep

6
Docs/Abstractions.md Normal file
View File

@@ -0,0 +1,6 @@
# Abstractions
The Abstractions package consists of black-boxed functions for P2PRC.
## Functions
- ```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.

37
Docs/NAT-Traveral.md Normal file
View File

@@ -0,0 +1,37 @@
# NAT Traversal
P2PRC currently supports TURN for NAT traversal.
## TURN
The current TURN implementation used is FRP. The TURN server is also required when
a P2PRC node is acting as a Server. The TURN server is determined based on the Node
with the least amount of latency based on the Nodes available on the IPTable.
Once a TURN server is determined there are 2 actions performed. The first one is
```/FRPPort``` to the TURN server to receive a port which is used to generate the external
port from the TURN server. The flow below describes the workflow.
### Client mode
- Call ```/FRPPort```
```
http://<turn server ip>:<server port no>/FRPport
```
- Call the TURN server in the following manner. The following is a sample code snippet below.
```go
import (
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
)
func main() {
serverPort, err := frp.GetFRPServerPort("http://" + <lowestLatencyIpAddress.Ipv4> + ":" + lowestLatencyIpAddress.ServerPort)
if err != nil {
return nil, err
}
// Create 1 second delay to allow FRP server to start
time.Sleep(1 * time.Second)
// Starts FRP as a client with
proxyPort, err := frp.StartFRPClientForServer(<lowestLatencyIpAddress.Ipv4>, serverPort, <the port you want to expose externally>)
if err != nil {
return nil, err
}
}
```

View File

@@ -2,6 +2,7 @@
# Table of contents # Table of contents
1. [Introduction](Introduction.md) 1. [Introduction](Introduction.md)
2. [Installation](Installation.md) 2. [Installation](Installation.md)
3. [Abstractions](Abstractions.md)
3. [Design Architecture](DesignArchtectureIntro.md) 3. [Design Architecture](DesignArchtectureIntro.md)
1. [Client Module](ClientArchitecture.md) 1. [Client Module](ClientArchitecture.md)
2. [P2P Module](P2PArchitecture.md) 2. [P2P Module](P2PArchitecture.md)
@@ -13,6 +14,5 @@
4. [Config Module](ConfigImplementation.md) 4. [Config Module](ConfigImplementation.md)
5. [Cli Module](CliImplementation.md) 5. [Cli Module](CliImplementation.md)
6. [Plugin Module](PluginImplementation.md) 6. [Plugin Module](PluginImplementation.md)
7. [Generate Module](GenerateImplementation.md)
5. [Problems](https://github.com/Akilan1999/p2p-rendering-computation/issues) 5. [Problems](https://github.com/Akilan1999/p2p-rendering-computation/issues)

View File

@@ -45,6 +45,28 @@ This project aims to create a peer to peer (p2p) network, where a user can use t
<br> <br>
## Extend your application with P2PRC
```go
package main
import "github.com/Akilan1999/p2p-rendering-computation/abstractions"
func main() {
// Initialize with base p2prc config files
err := abstractions.Init("TEST")
if err != nil {
return
}
// start p2prc
_, err = abstractions.Start()
if err != nil {
return
}
}
```
[Read more](Docs/Abstractions.md) ...
## Installation from source ## Installation from source
1. Ensure the Go compiler is installed 1. Ensure the Go compiler is installed
``` ```

27
abstractions/init.go Normal file
View File

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

BIN
artwork/p2prc-logos/.DS_Store vendored Normal file

Binary file not shown.

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() 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() 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() 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() 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() 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() 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() 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() 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

@@ -1,304 +1,277 @@
package cmd package cmd
import ( import (
"fmt" "fmt"
"github.com/Akilan1999/p2p-rendering-computation/client" "github.com/Akilan1999/p2p-rendering-computation/client"
"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/generate"
"github.com/Akilan1999/p2p-rendering-computation/generate" "github.com/Akilan1999/p2p-rendering-computation/p2p"
"github.com/Akilan1999/p2p-rendering-computation/p2p" "github.com/Akilan1999/p2p-rendering-computation/plugin"
"github.com/Akilan1999/p2p-rendering-computation/plugin" "github.com/Akilan1999/p2p-rendering-computation/server"
"github.com/Akilan1999/p2p-rendering-computation/server" "github.com/urfave/cli/v2"
"github.com/urfave/cli/v2"
) )
var CliAction = func(ctx *cli.Context) error { var CliAction = func(ctx *cli.Context) error {
if Server { if Server {
err := server.Server() _, err := server.Server()
if err != nil { if err != nil {
fmt.Print(err) fmt.Print(err)
} }
//server.Rpc() //server.Rpc()
} for {
//Listing servers and also updates IP tables (Default 3 hops) }
if UpdateServerList { }
err := clientIPTable.UpdateIpTableListClient()
if err != nil {
fmt.Print(err)
}
// Reads from ip table and passes it
// on to struct print function
//Servers, err := p2p.ReadIpTable()
//if err != nil {
// return err
//}
//client.PrettyPrint(Servers)
p2p.PrintIpTable()
}
// Displays the IP table //Listing servers and also updates IP tables (Default 3 hops)
if ServerList { if UpdateServerList {
// Reads from ip table and passes it err := clientIPTable.UpdateIpTableListClient()
// on to struct print function if err != nil {
//Servers, err := p2p.ReadIpTable() fmt.Print(err)
//if err != nil { }
// return err // Reads from ip table and passes it
//} // on to struct print function
p2p.PrintIpTable() //Servers, err := p2p.ReadIpTable()
} //if err != nil {
// return err
//}
//client.PrettyPrint(Servers)
p2p.PrintIpTable()
}
// Add provided IP to the IP table // Displays the IP table
if AddServer != "" { if ServerList {
res, err := p2p.ReadIpTable() // Reads from ip table and passes it
if err != nil { // on to struct print function
fmt.Println(err) //Servers, err := p2p.ReadIpTable()
} //if err != nil {
// return err
//}
p2p.PrintIpTable()
}
//Create variable of type IpAddress and set IP address // Add provided IP to the IP table
// to it if AddServer != "" {
var IpAddr p2p.IpAddress res, err := p2p.ReadIpTable()
if err != nil {
fmt.Println(err)
}
//Checking if the address is a ipv4 //Create variable of type IpAddress and set IP address
// or ipv6 address // to it
ip4Orip6 := p2p.Ip4or6(AddServer) var IpAddr p2p.IpAddress
if ip4Orip6 == "version 6" {
IpAddr.Ipv6 = AddServer
} else {
IpAddr.Ipv4 = AddServer
}
// If a server port is provided then set it //Checking if the address is a ipv4
if Ports != "" { // or ipv6 address
IpAddr.ServerPort = Ports ip4Orip6 := p2p.Ip4or6(AddServer)
} else { if ip4Orip6 == "version 6" {
IpAddr.ServerPort = "8088" IpAddr.Ipv6 = AddServer
} } else {
// Append IP address to variable result which IpAddr.Ipv4 = AddServer
// is a list }
res.IpAddress = append(res.IpAddress, IpAddr)
// Adds the new server IP to the iptable
res.WriteIpTable()
} // If a server port is provided then set it
if Ports != "" {
IpAddr.ServerPort = Ports
} else {
IpAddr.ServerPort = "8088"
}
// Append IP address to variable result which
// is a list
res.IpAddress = append(res.IpAddress, IpAddr)
// Adds the new server IP to the iptable
res.WriteIpTable()
// Displays all images available on the server side }
if ViewImages != "" {
imageRes, err := client.ViewContainers(ViewImages)
if err != nil { // Displays all images available on the server side
fmt.Print(err) if ViewImages != "" {
} imageRes, err := client.ViewContainers(ViewImages)
client.PrettyPrint(imageRes)
}
// Function called to stop and remove server from Docker if err != nil {
if RemoveVM != "" && ID != "" { fmt.Print(err)
err := client.RemoveContianer(RemoveVM, ID) }
if err != nil { client.PrettyPrint(imageRes)
fmt.Print(err) }
}
}
//Call function to create Docker container // Function called to stop and remove server from Docker
if CreateVM != "" { if RemoveVM != "" {
if ID == "" {
fmt.Println("provide container ID via --ID or --id")
} else {
err := client.RemoveContianer(RemoveVM, ID)
if err != nil {
fmt.Print(err)
}
}
}
var PortsInt int //Call function to create Docker container
if CreateVM != "" {
if Ports != "" { var PortsInt int
// Convert Get Request value to int
fmt.Sscanf(Ports, "%d", &PortsInt)
}
// Calls function to do Api call to start the container on the server side if Ports != "" {
imageRes, err := client.StartContainer(CreateVM, PortsInt, GPU, ContainerName) // Convert Get Request value to int
fmt.Sscanf(Ports, "%d", &PortsInt)
}
if err != nil { // Calls function to do Api call to start the container on the server side
fmt.Print(err) imageRes, err := client.StartContainer(CreateVM, PortsInt, GPU, ContainerName)
}
client.PrettyPrint(imageRes)
}
//Call if specs flag is called if err != nil {
if Specs != "" { fmt.Print(err)
specs, err := client.GetSpecs(Specs) }
if err != nil { client.PrettyPrint(imageRes)
return err }
}
// Pretty print //Call if specs flag is called
client.PrettyPrint(specs) if Specs != "" {
} specs, err := client.GetSpecs(Specs)
if err != nil {
return err
}
//Sets default paths to the config file // Pretty print
if SetDefaultConfig { client.PrettyPrint(specs)
err := config.SetDefaults() }
if err != nil {
fmt.Print(err)
}
}
//If the network interface flag is called //Sets default paths to the config file
// Then all the network interfaces are displayed if SetDefaultConfig {
if NetworkInterface { _, err := generate.SetDefaults("P2PRC", false, nil, false)
err := p2p.ViewNetworkInterface() if err != nil {
if err != nil { fmt.Print(err)
fmt.Print(err) }
} }
}
// If the view plugin flag is called then display all //If the network interface flag is called
// plugins available // Then all the network interfaces are displayed
if ViewPlugin { if NetworkInterface {
plugins, err := plugin.DetectPlugins() err := p2p.ViewNetworkInterface()
if err != nil { if err != nil {
fmt.Print(err) fmt.Print(err)
} }
client.PrettyPrint(plugins) }
}
// If the flag Tracked Container is called or the flag // If the view plugin flag is called then display all
// --tc // plugins available
if TrackedContainers { if ViewPlugin {
err, trackedContainers := client.ViewTrackedContainers() plugins, err := plugin.DetectPlugins()
if err != nil { if err != nil {
fmt.Print(err) fmt.Print(err)
} }
client.PrettyPrint(trackedContainers) client.PrettyPrint(plugins)
} }
//Executing plugin when the plugin flag is called // If the flag Tracked Container is called or the flag
// --plugin // --tc
if ExecutePlugin != "" { if TrackedContainers {
// To execute plugin requires the container ID or group ID provided when being executed err, trackedContainers := client.ViewTrackedContainers()
if ID != "" { if err != nil {
err := plugin.CheckRunPlugin(ExecutePlugin, ID) fmt.Print(err)
if err != nil { }
fmt.Println(err) client.PrettyPrint(trackedContainers)
} else { }
fmt.Println("Success")
}
} else {
fmt.Println("provide container ID")
}
} //Executing plugin when the plugin flag is called
// --plugin
if ExecutePlugin != "" {
// To execute plugin requires the container ID or group ID provided when being executed
if ID != "" {
err := plugin.CheckRunPlugin(ExecutePlugin, ID)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Success")
}
} else {
fmt.Println("provide container ID via --ID or --id")
}
// Executing function to create new group }
// Creates new group and outputs JSON file
if CreateGroup {
group, err := client.CreateGroup()
if err != nil {
return err
}
client.PrettyPrint(group)
}
// Actions to be performed when the // Executing function to create new group
// group flag is called // Creates new group and outputs JSON file
// --group <Group ID> if CreateGroup {
if Group != "" { group, err := client.CreateGroup()
// Remove container from group based on group ID provided if err != nil {
// --rmcgroup --id <contianer id> return err
if RemoveContainerGroup && ID != "" { }
group, err := client.RemoveContainerGroup(ID, Group) client.PrettyPrint(group)
if err != nil { }
fmt.Println(err)
} else {
client.PrettyPrint(group)
}
} else if ID != "" { // Add container to group based on group ID provided
// --id <Container ID>
group, err := client.AddContainerToGroup(ID, Group)
if err != nil {
fmt.Println(err)
} else {
client.PrettyPrint(group)
}
} else { // View all information about current group
group, err := client.GetGroup(Group)
if err != nil {
fmt.Println(err)
} else {
client.PrettyPrint(group)
}
}
}
// Execute function to remove entire group // Actions to be performed when the
// when remove group flag is called // group flag is called
// --rmgroup // --group <Group ID>
if RemoveGroup != "" { if Group != "" {
err := client.RemoveGroup(RemoveGroup) // Remove container from group based on group ID provided
if err != nil { // --rmcgroup --id <contianer id>
fmt.Println(err) if RemoveContainerGroup && ID != "" {
} else { group, err := client.RemoveContainerGroup(ID, Group)
fmt.Println("Group Removed") if err != nil {
} fmt.Println(err)
} } else {
client.PrettyPrint(group)
}
} else if ID != "" { // Add container to group based on group ID provided
// --id <Container ID>
group, err := client.AddContainerToGroup(ID, Group)
if err != nil {
fmt.Println(err)
} else {
client.PrettyPrint(group)
}
} else { // View all information about current group
group, err := client.GetGroup(Group)
if err != nil {
fmt.Println(err)
} else {
client.PrettyPrint(group)
}
}
}
// Execute Function to view all groups // Execute function to remove entire group
if Groups { // when remove group flag is called
groups, err := client.ReadGroup() // --rmgroup
if err != nil { if RemoveGroup != "" {
fmt.Println(err) err := client.RemoveGroup(RemoveGroup)
} else { if err != nil {
client.PrettyPrint(groups) fmt.Println(err)
} } else {
} fmt.Println("Group Removed")
}
}
// Starts server as a reverse proxy so that // Execute Function to view all groups
// nodes can connect to each other behind NAT if Groups {
//if FRPProxy { groups, err := client.ReadGroup()
// err := frp.StartFRPProxyFromRandom() if err != nil {
// if err != nil { fmt.Println(err)
// fmt.Println(err) } else {
// } client.PrettyPrint(groups)
//} }
}
// -- REMOVE ON REGULAR RELEASE -- //--------------------------------
// when flag --gen is called an extension
// of the project is created to repurpose
// the project for custom purpose
if Generate != "" {
var err error
// If the module name is provided
if Modulename != "" {
err = generate.GenerateNewProject(Generate, Modulename)
} else {
err = generate.GenerateNewProject(Generate, Generate)
}
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Created new folder: " + Generate)
fmt.Println("1. Enter inside " + Generate + " directory")
fmt.Println("2. git remote add " + Generate + " <PATH to the github repo>")
fmt.Println("3. git push " + Generate + " <PATH to the github repo>")
fmt.Println("4. go mod tidy")
fmt.Println("5. sh install.sh " + Generate)
fmt.Println("6. ./" + Generate + " -h (This is to test if the binary is working)")
}
}
//--------------------------------
if PullPlugin != "" { if PullPlugin != "" {
err := plugin.DownloadPlugin(PullPlugin) err := plugin.DownloadPlugin(PullPlugin)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} else { } else {
fmt.Println("Success") fmt.Println("Success")
} }
} }
if RemovePlugin != "" { if RemovePlugin != "" {
err := plugin.DeletePlugin(RemovePlugin) err := plugin.DeletePlugin(RemovePlugin)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} else { } else {
fmt.Println("Success") fmt.Println("Success")
} }
} }
return nil return nil
} }

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,75 +1,52 @@
package config package config
import ( import (
"github.com/spf13/viper" "encoding/json"
"io" "io/ioutil"
"os" "os"
) )
var ( var (
defaultPath string //defaultPath string
defaults = map[string]interface{}{} defaults = map[string]interface{}{}
configName = "config" configName = "config"
configType = "json" configType = "json"
configFile = "config.json" configFile = "config.json"
configPaths []string configPaths []string
defaultEnvName = "P2PRC" defaultEnvName = "P2PRC"
) )
type Config struct { type Config struct {
MachineName string MachineName string
IPTable string IPTable string
DockerContainers string DockerContainers string
DefaultDockerFile string DefaultDockerFile string
SpeedTestFile string SpeedTestFile string
IPV6Address string IPV6Address string
PluginPath string PluginPath string
TrackContainersPath string TrackContainersPath string
ServerPort string ServerPort string
GroupTrackContainersPath string GroupTrackContainersPath string
FRPServerPort string FRPServerPort string
BehindNAT string BehindNAT string
//NetworkInterface string CustomConfig interface{}
//NetworkInterfaceIPV6Index int //NetworkInterface string
} //NetworkInterfaceIPV6Index int
// Exists reports whether the named file or directory exists.
func fileExists(name string) bool {
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}
// Copy the src file to dst. Any existing file will be overwritten and will not
// copy file attributes.
// Source: https://stackoverflow.com/questions/21060945/simple-way-to-copy-a-file
func Copy(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, in)
if err != nil {
return err
}
return out.Close()
} }
// GetPathP2PRC Getting P2PRC Directory from environment variable // GetPathP2PRC Getting P2PRC Directory from environment variable
func GetPathP2PRC() (string, error) { func GetPathP2PRC(Envname string) (string, error) {
curDir := os.Getenv(defaultEnvName) if Envname != "" {
return curDir + "/", nil err := SetEnvName(Envname)
if err != nil {
return "", err
}
}
curDir := os.Getenv(defaultEnvName)
if curDir == "" {
return curDir, nil
}
return curDir + "/", nil
} }
// SetEnvName Sets the environment name // SetEnvName Sets the environment name
@@ -77,120 +54,103 @@ func GetPathP2PRC() (string, error) {
// your environment variable // your environment variable
// This is useful when extending the use case of P2PRC // This is useful when extending the use case of P2PRC
func SetEnvName(EnvName string) error { func SetEnvName(EnvName string) error {
defaultEnvName = EnvName defaultEnvName = EnvName
// Handling error to be implemented only if needed // Handling error to be implemented only if needed
return nil return nil
} }
// GetCurrentPath Getting P2PRC Directory from environment variable func GetEnvName() string {
func GetCurrentPath() (string, error) { return defaultEnvName
curDir := os.Getenv("PWD")
return curDir + "/", nil
} }
// SetDefaults This function to be called only during a // ConfigInit Pass environment name as an optional parameter
// make install func ConfigInit(defaultsParameter map[string]interface{}, CustomConfig interface{}, envNameOptional ...string) (*Config, error) {
func SetDefaults() error { if len(envNameOptional) > 0 {
//Setting current directory to default path defaultEnvName = envNameOptional[0]
defaultPath, err := GetPathP2PRC() }
if err != nil { //
return err ////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
//Creates ip_table.json in the json directory defaultPath, err := GetPathP2PRC(defaultEnvName)
err = Copy("p2p/ip_table.json", "p2p/iptable/ip_table.json") if err != nil {
if err != nil { return nil, err
return err }
}
//Creates a copy of trackcontainers.json in the appropriate directory // Open our jsonFile
err = Copy("client/trackcontainers.json", "client/trackcontainers/trackcontainers.json") jsonFile, err := os.Open(defaultPath + configFile)
if err != nil { // if we os.Open returns an error then handle it
return err if err != nil {
} return nil, err
}
//Creates a copy of trackcontainers.json in the appropriate directory // defer the closing of our jsonFile so that we can parse it later on
err = Copy("client/grouptrackcontainers.json", "client/trackcontainers/grouptrackcontainers.json") defer jsonFile.Close()
if err != nil {
return err
}
//Setting default paths for the config file byteValue, _ := ioutil.ReadAll(jsonFile)
defaults["IPTable"] = defaultPath + "p2p/iptable/ip_table.json"
defaults["DefaultDockerFile"] = defaultPath + "server/docker/containers/docker-ubuntu-sshd/"
defaults["DockerContainers"] = defaultPath + "server/docker/containers/"
defaults["SpeedTestFile"] = defaultPath + "p2p/50.bin"
defaults["IPV6Address"] = ""
defaults["PluginPath"] = defaultPath + "plugin/deploy"
defaults["TrackContainersPath"] = defaultPath + "client/trackcontainers/trackcontainers.json"
defaults["GroupTrackContainersPath"] = defaultPath + "client/trackcontainers/grouptrackcontainers.json"
defaults["ServerPort"] = "8088"
defaults["FRPServerPort"] = "0"
defaults["BehindNAT"] = "True"
// Random name generator
hostname, err := os.Hostname()
if err != nil {
return err
}
defaults["MachineName"] = hostname var config Config
//defaults["NetworkInterface"] = "wlp0s20f3" json.Unmarshal(byteValue, &config)
//defaults["NetworkInterfaceIPV6Index"] = "2"
//Paths to search for config file if CustomConfig != nil {
configPaths = append(configPaths, defaultPath) // Convert Custom Config to byte
customConfigByte, err := json.Marshal(config.CustomConfig)
if err != nil {
return nil, err
}
if fileExists(defaultPath + "config.json") { // Again map the byte to the CustomConfig interface
err := os.Remove(defaultPath + "config.json") json.Unmarshal(customConfigByte, &CustomConfig)
if err != nil { }
return err
}
}
//Calling configuration file return &config, nil
_, err = ConfigInit()
if err != nil {
return err
}
return nil
} }
func ConfigInit() (*Config, error) { func (c *Config) WriteConfig() error {
//Getting Current Directory from environment variable
//curDir := os.Getenv("REMOTEGAMING")
//Setting current directory to default path defaultPath, err := GetPathP2PRC(defaultEnvName)
defaultPath, err := GetPathP2PRC() if err != nil {
if err != nil { return err
return nil, err }
}
//Paths to search for config file
configPaths = append(configPaths, defaultPath)
//Add all possible configurations paths file, _ := json.MarshalIndent(c, "", " ")
for _, v := range configPaths {
viper.AddConfigPath(v)
}
//Read config file _ = ioutil.WriteFile(defaultPath+"config.json", file, 0644)
if err := viper.ReadInConfig(); err != nil { return 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
} }

View File

@@ -1,63 +0,0 @@
package config
import (
"fmt"
"os"
"testing"
)
func TestConfigInit(t *testing.T) {
_,err := ConfigInit()
if err != nil {
t.Error(err)
}
}
func TestSetDefaults(t *testing.T) {
err := SetDefaults()
if err != nil {
t.Error(err)
}
}
func TestGetCurrentPath(t *testing.T) {
path, err := GetCurrentPath()
if err != nil {
fmt.Println(err)
t.Error(err)
}
fmt.Println(path)
}
func TestGetPathP2PRC(t *testing.T) {
path, err := GetPathP2PRC()
if err != nil {
fmt.Println(err)
t.Error(err)
}
fmt.Println(path)
}
func TestSetEnvName(t *testing.T) {
// Create an Env variable TEST with the value "lol"
err := os.Setenv("TEST", "lol")
if err != nil {
fmt.Println(err)
t.Error(err)
}
// Sets the environment variable as the default to read
// for P2PRC
err = SetEnvName("TEST")
if err != nil {
fmt.Println(err)
t.Error(err)
}
// Checks if the output for the default read is "lol"
path, err := GetPathP2PRC()
if err != nil {
fmt.Println(err)
t.Error(err)
}
fmt.Println(path)
}

View File

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

131
config/generate/generate.go Normal file
View File

@@ -0,0 +1,131 @@
package generate
import (
"github.com/Akilan1999/p2p-rendering-computation/config"
"os"
)
var (
defaults = map[string]interface{}{}
configPaths []string
defaultEnvName = "P2PRC"
)
// GetPathP2PRC Getting P2PRC Directory from environment variable
func GetPathP2PRC() (string, error) {
curDir := os.Getenv(defaultEnvName)
return curDir + "/", nil
}
// SetEnvName Sets the environment name
// This is to ensure that the Path of your project is detected from
// your environment variable
// This is useful when extending the use case of P2PRC
func SetEnvName(EnvName string) error {
if EnvName != "" {
defaultEnvName = EnvName
}
// Handling error to be implemented only if needed
return nil
}
// GetCurrentPath Getting P2PRC Directory from environment variable
func GetCurrentPath() (string, error) {
curDir := os.Getenv("PWD")
return curDir + "/", nil
}
// SetDefaults This function to be called only during a
// make install
func SetDefaults(envName string, forceDefault bool, CustomConfig interface{}, NoBoilerPlate bool, ConfigUpdate ...*config.Config) (*config.Config, error) {
//Setting current directory to default path
defaultPath, err := GetCurrentPath()
if err != nil {
return nil, err
}
// Set Env name
err = config.SetEnvName(envName)
if err != nil {
return nil, err
}
////Creates ip_table.json in the json directory
//err = Copy("p2p/ip_table.json", "p2p/iptable/ip_table.json")
//if err != nil {
// return err
//}
//
////Creates a copy of trackcontainers.json in the appropriate directory
//err = Copy("client/trackcontainers.json", "client/trackcontainers/trackcontainers.json")
//if err != nil {
// return err
//}
//
////Creates a copy of trackcontainers.json in the appropriate directory
//err = Copy("client/grouptrackcontainers.json", "client/trackcontainers/grouptrackcontainers.json")
//if err != nil {
// return err
//}
var Defaults config.Config
if len(ConfigUpdate) == 0 {
//Setting default paths for the config file
Defaults.IPTable = defaultPath + "p2p/iptable/ip_table.json"
Defaults.DefaultDockerFile = defaultPath + "server/docker/containers/docker-ubuntu-sshd/"
Defaults.DockerContainers = defaultPath + "server/docker/containers/"
Defaults.SpeedTestFile = defaultPath + "p2p/50.bin"
Defaults.IPV6Address = ""
Defaults.PluginPath = defaultPath + "plugin/deploy"
Defaults.TrackContainersPath = defaultPath + "client/trackcontainers/trackcontainers.json"
Defaults.GroupTrackContainersPath = defaultPath + "client/trackcontainers/grouptrackcontainers.json"
Defaults.ServerPort = "8088"
Defaults.FRPServerPort = "True"
Defaults.CustomConfig = CustomConfig
Defaults.BehindNAT = "True"
// Random name generator
hostname, err := os.Hostname()
if err != nil {
return nil, err
}
Defaults.MachineName = hostname
} else {
Defaults = *ConfigUpdate[0]
}
//defaults["NetworkInterface"] = "wlp0s20f3"
//defaults["NetworkInterfaceIPV6Index"] = "2"
//Paths to search for config file
configPaths = append(configPaths, defaultPath)
if fileExists(defaultPath+"config.json") && forceDefault {
err := os.Remove(defaultPath + "config.json")
if err != nil {
return nil, err
}
}
// write defaults to the config file
err = Defaults.WriteConfig()
if err != nil {
return nil, err
}
//Calling configuration file
Config, err := config.ConfigInit(defaults, nil, envName)
if err != nil {
return nil, err
}
if !NoBoilerPlate {
err = GenerateFiles()
if err != nil {
return nil, err
}
}
return Config, nil
}

View File

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

View File

@@ -0,0 +1,39 @@
package generate
import (
"io"
"os"
)
// Exists reports whether the named file or directory exists.
func fileExists(name string) bool {
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}
// Copy the src file to dst. Any existing file will be overwritten and will not
// copy file attributes.
// Source: https://stackoverflow.com/questions/21060945/simple-way-to-copy-a-file
func Copy(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, in)
if err != nil {
return err
}
return out.Close()
}

View File

@@ -1,386 +0,0 @@
// Package generate The purpose of this package is to ensure that we can extend the use-case of P2PRC.
// We will create a project directory with the template to extend the use-case of P2PRC
package generate
import (
"fmt"
"github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/otiai10/copy"
"go/ast"
"go/token"
modfile "golang.org/x/mod/modfile"
"io/ioutil"
"os"
"os/exec"
"strings"
)
// NewProject Struct information required when creating a new project
type NewProject struct {
Name string
Module string
NewDir string
P2PRCPath string
CurrentModule string
Option *copy.Options
Token *token.FileSet
AST *ast.File
FileNameAST string
}
// GenerateNewProject creates a new copy of the P2PRC
// project for custom modification
func GenerateNewProject(name string, module string) error {
// Create new variable of type NewProject
var newProject NewProject
//Setting module name to the new project
newProject.Module = module
// Get path of the current directory
curDir, err := config.GetCurrentPath()
if err != nil {
return err
}
// Folder name of the new generated project
newProject.NewDir = curDir + name + "/"
// Create a new folder based on name entered
err = CreateFolder(name, curDir)
if err != nil {
return err
}
// get path of P2PRC
P2PRCPATH, err := config.GetPathP2PRC()
if err != nil {
return err
}
// Assign P2PRC path to the newly generated project
newProject.P2PRCPath = P2PRCPATH
// Steps:
// - copy all files from P2PRC
// - remove go.mod and go.sum and create new ones
// Files we require to skip
var Options copy.Options
// IF YOU ARE RELEASING AN EXTENSION OF P2PRC
// MODIFY HERE (AN EXTENSION FROM YOUR EXTENSION :P)
// Skip or have the appropriate files and directories not needed
//----------------------------------------------------------------
// Action performed:
// - Ensuring main.go file exists
// - Ensuring generate.go file exists
// - Ensuring modifyGenerate.go file exists
// - Ensuring generate_test.go file exists
// - Ensuring server/server.go file exists
// - Ensuring server/gopsutil.go file exists
// - Ensuring server/gpu.go file exists
// - Ensuring cmd/action.go file exists
// - Ensuring cmd/flags.go file exists
// - Skipping all .go files apart from the ones listed above
// - Skipping go.mod file
// - Skipping go.sum file
// - Skipping .idea/ directory
// - Skipping Makefile file
// - Skipping <Project Name>/ directory
//----------------------------------------------------------------
Options.Skip = func(src string) (bool, error) {
switch {
case strings.HasSuffix(src, "main.go"):
return false, nil
case strings.HasSuffix(src, "generate.go"):
return false, nil
case strings.HasSuffix(src, "modifyGenerate.go"):
return false, nil
case strings.HasSuffix(src, "generate_test.go"):
return false, nil
case strings.HasSuffix(src, "server/server.go"):
return false, nil
case strings.HasSuffix(src, "server/gopsutil.go"):
return false, nil
case strings.HasSuffix(src, "server/gpu.go"):
return false, nil
case strings.HasSuffix(src, "cmd/action.go"):
return false, nil
case strings.HasSuffix(src, "cmd/flags.go"):
return false, nil
case strings.HasSuffix(src, "config/config.go"):
return false, nil
case strings.HasSuffix(src, "config/config_test.go"):
return false, nil
case strings.HasSuffix(src, ".go"):
return true, nil
case strings.HasSuffix(src, "go.mod"):
return true, nil
case strings.HasSuffix(src, "go.sum"):
return true, nil
case strings.HasSuffix(src, ".idea"):
return true, nil
case strings.HasSuffix(src, "Makefile"):
return true, nil
case strings.HasSuffix(src, name):
return true, nil
default:
return false, nil
}
}
// Storing type option in the struct new project
newProject.Option = &Options
// Copies all files from P2PRC to the new project created
err = copy.Copy(newProject.P2PRCPath, newProject.NewDir, *newProject.Option)
if err != nil {
return err
}
// Creating a new go.mod file in the appropriate directory
err = newProject.CreateGoMod()
if err != nil {
return err
}
// Get current project mod name
err = newProject.GetCurrentGoModule()
if err != nil {
return err
}
// Change the appropriate imports
err = newProject.ChangeImportFiles()
if err != nil {
return err
}
// Add changes inside the new project
err = newProject.GitAdd()
if err != nil {
return err
}
// commit changes inside the new project
err = newProject.GitCommit()
if err != nil {
return err
}
// Creates go.sum file
//err = newProject.CreateGoModTidy()
//if err != nil {
// return err
//}
return nil
}
// CreateFolder Creates a new folder based on the name and path provided
func CreateFolder(name string, path string) error {
//Create a folder/directory at a full qualified path
err := os.Mkdir(path+name, 0755)
if err != nil {
return err
}
return nil
}
// CreateGoMod Creates a new go module for the new project created
func (a *NewProject) CreateGoMod() error {
// Create new go.mod in the appropriate directory
cmd := exec.Command("go", "mod", "init", a.Module)
cmd.Dir = a.NewDir
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func (a *NewProject) CreateGoModTidy() error {
// Installs all the appropriate dependencies and creates go.sum
cmd := exec.Command("go", "mod", "tidy")
cmd.Dir = a.NewDir
if err := cmd.Run(); err != nil {
return err
}
return nil
}
// ChangeImportFiles Changes Appropriate imports in the appropriate file
func (a *NewProject) ChangeImportFiles() error {
// IF YOU ARE RELEASING AN EXTENSION OF P2PRC
// MODIFY HERE (AN EXTENSION FROM YOUR EXTENSION :P)
//----------------------------------------------------------------
// Action performed:
// Files we would need to modify the imports in
// - generate/generate.go -> config module
// - generate/generate_test.go -> config module
// - cmd/action.go -> config module, server module, generate module
// - cmd/flags.go -> config module, server module, generate module
// - server/server.go -> config module
// - main.go -> cmd module
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// 1.0 - generate/generate.go -> config module
a.FileNameAST = a.NewDir + "generate/generate.go"
// Get AST information of the file
err := a.GetASTGoFile()
if err != nil {
return err
}
// Change the appropriate Go file
err = a.ChangeImports(a.CurrentModule+"/config", a.Module+"/config")
if err != nil {
return err
}
// Writes the change to the appropriate file
err = a.WriteGoAst()
if err != nil {
return err
}
//-----------------------------------------------------------------
// 1.1 - generate/generate_test.go -> config module
a.FileNameAST = a.NewDir + "generate/generate_test.go"
// Get AST information of the file
err = a.GetASTGoFile()
if err != nil {
return err
}
// Change the appropriate Go file
err = a.ChangeImports(a.CurrentModule+"/config", a.Module+"/config")
if err != nil {
return err
}
// Writes the change to the appropriate file
err = a.WriteGoAst()
if err != nil {
return err
}
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// 2.0 - cmd/action.go -> config module, server module, generate module
a.FileNameAST = a.NewDir + "cmd/action.go"
// Get AST information of the file
err = a.GetASTGoFile()
if err != nil {
return err
}
// Change the appropriate Go file
err = a.ChangeImports(a.CurrentModule+"/config", a.Module+"/config")
if err != nil {
return err
}
err = a.ChangeImports(a.CurrentModule+"/server", a.Module+"/server")
if err != nil {
return err
}
err = a.ChangeImports(a.CurrentModule+"/generate", a.Module+"/generate")
if err != nil {
return err
}
// Writes the change to the appropriate file
err = a.WriteGoAst()
if err != nil {
return err
}
//-----------------------------------------------------------------
// 2.1 - cmd/flags.go -> config module, server module, generate module
a.FileNameAST = a.NewDir + "cmd/flags.go"
// Get AST information of the file
err = a.GetASTGoFile()
if err != nil {
return err
}
// Change the appropriate Go file
err = a.ChangeImports(a.CurrentModule+"/config", a.Module+"/config")
if err != nil {
return err
}
err = a.ChangeImports(a.CurrentModule+"/server", a.Module+"/server")
if err != nil {
return err
}
err = a.ChangeImports(a.CurrentModule+"/generate", a.Module+"/generate")
if err != nil {
return err
}
// Writes the change to the appropriate file
err = a.WriteGoAst()
if err != nil {
return err
}
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// 3.0 - server/server.go -> config module
a.FileNameAST = a.NewDir + "server/server.go"
// Get AST information of the file
err = a.GetASTGoFile()
if err != nil {
return err
}
// Change the appropriate Go file
err = a.ChangeImports(a.CurrentModule+"/config", a.Module+"/config")
if err != nil {
return err
}
// Writes the change to the appropriate file
err = a.WriteGoAst()
if err != nil {
return err
}
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// 4.0 - server/server.go -> config module
a.FileNameAST = a.NewDir + "main.go"
// Get AST information of the file
err = a.GetASTGoFile()
if err != nil {
return err
}
// Change the appropriate Go file
err = a.ChangeImports(a.CurrentModule+"/cmd", a.Module+"/cmd")
if err != nil {
return err
}
// Writes the change to the appropriate file
err = a.WriteGoAst()
if err != nil {
return err
}
//-----------------------------------------------------------------
return nil
}
// GetCurrentGoModule Gets the current go module name
func (a *NewProject) GetCurrentGoModule() error {
goModBytes, err := ioutil.ReadFile(a.P2PRCPath + "go.mod")
if err != nil {
return err
}
modName := modfile.ModulePath(goModBytes)
fmt.Fprintf(os.Stdout, "modName=%+v\n", modName)
// Set current module to struct of file NewProject
a.CurrentModule = modName
return nil
}
func (a *NewProject) GitAdd() error {
// Installs all the appropriate dependencies and creates go.sum
cmd := exec.Command("git", "add", ".")
cmd.Dir = a.NewDir
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func (a *NewProject) GitCommit() error {
// Installs all the appropriate dependencies and creates go.sum
cmd := exec.Command("git", "commit", "-m=removed appropriate go files")
cmd.Dir = a.NewDir
if err := cmd.Run(); err != nil {
return err
}
return nil
}

View File

@@ -1,112 +0,0 @@
package generate
import (
"fmt"
"github.com/Akilan1999/p2p-rendering-computation/config"
"testing"
)
// Tests the create folder function creates a folder
// This test will create a folder in the temporary
// directory
func TestCreateFolder(t *testing.T) {
err := CreateFolder("test", "/tmp/")
if err != nil {
t.Error(err)
}
}
// Testing if a new project is created successfully
func TestGenerateNewProject(t *testing.T) {
// Checking if a new project is created successfully
err := GenerateNewProject("p2prctest", "p2prctest")
if err != nil {
fmt.Println(err)
t.Error(err)
}
}
// Testing AST function to ensure imports are
// working as intended
func TestChangingImportAST(t *testing.T) {
// Create a new variable of type NewProject
var np NewProject
// Get current directory
path, err := config.GetCurrentPath()
if err != nil {
fmt.Println(err)
t.Error(err)
}
// Create testcase scenario
err = config.Copy(path+"testcaseAST.go", path+"/Test/testcaseAST.go")
if err != nil {
fmt.Println(err)
t.Error(err)
}
// Sets new directory to the folder test
np.NewDir = path + "Test/"
// Sets file name to be opened and modified in the AST
np.FileNameAST = path + "Test/" + "testcaseAST.go"
// Call the Read AST function
err = np.GetASTGoFile()
if err != nil {
fmt.Println(err)
t.Error(err)
}
// Change an import
err = np.ChangeImports("fmt", "lolol")
if err != nil {
fmt.Println(err)
t.Error(err)
}
// Write those saved changes
err = np.WriteGoAst()
if err != nil {
fmt.Println(err)
t.Error(err)
}
}
// Testing the if Go Mod is created
func TestNewProject_CreateGoMod(t *testing.T) {
// Create a new variable of type NewProject
var np NewProject
path, err := config.GetCurrentPath()
if err != nil {
fmt.Println(err)
t.Error(err)
}
// Set new project name as Test
np.Name = "Test"
// Set new project module as github.com/Test
np.Module = "github.com/Test"
// Set Path of the new project
np.NewDir = path + "Test/"
// Creating a go.mod file
err = np.CreateGoMod()
if err != nil {
fmt.Println(err)
t.Error(err)
}
}
// Testing if the current go module is returned
func TestNewProject_GetCurrentGoModule(t *testing.T) {
// Create a new variable of type NewProject
var np NewProject
path, err := config.GetPathP2PRC()
if err != nil {
fmt.Println(err)
t.Error(err)
}
// Set Current project path
np.P2PRCPath = path
// Get module name
err = np.GetCurrentGoModule()
if err != nil {
fmt.Println(err)
t.Error(err)
}
fmt.Println(np.CurrentModule)
}

View File

@@ -1,49 +0,0 @@
package generate
import (
"go/parser"
"go/printer"
"go/token"
"os"
)
// GetASTGoFile Gets AST of the Go file provided
func (np *NewProject)GetASTGoFile() error{
fset := token.NewFileSet()
node, err := parser.ParseFile(fset, np.FileNameAST, nil, parser.ParseComments)
if err != nil {
return err
}
//Write Token information to the struct
np.Token = fset
// Write AST information the struct
np.AST = node
return nil
}
// ChangeImports Changes import of the AST
func (np *NewProject)ChangeImports(CurrentImport string,ChangedImport string) error {
// Iterating through the loop and changing the appropriate import
for i, spec := range np.AST.Imports {
// If the current import is found then change it
if spec.Path.Value == "\"" + CurrentImport + "\"" {
np.AST.Imports[i].Path.Value = "\"" + ChangedImport + "\""
}
}
return nil
}
// WriteGoAst Write changed imports back to the AST
func (np *NewProject)WriteGoAst() error {
// write new AST to file
f, err := os.Create(np.FileNameAST)
if err != nil {
return nil
}
defer f.Close()
if err := printer.Fprint(f, np.Token, np.AST); err != nil {
return err
}
return nil
}

View File

@@ -1,9 +0,0 @@
package generate
import (
"fmt"
)
func TestCaseAST() {
fmt.Println("lol")
}

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() 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() 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() 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() 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() 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() 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() 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() 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() 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)
} }
} }

BIN
server/.DS_Store vendored Normal file

Binary file not shown.

BIN
server/docker/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -1,7 +0,0 @@
Containers
===========
Structure
|_ Containers
|_ <name> (To ensure the name is the same as the tag name)
|_ DockerFile

View File

@@ -1,43 +0,0 @@
from horovod/horovod-cpu
# Switch to root user to install additional software
USER 0
# Make sure we don't get notifications we can't answer during building.
env DEBIAN_FRONTEND noninteractive
run apt-get -q -y update; apt-get -q -y upgrade
run apt install net-tools
# Prepare scripts and configs
add ./scripts/start /start
# Set root password
run echo 'root:password' >> /root/passwdfile
# Create user and it's password
run useradd -m -G sudo master && \
echo 'master:password' >> /root/passwdfile
# Apply root password
run chpasswd -c SHA512 < /root/passwdfile && \
rm /root/passwdfile
# Port 22 is used for ssh
expose 22
# Assign /data as static volume.
volume ["/data"]
# Fix all permissions
run chmod +x /start
# Starting sshd
cmd ["/start"]

View File

@@ -1 +0,0 @@
Running official horovod dockerfile cpu version

View File

@@ -1,11 +0,0 @@
#!/bin/bash
# -----------------------------------------------------------------------------
# docker-ubuntu-sshd /start script
#
# Authors: Art567
# Updated: Sep 20th, 2015
# -----------------------------------------------------------------------------
# Run OpenSSH server in daemon mode
/usr/sbin/sshd -D

View File

@@ -1,61 +0,0 @@
# -----------------------------------------------------------------------------
# This is base image of Ubuntu LTS with SSHD service.
#
# Authors: Art567
# Updated: Sep 20th, 2015
# Require: Docker (http://www.docker.io/)
# -----------------------------------------------------------------------------
# Base system is the latest LTS version of Ubuntu.
# from consol/ubuntu-xfce-vnc
# due to dependency issues vnc is still work in progress
from ubuntu:20.04
# Switch to root user to install additional software
USER 0
# Make sure we don't get notifications we can't answer during building.
env DEBIAN_FRONTEND noninteractive
# Prepare scripts and configs
add ./scripts/start /start
# Download and install everything from the repos.
run apt-get -q -y update; apt-get -q -y upgrade && \
apt-get -q -y install sudo openssh-server && \
mkdir /var/run/sshd
# Set root password
run echo 'root:password' >> /root/passwdfile
# Create user and it's password
run useradd -m -G sudo master && \
echo 'master:password' >> /root/passwdfile
# Apply root password
run chpasswd -c SHA512 < /root/passwdfile && \
rm /root/passwdfile
# Port 22 is used for ssh
expose 22
# Assign /data as static volume.
volume ["/data"]
# Fix all permissions
run chmod +x /start
# Starting sshd
cmd ["/start"]

View File

@@ -1,72 +0,0 @@
Ubuntu LTS with SSH (Docker)
=========
A Docker file to build a [docker.io] base container with Ubuntu LTS and a sshd service
[docker.io]: http://docker.io
Nice and easy way to get any server up and running using docker
Instructions
-----------
- Install Docker first.
Read [installation instructions] (http://docs.docker.io/en/latest/installation/).
- Clone this repository:
`$ git clone https://github.com/art567/docker-ubuntu-sshd.git`
- Enter local directory:
`$ cd docker-ubuntu-sshd`
- Change passwords in Dockerfile:
`$ vi Dockerfile`
- Build the container:
`$ sudo docker build -t art567/ubuntu .`
- Run the container:
`$ sudo docker run -d=true --name=ubuntu --restart=always -p=2222:22 -v=/opt/data:/data art567/ubuntu /start`
- Your container will start and bind ssh to 2222 port.
- Find your local IP Address:
`$ ifconfig`
- Connect to the SSH server:
`$ ssh root@<ip-address> -p 2222`
- If you don't want to deal with root:
`$ ssh master@<ip-address> -p 2222`
**VERY IMPORTANT!!!**
-----------
**Don't forget to change passwords in Dockerfile before building image!**
Versions
-----------
Some branches represents Ubuntu versions.
Branch `master` is always represented by latest Ubuntu LTS
For example:
- 12.04 - Ubuntu 12.04 LTS
- 14.04 - Ubuntu 14.04 LTS
- 16.04 - Ubuntu 16.04 LTS

View File

@@ -1 +0,0 @@
Simple Ubuntu 20.04 image

View File

@@ -1,16 +0,0 @@
{
"Port": [
{
"PortName": "SSH",
"InternalPort": 22,
"Type": "tcp",
"Description": "SSH Port"
},
{
"PortName": "VNC",
"InternalPort": 5900,
"Type": "tcp",
"Description": "VNC port"
}
]
}

View File

@@ -1,14 +0,0 @@
#!/bin/bash
# -----------------------------------------------------------------------------
# docker-ubuntu-sshd /start script
#
# Authors: Art567
# Updated: Sep 20th, 2015
# -----------------------------------------------------------------------------
# Run OpenSSH server in daemon mode
/usr/sbin/sshd -D
# Running x11 server with password

View File

@@ -1,61 +0,0 @@
# -----------------------------------------------------------------------------
# This is base image of Ubuntu LTS with SSHD service.
#
# Authors: Art567
# Updated: Sep 20th, 2015
# Require: Docker (http://www.docker.io/)
# -----------------------------------------------------------------------------
# Base system is the latest LTS version of Ubuntu.
# from consol/ubuntu-xfce-vnc
# due to dependency issues vnc is still work in progress
from ubuntu:20.04
# Switch to root user to install additional software
USER 0
# Make sure we don't get notifications we can't answer during building.
env DEBIAN_FRONTEND noninteractive
# Prepare scripts and configs
add ./scripts/start /start
# Download and install everything from the repos.
run apt-get -q -y update; apt-get -q -y upgrade && \
apt-get -q -y install sudo openssh-server && \
mkdir /var/run/sshd
# Set root password
run echo 'root:password' >> /root/passwdfile
# Create user and it's password
run useradd -m -G sudo master && \
echo 'master:password' >> /root/passwdfile
# Apply root password
run chpasswd -c SHA512 < /root/passwdfile && \
rm /root/passwdfile
# Port 22 is used for ssh
expose 22
# Assign /data as static volume.
volume ["/data"]
# Fix all permissions
run chmod +x /start
# Starting sshd
cmd ["/start"]

View File

@@ -1,72 +0,0 @@
Ubuntu LTS with SSH (Docker)
=========
A Docker file to build a [docker.io] base container with Ubuntu LTS and a sshd service
[docker.io]: http://docker.io
Nice and easy way to get any server up and running using docker
Instructions
-----------
- Install Docker first.
Read [installation instructions] (http://docs.docker.io/en/latest/installation/).
- Clone this repository:
`$ git clone https://github.com/art567/docker-ubuntu-sshd.git`
- Enter local directory:
`$ cd docker-ubuntu-sshd`
- Change passwords in Dockerfile:
`$ vi Dockerfile`
- Build the container:
`$ sudo docker build -t art567/ubuntu .`
- Run the container:
`$ sudo docker run -d=true --name=ubuntu --restart=always -p=2222:22 -v=/opt/data:/data art567/ubuntu /start`
- Your container will start and bind ssh to 2222 port.
- Find your local IP Address:
`$ ifconfig`
- Connect to the SSH server:
`$ ssh root@<ip-address> -p 2222`
- If you don't want to deal with root:
`$ ssh master@<ip-address> -p 2222`
**VERY IMPORTANT!!!**
-----------
**Don't forget to change passwords in Dockerfile before building image!**
Versions
-----------
Some branches represents Ubuntu versions.
Branch `master` is always represented by latest Ubuntu LTS
For example:
- 12.04 - Ubuntu 12.04 LTS
- 14.04 - Ubuntu 14.04 LTS
- 16.04 - Ubuntu 16.04 LTS

View File

@@ -1 +0,0 @@
Simple Ubuntu 20.04 image

View File

@@ -1,22 +0,0 @@
{
"Port": [
{
"PortName": "SSH",
"InternalPort": 22,
"Type": "tcp",
"Description": "SSH Port"
},
{
"PortName": "NoVNC",
"InternalPort": 5901,
"Type": "tcp",
"Description": "NoVNC port"
},
{
"PortName": "NoVNC",
"InternalPort": 6081,
"Type": "tcp",
"Description": "NoVNC port"
}
]
}

View File

@@ -1,11 +0,0 @@
#!/bin/bash
# -----------------------------------------------------------------------------
# docker-ubuntu-sshd /start script
#
# Authors: Art567
# Updated: Sep 20th, 2015
# -----------------------------------------------------------------------------
# Run OpenSSH server in daemon mode
/usr/sbin/sshd -D

View File

@@ -1,41 +0,0 @@
from horovod/horovod
# Switch to root user to install additional software
USER 0
# Make sure we don't get notifications we can't answer during building.
env DEBIAN_FRONTEND noninteractive
# Prepare scripts and configs
add ./scripts/start /start
# Set root password
run echo 'root:password' >> /root/passwdfile
# Create user and it's password
run useradd -m -G sudo master && \
echo 'master:password' >> /root/passwdfile
# Apply root password
run chpasswd -c SHA512 < /root/passwdfile && \
rm /root/passwdfile
# Port 22 is used for ssh
expose 22
# Assign /data as static volume.
volume ["/data"]
# Fix all permissions
run chmod +x /start
# Starting sshd
cmd ["/start"]

View File

@@ -1 +0,0 @@
Running official horovod dockerfile cpu version

View File

@@ -1,11 +0,0 @@
#!/bin/bash
# -----------------------------------------------------------------------------
# docker-ubuntu-sshd /start script
#
# Authors: Art567
# Updated: Sep 20th, 2015
# -----------------------------------------------------------------------------
# Run OpenSSH server in daemon mode
/usr/sbin/sshd -D

View File

@@ -1,61 +0,0 @@
# -----------------------------------------------------------------------------
# This is base image of Ubuntu LTS with SSHD service.
#
# Authors: Art567
# Updated: Sep 20th, 2015
# Require: Docker (http://www.docker.io/)
# -----------------------------------------------------------------------------
# Base system is the latest LTS version of Ubuntu.
# from consol/ubuntu-xfce-vnc
# due to dependency issues vnc is still work in progress
from dorowu/ubuntu-desktop-lxde-vnc
# Switch to root user to install additional software
USER 0
# Make sure we don't get notifications we can't answer during building.
env DEBIAN_FRONTEND noninteractive
# Prepare scripts and configs
add ./scripts/start /start
# Download and install everything from the repos.
run apt-get -q -y update; apt-get -q -y upgrade && \
apt-get -q -y install sudo openssh-server && \
mkdir /var/run/sshd
# Set root password
run echo 'root:password' >> /root/passwdfile
# Create user and it's password
run useradd -m -G sudo master && \
echo 'master:password' >> /root/passwdfile
# Apply root password
run chpasswd -c SHA512 < /root/passwdfile && \
rm /root/passwdfile
# Port 22 is used for ssh
expose 22
# Assign /data as static volume.
volume ["/data"]
# Fix all permissions
run chmod +x /start
# Starting sshd
cmd ["/start"]

View File

@@ -1,72 +0,0 @@
Ubuntu LTS with SSH (Docker)
=========
A Docker file to build a [docker.io] base container with Ubuntu LTS and a sshd service
[docker.io]: http://docker.io
Nice and easy way to get any server up and running using docker
Instructions
-----------
- Install Docker first.
Read [installation instructions] (http://docs.docker.io/en/latest/installation/).
- Clone this repository:
`$ git clone https://github.com/art567/docker-ubuntu-sshd.git`
- Enter local directory:
`$ cd docker-ubuntu-sshd`
- Change passwords in Dockerfile:
`$ vi Dockerfile`
- Build the container:
`$ sudo docker build -t art567/ubuntu .`
- Run the container:
`$ sudo docker run -d=true --name=ubuntu --restart=always -p=2222:22 -v=/opt/data:/data art567/ubuntu /start`
- Your container will start and bind ssh to 2222 port.
- Find your local IP Address:
`$ ifconfig`
- Connect to the SSH server:
`$ ssh root@<ip-address> -p 2222`
- If you don't want to deal with root:
`$ ssh master@<ip-address> -p 2222`
**VERY IMPORTANT!!!**
-----------
**Don't forget to change passwords in Dockerfile before building image!**
Versions
-----------
Some branches represents Ubuntu versions.
Branch `master` is always represented by latest Ubuntu LTS
For example:
- 12.04 - Ubuntu 12.04 LTS
- 14.04 - Ubuntu 14.04 LTS
- 16.04 - Ubuntu 16.04 LTS

View File

@@ -1 +0,0 @@
Simple Ubuntu 20.04 image

View File

@@ -1,11 +0,0 @@
#!/bin/bash
# -----------------------------------------------------------------------------
# docker-ubuntu-sshd /start script
#
# Authors: Art567
# Updated: Sep 20th, 2015
# -----------------------------------------------------------------------------
# Run OpenSSH server in daemon mode
/usr/sbin/sshd -D

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() 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() 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,50 +1,50 @@
package server package server
import ( import (
"github.com/shirou/gopsutil/v3/cpu" "github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/disk" "github.com/shirou/gopsutil/v3/disk"
"github.com/shirou/gopsutil/v3/host" "github.com/shirou/gopsutil/v3/host"
"github.com/shirou/gopsutil/v3/mem" "github.com/shirou/gopsutil/v3/mem"
) )
// SysInfo saves the basic system information // SysInfo saves the basic system information
type SysInfo struct { type SysInfo struct {
Hostname string `bson:hostname` Hostname string `bson:hostname`
Platform string `bson:platform` Platform string `bson:platform`
CPU string `bson:cpu` CPU string `bson:cpu`
RAM uint64 `bson:ram` RAM uint64 `bson:ram`
Disk uint64 `bson:disk` Disk uint64 `bson:disk`
GPU *Query `xml: GpuInfo` GPU *Query `xml: GpuInfo`
} }
func ServerInfo() interface{} { func ServerInfo() *SysInfo {
hostStat, _ := host.Info() hostStat, _ := host.Info()
cpuStat, _ := cpu.Info() cpuStat, _ := cpu.Info()
vmStat, _ := mem.VirtualMemory() vmStat, _ := mem.VirtualMemory()
info := new(SysInfo) info := new(SysInfo)
filesystem := "/" filesystem := "/"
// If the server is running windows // If the server is running windows
if info.Hostname == "windows" { if info.Hostname == "windows" {
filesystem = "\\" filesystem = "\\"
} }
diskStat, _ := disk.Usage(filesystem) // If you're in Unix change this "\\" for "/" diskStat, _ := disk.Usage(filesystem) // If you're in Unix change this "\\" for "/"
info.Hostname = hostStat.Hostname info.Hostname = hostStat.Hostname
info.Platform = hostStat.Platform info.Platform = hostStat.Platform
info.CPU = cpuStat[0].ModelName info.CPU = cpuStat[0].ModelName
info.RAM = vmStat.Total / 1024 / 1024 info.RAM = vmStat.Total / 1024 / 1024
info.Disk = diskStat.Total / 1024 / 1024 info.Disk = diskStat.Total / 1024 / 1024
gpu, err := GPUInfo() gpu, err := GPUInfo()
if err == nil { if err == nil {
info.GPU = gpu info.GPU = gpu
} }
return info return info
} }

View File

@@ -1,229 +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() 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() config, err := config.ConfigInit(nil, nil)
if err != nil { if err != nil {
return 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 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 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 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
err = r.Run(":" + config.ServerPort) go r.Run(":" + config.ServerPort)
if err != nil {
return err
}
return nil return r, nil
} }