Compare commits
5 Commits
haskell-bi
...
untracked-
| Author | SHA1 | Date | |
|---|---|---|---|
| d2d1b5bc9f | |||
| 888ad8acb7 | |||
| e5d4381fd9 | |||
| c7be50d3b7 | |||
| 1c06d5b882 |
25
.gitignore
vendored
25
.gitignore
vendored
@@ -11,30 +11,23 @@ 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/
|
||||||
# Ignore any sort of logs
|
|
||||||
logs/
|
|
||||||
|
|
||||||
# ignore docker image files
|
#MACOS .idea file
|
||||||
server/docker/containers/
|
.DS_Store
|
||||||
*.h
|
.gitkeep
|
||||||
*.so
|
|
||||||
|
|
||||||
# generic folder to ignore
|
|
||||||
export/
|
|
||||||
|
|
||||||
# Any testing file
|
|
||||||
test*
|
|
||||||
|
|
||||||
# Ignore public and private keys
|
|
||||||
p2prc.publicKey
|
|
||||||
p2prc.privateKey
|
|
||||||
|
|||||||
@@ -1,170 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/abstractions"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The Client package where data-types
|
|
||||||
// are manually converted to the
|
|
||||||
// to a string so that it can
|
|
||||||
// be export
|
|
||||||
|
|
||||||
// --------------------------------- Container Control ----------------------------------------
|
|
||||||
|
|
||||||
//export StartContainer
|
|
||||||
func StartContainer(IP *C.char) (output *C.char) {
|
|
||||||
container, err := abstractions.StartContainer(C.GoString(IP))
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
return ConvertStructToJSONString(container)
|
|
||||||
}
|
|
||||||
|
|
||||||
//export RemoveContainer
|
|
||||||
func RemoveContainer(IP *C.char, ID *C.char) (output *C.char) {
|
|
||||||
err := abstractions.RemoveContainer(C.GoString(IP), C.GoString(ID))
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
return C.CString("Success")
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------- Plugin Control ----------------------------------------
|
|
||||||
|
|
||||||
// DEPRECATED
|
|
||||||
////export ViewPlugin
|
|
||||||
//func ViewPlugin() (output *C.char) {
|
|
||||||
// plugins, err := plugin.DetectPlugins()
|
|
||||||
// if err != nil {
|
|
||||||
// return C.CString(err.Error())
|
|
||||||
// }
|
|
||||||
// return ConvertStructToJSONString(plugins)
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
////export PullPlugin
|
|
||||||
//func PullPlugin(pluginUrl string) (output *C.char) {
|
|
||||||
// err := plugin.DownloadPlugin(pluginUrl)
|
|
||||||
// if err != nil {
|
|
||||||
// return C.CString(err.Error())
|
|
||||||
// }
|
|
||||||
// return C.CString("Success")
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
////export DeletePlugin
|
|
||||||
//func DeletePlugin(pluginName string) (output *C.char) {
|
|
||||||
// err := plugin.DeletePlugin(pluginName)
|
|
||||||
// if err != nil {
|
|
||||||
// return C.CString(err.Error())
|
|
||||||
// }
|
|
||||||
// return C.CString("Success")
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
////export ExecutePlugin
|
|
||||||
//func ExecutePlugin(pluginname string, ContainerID string) (output *C.char) {
|
|
||||||
// err := plugin.RunPluginContainer(pluginname, ContainerID)
|
|
||||||
// if err != nil {
|
|
||||||
// return C.CString(err.Error())
|
|
||||||
// }
|
|
||||||
// return C.CString("Success")
|
|
||||||
//}
|
|
||||||
|
|
||||||
// --------------------------------- Get Specs ----------------------------------------
|
|
||||||
|
|
||||||
//export GetSpecs
|
|
||||||
func GetSpecs(IP *C.char) (output *C.char) {
|
|
||||||
specs, err := abstractions.GetSpecs(C.GoString(IP))
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
return ConvertStructToJSONString(specs)
|
|
||||||
}
|
|
||||||
|
|
||||||
//export Init
|
|
||||||
func Init(customConfig *C.char) (output *C.char) {
|
|
||||||
init, err := abstractions.Init(C.GoString(customConfig))
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
return ConvertStructToJSONString(init)
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------- P2P Controls -----------------------------------
|
|
||||||
|
|
||||||
//export ViewIPTable
|
|
||||||
func ViewIPTable() (output *C.char) {
|
|
||||||
table, err := abstractions.ViewIPTable()
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
return ConvertStructToJSONString(table)
|
|
||||||
}
|
|
||||||
|
|
||||||
//export UpdateIPTable
|
|
||||||
func UpdateIPTable() (output *C.char) {
|
|
||||||
err := abstractions.UpdateIPTable()
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
return C.CString("Success")
|
|
||||||
}
|
|
||||||
|
|
||||||
//export EscapeFirewall
|
|
||||||
func EscapeFirewall(HostOutsideNATIP *C.char, HostOutsideNATPort *C.char, internalPort *C.char) (output *C.char) {
|
|
||||||
// Get free port from P2PRC server node
|
|
||||||
serverPort, err := frp.GetFRPServerPort("http://" + C.GoString(HostOutsideNATIP) + ":" + C.GoString(HostOutsideNATPort))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(5 * time.Second)
|
|
||||||
|
|
||||||
ExposedPort, err := frp.StartFRPClientForServer(C.GoString(HostOutsideNATIP)+":"+C.GoString(HostOutsideNATPort), serverPort, C.GoString(internalPort), "")
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return C.CString(ExposedPort)
|
|
||||||
}
|
|
||||||
|
|
||||||
//export MapPort
|
|
||||||
func MapPort(Port *C.char) *C.char {
|
|
||||||
fmt.Println(C.GoString(Port))
|
|
||||||
entireAddress, _, err := abstractions.MapPort(C.GoString(Port))
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
return C.CString(entireAddress)
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------- Controlling Server ----------------------------------------
|
|
||||||
|
|
||||||
//export Server
|
|
||||||
func Server() (output *C.char) {
|
|
||||||
_, err := abstractions.Start()
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return ConvertStructToJSONString("")
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------- Helper Functions ----------------------------------------
|
|
||||||
|
|
||||||
func ConvertStructToJSONString(Struct interface{}) *C.char {
|
|
||||||
jsonBytes, err := json.Marshal(Struct)
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the JSON bytes to a string
|
|
||||||
return C.CString(string(jsonBytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {}
|
|
||||||
BIN
Bindings/python/.DS_Store
vendored
BIN
Bindings/python/.DS_Store
vendored
Binary file not shown.
@@ -1,11 +0,0 @@
|
|||||||
import ctypes
|
|
||||||
|
|
||||||
p2prc = ctypes.CDLL("SharedOBjects/p2prc.so")
|
|
||||||
|
|
||||||
p2prc.Init("")
|
|
||||||
|
|
||||||
def StartServer():
|
|
||||||
# Starting P2PRC as a server mode
|
|
||||||
p2prc.Server()
|
|
||||||
for _ in iter(int, 1):
|
|
||||||
pass
|
|
||||||
@@ -5,5 +5,5 @@ authors:
|
|||||||
given-names: Akilan
|
given-names: Akilan
|
||||||
title: P2PRC
|
title: P2PRC
|
||||||
license: "GPL-2.0"
|
license: "GPL-2.0"
|
||||||
version: 2.0.0
|
version: 1.0.0
|
||||||
date-released: 2023-06-08
|
date-released: 2021-07-22
|
||||||
|
|||||||
BIN
Docs/.DS_Store
vendored
BIN
Docs/.DS_Store
vendored
Binary file not shown.
@@ -1,20 +0,0 @@
|
|||||||
# Abstractions
|
|
||||||
|
|
||||||
| [◀ Previous](Installation.md) | [Next ▶](Implementation.md) |
|
|
||||||
|:-----------:|---------|
|
|
||||||
|
|
||||||
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.
|
|
||||||
- ```MapPort(<port no>)```: On the local machine the port you want to export to world.
|
|
||||||
- ```StartContainer(<ip address>)```: The machine on the p2p network where you want to spin up a docker container.
|
|
||||||
- ```RemoveContainer(<ip address>,<container id>)```: Terminate container based on the IP address and container name.
|
|
||||||
- ```GetSpecs(<ip address>)```: Get specs of a machine on the network based on the IP address.
|
|
||||||
- ```ViewIPTable()```: View the IP table which about nodes in the network.
|
|
||||||
- ```UpdateIPTable()```: Force update IP table to learn about new nodes faster.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Next Chapter: [Implementation](Implementation.md)
|
|
||||||
139
Docs/Bindings.md
139
Docs/Bindings.md
@@ -1,139 +0,0 @@
|
|||||||
# Language Bindings
|
|
||||||
[Language bindings](https://en.wikipedia.org/wiki/Language_binding) refers to wrappers to bridge 2 programming languages. This is used in P2PRC to extend calling P2PRC functions in other programming languages. Currently this is done by generating ```.so``` and ```.h``` from the Go compiler.
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## How to build shared object files
|
|
||||||
#### The easier way
|
|
||||||
```bash
|
|
||||||
# Run
|
|
||||||
make sharedObjects
|
|
||||||
```
|
|
||||||
#### Or the direct way
|
|
||||||
```bash
|
|
||||||
# Run
|
|
||||||
cd Bindings && go build -buildmode=c-shared -o p2prc.so
|
|
||||||
```
|
|
||||||
#### If successfully built:
|
|
||||||
```bash
|
|
||||||
# Enter into the Bindings directory
|
|
||||||
cd Bindings
|
|
||||||
# List files
|
|
||||||
ls
|
|
||||||
# Find files
|
|
||||||
p2prc.h p2prc.so
|
|
||||||
```
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## Workings under the hood
|
|
||||||
Below are a sample set of commands to
|
|
||||||
open the bindings implementation.
|
|
||||||
```
|
|
||||||
# run
|
|
||||||
cd Bindings/
|
|
||||||
# list files
|
|
||||||
ls
|
|
||||||
# search for file
|
|
||||||
Client.go
|
|
||||||
```
|
|
||||||
### In Client go
|
|
||||||
There a few things to notice which are different from
|
|
||||||
your standard Go programs:
|
|
||||||
|
|
||||||
#### 1. We import "C" which means [Cgo](https://pkg.go.dev/cmd/cgo) is required.
|
|
||||||
```go
|
|
||||||
import "C"
|
|
||||||
```
|
|
||||||
#### 2. All functions which are required to be called from other programming languages have comment such as.
|
|
||||||
```go
|
|
||||||
//export <function name>
|
|
||||||
|
|
||||||
// ------------ Example ----------------
|
|
||||||
// The function below allows to externally
|
|
||||||
// to call the P2PRC function to start containers
|
|
||||||
// in a specific node in the know list of nodes
|
|
||||||
// in the p2p network.
|
|
||||||
// Note: the comment "//export StartContainer".
|
|
||||||
|
|
||||||
//export StartContainer
|
|
||||||
func StartContainer(IP string) (output *C.char) {
|
|
||||||
container, err := client.StartContainer(IP, 0, false, "", "")
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
return ConvertStructToJSONString(container)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
#### 3. While looking through the file (If 2 files are compared it is pretty trivial to notice a common structure).
|
|
||||||
```go
|
|
||||||
// --------- Example ------------
|
|
||||||
|
|
||||||
//export StartContainer
|
|
||||||
func StartContainer(IP string) (output *C.char) {
|
|
||||||
container, err := client.StartContainer(IP, 0, false, "", "")
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
return ConvertStructToJSONString(container)
|
|
||||||
}
|
|
||||||
|
|
||||||
//export ViewPlugin
|
|
||||||
func ViewPlugin() (output *C.char) {
|
|
||||||
plugins, err := plugin.DetectPlugins()
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(err.Error())
|
|
||||||
}
|
|
||||||
return ConvertStructToJSONString(plugins)
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
#### It is easy to notice that:
|
|
||||||
- ```ConvertStructToJSONString(<go object>)```: This is a helper function that convert
|
|
||||||
a go object to JSON string initially and converts it to ```CString```.
|
|
||||||
- ```(output *C.char)```: This is the return type for most of the functions.
|
|
||||||
|
|
||||||
#### A Pseudo code to refer to the common function implementation shape could be represented as:
|
|
||||||
```
|
|
||||||
func <Function name> (output *C.char) {
|
|
||||||
<response>,<error> := <P2PRC function name>(<parameters if needed>)
|
|
||||||
if <error> != nil {
|
|
||||||
return C.CString(<error>.Error())
|
|
||||||
}
|
|
||||||
return ConvertStructToJSONString(<response>)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
|
|
||||||
## Current languages supported
|
|
||||||
- Python
|
|
||||||
|
|
||||||
### Build sample python program
|
|
||||||
The easier way
|
|
||||||
```bash
|
|
||||||
# Run
|
|
||||||
make python
|
|
||||||
# Expected ouput
|
|
||||||
Output is in the Directory Bindings/python/export/
|
|
||||||
# Run
|
|
||||||
cd Bindings/python/export/
|
|
||||||
# list files
|
|
||||||
ls
|
|
||||||
# Expected output
|
|
||||||
SharedObjects/ p2prc.py
|
|
||||||
```
|
|
||||||
Above shows a generated folder which consists of a folder
|
|
||||||
called "SharedObjects/" which consists of ```p2prc.so```
|
|
||||||
and ```p2prc.h``` files. ```p2prc.py``` refers to a
|
|
||||||
sample python script calling P2PRC go functions.
|
|
||||||
To start an any project to extend P2PRC with python,
|
|
||||||
This generated folder can copied and created as a new
|
|
||||||
git repo for P2PRC extensions scripted or used a reference
|
|
||||||
point as proof of concept that P2PRC can be called from
|
|
||||||
other programming languages.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ commands as possible. The cli was built using the library called urfave cli v2 .
|
|||||||
major files created named as flags.go and actions.go.
|
major files created named as flags.go and actions.go.
|
||||||
### Flags.go
|
### Flags.go
|
||||||
The flags .go file is responsible to create the appropriate flags for the cli. There are 2 types of flags
|
The flags .go file is responsible to create the appropriate flags for the cli. There are 2 types of flags
|
||||||
called boolean and string. Each of the flags outputs are assigned to a
|
called boolean and string as described in Fig 5.3.1. Each of the flags outputs are assigned to a
|
||||||
variable to be handled. The flags can also detect environment variables set. This feature is useful
|
variable to be handled. The flags can also detect environment variables set. This feature is useful
|
||||||
because if the user wants to call certain flags in a repeated sequence it only has to be initialized
|
because if the user wants to call certain flags in a repeated sequence it only has to be initialized
|
||||||
once.
|
once.
|
||||||
@@ -14,4 +14,4 @@ once.
|
|||||||
### Actions.go
|
### Actions.go
|
||||||
The actions.go file is implemented to call the appropriate functions when the flags are called. It
|
The actions.go file is implemented to call the appropriate functions when the flags are called. It
|
||||||
interacts directly with the modules in the project. Action.go checks if variables
|
interacts directly with the modules in the project. Action.go checks if variables
|
||||||
are not empty string or the boolean value is true.
|
are not empty string or the boolean value is true.
|
||||||
@@ -1,13 +1,25 @@
|
|||||||
# Client Module
|
# Client Module
|
||||||
This module is incharge of communicating with the server and receiving the appropriate information back from the server.
|
This module is incharge of communicating with the server and receiving the appropriate information back from the server.
|
||||||
|
Note: To [read more about the functions](https://pkg.go.dev/git.sr.ht/~akilan1999/p2p-rendering-computation@v0.0.0-20210404191839-6a046babcb02/client)
|
||||||
|
|
||||||
## Functions of the Client Module
|
## Functions of the Client Module
|
||||||
<!-- - [Interact with the Server Api](#functions-of-the-client-module) -->
|
- [Interact with the Server Api](#functions-of-the-client-module)
|
||||||
- [Decision maker on how the ip table is created or updated](#decision-maker-on-how-the-ip-table-is-created-or-updated)
|
- [Decision maker on how the ip table is created or updated](#decision-maker-on-how-the-ip-table-is-created-or-updated)
|
||||||
|
|
||||||
|
|
||||||
|
## Interact with the Server Api
|
||||||
|
This sections talks about the functionality implemented till now.
|
||||||
|
- The client can start docker containers using the function StartContainer.
|
||||||
|
This functions calls the route:
|
||||||
|
```
|
||||||
|
http://<server IP address>:<server port>/startcontainer
|
||||||
|
```
|
||||||
|
TODO: Outputs and how it's printed
|
||||||
|
|
||||||
## Decision maker on how the IP table is created or updated
|
## Decision maker on how the IP table is created or updated
|
||||||
- Does a local speedtest to verify and see if the server IP's in the IP table
|
- Does a local speedtest to verify and see if the server IP's in the IP table
|
||||||
are pingable.
|
are pingable.
|
||||||
|
- Downloads the Servers IP table.
|
||||||
- Tries to ping the servers IP Table addresses.
|
- Tries to ping the servers IP Table addresses.
|
||||||
- If it's pingable then it's added as a new entry in the IP table.
|
- If it's pingable then it's added as a new entry in the IP table.
|
||||||
- The following steps occurs in the clients IP table.
|
- The following steps occurs in the clients IP table.
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
# Client Module Implementation
|
# Client Module Implementation
|
||||||
|
|
||||||
The Client Module interacts with the P2P module and Server Module. It is responsible for interacting with the server module and appropriately updating the IP table on the client side. It connects to the server using the server's REST Apis. It is also the primary decision maker on how the IP table is updated is on the client side. This is because each user can have requirements like how many number of hops they would want to do to update their IP table. Hops is the number of times the client is going to download the IP table from different servers ,once it gets the IP tables from the previous servers.
|
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
## Topics
|
## Topics
|
||||||
1. [Updating the IP table](#updating-the-IP-table)
|
1. [Updating the IP table](#updating-the-IP-table)
|
||||||
2. [Reading server specifications](#reading-server-specifications)
|
2. [Reading server specifications](#reading-server-specifications)
|
||||||
@@ -83,6 +78,8 @@ show a sample structure of file ```grouptrackcontainer.json```.
|
|||||||
```
|
```
|
||||||
The default path to the container tracker is ```client/trackcontainers/grouptrackcontainer.json```.
|
The default path to the container tracker is ```client/trackcontainers/grouptrackcontainer.json```.
|
||||||
|
|
||||||
> [!NOTE]
|
### Note:
|
||||||
> The group id will be auto-generated and will have its own prefix in the start which will mostly be ```grp<UUID>```.
|
The group id will be auto-generated and will have its own prefix in the start which will mostly be ```grp<UUID>```.
|
||||||
> When a container is removed using the command. ```p2prc --rm <IP Address> --id <Container id>```. It will be automatically deleted from the groups it exists in.
|
When a container is removed using the command. ```p2prc --rm <IP Address> --id <Container id>```. It will be automatically deleted
|
||||||
|
from the groups it exists in.
|
||||||
|
|
||||||
|
|||||||
@@ -13,19 +13,9 @@ JSON format.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"MachineName": "pc-74-120.customer.ask4.lan",
|
"dockerfile": "/<path>/p2p-rendering-computation/server/docker/containers/docker-ubuntu-sshd/",
|
||||||
"IPTable": "/Users/akilan/Documents/p2p-rendering-computation/p2p/iptable/ip_table.json",
|
"iptable": "/<path>/p2p-rendering-computation/p2p/ip_table.json",
|
||||||
"DockerContainers": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/",
|
"speedtestfile": "/<path>/p2p-rendering-computation/p2p/50.bin"
|
||||||
"DefaultDockerFile": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/docker-ubuntu-sshd/",
|
|
||||||
"SpeedTestFile": "/Users/akilan/Documents/p2p-rendering-computation/p2p/50.bin",
|
|
||||||
"IPV6Address": "",
|
|
||||||
"PluginPath": "/Users/akilan/Documents/p2p-rendering-computation/plugin/deploy",
|
|
||||||
"TrackContainersPath": "/Users/akilan/Documents/p2p-rendering-computation/client/trackcontainers/trackcontainers.json",
|
|
||||||
"ServerPort": "8088",
|
|
||||||
"GroupTrackContainersPath": "/Users/akilan/Documents/p2p-rendering-computation/client/trackcontainers/grouptrackcontainers.json",
|
|
||||||
"FRPServerPort": "True",
|
|
||||||
"BehindNAT": "True",
|
|
||||||
"CustomConfig": null
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
116
Docs/GenerateImplementation.md
Normal file
116
Docs/GenerateImplementation.md
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
# Generate Module
|
||||||
|
P2PRC is a great layer of abstraction. This means that in many cases it is not an end product but rather
|
||||||
|
a tool that customized as an end product. An example would be writing your own billing module to monetize
|
||||||
|
the computation power available. The generate module copies the current with the appropriate git histories
|
||||||
|
and keeps only the go files which would be useful to edit. To use the generate module the user will need
|
||||||
|
to have a go compiler present in his computer. Due to the introduction of this module there will 2 releases:
|
||||||
|
|
||||||
|
- Regular Release (Consists of only the build binary and cli command cannot access the generate module)
|
||||||
|
- Developer Release (Consists of important Go files and the cli can access the generate module)
|
||||||
|
|
||||||
|
## How does this work ?
|
||||||
|
|
||||||
|
### [Struct information](https://github.com/Akilan1999/p2p-rendering-computation/blob/9d69aed8ce0fe5273aaff2828f7d51c3d5ac2ce4/generate/generate.go#L19)
|
||||||
|
- ### ```Generate.go```:
|
||||||
|
This file creates a local copy of P2PRC from where the CLI was called from.
|
||||||
|
This go file also does various stuff like instruction of file should be ignored when copying and
|
||||||
|
which of should not be. Now let's understand this. Below is a sample code which does the following:
|
||||||
|
|
||||||
|
```go
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
// Action performed:
|
||||||
|
// - Ensuring main.go file exists
|
||||||
|
// - Skipping all .go files apart from the ones listed above
|
||||||
|
// - Skipping .idea/ directory
|
||||||
|
// - Skipping Makefile file
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
Options.Skip = func(src string) (bool, error) {
|
||||||
|
switch {
|
||||||
|
case strings.HasSuffix(src, "main.go"):
|
||||||
|
return false, nil
|
||||||
|
case strings.HasSuffix(src, ".go"):
|
||||||
|
return true, nil
|
||||||
|
case strings.HasSuffix(src, ".idea"):
|
||||||
|
return true, nil
|
||||||
|
case strings.HasSuffix(src, "Makefile"):
|
||||||
|
return true, nil
|
||||||
|
default:
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doing the copy
|
||||||
|
err = copy.Copy("<P2PRC folder you want to copy from>", "<PATH to the directory>", Options)
|
||||||
|
```
|
||||||
|
|
||||||
|
Unfortunately currently this will have to be manually edited in the ```Generate.go``` file. When using the generate
|
||||||
|
module the user also creates their own Go module which is the modified version of P2PRC. This means
|
||||||
|
if the 1 modified package is using another modified package then the appropriate import have to be modified
|
||||||
|
in the file where the import is called:
|
||||||
|
|
||||||
|
Ex:
|
||||||
|
```go
|
||||||
|
//Sample Project module name = Test
|
||||||
|
//Package names:
|
||||||
|
//- Test/Genius
|
||||||
|
//- Test/GeGeGenuis
|
||||||
|
//
|
||||||
|
// When we call the generate function with the new project with the module name = MicDrop
|
||||||
|
// The new package name would be:
|
||||||
|
// - MicDrop/Genius
|
||||||
|
// - MicDrop/GeGeGenuis
|
||||||
|
|
||||||
|
// Test/Genius code depends on the package Test/GeGeGenuis
|
||||||
|
import (
|
||||||
|
"Test/GeGeGenuis"
|
||||||
|
)
|
||||||
|
|
||||||
|
// When we create a new module with the copy of the
|
||||||
|
// existing project we need change:
|
||||||
|
import (
|
||||||
|
"MicDrop/GeGeGenuis"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
To do this we have built functions which can modify import names in the Go file provided.
|
||||||
|
To customize the use case of your generate module you would need to manually add your own
|
||||||
|
imports which are supposed to be replaced and in which files they are supposed to be replaced
|
||||||
|
in.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// 1.0 - Test/Genius.go -> GeGeGenuis module
|
||||||
|
// a is struct of type NewProject
|
||||||
|
a.FileNameAST = "<path to project to copy from>/Test/Genius.go"
|
||||||
|
// Get AST information of the file
|
||||||
|
err := a.GetASTGoFile()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Change the appropriate Go file
|
||||||
|
err = a.ChangeImports("Test/GeGeGenuis", "MicDrop/GeGeGenuis")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Writes the change to the appropriate file
|
||||||
|
err = a.WriteGoAst()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Higher order of execution of ```Generate.go```:
|
||||||
|
1. Copy entire P2PRC project and ignores files which are not meant to be copied
|
||||||
|
2. The folder name will be based on the new project name and the module name based on the new
|
||||||
|
module name provided.
|
||||||
|
3. Modifies the appropriate imports in the project as instructed in the code.
|
||||||
|
4. Creates a commit with the new changes in the new project.
|
||||||
|
|
||||||
|
|
||||||
|
- ### ``` modifyGenerate.go```:
|
||||||
|
This a really simple implementation where we replace the imports
|
||||||
|
in certain files as instructed from ```generate.go```. To do we create an AST (i.e Abstract Syntax tree)
|
||||||
|
from new file we want to change the imports in. AST create a tree structure of expression. To change the
|
||||||
|
import we can just traverse to the appropriate expression and change the value of that expression in
|
||||||
|
the case of modifying imports. This approach is more simple than using templates.
|
||||||
|
|
||||||
|
|
||||||
@@ -1,23 +1,20 @@
|
|||||||
# Implementation
|
# Implementation
|
||||||
| [◀ Previous](Introduction.md) | [Back to TOC](README.md) |
|
|
||||||
|:-----------:|---------|
|
|
||||||
|
|
||||||
This chapter describes how the project was built. It talks in depth of the implementation
|
This chapter describes how the project was built. It talks in depth of the implementation
|
||||||
performed to give a better understanding of the project.
|
performed to give a better understanding of the project.
|
||||||
|
|
||||||
## Programming langauge used
|
## Programming langauge used
|
||||||
The programming language used for this project was [Golang](https://go.dev/). The reason Go lang was chosen was
|
The programming language used for this project was Golang. The reason Go lang was chosen was
|
||||||
because it is a compiled language.<br>
|
because it is a compiled language.
|
||||||
The entire codebase is just a single binary file. When
|
The entire codebase is just a single binary file. When
|
||||||
distributing to other linux distributing the only requirement would be the binary file to run the
|
distributing to other linux distributing the only requirement would be the binary file to run the
|
||||||
code. It is easy to write independant modules and be monolithic at the sametime using Go.<br>
|
code. It is easy to write independant modules and be monolithic at the sametime using Go. Using
|
||||||
Using Go.mod makes it very easy to handle external libraries and modularise code. The go.mod name for
|
Go.mod makes it very easy to handle external libraries and modularise code. The go.mod name for
|
||||||
the project is [git.sr.ht/~akilan1999/p2p-rendering-computation](https://git.sr.ht/~akilan1999/p2p-rendering-computation).
|
the project is git.sr.ht/~akilan1999/p2p-rendering-computation.
|
||||||
|
|
||||||
- ## [Cli Module](CliImplementation.md)
|
## [Cli Module](CliImplementation.md)
|
||||||
- ## [Config Module](ConfigImplementation.md)
|
## [Config Module](ConfigImplementation.md)
|
||||||
- ## [Server Module](ServerImplementation.md)
|
## [Server Module](ServerImplementation.md)
|
||||||
- ## [Client Module](ClientImplementation.md)
|
## [Client Module](ClientImplementation.md)
|
||||||
- ## [P2P Module](P2PImplementation.md)
|
## [P2P Module](P2PImplementation.md)
|
||||||
- ## [Plugin Module](PluginImplementation.md)
|
## [Plugin Module](PluginImplementation.md)
|
||||||
- ## [Generate Module](GenerateImplementation.md)
|
## [Generate Module](GenerateImplementation.md)
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
| [◀ Previous](Introduction.md) | [Next ▶](Abstractions.md) |
|
|
||||||
|:-----------:|---------|
|
|
||||||
|
|
||||||
Over here we will cover the basic steps to get the server and client side running.
|
Over here we will cover the basic steps to get the server and client side running.
|
||||||
|
|
||||||
## Latest release install
|
## Alpha release install
|
||||||
https://github.com/Akilan1999/p2p-rendering-computation/releases
|
https://github.com/Akilan1999/p2p-rendering-computation/releases/tag/v1.0.0-alpha
|
||||||
|
|
||||||
## Install from Github master branch
|
## Install from Github master branch
|
||||||
|
|
||||||
@@ -42,7 +39,7 @@ To set up P2PRC on Windows, simply run this batch file.
|
|||||||
.\install.bat
|
.\install.bat
|
||||||
```
|
```
|
||||||
|
|
||||||
### Add appropriate paths to `.bashrc`
|
### Add appropriate paths to .bashrc
|
||||||
```
|
```
|
||||||
export P2PRC=/<PATH>/p2p-rendering-computation
|
export P2PRC=/<PATH>/p2p-rendering-computation
|
||||||
export PATH=/<PATH>/p2p-rendering-computation:${PATH}
|
export PATH=/<PATH>/p2p-rendering-computation:${PATH}
|
||||||
@@ -68,7 +65,7 @@ USAGE:
|
|||||||
p2prc [global options] command [command options] [arguments...]
|
p2prc [global options] command [command options] [arguments...]
|
||||||
|
|
||||||
VERSION:
|
VERSION:
|
||||||
2.0.0
|
1.0.0
|
||||||
|
|
||||||
COMMANDS:
|
COMMANDS:
|
||||||
help, h Shows a list of commands or help for one command
|
help, h Shows a list of commands or help for one command
|
||||||
@@ -81,8 +78,7 @@ GLOBAL OPTIONS:
|
|||||||
--ViewImages value, --vi value View images available on the server IP address [$VIEW_IMAGES]
|
--ViewImages value, --vi value View images available on the server IP address [$VIEW_IMAGES]
|
||||||
--CreateVM value, --touch value Creates Docker container on the selected server [$CREATE_VM]
|
--CreateVM value, --touch value Creates Docker container on the selected server [$CREATE_VM]
|
||||||
--ContainerName value, --cn value Specifying the container run on the server side [$CONTAINER_NAME]
|
--ContainerName value, --cn value Specifying the container run on the server side [$CONTAINER_NAME]
|
||||||
--BaseImage value, --bi value Specifying the docker base image to template the dockerfile [$CONTAINER_NAME]
|
--RemoveVM value, --rm value Stop and Remove Docker container [$REMOVE_VM]
|
||||||
--RemoveVM value, --rm value Stop and Remove Docker container (IP:port) accompanied by container ID via --ID or --id [$REMOVE_VM]
|
|
||||||
--ID value, --id value Docker Container ID [$ID]
|
--ID value, --id value Docker Container ID [$ID]
|
||||||
--Ports value, -p value Number of ports to open for the Docker Container [$NUM_PORTS]
|
--Ports value, -p value Number of ports to open for the Docker Container [$NUM_PORTS]
|
||||||
--GPU, --gpu Create Docker Containers to access GPU (default: false) [$USE_GPU]
|
--GPU, --gpu Create Docker Containers to access GPU (default: false) [$USE_GPU]
|
||||||
@@ -90,23 +86,10 @@ GLOBAL OPTIONS:
|
|||||||
--SetDefaultConfig, --dc Sets a default configuration file (default: false) [$SET_DEFAULT_CONFIG]
|
--SetDefaultConfig, --dc Sets a default configuration file (default: false) [$SET_DEFAULT_CONFIG]
|
||||||
--NetworkInterfaces, --ni Shows the network interface in your computer (default: false) [$NETWORK_INTERFACE]
|
--NetworkInterfaces, --ni Shows the network interface in your computer (default: false) [$NETWORK_INTERFACE]
|
||||||
--ViewPlugins, --vp Shows plugins available to be executed (default: false) [$VIEW_PLUGIN]
|
--ViewPlugins, --vp Shows plugins available to be executed (default: false) [$VIEW_PLUGIN]
|
||||||
--TrackedContainers, --tc View (currently running) containers which have been created from the client side (default: false) [$TRACKED_CONTAINERS]
|
--TrackedContainers, --tc View containers which have been created from the client side (default: false) [$TRACKED_CONTAINERS]
|
||||||
--ExecutePlugin value, --plugin value Plugin which needs to be executed [$EXECUTE_PLUGIN]
|
--ExecutePlugin value, --plugin value Plugin which needs to be executed [$EXECUTE_PLUGIN]
|
||||||
--CreateGroup, --cgroup Creates a new group (default: false) [$CREATE_GROUP]
|
|
||||||
--Group value, --group value group flag with argument group ID [$GROUP]
|
|
||||||
--Groups, --groups View all groups (default: false) [$GROUPS]
|
|
||||||
--RemoveContainerGroup, --rmcgroup Remove specific container in the group (default: false) [$REMOVE_CONTAINER_GROUP]
|
|
||||||
--RemoveGroup value, --rmgroup value Removes the entire group [$REMOVE_GROUP]
|
|
||||||
--MAPPort value, --mp value Maps port for a specific port provided as the parameter [$MAPPORT]
|
|
||||||
--DomainName value, --dn value While mapping ports allows to set a domain name to create a mapping in the proxy server [$DOMAINNAME]
|
|
||||||
--Generate value, --gen value Generates a new copy of P2PRC which can be modified based on your needs [$GENERATE]
|
|
||||||
--ModuleName value, --mod value New go project module name [$MODULENAME]
|
|
||||||
--PullPlugin value, --pp value Pulls plugin from git repos [$PULLPLUGIN]
|
|
||||||
--RemovePlugin value, --rp value Removes plugin [$REMOVEPLUGIN]
|
|
||||||
--AddMetaData value, --amd value Adds metadata about the current node in the p2p network which is then propagated through the network [$ADDMETADATA]
|
|
||||||
--help, -h show help (default: false)
|
--help, -h show help (default: false)
|
||||||
--version, -v print the version (default: false)
|
--version, -v print the version (default: false)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@@ -118,7 +101,7 @@ GLOBAL OPTIONS:
|
|||||||
# Using basic commands
|
# Using basic commands
|
||||||
|
|
||||||
### Start as a server
|
### Start as a server
|
||||||
Do ensure you have Docker installed for this
|
Do ensure you have docker installed for this
|
||||||
```
|
```
|
||||||
p2prc -s
|
p2prc -s
|
||||||
```
|
```
|
||||||
@@ -212,16 +195,6 @@ p2prc --pp <repo link>
|
|||||||
p2prc --rp <plugin name>
|
p2prc --rp <plugin name>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Added custom metadata about the current node
|
|
||||||
```
|
|
||||||
p2prc --amd "custom metadata"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Map port
|
|
||||||
```
|
|
||||||
p2prc --mp <internal port no from your machine> --dn <domain name you want the port linked to>
|
|
||||||
```
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
@@ -236,18 +209,24 @@ This feature is still Under Development:
|
|||||||
- Ansible:
|
- Ansible:
|
||||||
- Debian/ubuntu: ```sudo apt install ansible```
|
- Debian/ubuntu: ```sudo apt install ansible```
|
||||||
- Others: [Installation link](https://ansible-tips-and-tricks.readthedocs.io/en/latest/ansible/install/)
|
- Others: [Installation link](https://ansible-tips-and-tricks.readthedocs.io/en/latest/ansible/install/)
|
||||||
|
|
||||||
|
#### Set ansible host_key_checking to false
|
||||||
|
- On linux
|
||||||
|
- ```sudo nano /etc/ansible/ansible.cfg```: Open the following file. If this file is not found then where
|
||||||
|
ever the file ```ansible.cfg``` is located.
|
||||||
|
- Add or uncomment ```host_key_checking = False```
|
||||||
|
|
||||||
#### Run Test Cases
|
#### Run Test Cases
|
||||||
- Generate Test Case Ansible file
|
- Generate Test Case Ansible file
|
||||||
- ```make testcases```
|
- ```make testcases```
|
||||||
- Enter inside plugin directory and run tests.<br>
|
- Enter inside plugin directory and run tests.
|
||||||
|
Note: That docker needs to installed and needs to run without
|
||||||
> [!NOTE]
|
sudo. Refer the section install Docker.
|
||||||
> That docker needs to installed and needs to run without
|
- ```cd plugin```
|
||||||
> sudo. Refer the section [Install Docker](#install-docker).
|
- ```go test .```
|
||||||
> - ```cd plugin```
|
|
||||||
> - ```go test .```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Next Chapter: [Abstractions](Abstractions.md)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
# Chapter 1: Introduction
|
# Chapter 1: Introduction
|
||||||
|
|
||||||
| [◀ Back to TOC](README.md) | [Next ▶](Installation.md) |
|
|
||||||
|:-----------:|---------|
|
|
||||||
|
|
||||||
## Abstract
|
## Abstract
|
||||||
This project focuses on creating a framework on running heavy tasks that a regular computer
|
This project focuses on creating a framework on running heavy tasks that a regular computer
|
||||||
cannot run easily such as graphically demanding video games, rendering 3D animations , protein
|
cannot run easily such as graphically demanding video games, rendering 3D animations , protein
|
||||||
@@ -24,7 +21,7 @@ run these heavy tasks can be really useful. Ethically speaking this is leading t
|
|||||||
computing power similar to what is happening in the web server area. By using peer to peer
|
computing power similar to what is happening in the web server area. By using peer to peer
|
||||||
principles it is possible to remove the monopolisation factor and increase the bandwidth between
|
principles it is possible to remove the monopolisation factor and increase the bandwidth between
|
||||||
the client and server.
|
the client and server.
|
||||||
<!--
|
|
||||||
## Aim
|
## Aim
|
||||||
This project aims to create a peer to peer (p2p) network, where a user can use the p2p network to
|
This project aims to create a peer to peer (p2p) network, where a user can use the p2p network to
|
||||||
act as a client (i.e sending tasks) or the server (i.e executing the tasks). A prototype application will
|
act as a client (i.e sending tasks) or the server (i.e executing the tasks). A prototype application will
|
||||||
@@ -36,8 +33,4 @@ or virtual environments across selected nodes.
|
|||||||
rendering tools and tools to batch any sort of tasks.
|
rendering tools and tools to batch any sort of tasks.
|
||||||
- Creating p2p network
|
- Creating p2p network
|
||||||
- Server to create a containerised environment
|
- Server to create a containerised environment
|
||||||
- The client node to run tasks on Server containerised node -->
|
- The client node to run tasks on Server containerised node
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Next Chapter: [Installation](Installation.md)
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
# 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
@@ -19,9 +19,11 @@ In this repository the P2P module has been designed from sratch at the point of
|
|||||||
|
|
||||||
|
|
||||||
## Responsibility
|
## Responsibility
|
||||||
|
- To perform speed test to determine best node to connect
|
||||||
- To ensure the IP table has nodes which are pingable
|
- To ensure the IP table has nodes which are pingable
|
||||||
- Taking to nodes behind NAT. [More about the implementation](NAT-Traversal)...
|
- Using techniques such as [UPNP](https://en.wikipedia.org/wiki/Universal_Plug_and_Play). Still under development
|
||||||
|
- Port Forwarding (To be introducted in a future release)
|
||||||
|
|
||||||
|
|
||||||
> [!NOTE]
|
## Note:
|
||||||
> If you are running in server mode it is recommended to use [DMZ](https://routerguide.net/when-and-how-to-setup-dmz-host-for-home-use/) to bypass the [NAT](https://en.wikipedia.org/wiki/Network_address_translation).
|
If you are running in server mode it is recommended to use [DMZ](https://routerguide.net/when-and-how-to-setup-dmz-host-for-home-use/) to bypass the [NAT](https://en.wikipedia.org/wiki/Network_address_translation).
|
||||||
|
|||||||
@@ -1,20 +1,10 @@
|
|||||||
# P2P Module Implementation
|
# P2P Module Implementation
|
||||||
|
|
||||||
The P2P module (i.e Peer to Peer Module) is responsible for storing the IP table and interacting
|
|
||||||
with the IP table. In the following implementation of the P2P module ,the IP table stores
|
|
||||||
information about servers available in the network. The other functionality the P2P module takes
|
|
||||||
care of is doing the appropriate speed tests to the servers in the IP table. This is for informing the
|
|
||||||
users about nodes which are close by and nodes which have quicker uploads and downloads
|
|
||||||
speeds. The module is responsible to ensure that there are no duplicate server IPs in the IP table
|
|
||||||
and to remove all server IPs which are not pingable.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
The peer to peer implementation was built from scratch. This is because other peer to peer
|
The peer to peer implementation was built from scratch. This is because other peer to peer
|
||||||
libraries were on the implementation of the Distributed hash table. At the current moment all
|
libraries were on the implementation of the Distributed hash table. At the current moment all
|
||||||
those heavy features are not needed because the objective is to search and list all possible servers
|
those heavy features are not needed because the objective is to search and list all possible servers
|
||||||
available. The limitation being that to be a part of the network the user has to know at least 1
|
available. The limitation being that to be a part of the network the user has to know at least 1
|
||||||
server. The advantage of building from scratch makes the module super light and
|
server and has to have DMZ enabled from the router if the user wants to act as a server out of the
|
||||||
|
users local network. The advantage of building from scratch makes the module super light and
|
||||||
possibility for custom functions and structs. The sub topics below will mention the
|
possibility for custom functions and structs. The sub topics below will mention the
|
||||||
implementations of each functionality in depth.
|
implementations of each functionality in depth.
|
||||||
|
|
||||||
@@ -33,53 +23,27 @@ path of the IP table json file is received from the configuration module.
|
|||||||
"latency": "<latency>",
|
"latency": "<latency>",
|
||||||
"download": "<download>",
|
"download": "<download>",
|
||||||
"upload": "<upload>"
|
"upload": "<upload>"
|
||||||
"port no": "<server port no>",
|
"port no": "<server port no>"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Speed Test
|
||||||
|
The speed test functions populate the fields which are latency, download, upload speed. Before the
|
||||||
|
speed test begins for each server IP address. The p2p module ensures that each server IP address
|
||||||
|
is pingable. If the server IP address is not pingable then it removes that IP address from the struct.
|
||||||
|
|
||||||
### Latency
|
### Latency
|
||||||
The latency is measured in milliseconds. The route /server_info is called from the
|
The latency is measured in milliseconds. The route /server_info is called from the
|
||||||
server and time it takes to provide a json response is recorded.
|
server and time it takes to provide a json response is recorded.
|
||||||
|
|
||||||
## NAT Traversal
|
### Download speed
|
||||||
P2PRC currently supports TURN for NAT traversal.
|
The download speed is measured as (<file size>/<time taken to
|
||||||
|
download>)*8. This gives the result in megabits per second. The file downloaded is a 50 mb
|
||||||
|
auto generated file.
|
||||||
|
|
||||||
## 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
### Upload speed
|
||||||
|
The upload speed is measured as (<file size>/<time taken to upload>)*8. This
|
||||||
|
gives the results in megabits per second. The file uploaded is a 50 mb auto generated file.
|
||||||
|
The route /upload is called from the server side to upload the file.
|
||||||
|
|||||||
@@ -54,23 +54,22 @@ nodes to execute Ansible instructions. In this project this file needs to be set
|
|||||||
go code or binary will populate this file automatically with the appropriate information required to connect to local or
|
go code or binary will populate this file automatically with the appropriate information required to connect to local or
|
||||||
remote containers.
|
remote containers.
|
||||||
|
|
||||||
> [!NOTE]
|
#### Note: Add as exactly specified below
|
||||||
> Add as exactly specified below:
|
```
|
||||||
> ```
|
all:
|
||||||
>all:
|
vars:
|
||||||
> vars:
|
ansible_python_interpreter: /usr/bin/python3 // Path to your python 3 interpreter
|
||||||
> ansible_python_interpreter: /usr/bin/python3 // Path to your python 3 interpreter
|
main:
|
||||||
>main:
|
hosts:
|
||||||
> hosts:
|
host1:
|
||||||
> host1:
|
// Note: These values will be automatically overwritten
|
||||||
> // Note: These values will be automatically overwritten
|
// by the Go functions
|
||||||
> // by the Go functions
|
ansible_host: 0.0.0.0
|
||||||
> ansible_host: 0.0.0.0
|
ansible_port: 39269
|
||||||
> ansible_port: 39269
|
ansible_user: master
|
||||||
> ansible_user: master
|
ansible_ssh_pass: password
|
||||||
> ansible_ssh_pass: password
|
ansible_sudo_pass: password
|
||||||
> ansible_sudo_pass: password
|
```
|
||||||
>```
|
|
||||||
|
|
||||||
## Ports.json
|
## Ports.json
|
||||||
The ```ports.json``` file is intended to mention the number of ports required
|
The ```ports.json``` file is intended to mention the number of ports required
|
||||||
|
|||||||
35
Docs/Problems.md
Normal file
35
Docs/Problems.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Problems in implementation
|
||||||
|
|
||||||
|
### Number of Devices in the network:
|
||||||
|
The current implementation has the major flaw which is that
|
||||||
|
the server has to be in port 8088 to detected in the public
|
||||||
|
network. As we know most personal networks have a single IP
|
||||||
|
address. This means we cannot have duplicate ports. A fix can
|
||||||
|
be to mention the open port on the IP table file.
|
||||||
|
(Ex: Possible feild to be added)
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"ip_address": [
|
||||||
|
{
|
||||||
|
"ipv4": "localhost",
|
||||||
|
"latency": 14981051,
|
||||||
|
"download": 8142.122540206258,
|
||||||
|
"upload": 3578.766512629995,
|
||||||
|
"port": 8088
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Broadcast of container specs
|
||||||
|
At the moment the container specs are not broadcasted rather
|
||||||
|
just the machines specs and this module has yet to be tested
|
||||||
|
rigorously.
|
||||||
|
|
||||||
|
### Intergration with GPU
|
||||||
|
Certain machines have GPUs present in them which provide a
|
||||||
|
huge advantage for those who want to do rendering and certain
|
||||||
|
sort of computation. The Aim is to only allow it to be compatible
|
||||||
|
with Nvidia. But an better idea would be to provide compatability
|
||||||
|
with multiple GPU providers.
|
||||||
|
|
||||||
@@ -2,11 +2,10 @@
|
|||||||
# 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)
|
||||||
3. [Server Module](ServerArchitecture.md) -->
|
3. [Server Module](ServerArchitecture.md)
|
||||||
4. [Implementation](Implementation.md)
|
4. [Implementation](Implementation.md)
|
||||||
1. [Client Module](ClientImplementation.md)
|
1. [Client Module](ClientImplementation.md)
|
||||||
2. [P2P Module](P2PImplementation.md)
|
2. [P2P Module](P2PImplementation.md)
|
||||||
@@ -14,6 +13,6 @@
|
|||||||
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. [Language bindings](Bindings.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)
|
||||||
|
|
||||||
|
|||||||
@@ -4,14 +4,6 @@ This section focuses on an in-depth understanding of the server module implement
|
|||||||
understand the architecture of the server module refer. The server module can be split
|
understand the architecture of the server module refer. The server module can be split
|
||||||
into various sections. Each section will provide information on how a certain feature works.
|
into various sections. Each section will provide information on how a certain feature works.
|
||||||
|
|
||||||
The server module takes care of setting and removing the virtualization environment (i.e
|
|
||||||
containers) for accessing and doing the appropriate computation. It also interacts with the peer to
|
|
||||||
peer module to update the IP table on the server side. The server module
|
|
||||||
accesses information regarding CPU and GPU specifications of the machine running the server
|
|
||||||
module. To do Speed tests the server has routes which allows it to upload and download a 50mb.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Web framework
|
## Web framework
|
||||||
The web framework used for the server module is called Gin. The reason Gin was chosen is due to
|
The web framework used for the server module is called Gin. The reason Gin was chosen is due to
|
||||||
its wide use and strong documentation available on the official github repository. The default
|
its wide use and strong documentation available on the official github repository. The default
|
||||||
|
|||||||
9
Makefile
9
Makefile
@@ -9,12 +9,3 @@ testcases:
|
|||||||
run:
|
run:
|
||||||
go run main.go
|
go run main.go
|
||||||
|
|
||||||
sharedObjects:
|
|
||||||
sh build-bindings.sh
|
|
||||||
|
|
||||||
python:
|
|
||||||
sh build-python-package.sh
|
|
||||||
|
|
||||||
clean:
|
|
||||||
go clean -modcache
|
|
||||||
rm -fr .go-build vendor result*
|
|
||||||
|
|||||||
70
README.md
70
README.md
@@ -1,6 +1,3 @@
|
|||||||
> [!NOTE]
|
|
||||||
> Fixing documentation to latest changes. If you have any questions setting up P2PRC either [create an issue](https://github.com/Akilan1999/p2p-rendering-computation/issues/new/choose) or send me an email (me AT akilan dot io).
|
|
||||||
> Currently HEAD is always intended to stay on a working state. It is recommended to always use HEAD in your go.mod file.
|
|
||||||
|
|
||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
<br>
|
<br>
|
||||||
@@ -21,40 +18,20 @@ The main aim of this project was to create a custom peer to peer network. The us
|
|||||||
client has total flexibility on how to batch the tasks and the user acting as the server has complete
|
client has total flexibility on how to batch the tasks and the user acting as the server has complete
|
||||||
flexibility on tracking the container's usages and killing the containers at any point of time.
|
flexibility on tracking the container's usages and killing the containers at any point of time.
|
||||||
|
|
||||||
## Latest tutorial
|
## Gophers talk
|
||||||
[](https://www.youtube.com/watch?v=OMwCpedu5cs")
|
[](https://www.youtube.com/watch?v=ovcZLEhQxWk "P2PRC - Gophers monthly talk")
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## Table of contents in the current README
|
## Table of contents
|
||||||
1. [Introduction](#Introduction)
|
1. [Introduction](#Introduction)
|
||||||
2. [Installation](#extend-your-application-with-p2prc)
|
2. [Installation](#Installation.md)
|
||||||
3. [Design Architecture](#Design-Architecture)
|
3. [Design Architecture](#Design-Architecture)
|
||||||
4. [Implementation](#Implementation)
|
4. [Implementation](#Implementation)
|
||||||
5. [Find out more](#Find-out-more)
|
5. [Find out more](#Find-out-more)
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
# Table of contents in the Docs folder
|
|
||||||
1. [Introduction](Docs/Introduction.md)
|
|
||||||
2. [Installation](Docs/Installation.md)
|
|
||||||
3. [Abstractions](Docs/Abstractions.md)
|
|
||||||
<!-- 3. [Design Architecture](DesignArchtectureIntro.md)
|
|
||||||
1. [Client Module](ClientArchitecture.md)
|
|
||||||
2. [P2P Module](P2PArchitecture.md)
|
|
||||||
3. [Server Module](ServerArchitecture.md) -->
|
|
||||||
4. [Implementation](Docs/Implementation.md)
|
|
||||||
1. [Client Module](Docs/ClientImplementation.md)
|
|
||||||
2. [P2P Module](Docs/P2PImplementation.md)
|
|
||||||
3. [Server Module](Docs/ServerImplementation.md)
|
|
||||||
4. [Config Module](Docs/ConfigImplementation.md)
|
|
||||||
5. [Cli Module](Docs/CliImplementation.md)
|
|
||||||
6. [Plugin Module](Docs/PluginImplementation.md)
|
|
||||||
7. [Language Bindings](Docs/Bindings.md)
|
|
||||||
<!-- 5. [Problems](https://github.com/Akilan1999/p2p-rendering-computation/issues) -->
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
This project aims to create a peer to peer (p2p) network, where a user can use the p2p network to act as a client (i.e sending tasks) or the server (i.e executing the tasks). A prototype application will be developed, which comes bundled with a p2p module and possible to execute docker containers or virtual environments across selected nodes.
|
This project aims to create a peer to peer (p2p) network, where a user can use the p2p network to act as a client (i.e sending tasks) or the server (i.e executing the tasks). A prototype application will be developed, which comes bundled with a p2p module and possible to execute docker containers or virtual environments across selected nodes.
|
||||||
|
|
||||||
@@ -68,44 +45,6 @@ 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 (
|
|
||||||
"fmt"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/abstractions"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
_, err := abstractions.Init(nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// start p2prc
|
|
||||||
_, err = abstractions.Start()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run server till termination
|
|
||||||
for {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### Export once this is added export P2PRC as environment paths
|
|
||||||
```
|
|
||||||
export P2PRC=<PROJECT PATH>
|
|
||||||
export PATH=<PROJECT PATH>:${PATH}
|
|
||||||
```
|
|
||||||
[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
|
||||||
```
|
```
|
||||||
@@ -162,3 +101,4 @@ or just providing feedback on new features to build or even just curious about
|
|||||||
[](https://discord.gg/b4nRGTjYqy)
|
[](https://discord.gg/b4nRGTjYqy)
|
||||||
|
|
||||||
[](https://github.com/Gaurav-Gosain)
|
[](https://github.com/Gaurav-Gosain)
|
||||||
|
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
package abstractions
|
|
||||||
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/client"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
|
|
||||||
Config "github.com/Akilan1999/p2p-rendering-computation/config"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config/generate"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/server"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Init Initialises p2prc
|
|
||||||
func Init(customConfig interface{}) (config *Config.Config, err error) {
|
|
||||||
|
|
||||||
// Get config file path
|
|
||||||
// Checks P2PRC path initially
|
|
||||||
// - Get PATH if environment varaible
|
|
||||||
path, err := Config.GetPathP2PRC("P2PRC")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// check if the config file exists
|
|
||||||
if _, err = os.Stat(path + "config.json"); err != nil {
|
|
||||||
// Initialize with base p2prc config files
|
|
||||||
// set the config file with default paths
|
|
||||||
config, err = generate.SetDefaults("P2PRC", false, customConfig, false)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If the configs are available then use them over generating new ones.
|
|
||||||
config, err = Config.ConfigInit(nil, nil)
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// MapPort Creates a reverse proxy connection and maps the appropriate port
|
|
||||||
func MapPort(port string) (entireAddres string, mapPort string, err error) {
|
|
||||||
entireAddres, mapPort, err = server.MapPort(port)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartContainer Starts docker container on the remote machine
|
|
||||||
func StartContainer(IP string) (container *docker.DockerVM, err error) {
|
|
||||||
container, err = client.StartContainer(IP, 0, false, "", "")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveContainer Removes docker container based on the IP address and ID
|
|
||||||
// provided
|
|
||||||
func RemoveContainer(IP string, ID string) error {
|
|
||||||
return client.RemoveContianer(IP, ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSpecs Get spec information about the remote server
|
|
||||||
func GetSpecs(IP string) (specs *server.SysInfo, err error) {
|
|
||||||
specs, err = client.GetSpecs(IP)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ViewIPTable View information of nodes in the network
|
|
||||||
func ViewIPTable() (table *p2p.IpAddresses, err error) {
|
|
||||||
table, err = p2p.ReadIpTable()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateIPTable Force updates IP tables based on new
|
|
||||||
// new nodes discovered in the network
|
|
||||||
func UpdateIPTable() (err error) {
|
|
||||||
return clientIPTable.UpdateIpTableListClient()
|
|
||||||
}
|
|
||||||
BIN
artwork/.DS_Store
vendored
BIN
artwork/.DS_Store
vendored
Binary file not shown.
@@ -4,11 +4,13 @@
|
|||||||
## Pure HTML Version of the p2prc Logo :)
|
## Pure HTML Version of the p2prc Logo :)
|
||||||

|

|
||||||
|
|
||||||
> [!NOTE]
|
> Note: To change the size of the logo simply edit the CSS variable of `--size` under the `style` tag!
|
||||||
> To change the size of the logo simply edit the CSS variable of `--size` under the `style` tag!
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Embedding the HTML as a `foreignObject` element inside an SVG directly
|
### Embedding the HTML as a `foreignObject` element inside an SVG directly
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
BIN
artwork/p2prc-logos/.DS_Store
vendored
BIN
artwork/p2prc-logos/.DS_Store
vendored
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
cd Bindings && go build -buildmode=c-shared -o p2prc.so
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/bash
|
|
||||||
|
|
||||||
# Create export directory for python
|
|
||||||
mkdir Bindings/python/export
|
|
||||||
|
|
||||||
# Creating SharedObjects directory for python
|
|
||||||
mkdir Bindings/python/export/SharedObjects
|
|
||||||
|
|
||||||
sh build-bindings.sh
|
|
||||||
|
|
||||||
cp Bindings/p2prc.h Bindings/python/export/SharedObjects/
|
|
||||||
cp Bindings/p2prc.so Bindings/python/export/SharedObjects/
|
|
||||||
|
|
||||||
cp Bindings/python/p2prc.py Bindings/python/export/
|
|
||||||
|
|
||||||
echo "Output is in the Directory Bindings/python/export/"
|
|
||||||
|
|
||||||
# Architectures for Linux
|
|
||||||
#archs=(amd64 arm64)
|
|
||||||
#
|
|
||||||
#for arch in ${archs[@]}
|
|
||||||
#do
|
|
||||||
# mkdir Bindings/python/export/SharedObjects/linux-${arch}
|
|
||||||
# cd Bindings/
|
|
||||||
# env GOOS=linux GOARCH=${arch} go build -buildmode=c-shared -o python/export/SharedObjects/linux-${arch}/p2prc.so
|
|
||||||
# echo "GOOS=linux GOARCH=${arch} go build -buildmode=c-shared -o python/export/SharedObjects/linux-${arch}/p2prc.so"
|
|
||||||
# cd ..
|
|
||||||
#done
|
|
||||||
@@ -1,310 +1,310 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Groups Data Structure type
|
// Groups Data Structure type
|
||||||
type Groups struct {
|
type Groups struct {
|
||||||
GroupList []*Group `json:"Groups"`
|
GroupList []*Group `json:"Groups"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group Information about a single group
|
// Group Information about a single group
|
||||||
type Group struct {
|
type Group struct {
|
||||||
ID string `json:"ID"`
|
ID string `json:"ID"`
|
||||||
TrackContainerList []*TrackContainer `json:"TrackContainer"`
|
TrackContainerList []*TrackContainer `json:"TrackContainer"`
|
||||||
// Sneaky as required only when removing the element
|
// Sneaky as required only when removing the element
|
||||||
// Set when GetGroup function is called
|
// Set when GetGroup function is called
|
||||||
index int
|
index int
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateGroup Creates a new group to add a set of track containers
|
// CreateGroup Creates a new group to add a set of track containers
|
||||||
func CreateGroup() (*Group, error) {
|
func CreateGroup() (*Group, error) {
|
||||||
// Creating variable of type new group
|
// Creating variable of type new group
|
||||||
var NewGroup Group
|
var NewGroup Group
|
||||||
// Generate new UUID for group ID
|
// Generate new UUID for group ID
|
||||||
id := uuid.New()
|
id := uuid.New()
|
||||||
// Add new group id and prepend with the string "grp"
|
// Add new group id and prepend with the string "grp"
|
||||||
// The reason this is done is to differentiate between a
|
// The reason this is done is to differentiate between a
|
||||||
// group ID and docker container ID
|
// group ID and docker container ID
|
||||||
NewGroup.ID = "grp" + id.String()
|
NewGroup.ID = "grp" + id.String()
|
||||||
// Adding the new group to the
|
// Adding the new group to the
|
||||||
// GroupTrackContainer File
|
// GroupTrackContainer File
|
||||||
err := NewGroup.AddGroupToFile()
|
err := NewGroup.AddGroupToFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &NewGroup, nil
|
return &NewGroup, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveGroup Removes group based on the group ID provided
|
// RemoveGroup Removes group based on the group ID provided
|
||||||
func RemoveGroup(GroupID string) error {
|
func RemoveGroup(GroupID string) error {
|
||||||
// Read group information from the
|
// Read group information from the
|
||||||
//grouptrackcontainer json file
|
//grouptrackcontainer json file
|
||||||
groups, err := ReadGroup()
|
groups, err := ReadGroup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Gets Group struct based on group ID
|
// Gets Group struct based on group ID
|
||||||
// provided
|
// provided
|
||||||
group, err := GetGroup(GroupID)
|
group, err := GetGroup(GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Remove Group struct from the groups variable
|
// Remove Group struct from the groups variable
|
||||||
groups.GroupList = append(groups.GroupList[:group.index], groups.GroupList[group.index+1:]...)
|
groups.GroupList = append(groups.GroupList[:group.index], groups.GroupList[group.index+1:]...)
|
||||||
|
|
||||||
// Write new groups to the grouptrackcontainer json file
|
// Write new groups to the grouptrackcontainer json file
|
||||||
err = groups.WriteGroup()
|
err = groups.WriteGroup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddContainerToGroup Adds container information to the Group based on the Group ID
|
// AddContainerToGroup Adds container information to the Group based on the Group ID
|
||||||
func AddContainerToGroup(ContainerID string, GroupID string) (*Group, error) {
|
func AddContainerToGroup(ContainerID string, GroupID string) (*Group, error) {
|
||||||
// Gets container information based on container ID provided
|
// Gets container information based on container ID provided
|
||||||
containerInfo, err := GetContainerInformation(ContainerID)
|
containerInfo, err := GetContainerInformation(ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Gets group information based on the group ID provided
|
// Gets group information based on the group ID provided
|
||||||
group, err := GetGroup(GroupID)
|
group, err := GetGroup(GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Adds container information the group
|
// Adds container information the group
|
||||||
group.AddContainer(containerInfo)
|
group.AddContainer(containerInfo)
|
||||||
|
|
||||||
// Get Groups information from reading the grouptrackcontainer.json file
|
// Get Groups information from reading the grouptrackcontainer.json file
|
||||||
groups, err := ReadGroup()
|
groups, err := ReadGroup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Updating specific element in the group list with the added container
|
// Updating specific element in the group list with the added container
|
||||||
groups.GroupList[group.index] = group
|
groups.GroupList[group.index] = group
|
||||||
// Write groups information on the grouptrackcontainer.json file
|
// Write groups information on the grouptrackcontainer.json file
|
||||||
err = groups.WriteGroup()
|
err = groups.WriteGroup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return group, nil
|
return group, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveContainerGroup Remove Container from the group ID specified
|
// RemoveContainerGroup Remove Container from the group ID specified
|
||||||
func RemoveContainerGroup(ContainerID string, GroupID string) (*Group, error) {
|
func RemoveContainerGroup(ContainerID string, GroupID string) (*Group, error) {
|
||||||
// Get container information based on container ID provided
|
// Get container information based on container ID provided
|
||||||
containerInfo, err := GetContainerInformation(ContainerID)
|
containerInfo, err := GetContainerInformation(ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Gets group information based on the group ID provided
|
// Gets group information based on the group ID provided
|
||||||
group, err := GetGroup(GroupID)
|
group, err := GetGroup(GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Remove container from the appropriate group
|
// Remove container from the appropriate group
|
||||||
err = group.RemoveContainerGroup(containerInfo)
|
err = group.RemoveContainerGroup(containerInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Get Groups information from reading the grouptrackcontainer.json file
|
// Get Groups information from reading the grouptrackcontainer.json file
|
||||||
groups, err := ReadGroup()
|
groups, err := ReadGroup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Updating specific element in the group list with the remove container
|
// Updating specific element in the group list with the remove container
|
||||||
groups.GroupList[group.index] = group
|
groups.GroupList[group.index] = group
|
||||||
// Write groups information on the grouptrackcontainer.json file
|
// Write groups information on the grouptrackcontainer.json file
|
||||||
err = groups.WriteGroup()
|
err = groups.WriteGroup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return group, nil
|
return group, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveContainerGroups Remove Container from groups (i.e which ever groups has information
|
// RemoveContainerGroups Remove Container from groups (i.e which ever groups has information
|
||||||
// about that container). This is mostly called when a container is deleted or removed from
|
// about that container). This is mostly called when a container is deleted or removed from
|
||||||
// the tracked container list
|
// the tracked container list
|
||||||
func RemoveContainerGroups(ContainerID string) error {
|
func RemoveContainerGroups(ContainerID string) error {
|
||||||
// Get container information based on container ID provided
|
// Get container information based on container ID provided
|
||||||
containerInfo, err := GetContainerInformation(ContainerID)
|
containerInfo, err := GetContainerInformation(ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Get Groups information from reading the grouptrackcontainer.json file
|
// Get Groups information from reading the grouptrackcontainer.json file
|
||||||
groups, err := ReadGroup()
|
groups, err := ReadGroup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Removes container information from all groups it is found in
|
// Removes container information from all groups it is found in
|
||||||
err = groups.RemoveContainerGroups(containerInfo)
|
err = groups.RemoveContainerGroups(containerInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Write groups information on the grouptrackcontainer.json file
|
// Write groups information on the grouptrackcontainer.json file
|
||||||
err = groups.WriteGroup()
|
err = groups.WriteGroup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetGroup Gets group information based on
|
// GetGroup Gets group information based on
|
||||||
// group id provided
|
// group id provided
|
||||||
func GetGroup(GroupID string) (*Group, error) {
|
func GetGroup(GroupID string) (*Group, error) {
|
||||||
// Read group information from the
|
// Read group information from the
|
||||||
//grouptrackcontainer json file
|
//grouptrackcontainer json file
|
||||||
groups, err := ReadGroup()
|
groups, err := ReadGroup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Iterate through the set of groups and
|
// Iterate through the set of groups and
|
||||||
// if the group ID matches then return it
|
// if the group ID matches then return it
|
||||||
for i, group := range groups.GroupList {
|
for i, group := range groups.GroupList {
|
||||||
if group.ID == GroupID {
|
if group.ID == GroupID {
|
||||||
group.index = i
|
group.index = i
|
||||||
return group, nil
|
return group, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errors.New("Group not found. ")
|
return nil, errors.New("Group not found. ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddGroupToFile Adds Group struct to the GroupTrackContainer File
|
// AddGroupToFile Adds Group struct to the GroupTrackContainer File
|
||||||
func (grp *Group) AddGroupToFile() error {
|
func (grp *Group) AddGroupToFile() error {
|
||||||
// Gets all group information from the
|
// Gets all group information from the
|
||||||
// GroupTrackContainer JSON file
|
// GroupTrackContainer JSON file
|
||||||
groups, err := ReadGroup()
|
groups, err := ReadGroup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Appending the newly created group
|
// Appending the newly created group
|
||||||
groups.GroupList = append(groups.GroupList, grp)
|
groups.GroupList = append(groups.GroupList, grp)
|
||||||
// Writing Group information to the GroupTrackContainer
|
// Writing Group information to the GroupTrackContainer
|
||||||
// JSON file
|
// JSON file
|
||||||
err = groups.WriteGroup()
|
err = groups.WriteGroup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadGroup Function reads grouptrackcontainers.json and converts
|
// ReadGroup Function reads grouptrackcontainers.json and converts
|
||||||
// result to Groups
|
// result to Groups
|
||||||
func ReadGroup() (*Groups, error) {
|
func ReadGroup() (*Groups, error) {
|
||||||
// Get Path from config
|
// Get Path from config
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
jsonFile, err := os.Open(config.GroupTrackContainersPath)
|
jsonFile, err := os.Open(config.GroupTrackContainersPath)
|
||||||
// if we os.Open returns an error then handle it
|
// if we os.Open returns an error then handle it
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// defer the closing of our jsonFile so that we can parse it later on
|
// defer the closing of our jsonFile so that we can parse it later on
|
||||||
defer jsonFile.Close()
|
defer jsonFile.Close()
|
||||||
// read our opened xmlFile as a byte array.
|
// read our opened xmlFile as a byte array.
|
||||||
byteValue, _ := ioutil.ReadAll(jsonFile)
|
byteValue, _ := ioutil.ReadAll(jsonFile)
|
||||||
// we initialize our Users array
|
// we initialize our Users array
|
||||||
var groups Groups
|
var groups Groups
|
||||||
// we unmarshal our byteArray which contains our
|
// we unmarshal our byteArray which contains our
|
||||||
// jsonFile's content into 'users' which we defined above
|
// jsonFile's content into 'users' which we defined above
|
||||||
json.Unmarshal(byteValue, &groups)
|
json.Unmarshal(byteValue, &groups)
|
||||||
return &groups, nil
|
return &groups, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteGroup Function to write type Groups to the grouptrackcontainers.json file
|
// WriteGroup Function to write type Groups to the grouptrackcontainers.json file
|
||||||
func (grp *Groups) WriteGroup() error {
|
func (grp *Groups) WriteGroup() error {
|
||||||
file, err := json.MarshalIndent(grp, "", " ")
|
file, err := json.MarshalIndent(grp, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Get Path from config
|
// Get Path from config
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func MAPPort(port string) (string, error) {
|
|
||||||
Config, err := config.ConfigInit(nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
//if version == "version 6" {
|
|
||||||
URL := "http://0.0.0.0:" + Config.ServerPort + "/MAPPort?port=" + port
|
|
||||||
//} else {
|
|
||||||
// URL = "http://" + IP + ":" + serverPort + "/server_info"
|
|
||||||
//}
|
|
||||||
resp, err := http.Get(URL)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert response to byte value
|
|
||||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(byteValue), nil
|
|
||||||
}
|
|
||||||
@@ -1,149 +1,149 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TrackContainers This struct stores arrays of current containers running
|
// TrackContainers This struct stores arrays of current containers running
|
||||||
type TrackContainers struct {
|
type TrackContainers struct {
|
||||||
TrackContainerList []TrackContainer `json:"TrackContainer"`
|
TrackContainerList []TrackContainer `json:"TrackContainer"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TrackContainer Stores information of current containers
|
// TrackContainer Stores information of current containers
|
||||||
type TrackContainer struct {
|
type TrackContainer struct {
|
||||||
Id string `json:"ID"`
|
Id string `json:"ID"`
|
||||||
Container *docker.DockerVM `json:"Container"`
|
Container *docker.DockerVM `json:"Container"`
|
||||||
IpAddress string `json:"IpAddress"`
|
IpAddress string `json:"IpAddress"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddTrackContainer Adds new container which has been added to the track container
|
// AddTrackContainer Adds new container which has been added to the track container
|
||||||
func AddTrackContainer(d *docker.DockerVM, ipAddress string) error {
|
func AddTrackContainer(d *docker.DockerVM, ipAddress string) error {
|
||||||
// Checking if pointer d is null
|
// Checking if pointer d is null
|
||||||
if d == nil {
|
if d == nil {
|
||||||
return errors.New("d is nil")
|
return errors.New("d is nil")
|
||||||
}
|
}
|
||||||
//Get config information to derive paths for track containers json file
|
//Get config information to derive paths for track containers json file
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getting information about the file trackcontainers.json file
|
// Getting information about the file trackcontainers.json file
|
||||||
stat, err := os.Stat(config.TrackContainersPath)
|
stat, err := os.Stat(config.TrackContainersPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Initialize variable for TrackContainers
|
// Initialize variable for TrackContainers
|
||||||
var trackContainers TrackContainers
|
var trackContainers TrackContainers
|
||||||
// If the trackcontainers.json file is not empty then
|
// If the trackcontainers.json file is not empty then
|
||||||
// Read from that file
|
// Read from that file
|
||||||
if stat.Size() != 0 {
|
if stat.Size() != 0 {
|
||||||
// Reads tracked container file
|
// Reads tracked container file
|
||||||
trackContainersFile, err := ReadTrackContainers(config.TrackContainersPath)
|
trackContainersFile, err := ReadTrackContainers(config.TrackContainersPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
trackContainers = *trackContainersFile
|
trackContainers = *trackContainersFile
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize new variable with type struct TrackContainers and
|
// Initialize new variable with type struct TrackContainers and
|
||||||
// add container struct and ip address
|
// add container struct and ip address
|
||||||
var trackContainer TrackContainer
|
var trackContainer TrackContainer
|
||||||
trackContainer.Id = d.ID
|
trackContainer.Id = d.ID
|
||||||
trackContainer.Container = d
|
trackContainer.Container = d
|
||||||
trackContainer.IpAddress = ipAddress
|
trackContainer.IpAddress = ipAddress
|
||||||
|
|
||||||
// Adds new container as passed in the parameter to the struct
|
// Adds new container as passed in the parameter to the struct
|
||||||
if &trackContainer == nil {
|
if &trackContainer == nil {
|
||||||
return errors.New("trackContainer variable is nil")
|
return errors.New("trackContainer variable is nil")
|
||||||
}
|
}
|
||||||
trackContainers.TrackContainerList = append(trackContainers.TrackContainerList, trackContainer)
|
trackContainers.TrackContainerList = append(trackContainers.TrackContainerList, trackContainer)
|
||||||
|
|
||||||
// write modified information to the tracked json file
|
// write modified information to the tracked json file
|
||||||
data, err := json.MarshalIndent(trackContainers, "", "\t")
|
data, err := json.MarshalIndent(trackContainers, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveTrackedContainer This function removos tracked container from the trackcontainer JSON file
|
// RemoveTrackedContainer This function removos tracked container from the trackcontainer JSON file
|
||||||
func RemoveTrackedContainer(id string) error {
|
func RemoveTrackedContainer(id string) error {
|
||||||
//Get config information to derive paths for track containers json file
|
//Get config information to derive paths for track containers json file
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Getting tracked container struct
|
// Getting tracked container struct
|
||||||
trackedContainers, err := ReadTrackContainers(config.TrackContainersPath)
|
trackedContainers, err := ReadTrackContainers(config.TrackContainersPath)
|
||||||
// Storing index of element to remove
|
// Storing index of element to remove
|
||||||
var removeElement int
|
var removeElement int
|
||||||
removeElement = -1
|
removeElement = -1
|
||||||
for i := range trackedContainers.TrackContainerList {
|
for i := range trackedContainers.TrackContainerList {
|
||||||
if trackedContainers.TrackContainerList[i].Id == id {
|
if trackedContainers.TrackContainerList[i].Id == id {
|
||||||
removeElement = i
|
removeElement = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Checks if the element to be removed has been detected
|
// Checks if the element to be removed has been detected
|
||||||
if removeElement == -1 {
|
if removeElement == -1 {
|
||||||
return errors.New("Container ID not found in the tracked list")
|
return errors.New("Container ID not found in the tracked list")
|
||||||
}
|
}
|
||||||
// Remove the detected element from the struct
|
// Remove the detected element from the struct
|
||||||
trackedContainers.TrackContainerList = append(trackedContainers.TrackContainerList[:removeElement], trackedContainers.TrackContainerList[removeElement+1:]...)
|
trackedContainers.TrackContainerList = append(trackedContainers.TrackContainerList[:removeElement], trackedContainers.TrackContainerList[removeElement+1:]...)
|
||||||
|
|
||||||
// write modified information to the tracked json file
|
// write modified information to the tracked json file
|
||||||
data, err := json.MarshalIndent(trackedContainers, "", "\t")
|
data, err := json.MarshalIndent(trackedContainers, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ViewTrackedContainers View Containers currently tracked
|
// ViewTrackedContainers View Containers currently tracked
|
||||||
func ViewTrackedContainers() (error, *TrackContainers) {
|
func ViewTrackedContainers() (error, *TrackContainers) {
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err, nil
|
return err, nil
|
||||||
}
|
}
|
||||||
trackedContianers, err := ReadTrackContainers(config.TrackContainersPath)
|
trackedContianers, err := ReadTrackContainers(config.TrackContainersPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err, nil
|
return err, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, trackedContianers
|
return nil, trackedContianers
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadTrackContainers Reads containers which are currently tracked
|
// ReadTrackContainers Reads containers which are currently tracked
|
||||||
func ReadTrackContainers(filename string) (*TrackContainers, error) {
|
func ReadTrackContainers(filename string) (*TrackContainers, error) {
|
||||||
buf, err := ioutil.ReadFile(filename)
|
buf, err := ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c := &TrackContainers{}
|
c := &TrackContainers{}
|
||||||
err = json.Unmarshal(buf, c)
|
err = json.Unmarshal(buf, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("in file %q: %v", filename, err)
|
return nil, fmt.Errorf("in file %q: %v", filename, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//func ModifyTrackContainers()
|
//func ModifyTrackContainers()
|
||||||
@@ -151,70 +151,70 @@ func ReadTrackContainers(filename string) (*TrackContainers, error) {
|
|||||||
// GetContainerInformation gets information about container based on
|
// GetContainerInformation gets information about container based on
|
||||||
// container ID provided
|
// container ID provided
|
||||||
func GetContainerInformation(ID string) (*TrackContainer, error) {
|
func GetContainerInformation(ID string) (*TrackContainer, error) {
|
||||||
// Getting the current containers
|
// Getting the current containers
|
||||||
err, CurrentContainers := ViewTrackedContainers()
|
err, CurrentContainers := ViewTrackedContainers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Iterating through all tracked containers to get the container information
|
// Iterating through all tracked containers to get the container information
|
||||||
// of the ID passed through the function parameter
|
// of the ID passed through the function parameter
|
||||||
for _, container := range CurrentContainers.TrackContainerList {
|
for _, container := range CurrentContainers.TrackContainerList {
|
||||||
if container.Container.ID == ID {
|
if container.Container.ID == ID {
|
||||||
return &container, nil
|
return &container, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, errors.New("Container not found. ")
|
return nil, errors.New("Container not found. ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ModifyContainerInformation Modifies information inside the container
|
// ModifyContainerInformation Modifies information inside the container
|
||||||
func (TC *TrackContainer) ModifyContainerInformation() error {
|
func (TC *TrackContainer) ModifyContainerInformation() error {
|
||||||
// Gets all the information of tracker containers
|
// Gets all the information of tracker containers
|
||||||
err, t := ViewTrackedContainers()
|
err, t := ViewTrackedContainers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Find the element where the containers match and
|
// Find the element where the containers match and
|
||||||
// change them
|
// change them
|
||||||
for i, container := range t.TrackContainerList {
|
for i, container := range t.TrackContainerList {
|
||||||
if TC.Id == container.Id {
|
if TC.Id == container.Id {
|
||||||
t.TrackContainerList[i] = *TC
|
t.TrackContainerList[i] = *TC
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Write the modified information to the file
|
// Write the modified information to the file
|
||||||
// write modified information to the tracked json file
|
// write modified information to the tracked json file
|
||||||
err = t.WriteContainers()
|
err = t.WriteContainers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContainers Write information back to the config file
|
// WriteContainers Write information back to the config file
|
||||||
func (TC *TrackContainers) WriteContainers() error {
|
func (TC *TrackContainers) WriteContainers() error {
|
||||||
// Initialize config file
|
// Initialize config file
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
// 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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
package clientIPTable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
|
||||||
)
|
|
||||||
|
|
||||||
func AddCustomInformationToIPTable(text string) error {
|
|
||||||
// Get config information
|
|
||||||
Config, err := config.ConfigInit(nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get IPTable information
|
|
||||||
table, err := p2p.ReadIpTable()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
found := false
|
|
||||||
|
|
||||||
for i, _ := range table.IpAddress {
|
|
||||||
if table.IpAddress[i].Name == Config.MachineName {
|
|
||||||
table.IpAddress[i].CustomInformation = text
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if found {
|
|
||||||
table.WriteIpTable()
|
|
||||||
// update IPTable after modified entry
|
|
||||||
UpdateIpTableListClient()
|
|
||||||
} else {
|
|
||||||
return errors.New("start server with p2prc -s as the server is currently not running")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -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,145 +18,136 @@ var mu sync.Mutex
|
|||||||
// UpdateIpTable Does the following to update it's IP table
|
// UpdateIpTable Does the following to update it's IP table
|
||||||
func UpdateIpTable(IpAddress string, serverPort string, wg *sync.WaitGroup) error {
|
func UpdateIpTable(IpAddress string, serverPort string, wg *sync.WaitGroup) error {
|
||||||
|
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
client := http.Client{}
|
client := http.Client{}
|
||||||
|
|
||||||
var resp []byte
|
var resp []byte
|
||||||
|
|
||||||
version := p2p.Ip4or6(IpAddress)
|
version := p2p.Ip4or6(IpAddress)
|
||||||
if version == "version 6" {
|
if version == "version 6" {
|
||||||
resp, err = UploadMultipartFile(client, "http://["+IpAddress+"]:"+serverPort+"/IpTable", "json", config.IPTable)
|
resp, err = UploadMultipartFile(client, "http://["+IpAddress+"]:"+serverPort+"/IpTable", "json", config.IPTable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resp, err = UploadMultipartFile(client, "http://"+IpAddress+":"+serverPort+"/IpTable", "json", config.IPTable)
|
resp, err = UploadMultipartFile(client, "http://"+IpAddress+":"+serverPort+"/IpTable", "json", config.IPTable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp == nil {
|
if resp == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//resp, err := SendPostRequest("http://"+IpAddress+":8088/IpTable",
|
//resp, err := SendPostRequest("http://"+IpAddress+":8088/IpTable",
|
||||||
// config.IPTable,
|
// config.IPTable,
|
||||||
// "json")
|
// "json")
|
||||||
//
|
//
|
||||||
//if err != nil {
|
//if err != nil {
|
||||||
// return err
|
// return err
|
||||||
//}
|
//}
|
||||||
|
|
||||||
var ipStruct p2p.IpAddresses
|
var ipStruct p2p.IpAddresses
|
||||||
json.Unmarshal(resp, &ipStruct)
|
json.Unmarshal(resp, &ipStruct)
|
||||||
|
|
||||||
// Updates IP table based on information provided
|
// Updates IP table based on information provided
|
||||||
// by the server
|
// by the server
|
||||||
if len(ipStruct.IpAddress) > 0 {
|
if len(ipStruct.IpAddress) > 0 {
|
||||||
err = ipStruct.SpeedTestUpdatedIPTable()
|
err = ipStruct.SpeedTestUpdatedIPTable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ipStruct.WriteIpTable()
|
err = ipStruct.WriteIpTable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Done()
|
wg.Done()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateIpTableListClient updates IP tables (Default 3 hops) based on server information available
|
// UpdateIpTableListClient updates IP tables (Default 3 hops) based on server information available
|
||||||
// on the ip tables
|
// on the ip tables
|
||||||
func UpdateIpTableListClient() error {
|
func UpdateIpTableListClient() error {
|
||||||
// Get config information
|
// Get config information
|
||||||
Config, err := config.ConfigInit(nil, nil)
|
Config, err := config.ConfigInit()
|
||||||
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
|
||||||
}
|
|
||||||
|
|
||||||
func RemoveOfflineNodes() error {
|
|
||||||
// Ensure that the IP Table has Node pingable
|
|
||||||
err := p2p.LocalSpeedTestIpTable()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendPostRequest Sends a file as a
|
// SendPostRequest Sends a file as a
|
||||||
@@ -206,58 +197,58 @@ func RemoveOfflineNodes() 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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
b64 "encoding/base64"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"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/server/docker"
|
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -21,7 +19,7 @@ var (
|
|||||||
// From the selected server IP address
|
// From the selected server IP address
|
||||||
// TODO: Test cases for this function
|
// TODO: Test cases for this function
|
||||||
// Calls URL ex: http://0.0.0.0:8088/startcontainer?ports=0&GPU=false&ContainerName=docker-ubuntu-sshd
|
// Calls URL ex: http://0.0.0.0:8088/startcontainer?ports=0&GPU=false&ContainerName=docker-ubuntu-sshd
|
||||||
func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string, baseImage string) (*docker.DockerVM, error) {
|
func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string) (*docker.DockerVM, error) {
|
||||||
// Passes URL with number of TCP ports to allocated and to give GPU access to the docker container
|
// Passes URL with number of TCP ports to allocated and to give GPU access to the docker container
|
||||||
var URL string
|
var URL string
|
||||||
//version := p2p.Ip4or6(IP)
|
//version := p2p.Ip4or6(IP)
|
||||||
@@ -35,22 +33,9 @@ func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string, bas
|
|||||||
//if version == "version 6" {
|
//if version == "version 6" {
|
||||||
// URL = "http://[" + IP + "]:" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
// URL = "http://[" + IP + "]:" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
||||||
//} else {
|
//} else {
|
||||||
// Get config information
|
URL = "http://" + IP + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
||||||
Config, err := config.ConfigInit(nil, nil)
|
//}
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get public key
|
|
||||||
PublicKey, err := Config.GetPublicKey()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used in URL to pass public key -> b64.StdEncoding.EncodeToString([]byte(PublicKey))
|
|
||||||
URL = `http://` + IP + `/startcontainer?ports=` + fmt.Sprint(NumPorts) + `&GPU=` + strconv.FormatBool(GPU) + `&ContainerName=` + ContainerName + `&BaseImage=` + baseImage + `&PublicKey=` + b64.StdEncoding.EncodeToString([]byte(PublicKey))
|
|
||||||
|
|
||||||
// Encode URL due to public key passed.
|
|
||||||
resp, err := http.Get(URL)
|
resp, err := http.Get(URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
@@ -4,7 +4,8 @@ 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/generate"
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
|
"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"
|
||||||
@@ -13,14 +14,11 @@ import (
|
|||||||
|
|
||||||
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)
|
//Listing servers and also updates IP tables (Default 3 hops)
|
||||||
@@ -95,14 +93,10 @@ var CliAction = func(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Function called to stop and remove server from Docker
|
// Function called to stop and remove server from Docker
|
||||||
if RemoveVM != "" {
|
if RemoveVM != "" && ID != "" {
|
||||||
if ID == "" {
|
err := client.RemoveContianer(RemoveVM, ID)
|
||||||
fmt.Println("provide container ID via --ID or --id")
|
if err != nil {
|
||||||
} else {
|
fmt.Print(err)
|
||||||
err := client.RemoveContianer(RemoveVM, ID)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Print(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +111,7 @@ var CliAction = func(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calls function to do Api call to start the container on the server side
|
// Calls function to do Api call to start the container on the server side
|
||||||
imageRes, err := client.StartContainer(CreateVM, PortsInt, GPU, ContainerName, BaseImage)
|
imageRes, err := client.StartContainer(CreateVM, PortsInt, GPU, ContainerName)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Print(err)
|
fmt.Print(err)
|
||||||
@@ -138,7 +132,7 @@ var CliAction = func(ctx *cli.Context) error {
|
|||||||
|
|
||||||
//Sets default paths to the config file
|
//Sets default paths to the config file
|
||||||
if SetDefaultConfig {
|
if SetDefaultConfig {
|
||||||
_, err := generate.SetDefaults("P2PRC", false, nil, false)
|
err := config.SetDefaults()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Print(err)
|
fmt.Print(err)
|
||||||
}
|
}
|
||||||
@@ -185,7 +179,7 @@ var CliAction = func(ctx *cli.Context) error {
|
|||||||
fmt.Println("Success")
|
fmt.Println("Success")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("provide container ID via --ID or --id")
|
fmt.Println("provide container ID")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -253,6 +247,39 @@ var CliAction = func(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Starts server as a reverse proxy so that
|
||||||
|
// nodes can connect to each other behind NAT
|
||||||
|
//if FRPProxy {
|
||||||
|
// err := frp.StartFRPProxyFromRandom()
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Println(err)
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
// -- 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 != "" {
|
||||||
@@ -273,26 +300,5 @@ var CliAction = func(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if AddMetaData != "" {
|
|
||||||
err := clientIPTable.AddCustomInformationToIPTable(AddMetaData)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
} else {
|
|
||||||
fmt.Println("Success")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if MAPPort != "" {
|
|
||||||
address, err := client.MAPPort(MAPPort)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
} else {
|
|
||||||
fmt.Println(address)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
28
cmd/flags.go
28
cmd/flags.go
@@ -10,7 +10,6 @@ var (
|
|||||||
ViewImages string
|
ViewImages string
|
||||||
CreateVM string
|
CreateVM string
|
||||||
ContainerName string
|
ContainerName string
|
||||||
BaseImage string
|
|
||||||
Ports string
|
Ports string
|
||||||
Server bool
|
Server bool
|
||||||
RemoveVM string
|
RemoveVM string
|
||||||
@@ -29,7 +28,6 @@ var (
|
|||||||
Groups bool
|
Groups bool
|
||||||
RemoveContainerGroup bool
|
RemoveContainerGroup bool
|
||||||
RemoveGroup string
|
RemoveGroup string
|
||||||
MAPPort string
|
|
||||||
//FRPProxy bool
|
//FRPProxy bool
|
||||||
// Generate only allowed in dev release
|
// Generate only allowed in dev release
|
||||||
// -- REMOVE ON REGULAR RELEASE --
|
// -- REMOVE ON REGULAR RELEASE --
|
||||||
@@ -38,7 +36,6 @@ var (
|
|||||||
//--------------------------------
|
//--------------------------------
|
||||||
PullPlugin string
|
PullPlugin string
|
||||||
RemovePlugin string
|
RemovePlugin string
|
||||||
AddMetaData string
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var AppConfigFlags = []cli.Flag{
|
var AppConfigFlags = []cli.Flag{
|
||||||
@@ -92,17 +89,10 @@ var AppConfigFlags = []cli.Flag{
|
|||||||
EnvVars: []string{"CONTAINER_NAME"},
|
EnvVars: []string{"CONTAINER_NAME"},
|
||||||
Destination: &ContainerName,
|
Destination: &ContainerName,
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "BaseImage",
|
|
||||||
Aliases: []string{"bi"},
|
|
||||||
Usage: "Specifying the docker base image to template the dockerfile",
|
|
||||||
EnvVars: []string{"CONTAINER_NAME"},
|
|
||||||
Destination: &BaseImage,
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "RemoveVM",
|
Name: "RemoveVM",
|
||||||
Aliases: []string{"rm"},
|
Aliases: []string{"rm"},
|
||||||
Usage: "Stop and Remove Docker container (IP:port) accompanied by container ID via --ID or --id",
|
Usage: "Stop and Remove Docker container",
|
||||||
EnvVars: []string{"REMOVE_VM"},
|
EnvVars: []string{"REMOVE_VM"},
|
||||||
Destination: &RemoveVM,
|
Destination: &RemoveVM,
|
||||||
},
|
},
|
||||||
@@ -158,7 +148,7 @@ var AppConfigFlags = []cli.Flag{
|
|||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "TrackedContainers",
|
Name: "TrackedContainers",
|
||||||
Aliases: []string{"tc"},
|
Aliases: []string{"tc"},
|
||||||
Usage: "View (currently running) containers which have " +
|
Usage: "View 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,
|
||||||
@@ -205,13 +195,6 @@ var AppConfigFlags = []cli.Flag{
|
|||||||
EnvVars: []string{"REMOVE_GROUP"},
|
EnvVars: []string{"REMOVE_GROUP"},
|
||||||
Destination: &RemoveGroup,
|
Destination: &RemoveGroup,
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "MAPPort",
|
|
||||||
Aliases: []string{"mp"},
|
|
||||||
Usage: "Maps port for a specific port provided as the parameter",
|
|
||||||
EnvVars: []string{"MAPPORT"},
|
|
||||||
Destination: &MAPPort,
|
|
||||||
},
|
|
||||||
// Generate only allowed in dev release
|
// Generate only allowed in dev release
|
||||||
// -- REMOVE ON REGULAR RELEASE --
|
// -- REMOVE ON REGULAR RELEASE --
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
@@ -250,11 +233,4 @@ var AppConfigFlags = []cli.Flag{
|
|||||||
EnvVars: []string{"REMOVEPLUGIN"},
|
EnvVars: []string{"REMOVEPLUGIN"},
|
||||||
Destination: &RemovePlugin,
|
Destination: &RemovePlugin,
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "AddMetaData",
|
|
||||||
Aliases: []string{"amd"},
|
|
||||||
Usage: "Adds metadata about the current node in the p2p network which is then propagated through the network",
|
|
||||||
EnvVars: []string{"ADDMETADATA"},
|
|
||||||
Destination: &AddMetaData,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|||||||
253
config/config.go
253
config/config.go
@@ -1,13 +1,13 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"github.com/spf13/viper"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//defaultPath string
|
defaultPath string
|
||||||
defaults = map[string]interface{}{}
|
defaults = map[string]interface{}{}
|
||||||
configName = "config"
|
configName = "config"
|
||||||
configType = "json"
|
configType = "json"
|
||||||
@@ -21,7 +21,6 @@ type Config struct {
|
|||||||
IPTable string
|
IPTable string
|
||||||
DockerContainers string
|
DockerContainers string
|
||||||
DefaultDockerFile string
|
DefaultDockerFile string
|
||||||
DockerRunLogs string
|
|
||||||
SpeedTestFile string
|
SpeedTestFile string
|
||||||
IPV6Address string
|
IPV6Address string
|
||||||
PluginPath string
|
PluginPath string
|
||||||
@@ -30,36 +29,46 @@ type Config struct {
|
|||||||
GroupTrackContainersPath string
|
GroupTrackContainersPath string
|
||||||
FRPServerPort string
|
FRPServerPort string
|
||||||
BehindNAT string
|
BehindNAT string
|
||||||
IPTableKey string
|
|
||||||
PublicKeyFile string
|
|
||||||
PrivateKeyFile string
|
|
||||||
BareMetal string
|
|
||||||
CustomConfig interface{}
|
|
||||||
//NetworkInterface string
|
//NetworkInterface string
|
||||||
//NetworkInterfaceIPV6Index int
|
//NetworkInterfaceIPV6Index int
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentPath Getting P2PRC Directory from environment variable
|
// Exists reports whether the named file or directory exists.
|
||||||
func GetCurrentPath() (string, error) {
|
func fileExists(name string) bool {
|
||||||
curDir := os.Getenv("PWD")
|
if _, err := os.Stat(name); err != nil {
|
||||||
return curDir + "/", 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(Envname string) (string, error) {
|
func GetPathP2PRC() (string, error) {
|
||||||
if Envname != "" {
|
|
||||||
err := SetEnvName(Envname)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
curDir := os.Getenv(defaultEnvName)
|
curDir := os.Getenv(defaultEnvName)
|
||||||
if curDir == "" {
|
|
||||||
// if the OS env path is not found then you use
|
|
||||||
// the current directory path.
|
|
||||||
currentPath, _ := GetCurrentPath()
|
|
||||||
return currentPath, nil
|
|
||||||
}
|
|
||||||
return curDir + "/", nil
|
return curDir + "/", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,109 +82,115 @@ func SetEnvName(EnvName string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetEnvName() string {
|
// GetCurrentPath Getting P2PRC Directory from environment variable
|
||||||
return defaultEnvName
|
func GetCurrentPath() (string, error) {
|
||||||
|
curDir := os.Getenv("PWD")
|
||||||
|
return curDir + "/", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigInit Pass environment name as an optional parameter
|
// SetDefaults This function to be called only during a
|
||||||
func ConfigInit(defaultsParameter map[string]interface{}, CustomConfig interface{}, envNameOptional ...string) (*Config, error) {
|
// make install
|
||||||
if len(envNameOptional) > 0 {
|
func SetDefaults() error {
|
||||||
defaultEnvName = envNameOptional[0]
|
//Setting current directory to default path
|
||||||
}
|
defaultPath, err := GetPathP2PRC()
|
||||||
//
|
|
||||||
////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
|
|
||||||
|
|
||||||
defaultPath, err := GetPathP2PRC(defaultEnvName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open our jsonFile
|
|
||||||
jsonFile, err := os.Open(defaultPath + configFile)
|
|
||||||
// if we os.Open returns an error then handle it
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// defer the closing of our jsonFile so that we can parse it later on
|
|
||||||
defer jsonFile.Close()
|
|
||||||
|
|
||||||
byteValue, _ := ioutil.ReadAll(jsonFile)
|
|
||||||
|
|
||||||
var config Config
|
|
||||||
json.Unmarshal(byteValue, &config)
|
|
||||||
|
|
||||||
if CustomConfig != nil {
|
|
||||||
// Convert Custom Config to byte
|
|
||||||
customConfigByte, err := json.Marshal(config.CustomConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Again map the byte to the CustomConfig interface
|
|
||||||
json.Unmarshal(customConfigByte, &CustomConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &config, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) WriteConfig() error {
|
|
||||||
//Getting Current Directory from environment variable
|
|
||||||
//curDir := os.Getenv("REMOTEGAMING")
|
|
||||||
|
|
||||||
defaultPath, err := GetPathP2PRC(defaultEnvName)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
file, _ := json.MarshalIndent(c, "", " ")
|
//Creates ip_table.json in the json directory
|
||||||
|
err = Copy("p2p/ip_table.json", "p2p/iptable/ip_table.json")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
_ = ioutil.WriteFile(defaultPath+"config.json", file, 0644)
|
//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
|
||||||
|
}
|
||||||
|
|
||||||
|
//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"] = "0"
|
||||||
|
defaults["BehindNAT"] = "True"
|
||||||
|
// Random name generator
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults["MachineName"] = hostname
|
||||||
|
//defaults["NetworkInterface"] = "wlp0s20f3"
|
||||||
|
//defaults["NetworkInterfaceIPV6Index"] = "2"
|
||||||
|
|
||||||
|
//Paths to search for config file
|
||||||
|
configPaths = append(configPaths, defaultPath)
|
||||||
|
|
||||||
|
if fileExists(defaultPath + "config.json") {
|
||||||
|
err := os.Remove(defaultPath + "config.json")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Calling configuration file
|
||||||
|
_, err = ConfigInit()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPublicKey Gets public key of the current machine
|
func ConfigInit() (*Config, error) {
|
||||||
// based on the path provided on the
|
|
||||||
// config file
|
//Setting current directory to default path
|
||||||
func (c *Config) GetPublicKey() (string, error) {
|
defaultPath, err := GetPathP2PRC()
|
||||||
publicKey, err := ioutil.ReadFile(c.PublicKeyFile) // just pass the file name
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
return string(publicKey), nil
|
//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
|
||||||
}
|
}
|
||||||
|
|||||||
63
config/config_test.go
Normal file
63
config/config_test.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
package generate
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
|
||||||
"math/rand"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 := config.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"
|
|
||||||
Defaults.DockerRunLogs = "/tmp/"
|
|
||||||
// Generate a random key to be added to IPTable
|
|
||||||
Defaults.IPTableKey = String(12)
|
|
||||||
// Random name generator
|
|
||||||
hostname, err := os.Hostname()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate Public and private keys and set path
|
|
||||||
Defaults.PublicKeyFile = defaultPath + "p2prc.PublicKeyBareMetal"
|
|
||||||
Defaults.PrivateKeyFile = defaultPath + "p2prc.privateKey"
|
|
||||||
Defaults.BareMetal = "False"
|
|
||||||
|
|
||||||
PrivateKeyExists, err := FileExists(Defaults.PrivateKeyFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !PrivateKeyExists {
|
|
||||||
// Generate SSH keys
|
|
||||||
err = MakeSSHKeyPair(Defaults.PublicKeyFile, Defaults.PrivateKeyFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Defaults.MachineName = hostname + "-" + String(7)
|
|
||||||
} 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generating a random string
|
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyz" +
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
||||||
|
|
||||||
var seededRand *rand.Rand = rand.New(
|
|
||||||
rand.NewSource(time.Now().UnixNano()))
|
|
||||||
|
|
||||||
func StringWithCharset(length int, charset string) string {
|
|
||||||
b := make([]byte, length)
|
|
||||||
for i := range b {
|
|
||||||
b[i] = charset[seededRand.Intn(len(charset))]
|
|
||||||
}
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func String(length int) string {
|
|
||||||
return StringWithCharset(length, charset)
|
|
||||||
}
|
|
||||||
@@ -1,290 +0,0 @@
|
|||||||
package generate
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/pem"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
|
||||||
"github.com/go-git/go-git/v5"
|
|
||||||
"golang.org/x/crypto/ssh"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GenerateFiles Generates all the files needed to setup P2PRC
|
|
||||||
func GenerateFiles(rootNodes ...p2p.IpAddress) (err error) {
|
|
||||||
err = GenerateIPTableFile(rootNodes)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = GenerateDockerFiles()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = GeneratePluginDirectory()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
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 = "8078"
|
|
||||||
rootnode.NAT = "False"
|
|
||||||
rootnode.Ipv4 = "217.76.63.222"
|
|
||||||
|
|
||||||
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 := config.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 := config.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 := config.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 := config.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.Mkdir(path+"client/trackcontainers", os.ModePerm); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = os.Stat(path + "client/trackcontainers/trackcontainers.json"); os.IsNotExist(err) {
|
|
||||||
_, err = os.Create(path + "client/trackcontainers/trackcontainers.json")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = os.Create(path + "client/trackcontainers/grouptrackcontainers.json")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeSSHKeyPair make a pair of public and private keys for SSH access.
|
|
||||||
// Public key is encoded in the format for inclusion in an OpenSSH authorized_keys file.
|
|
||||||
// Private Key generated is PEM encoded
|
|
||||||
// source: https://gist.github.com/goliatone/e9c13e5f046e34cef6e150d06f20a34c
|
|
||||||
func MakeSSHKeyPair(pubKeyPath, privateKeyPath string) error {
|
|
||||||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// generate and write private key as PEM
|
|
||||||
privateKeyFile, err := os.Create(privateKeyPath)
|
|
||||||
defer privateKeyFile.Close()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set permission to private key to SSH into docker machine
|
|
||||||
err = os.Chmod(privateKeyPath, 600)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}
|
|
||||||
if err := pem.Encode(privateKeyFile, privateKeyPEM); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// generate and write public key
|
|
||||||
pub, err := ssh.NewPublicKey(&privateKey.PublicKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return ioutil.WriteFile(pubKeyPath, ssh.MarshalAuthorizedKey(pub), 0655)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileExists exists returns whether the given file or directory exists
|
|
||||||
// source: https://stackoverflow.com/questions/10510691/how-to-check-whether-a-file-or-directory-exists
|
|
||||||
func FileExists(path string) (bool, error) {
|
|
||||||
_, err := os.Stat(path)
|
|
||||||
if err == nil {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuthorizedKey struct represents the structure of an authorized key
|
|
||||||
type AuthorizedKey struct {
|
|
||||||
Username string
|
|
||||||
Key string
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddPublicKeyBareMetal Adds the parameter public key to the auth list
|
|
||||||
// Generated by ChatGPT
|
|
||||||
// Prompts:
|
|
||||||
// - Generate a go program to read authorised key and map it to a struct and write it back to the same location.
|
|
||||||
// - Can you follow the original format
|
|
||||||
// (TURNED OUT TO BE PRETTY SHITTY GENERATED CODE)
|
|
||||||
//func AddPublicKeyBareMetal(PublicKey string) error {
|
|
||||||
// // Specify the path to the authorized_keys file
|
|
||||||
// dirname, err := os.UserHomeDir()
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// authorizedKeysPath := dirname + "/.ssh/" + "authorized_keys"
|
|
||||||
//
|
|
||||||
// // Read the contents of the authorized_keys file
|
|
||||||
// file, err := os.Open(authorizedKeysPath)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// defer file.Close()
|
|
||||||
//
|
|
||||||
// // Create a slice to store AuthorizedKey structs
|
|
||||||
// var authorizedKeys []AuthorizedKey
|
|
||||||
//
|
|
||||||
// // Read each line of the file and parse the data
|
|
||||||
// scanner := bufio.NewScanner(file)
|
|
||||||
// for scanner.Scan() {
|
|
||||||
// line := scanner.Text()
|
|
||||||
// parts := strings.Fields(line)
|
|
||||||
// if len(parts) >= 2 {
|
|
||||||
// authorizedKey := AuthorizedKey{
|
|
||||||
// Username: parts[0],
|
|
||||||
// Key: parts[1],
|
|
||||||
// }
|
|
||||||
// authorizedKeys = append(authorizedKeys, authorizedKey)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if err := scanner.Err(); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Modify the slice of structs if needed
|
|
||||||
// // authorizedKeys[0].Username = "newUsername"
|
|
||||||
// // authorizedKeys[0].Key = "newKey"
|
|
||||||
// authorizedKeys = append(authorizedKeys, AuthorizedKey{Username: "", Key: PublicKey})
|
|
||||||
//
|
|
||||||
// // Write the modified data back to the authorized_keys file
|
|
||||||
// newFile, err := os.Create(authorizedKeysPath)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// defer newFile.Close()
|
|
||||||
//
|
|
||||||
// return nil
|
|
||||||
//}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
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)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test case to generate public and private keys
|
|
||||||
func TestGeneratePublicAndPrivateKeys(t *testing.T) {
|
|
||||||
MakeSSHKeyPair("test.pub", "test.prv")
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
||||||
22
default.nix
22
default.nix
@@ -1,22 +0,0 @@
|
|||||||
{ nixpkgs ? import <nixpkgs> { } }:
|
|
||||||
|
|
||||||
let
|
|
||||||
pkgs = [
|
|
||||||
nixpkgs.go
|
|
||||||
nixpkgs.tmux
|
|
||||||
nixpkgs.docker
|
|
||||||
nixpkgs.vim
|
|
||||||
];
|
|
||||||
|
|
||||||
in
|
|
||||||
nixpkgs.stdenv.mkDerivation {
|
|
||||||
name = "env";
|
|
||||||
buildInputs = pkgs;
|
|
||||||
pure-eval = true;
|
|
||||||
shellHook =
|
|
||||||
''
|
|
||||||
make
|
|
||||||
export P2PRC=$PWD
|
|
||||||
export PATH=$PWD:$PATH
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
386
generate/generate.go
Normal file
386
generate/generate.go
Normal file
@@ -0,0 +1,386 @@
|
|||||||
|
// 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
|
||||||
|
}
|
||||||
112
generate/generate_test.go
Normal file
112
generate/generate_test.go
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
49
generate/modifyGenerate.go
Normal file
49
generate/modifyGenerate.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
9
generate/testcaseAST.go
Normal file
9
generate/testcaseAST.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCaseAST() {
|
||||||
|
fmt.Println("lol")
|
||||||
|
}
|
||||||
11
go.mod
11
go.mod
@@ -3,25 +3,28 @@ module github.com/Akilan1999/p2p-rendering-computation
|
|||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3 // indirect
|
github.com/Microsoft/hcsshim v0.8.15 // indirect
|
||||||
github.com/apenella/go-ansible v1.1.0
|
github.com/apenella/go-ansible v1.1.0
|
||||||
github.com/containerd/containerd v1.5.0-beta.1 // indirect
|
github.com/containerd/continuity v0.0.0-20210315143101-93e15499afd5 // indirect
|
||||||
github.com/docker/docker v20.10.0-beta1.0.20201113105859-b6bfff2a628f+incompatible
|
github.com/docker/docker v20.10.0-beta1.0.20201113105859-b6bfff2a628f+incompatible
|
||||||
github.com/docker/go-connections v0.4.0 // indirect
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/fatedier/frp v0.45.0
|
github.com/fatedier/frp v0.45.0
|
||||||
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/term v0.0.0-20201110203204-bea5bbe245bf // indirect
|
github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf // indirect
|
||||||
github.com/morikuni/aec v1.0.0 // indirect
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
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/crypto v0.16.0
|
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
|
||||||
)
|
)
|
||||||
|
|||||||
52
go.sum
52
go.sum
@@ -65,6 +65,7 @@ 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=
|
||||||
@@ -79,6 +80,8 @@ github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3h
|
|||||||
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
|
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
|
||||||
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
|
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
|
||||||
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
||||||
|
github.com/Microsoft/hcsshim v0.8.15 h1:Aof83YILRs2Vx3GhHqlvvfyx1asRJKMFIMeVlHsZKtI=
|
||||||
|
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
|
||||||
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
||||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
@@ -153,6 +156,7 @@ github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLE
|
|||||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
||||||
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
|
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
|
||||||
github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||||
|
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102 h1:Qf4HiqfvmB7zS6scsmNgTLmByHbq8n9RTF39v+TzP7A=
|
||||||
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||||
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||||
@@ -171,6 +175,8 @@ github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL
|
|||||||
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||||
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
|
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
|
||||||
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
|
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
|
||||||
|
github.com/containerd/continuity v0.0.0-20210315143101-93e15499afd5 h1:k6Dn7shF+i1q4utvCyW4+o9REsCMAeRyORM5IhXMCnw=
|
||||||
|
github.com/containerd/continuity v0.0.0-20210315143101-93e15499afd5/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
|
||||||
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||||
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||||
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
|
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
|
||||||
@@ -279,6 +285,7 @@ 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=
|
||||||
@@ -362,6 +369,7 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er
|
|||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
@@ -443,6 +451,8 @@ 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=
|
||||||
@@ -476,6 +486,7 @@ 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=
|
||||||
@@ -547,6 +558,7 @@ 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=
|
||||||
@@ -577,9 +589,13 @@ 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=
|
||||||
|
github.com/moby/sys/mount v0.2.0 h1:WhCW5B355jtxndN5ovugJlMFJawbUODuW8fSnEH6SSM=
|
||||||
|
github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7sxOougM=
|
||||||
|
github.com/moby/sys/mountinfo v0.4.0 h1:1KInV3Huv18akCu58V7lzNlt+jFmqlu1EaErnEHE/VM=
|
||||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||||
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
|
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
|
||||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||||
@@ -639,6 +655,7 @@ github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5X
|
|||||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||||
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||||
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||||
|
github.com/opencontainers/runc v1.0.0-rc93 h1:x2UMpOOVf3kQ8arv/EsDGwim8PTNqzL1/EYDr/+scOM=
|
||||||
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
|
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
|
||||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
@@ -657,6 +674,7 @@ 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=
|
||||||
@@ -752,19 +770,24 @@ 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=
|
||||||
@@ -784,6 +807,7 @@ 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=
|
||||||
@@ -854,6 +878,7 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||||
|
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
|
||||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
@@ -878,9 +903,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm
|
|||||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38=
|
||||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
|
||||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@@ -917,8 +941,8 @@ 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/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|
||||||
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=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -977,10 +1001,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
|
|||||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
|
||||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@@ -1011,8 +1033,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -1108,17 +1130,11 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
|
||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
|
||||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
|
||||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@@ -1127,11 +1143,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@@ -1202,7 +1215,6 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
|||||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
setx PATH "%PATH%;%cd%"
|
|
||||||
setx P2PRC "%cd%"
|
|
||||||
|
|
||||||
p2p-rendering-computation.exe --dc
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# This script setups up the project P2PRC
|
|
||||||
echo '# Add the following paths to .bashrc or .zshrc based on the configuration you have set'
|
|
||||||
echo export P2PRC=$PWD
|
|
||||||
echo export PATH=$PWD:\${PATH}
|
|
||||||
export P2PRC=${PWD}
|
|
||||||
export PATH=${PWD}:${PATH}
|
|
||||||
|
|
||||||
./p2p-rendering-computation --dc
|
|
||||||
31
main.go
31
main.go
@@ -1,15 +1,14 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"github.com/Akilan1999/p2p-rendering-computation/cmd"
|
||||||
"os"
|
"github.com/urfave/cli/v2"
|
||||||
|
"log"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/cmd"
|
"os"
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// VERSION specifies the version of the platform
|
// VERSION specifies the version of the platform
|
||||||
var VERSION = "2.0.0"
|
var VERSION = "1.5.0"
|
||||||
var mode string
|
var mode string
|
||||||
|
|
||||||
// Varaibles if mode is client
|
// Varaibles if mode is client
|
||||||
@@ -17,15 +16,15 @@ var OS, Pull_location, Run_script string
|
|||||||
var List_servers, Ip_table bool
|
var List_servers, Ip_table bool
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
app.Name = "p2p-rendering-computation"
|
app.Name = "p2p-rendering-computation"
|
||||||
app.Usage = "p2p cli application to create and access VMs in other servers"
|
app.Usage = "p2p cli application to create and access VMs in other servers"
|
||||||
app.Version = VERSION
|
app.Version = VERSION
|
||||||
app.Flags = cmd.AppConfigFlags
|
app.Flags = cmd.AppConfigFlags
|
||||||
app.Action = cmd.CliAction
|
app.Action = cmd.CliAction
|
||||||
|
|
||||||
err := app.Run(os.Args)
|
err := app.Run(os.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,178 +1,165 @@
|
|||||||
package frp
|
package frp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
"fmt"
|
||||||
"github.com/fatedier/frp/client"
|
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||||
"github.com/fatedier/frp/pkg/config"
|
"github.com/fatedier/frp/client"
|
||||||
"math/rand"
|
"github.com/fatedier/frp/pkg/config"
|
||||||
"strconv"
|
"github.com/phayes/freeport"
|
||||||
"time"
|
"math/rand"
|
||||||
"github.com/phayes/freeport"
|
"strconv"
|
||||||
|
"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
|
||||||
// remote port is a custom external port a user would want
|
func StartFRPClientForServer(ipaddress string, port string, localport string) (string, error) {
|
||||||
// to open. This under the assumption the user knows the
|
// Setup server information
|
||||||
// exact port available in server doing the TURN connection.
|
var s Server
|
||||||
func StartFRPClientForServer(ipaddress string, port string, localport string, remoteport string) (string, error) {
|
s.address = ipaddress
|
||||||
// Setup server information
|
// convert port to int
|
||||||
var s Server
|
portInt, err := strconv.Atoi(port)
|
||||||
s.address = ipaddress
|
if err != nil {
|
||||||
// convert port to int
|
return "", err
|
||||||
portInt, err := strconv.Atoi(port)
|
}
|
||||||
if err != nil {
|
s.port = portInt
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
var OpenPorts []int
|
//random port
|
||||||
// if the remote port is
|
//randPort := rangeIn(10000, 99999)
|
||||||
// not empty then set the remote port to that.
|
OpenPorts, err := freeport.GetFreePorts(1)
|
||||||
if remoteport != "" {
|
if err != nil {
|
||||||
// converts localport to int
|
return "", err
|
||||||
portIntRemote, err := strconv.Atoi(remoteport)
|
}
|
||||||
if err != nil {
|
c.ClientMappings = []ClientMapping{
|
||||||
return "", err
|
{
|
||||||
}
|
LocalIP: "localhost",
|
||||||
OpenPorts = append(OpenPorts, portIntRemote)
|
LocalPort: portInt,
|
||||||
} else {
|
RemotePort: OpenPorts[0],
|
||||||
//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
|
||||||
for i, _ := range Docker.Ports.PortSet {
|
fmt.Println(len(Docker.Ports.PortSet))
|
||||||
portMap := Docker.Ports.PortSet[i].ExternalPort
|
for i, _ := range Docker.Ports.PortSet {
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
{
|
{
|
||||||
"ip_address": [
|
"ip_address": [
|
||||||
{
|
{
|
||||||
"Name": "Node1",
|
"Name": "Node1",
|
||||||
"IPV4": "139.59.162.154",
|
"IPV4": "64.227.168.102",
|
||||||
"IPV6": "",
|
"IPV6": "",
|
||||||
"Latency": 0,
|
"Latency": 0,
|
||||||
"Download": 0,
|
"ServerPort": "8088",
|
||||||
"Upload": 0,
|
"NAT": "False",
|
||||||
"ServerPort": "8078",
|
"EscapeImplementation": "None"
|
||||||
"NAT": "False",
|
}
|
||||||
"EscapeImplementation": "",
|
]
|
||||||
"CustomInformation": null
|
}
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package p2p
|
package p2p
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
@@ -27,11 +25,8 @@ type IpAddress struct {
|
|||||||
Download float64 `json:"Download"`
|
Download float64 `json:"Download"`
|
||||||
Upload float64 `json:"Upload"`
|
Upload float64 `json:"Upload"`
|
||||||
ServerPort string `json:"ServerPort"`
|
ServerPort string `json:"ServerPort"`
|
||||||
BareMetalSSHPort string `json:"BareMetalSSHPort"`
|
|
||||||
NAT string `json:"NAT"`
|
NAT string `json:"NAT"`
|
||||||
EscapeImplementation string `json:"EscapeImplementation"`
|
EscapeImplementation string `json:"EscapeImplementation"`
|
||||||
CustomInformation string `json:"CustomInformation"`
|
|
||||||
//CustomInformationKey []byte `json:"CustomInformationKey"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type IP struct {
|
type IP struct {
|
||||||
@@ -41,7 +36,7 @@ type IP struct {
|
|||||||
// ReadIpTable Read data from Ip tables from json file
|
// ReadIpTable Read data from Ip tables from json file
|
||||||
func ReadIpTable() (*IpAddresses, error) {
|
func ReadIpTable() (*IpAddresses, error) {
|
||||||
// Get Path from config
|
// Get Path from config
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -106,7 +101,7 @@ func (i *IpAddresses) WriteIpTable() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get Path from config
|
// Get Path from config
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -122,17 +117,17 @@ func (i *IpAddresses) WriteIpTable() error {
|
|||||||
// 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
|
||||||
}
|
}
|
||||||
@@ -194,7 +189,7 @@ func CurrentPublicIP() (string, error) {
|
|||||||
// GetCurrentIPV6 gets the current IPV6 address based on the interface
|
// GetCurrentIPV6 gets the current IPV6 address based on the interface
|
||||||
// specified in the config file
|
// specified in the config file
|
||||||
func GetCurrentIPV6() (string, error) {
|
func GetCurrentIPV6() (string, error) {
|
||||||
Config, err := config.ConfigInit(nil, nil)
|
Config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -259,36 +254,13 @@ func Ip4or6(s string) string {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrettyPrint(data interface{}) {
|
//func PrettyPrint(data interface{}) {
|
||||||
var p []byte
|
// var p []byte
|
||||||
// var err := error
|
// // var err := error
|
||||||
p, err := json.MarshalIndent(data, "", "\t")
|
// p, err := json.MarshalIndent(data, "", "\t")
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
fmt.Println(err)
|
// fmt.Println(err)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
fmt.Printf("%s \n", p)
|
// fmt.Printf("%s \n", p)
|
||||||
}
|
//}
|
||||||
|
|
||||||
func GenerateHashSHA256(text string) []byte {
|
|
||||||
h := sha256.New()
|
|
||||||
h.Write([]byte(text))
|
|
||||||
|
|
||||||
return h.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateHashSHA256 CustomInformationKey the text and check if the text and
|
|
||||||
// the hash are the same, if they are
|
|
||||||
// then return true
|
|
||||||
// SHA256 is the current hashing algorthm
|
|
||||||
// used.
|
|
||||||
func ValidateHashSHA256(text string, Hash []byte) bool {
|
|
||||||
h := sha256.New()
|
|
||||||
h.Write([]byte(text))
|
|
||||||
|
|
||||||
textHash := h.Sum(nil)
|
|
||||||
if bytes.Equal(textHash, Hash) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package p2p
|
package p2p
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// var dlSizes = [...]int{350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000}
|
// var dlSizes = [...]int{350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000}
|
||||||
@@ -80,100 +80,100 @@ var httpclient = http.Client{}
|
|||||||
|
|
||||||
// Download Speed
|
// Download Speed
|
||||||
func (s *IpAddress) DownloadSpeed() error {
|
func (s *IpAddress) DownloadSpeed() error {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
resp, err := httpclient.Get("http://" + s.Ipv4 + ":8088/50")
|
resp, err := httpclient.Get("http://" + s.Ipv4 + ":8088/50")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
ioutil.ReadAll(resp.Body)
|
ioutil.ReadAll(resp.Body)
|
||||||
t := time.Since(start)
|
t := time.Since(start)
|
||||||
//fmt.Println(s.Seconds())
|
//fmt.Println(s.Seconds())
|
||||||
// size * time (seconds)
|
// size * time (seconds)
|
||||||
s.Download = (50 / t.Seconds()) * 8
|
s.Download = (50 / t.Seconds()) * 8
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *IpAddress) UploadSpeed() error {
|
func (s *IpAddress) UploadSpeed() error {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
// Get upload file path from config file
|
// Get upload file path from config file
|
||||||
// Get Path from config
|
// Get Path from config
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +1,64 @@
|
|||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DownloadPlugin This functions downloads package from
|
// DownloadPlugin This functions downloads package from
|
||||||
// a git repo.
|
// a git repo.
|
||||||
func DownloadPlugin(pluginurl string) error {
|
func DownloadPlugin(pluginurl string) error {
|
||||||
// paring plugin url
|
// paring plugin url
|
||||||
u, err := url.Parse(pluginurl)
|
u, err := url.Parse(pluginurl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
path := u.Path
|
path := u.Path
|
||||||
// Trim first character of the string
|
// Trim first character of the string
|
||||||
path = path[1:]
|
path = path[1:]
|
||||||
// trim last element of the string
|
// trim last element of the string
|
||||||
path = path[:len(path)-1]
|
path = path[:len(path)-1]
|
||||||
// Replaces / with _
|
// Replaces / with _
|
||||||
folder := strings.Replace(path, "/", "_", -1)
|
folder := strings.Replace(path, "/", "_", -1)
|
||||||
// Reads plugin path from the config path
|
// Reads plugin path from the config path
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// clones a repo and stores it at the plugin directory
|
// clones a repo and stores it at the plugin directory
|
||||||
_, err = git.PlainClone(config.PluginPath+"/"+folder, false, &git.CloneOptions{
|
_, err = git.PlainClone(config.PluginPath+"/"+folder, false, &git.CloneOptions{
|
||||||
URL: pluginurl,
|
URL: pluginurl,
|
||||||
Progress: os.Stdout,
|
Progress: os.Stdout,
|
||||||
})
|
})
|
||||||
// returns error if raised
|
// returns error if raised
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeletePlugin The following function deletes a plugin based on
|
// DeletePlugin The following function deletes a plugin based on
|
||||||
// the plugin name provided.
|
// the plugin name provided.
|
||||||
func DeletePlugin(pluginname string) error {
|
func DeletePlugin(pluginname string) error {
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|||||||
704
plugin/plugin.go
704
plugin/plugin.go
@@ -1,362 +1,362 @@
|
|||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/client"
|
"github.com/Akilan1999/p2p-rendering-computation/client"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/apenella/go-ansible/pkg/execute"
|
"github.com/apenella/go-ansible/pkg/execute"
|
||||||
"github.com/apenella/go-ansible/pkg/options"
|
"github.com/apenella/go-ansible/pkg/options"
|
||||||
"github.com/apenella/go-ansible/pkg/playbook"
|
"github.com/apenella/go-ansible/pkg/playbook"
|
||||||
"github.com/apenella/go-ansible/pkg/stdoutcallback/results"
|
"github.com/apenella/go-ansible/pkg/stdoutcallback/results"
|
||||||
"github.com/otiai10/copy"
|
"github.com/otiai10/copy"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Plugins Array of all plugins detected
|
// Plugins Array of all plugins detected
|
||||||
type Plugins struct {
|
type Plugins struct {
|
||||||
PluginsDetected []*Plugin
|
PluginsDetected []*Plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugin Information about the plugins available
|
// Plugin Information about the plugins available
|
||||||
type Plugin struct {
|
type Plugin struct {
|
||||||
FolderName string
|
FolderName string
|
||||||
PluginDescription string
|
PluginDescription string
|
||||||
path string
|
path string
|
||||||
Execute []*ExecuteIP
|
Execute []*ExecuteIP
|
||||||
NumOfPorts int
|
NumOfPorts int
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecuteIP IP Address to execute Ansible instruction
|
// ExecuteIP IP Address to execute Ansible instruction
|
||||||
type ExecuteIP struct {
|
type ExecuteIP struct {
|
||||||
ContainerID string
|
ContainerID string
|
||||||
IPAddress string
|
IPAddress string
|
||||||
SSHPortNo string
|
SSHPortNo string
|
||||||
Success bool
|
Success bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Host Struct for ansible host
|
// Host Struct for ansible host
|
||||||
// Generated from https://zhwt.github.io/yaml-to-go/
|
// Generated from https://zhwt.github.io/yaml-to-go/
|
||||||
type Host struct {
|
type Host struct {
|
||||||
All struct {
|
All struct {
|
||||||
Vars struct {
|
Vars struct {
|
||||||
AnsiblePythonInterpreter string `yaml:"ansible_python_interpreter"`
|
AnsiblePythonInterpreter string `yaml:"ansible_python_interpreter"`
|
||||||
} `yaml:"vars"`
|
} `yaml:"vars"`
|
||||||
} `yaml:"all"`
|
} `yaml:"all"`
|
||||||
Main struct {
|
Main struct {
|
||||||
Hosts struct {
|
Hosts struct {
|
||||||
Host1 struct {
|
Host1 struct {
|
||||||
AnsibleHost string `yaml:"ansible_host"`
|
AnsibleHost string `yaml:"ansible_host"`
|
||||||
AnsiblePort int `yaml:"ansible_port"`
|
AnsiblePort int `yaml:"ansible_port"`
|
||||||
AnsibleUser string `yaml:"ansible_user"`
|
AnsibleUser string `yaml:"ansible_user"`
|
||||||
AnsibleSSHPass string `yaml:"ansible_ssh_pass"`
|
AnsibleSSHPass string `yaml:"ansible_ssh_pass"`
|
||||||
AnsibleSudoPass string `yaml:"ansible_sudo_pass"`
|
AnsibleSudoPass string `yaml:"ansible_sudo_pass"`
|
||||||
} `yaml:"host1"`
|
} `yaml:"host1"`
|
||||||
} `yaml:"hosts"`
|
} `yaml:"hosts"`
|
||||||
} `yaml:"main"`
|
} `yaml:"main"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DetectPlugins Detects all the plugins available
|
// DetectPlugins Detects all the plugins available
|
||||||
func DetectPlugins() (*Plugins, error) {
|
func DetectPlugins() (*Plugins, error) {
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
folders, err := ioutil.ReadDir(config.PluginPath)
|
folders, err := ioutil.ReadDir(config.PluginPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var plugins *Plugins = new(Plugins)
|
var plugins *Plugins = new(Plugins)
|
||||||
|
|
||||||
for _, f := range folders {
|
for _, f := range folders {
|
||||||
if f.IsDir() {
|
if f.IsDir() {
|
||||||
//Declare variable plugin of type Plugin
|
//Declare variable plugin of type Plugin
|
||||||
var plugin Plugin
|
var plugin Plugin
|
||||||
|
|
||||||
// Setting name of folder to plugin
|
// Setting name of folder to plugin
|
||||||
plugin.FolderName = f.Name()
|
plugin.FolderName = f.Name()
|
||||||
// Getting Description from file description.txt
|
// Getting Description from file description.txt
|
||||||
Description, err := ioutil.ReadFile(config.PluginPath + "/" + plugin.FolderName + "/description.txt")
|
Description, err := ioutil.ReadFile(config.PluginPath + "/" + plugin.FolderName + "/description.txt")
|
||||||
// if we os.Open returns an error then handle it
|
// if we os.Open returns an error then handle it
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Description from description.txt
|
// Get Description from description.txt
|
||||||
plugin.PluginDescription = string(Description)
|
plugin.PluginDescription = string(Description)
|
||||||
// Set plugin path
|
// Set plugin path
|
||||||
plugin.path = config.PluginPath + "/" + plugin.FolderName
|
plugin.path = config.PluginPath + "/" + plugin.FolderName
|
||||||
|
|
||||||
plugins.PluginsDetected = append(plugins.PluginsDetected, &plugin)
|
plugins.PluginsDetected = append(plugins.PluginsDetected, &plugin)
|
||||||
// Get the number of ports the plugin needs
|
// Get the number of ports the plugin needs
|
||||||
err = plugin.NumPorts()
|
err = plugin.NumPorts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return plugins, nil
|
return plugins, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchPlugin Detects plugin information based on the
|
// SearchPlugin Detects plugin information based on the
|
||||||
// name provided on the parameter
|
// name provided on the parameter
|
||||||
func SearchPlugin(pluginname string) (*Plugin, error) {
|
func SearchPlugin(pluginname string) (*Plugin, error) {
|
||||||
plugins, err := DetectPlugins()
|
plugins, err := DetectPlugins()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop ot find the plugin name that matches
|
// loop ot find the plugin name that matches
|
||||||
for _, plugin := range plugins.PluginsDetected {
|
for _, plugin := range plugins.PluginsDetected {
|
||||||
if pluginname == plugin.FolderName {
|
if pluginname == plugin.FolderName {
|
||||||
return plugin, nil
|
return plugin, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errors.New("plugin not detected")
|
return nil, errors.New("plugin not detected")
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunPlugin Executes plugins based on the plugin name provided
|
// RunPlugin Executes plugins based on the plugin name provided
|
||||||
func RunPlugin(pluginName string, IPAddresses []*ExecuteIP) (*Plugin, error) {
|
func RunPlugin(pluginName string, IPAddresses []*ExecuteIP) (*Plugin, error) {
|
||||||
plugins, err := DetectPlugins()
|
plugins, err := DetectPlugins()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variable to store struct information about the plugin
|
// Variable to store struct information about the plugin
|
||||||
var plugindetected *Plugin
|
var plugindetected *Plugin
|
||||||
for _, plugin := range plugins.PluginsDetected {
|
for _, plugin := range plugins.PluginsDetected {
|
||||||
if plugin.FolderName == pluginName {
|
if plugin.FolderName == pluginName {
|
||||||
plugindetected = plugin
|
plugindetected = plugin
|
||||||
plugindetected.Execute = IPAddresses
|
plugindetected.Execute = IPAddresses
|
||||||
// Get Execute plugin path from config file
|
// Get Execute plugin path from config file
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,257 +1,257 @@
|
|||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/client"
|
"github.com/Akilan1999/p2p-rendering-computation/client"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test if the dummy plugin added is detected
|
// Test if the dummy plugin added is detected
|
||||||
func TestDetectPlugins(t *testing.T) {
|
func TestDetectPlugins(t *testing.T) {
|
||||||
_, err := DetectPlugins()
|
_, err := DetectPlugins()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test ensures that the ansible are executed inside local containers
|
// Test ensures that the ansible are executed inside local containers
|
||||||
func TestRunPlugin(t *testing.T) {
|
func TestRunPlugin(t *testing.T) {
|
||||||
var testips []*ExecuteIP
|
var testips []*ExecuteIP
|
||||||
var testip1, testip2 ExecuteIP
|
var testip1, testip2 ExecuteIP
|
||||||
|
|
||||||
// Create docker container and get SSH port
|
// Create docker container and get SSH port
|
||||||
container1, err := docker.BuildRunContainer(0, "false", "")
|
container1, err := docker.BuildRunContainer(0, "false", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
//Test IP 1 configuration
|
//Test IP 1 configuration
|
||||||
testip1.IPAddress = "0.0.0.0"
|
testip1.IPAddress = "0.0.0.0"
|
||||||
testip1.SSHPortNo = strconv.Itoa(container1.Ports.PortSet[0].ExternalPort)
|
testip1.SSHPortNo = strconv.Itoa(container1.Ports.PortSet[0].ExternalPort)
|
||||||
|
|
||||||
// Create docker container and get SSH port
|
// Create docker container and get SSH port
|
||||||
container2, err := docker.BuildRunContainer(0, "false", "")
|
container2, err := docker.BuildRunContainer(0, "false", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
//Test IP 2 configuration
|
//Test IP 2 configuration
|
||||||
testip2.IPAddress = "0.0.0.0"
|
testip2.IPAddress = "0.0.0.0"
|
||||||
testip2.SSHPortNo = strconv.Itoa(container2.Ports.PortSet[0].ExternalPort)
|
testip2.SSHPortNo = strconv.Itoa(container2.Ports.PortSet[0].ExternalPort)
|
||||||
|
|
||||||
testips = append(testips, &testip1)
|
testips = append(testips, &testip1)
|
||||||
testips = append(testips, &testip2)
|
testips = append(testips, &testip2)
|
||||||
|
|
||||||
_, err = RunPlugin("TestAnsible", testips)
|
_, err = RunPlugin("TestAnsible", testips)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removing container1 after Ansible is executed
|
// Removing container1 after Ansible is executed
|
||||||
err = docker.StopAndRemoveContainer(container1.ID)
|
err = docker.StopAndRemoveContainer(container1.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
err = docker.StopAndRemoveContainer(container2.ID)
|
err = docker.StopAndRemoveContainer(container2.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test to ensure that the ansible host file is modified to
|
// Test to ensure that the ansible host file is modified to
|
||||||
// the appropriate IP
|
// the appropriate IP
|
||||||
func TestExecuteIP_ModifyHost(t *testing.T) {
|
func TestExecuteIP_ModifyHost(t *testing.T) {
|
||||||
var plugin Plugin
|
var plugin Plugin
|
||||||
var testip ExecuteIP
|
var testip ExecuteIP
|
||||||
|
|
||||||
// Get plugin path from config file
|
// Get plugin path from config file
|
||||||
Config, err := config.ConfigInit(nil, nil)
|
Config, err := config.ConfigInit()
|
||||||
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
BIN
server/.DS_Store
vendored
Binary file not shown.
BIN
server/docker/.DS_Store
vendored
BIN
server/docker/.DS_Store
vendored
Binary file not shown.
7
server/docker/containers/README
Normal file
7
server/docker/containers/README
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Containers
|
||||||
|
===========
|
||||||
|
|
||||||
|
Structure
|
||||||
|
|_ Containers
|
||||||
|
|_ <name> (To ensure the name is the same as the tag name)
|
||||||
|
|_ DockerFile
|
||||||
43
server/docker/containers/cpuhorovod/Dockerfile
Normal file
43
server/docker/containers/cpuhorovod/Dockerfile
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
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"]
|
||||||
1
server/docker/containers/cpuhorovod/description.txt
Normal file
1
server/docker/containers/cpuhorovod/description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Running official horovod dockerfile cpu version
|
||||||
11
server/docker/containers/cpuhorovod/scripts/start
Normal file
11
server/docker/containers/cpuhorovod/scripts/start
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# docker-ubuntu-sshd /start script
|
||||||
|
#
|
||||||
|
# Authors: Art567
|
||||||
|
# Updated: Sep 20th, 2015
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# Run OpenSSH server in daemon mode
|
||||||
|
/usr/sbin/sshd -D
|
||||||
61
server/docker/containers/docker-ubuntu-sshd-x11/Dockerfile
Normal file
61
server/docker/containers/docker-ubuntu-sshd-x11/Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 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"]
|
||||||
72
server/docker/containers/docker-ubuntu-sshd-x11/README.md
Normal file
72
server/docker/containers/docker-ubuntu-sshd-x11/README.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
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
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Simple Ubuntu 20.04 image
|
||||||
16
server/docker/containers/docker-ubuntu-sshd-x11/ports.json
Normal file
16
server/docker/containers/docker-ubuntu-sshd-x11/ports.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"Port": [
|
||||||
|
{
|
||||||
|
"PortName": "SSH",
|
||||||
|
"InternalPort": 22,
|
||||||
|
"Type": "tcp",
|
||||||
|
"Description": "SSH Port"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"PortName": "VNC",
|
||||||
|
"InternalPort": 5900,
|
||||||
|
"Type": "tcp",
|
||||||
|
"Description": "VNC port"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
61
server/docker/containers/docker-ubuntu-sshd/Dockerfile
Normal file
61
server/docker/containers/docker-ubuntu-sshd/Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 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"]
|
||||||
72
server/docker/containers/docker-ubuntu-sshd/README.md
Normal file
72
server/docker/containers/docker-ubuntu-sshd/README.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
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
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Simple Ubuntu 20.04 image
|
||||||
22
server/docker/containers/docker-ubuntu-sshd/ports.json
Normal file
22
server/docker/containers/docker-ubuntu-sshd/ports.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
11
server/docker/containers/docker-ubuntu-sshd/scripts/start
Normal file
11
server/docker/containers/docker-ubuntu-sshd/scripts/start
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# docker-ubuntu-sshd /start script
|
||||||
|
#
|
||||||
|
# Authors: Art567
|
||||||
|
# Updated: Sep 20th, 2015
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# Run OpenSSH server in daemon mode
|
||||||
|
/usr/sbin/sshd -D
|
||||||
41
server/docker/containers/gpuhorovod/Dockerfile
Normal file
41
server/docker/containers/gpuhorovod/Dockerfile
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
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"]
|
||||||
1
server/docker/containers/gpuhorovod/description.txt
Normal file
1
server/docker/containers/gpuhorovod/description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Running official horovod dockerfile cpu version
|
||||||
11
server/docker/containers/gpuhorovod/scripts/start
Normal file
11
server/docker/containers/gpuhorovod/scripts/start
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# docker-ubuntu-sshd /start script
|
||||||
|
#
|
||||||
|
# Authors: Art567
|
||||||
|
# Updated: Sep 20th, 2015
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# Run OpenSSH server in daemon mode
|
||||||
|
/usr/sbin/sshd -D
|
||||||
61
server/docker/containers/ubuntuvnc/Dockerfile
Normal file
61
server/docker/containers/ubuntuvnc/Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 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"]
|
||||||
72
server/docker/containers/ubuntuvnc/README.md
Normal file
72
server/docker/containers/ubuntuvnc/README.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
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
|
||||||
|
|
||||||
1
server/docker/containers/ubuntuvnc/description.txt
Normal file
1
server/docker/containers/ubuntuvnc/description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Simple Ubuntu 20.04 image
|
||||||
11
server/docker/containers/ubuntuvnc/scripts/start
Normal file
11
server/docker/containers/ubuntuvnc/scripts/start
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# docker-ubuntu-sshd /start script
|
||||||
|
#
|
||||||
|
# Authors: Art567
|
||||||
|
# Updated: Sep 20th, 2015
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# Run OpenSSH server in daemon mode
|
||||||
|
/usr/sbin/sshd -D
|
||||||
@@ -3,34 +3,32 @@ package docker
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"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/container"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/google/uuid"
|
"github.com/docker/docker/pkg/archive"
|
||||||
|
"github.com/docker/go-connections/nat"
|
||||||
"github.com/lithammer/shortuuid"
|
"github.com/lithammer/shortuuid"
|
||||||
"github.com/otiai10/copy"
|
|
||||||
"github.com/phayes/freeport"
|
"github.com/phayes/freeport"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"text/template"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DockerVM struct {
|
type DockerVM struct {
|
||||||
SSHUsername string `json:"SSHUsername"`
|
SSHUsername string `json:"SSHUsername"`
|
||||||
SSHPublcKey string `json:"SSHPublicKey"`
|
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"`
|
||||||
TempPath string
|
|
||||||
BaseImage string
|
|
||||||
LogsPath string
|
|
||||||
SSHCommand string `json:"SSHCommand"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type DockerContainers struct {
|
type DockerContainers struct {
|
||||||
@@ -67,34 +65,30 @@ 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, baseImage string, publicKey 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
|
||||||
|
|
||||||
// Get config informatopn
|
|
||||||
|
|
||||||
// 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 = "root"
|
RespDocker.SSHUsername = "master"
|
||||||
//RespDocker.BaseImage = "ubuntu:20.04"
|
RespDocker.SSHPassword = "password"
|
||||||
//RespDocker.VNCPassword = "vncpassword"
|
//RespDocker.VNCPassword = "vncpassword"
|
||||||
|
|
||||||
//Default parameters
|
//Default parameters
|
||||||
RespDocker.TagName = "p2p-ubuntu"
|
RespDocker.TagName = "p2p-ubuntu"
|
||||||
// Get Path from config
|
// Get Path from config
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
RespDocker.ImagePath = config.DefaultDockerFile
|
RespDocker.ImagePath = config.DefaultDockerFile
|
||||||
RespDocker.LogsPath = config.DockerRunLogs
|
|
||||||
RespDocker.SSHPublcKey = publicKey
|
|
||||||
|
|
||||||
// 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
|
||||||
@@ -116,22 +110,7 @@ func BuildRunContainer(NumPorts int, GPU string, ContainerName string, baseImage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checking if the base image is provided
|
PortsInformation, err := OpenPortsFile(RespDocker.ImagePath + "/ports.json")
|
||||||
if baseImage != "" {
|
|
||||||
RespDocker.BaseImage = baseImage
|
|
||||||
} else {
|
|
||||||
RespDocker.BaseImage = "ubuntu:20.04"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Template docker with the base image provided
|
|
||||||
err = RespDocker.TemplateDockerContainer()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Template the DockerFile and point to the temp location
|
|
||||||
|
|
||||||
PortsInformation, err := OpenPortsFile(RespDocker.ImagePath + "/" + RespDocker.TagName + "/ports.json")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -192,40 +171,30 @@ func BuildRunContainer(NumPorts int, GPU string, ContainerName string, baseImage
|
|||||||
|
|
||||||
// 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()
|
||||||
|
|
||||||
var cmd bytes.Buffer
|
tar, err := archive.TarWithOptions(d.ImagePath, &archive.TarOptions{})
|
||||||
cmd.WriteString("docker build -t " + d.TagName + " " + d.ImagePath + "/" + d.TagName + ` --build-arg SSH_KEY="` + d.SSHPublcKey + `"`)
|
|
||||||
//"-v=/opt/data:/data p2p-ubuntu /start > /dev/null"
|
|
||||||
cmdStr := cmd.String()
|
|
||||||
output, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
|
|
||||||
fmt.Printf("%s", output)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//tar, err := archive.TarWithOptions(d.ImagePath+"/"+d.TagName, &archive.TarOptions{})
|
opts := types.ImageBuildOptions{
|
||||||
//if err != nil {
|
Dockerfile: "Dockerfile",
|
||||||
// return err
|
Tags: []string{d.TagName},
|
||||||
//}
|
Remove: true,
|
||||||
//
|
}
|
||||||
//opts := types.ImageBuildOptions{
|
res, err := dockerClient.ImageBuild(ctx, tar, opts)
|
||||||
// Dockerfile: "Dockerfile",
|
if err != nil {
|
||||||
// Tags: []string{d.TagName},
|
return err
|
||||||
// Remove: true,
|
}
|
||||||
//}
|
|
||||||
//res, err := dockerClient.ImageBuild(ctx, tar, opts)
|
defer res.Body.Close()
|
||||||
//if err != nil {
|
|
||||||
// return err
|
err = print(res.Body)
|
||||||
//}
|
if err != nil {
|
||||||
//
|
return err
|
||||||
//defer res.Body.Close()
|
}
|
||||||
//
|
|
||||||
//err = print(res.Body)
|
|
||||||
//if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -236,101 +205,97 @@ 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{
|
|
||||||
// "22/tcp": struct{}{},
|
|
||||||
// //"6901/tcp": struct{}{},
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Port forwarding for VNC and SSH ports
|
|
||||||
// PortForwarding := nat.PortMap{
|
|
||||||
// //"22/tcp": []nat.PortBinding{
|
|
||||||
// // {
|
|
||||||
// // HostIP: "0.0.0.0",
|
|
||||||
// // HostPort: fmt.Sprint(d.SSHPort),
|
|
||||||
// // },
|
|
||||||
// //},
|
|
||||||
// //"6901/tcp": []nat.PortBinding{
|
|
||||||
// // {
|
|
||||||
// // HostIP: "0.0.0.0",
|
|
||||||
// // HostPort: fmt.Sprint(d.VNCPort),
|
|
||||||
// // },
|
|
||||||
// //},
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for i := range d.Ports.PortSet {
|
|
||||||
// // Parameters "tcp or udp", external port
|
|
||||||
// Port, err := nat.NewPort(d.Ports.PortSet[i].Type, fmt.Sprint(d.Ports.PortSet[i].InternalPort))
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Exposed Ports
|
|
||||||
// ExposedPort[Port] = struct{}{}
|
|
||||||
//
|
|
||||||
// PortForwarding[Port] = []nat.PortBinding{
|
|
||||||
// {
|
|
||||||
// HostIP: "0.0.0.0",
|
|
||||||
// HostPort: fmt.Sprint(d.Ports.PortSet[i].ExternalPort),
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// config := &container.Config{
|
|
||||||
// Image: d.TagName,
|
|
||||||
// Entrypoint: []string{"/start"},
|
|
||||||
// Volumes: map[string]struct{}{"/opt/data:/data": {}},
|
|
||||||
// ExposedPorts: ExposedPort,
|
|
||||||
// }
|
|
||||||
// hostConfig := &container.HostConfig{
|
|
||||||
// PortBindings: PortForwarding,
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// res, err := dockerClient.ContainerCreate(ctx, config, hostConfig,
|
|
||||||
// nil, nil, "")
|
|
||||||
//
|
|
||||||
// // Set response ID
|
|
||||||
// d.ID = res.ID
|
|
||||||
//
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// err = dockerClient.ContainerStart(ctx, res.ID, types.ContainerStartOptions{})
|
|
||||||
//
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
//} else {
|
|
||||||
// Generate Random ID
|
|
||||||
id := shortuuid.New()
|
|
||||||
d.ID = id
|
|
||||||
|
|
||||||
var cmd bytes.Buffer
|
ExposedPort = nat.PortSet{
|
||||||
cmd.WriteString("docker run -d=true --name=" + id + " --restart=always ")
|
"22/tcp": struct{}{},
|
||||||
if d.GPU == "true" {
|
//"6901/tcp": struct{}{},
|
||||||
cmd.WriteString("--gpus all ")
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for i := range d.Ports.PortSet {
|
// Port forwarding for VNC and SSH ports
|
||||||
cmd.WriteString("-p " + fmt.Sprint(d.Ports.PortSet[i].ExternalPort) + ":" + fmt.Sprint(d.Ports.PortSet[i].InternalPort) + " ")
|
PortForwarding := nat.PortMap{
|
||||||
|
//"22/tcp": []nat.PortBinding{
|
||||||
|
// {
|
||||||
|
// HostIP: "0.0.0.0",
|
||||||
|
// HostPort: fmt.Sprint(d.SSHPort),
|
||||||
|
// },
|
||||||
|
//},
|
||||||
|
//"6901/tcp": []nat.PortBinding{
|
||||||
|
// {
|
||||||
|
// HostIP: "0.0.0.0",
|
||||||
|
// HostPort: fmt.Sprint(d.VNCPort),
|
||||||
|
// },
|
||||||
|
//},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range d.Ports.PortSet {
|
||||||
|
// Parameters "tcp or udp", external port
|
||||||
|
Port, err := nat.NewPort(d.Ports.PortSet[i].Type, fmt.Sprint(d.Ports.PortSet[i].InternalPort))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exposed Ports
|
||||||
|
ExposedPort[Port] = struct{}{}
|
||||||
|
|
||||||
|
PortForwarding[Port] = []nat.PortBinding{
|
||||||
|
{
|
||||||
|
HostIP: "0.0.0.0",
|
||||||
|
HostPort: fmt.Sprint(d.Ports.PortSet[i].ExternalPort),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config := &container.Config{
|
||||||
|
Image: d.TagName,
|
||||||
|
Entrypoint: []string{"/start"},
|
||||||
|
Volumes: map[string]struct{}{"/opt/data:/data": {}},
|
||||||
|
ExposedPorts: ExposedPort,
|
||||||
|
}
|
||||||
|
hostConfig := &container.HostConfig{
|
||||||
|
PortBindings: PortForwarding,
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := dockerClient.ContainerCreate(ctx, config, hostConfig,
|
||||||
|
nil, nil, "")
|
||||||
|
|
||||||
|
// Set response ID
|
||||||
|
d.ID = res.ID
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dockerClient.ContainerStart(ctx, res.ID, types.ContainerStartOptions{})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Generate Random ID
|
||||||
|
id := shortuuid.New()
|
||||||
|
d.ID = id
|
||||||
|
|
||||||
|
var cmd bytes.Buffer
|
||||||
|
cmd.WriteString("docker run -d=true --name=" + id + " --restart=always --gpus all ")
|
||||||
|
for i := range d.Ports.PortSet {
|
||||||
|
cmd.WriteString("-p " + fmt.Sprint(d.Ports.PortSet[i].ExternalPort) + ":" + fmt.Sprint(d.Ports.PortSet[i].InternalPort) + " ")
|
||||||
|
}
|
||||||
|
cmd.WriteString("-v=/opt/data:/data " + d.TagName + " /start > /dev/null")
|
||||||
|
//"-v=/opt/data:/data p2p-ubuntu /start > /dev/null"
|
||||||
|
cmdStr := cmd.String()
|
||||||
|
_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cmd.WriteString("-v=/tmp:/data " + d.TagName + " > /dev/null")
|
|
||||||
//"-v=/opt/data:/data p2p-ubuntu /start > /dev/null"
|
|
||||||
cmdStr := cmd.String()
|
|
||||||
_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,45 +303,24 @@ func (d *DockerVM) runContainer(dockerClient *client.Client) error {
|
|||||||
// 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
|
|
||||||
//client, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
|
||||||
//if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//if err = client.ContainerStop(ctx, containername, nil); err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//removeOptions := types.ContainerRemoveOptions{
|
|
||||||
// RemoveVolumes: true,
|
|
||||||
// Force: true,
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//if err = client.ContainerRemove(ctx, containername, removeOptions); err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
|
|
||||||
// stop docker container
|
// Gets docker information from env variables
|
||||||
var stop bytes.Buffer
|
client, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||||
stop.WriteString("docker stop " + containername)
|
|
||||||
|
|
||||||
cmdStr := stop.String()
|
|
||||||
_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove docker container
|
if err = client.ContainerStop(ctx, containername, nil); err != nil {
|
||||||
var remove bytes.Buffer
|
return err
|
||||||
remove.WriteString("docker remove " + containername)
|
}
|
||||||
|
|
||||||
cmdStr = remove.String()
|
removeOptions := types.ContainerRemoveOptions{
|
||||||
|
RemoveVolumes: true,
|
||||||
|
Force: true,
|
||||||
|
}
|
||||||
|
|
||||||
_, err = exec.Command("/bin/sh", "-c", cmdStr).Output()
|
if err = client.ContainerRemove(ctx, containername, removeOptions); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,7 +330,7 @@ func StopAndRemoveContainer(containername string) error {
|
|||||||
// ViewAllContainers returns all containers runnable and which can be built
|
// ViewAllContainers returns all containers runnable and which can be built
|
||||||
func ViewAllContainers() (*DockerContainers, error) {
|
func ViewAllContainers() (*DockerContainers, error) {
|
||||||
// Traverse the deploy path as per given in the config file
|
// Traverse the deploy path as per given in the config file
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -458,51 +402,3 @@ func OpenPortsFile(filename string) (*Ports, error) {
|
|||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TemplateDockerContainer This function templates the docker container
|
|
||||||
// with the base docker image to use
|
|
||||||
func (d *DockerVM) TemplateDockerContainer() error {
|
|
||||||
err := d.CopyToTmpContainer()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// parses the site.yml file in the tmp directory
|
|
||||||
t, err := template.ParseFiles(d.ImagePath + "/" + d.TagName + "/Dockerfile")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// opens the output file
|
|
||||||
f, err := os.Create(d.ImagePath + "/" + d.TagName + "/Dockerfile")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
image := d.BaseImage
|
|
||||||
|
|
||||||
// Pass in Docker Base Image
|
|
||||||
err = t.Execute(f, image)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyToTmpContainer Creates a copy of the docker folder
|
|
||||||
func (d *DockerVM) CopyToTmpContainer() error {
|
|
||||||
// generate rand to UUID this is debug the ansible file if needed
|
|
||||||
id := uuid.New()
|
|
||||||
// copies the plugin to the tmp directory
|
|
||||||
err := copy.Copy(d.ImagePath+"/", d.LogsPath+id.String()+"_"+d.TagName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the plugin execution to the tmp location
|
|
||||||
d.TagName = id.String() + "_" + d.TagName
|
|
||||||
// removing slash
|
|
||||||
d.ImagePath = d.LogsPath[:len(d.LogsPath)-1]
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -99,8 +99,7 @@ The Docker Containers Dashboard shows key metrics for monitoring running contain
|
|||||||
* Container network inbound usage graph
|
* Container network inbound usage graph
|
||||||
* Container network outbound usage graph
|
* Container network outbound usage graph
|
||||||
|
|
||||||
> [!NOTE]
|
Note that this dashboard doesn't show the containers that are part of the monitoring stack.
|
||||||
> This dashboard doesn't show the containers that are part of the monitoring stack.
|
|
||||||
|
|
||||||
***Monitor Services Dashboard***
|
***Monitor Services Dashboard***
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ To get started on AWS ECS and EC2:
|
|||||||
- Copy prometheus.yml configuration present here to base prometheus configuration to enable EC2 service discovery
|
- Copy prometheus.yml configuration present here to base prometheus configuration to enable EC2 service discovery
|
||||||
- `docker compose up -d`
|
- `docker compose up -d`
|
||||||
|
|
||||||
> [!NOTE]
|
**Note**:
|
||||||
> Set query.staleness-delta to 1m make metrics more realtime
|
Set query.staleness-delta to 1m make metrics more realtime
|
||||||
|
|
||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
- [ ] Add alerting rules based on ECS
|
- Add alerting rules based on ECS
|
||||||
|
|||||||
@@ -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() *SysInfo {
|
func ServerInfo() interface{} {
|
||||||
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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
43
server/rpc.go
Normal file
43
server/rpc.go
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||||
|
"net"
|
||||||
|
"net/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
port = "8089"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Listener int
|
||||||
|
|
||||||
|
type Docker struct {
|
||||||
|
docker *docker.DockerVM
|
||||||
|
}
|
||||||
|
|
||||||
|
// Starts container using RPC calls
|
||||||
|
func (l *Listener) StartContainer(reply *Docker) error {
|
||||||
|
vm, err := docker.BuildRunContainer(3, "false", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("Receive: %v\n", vm)
|
||||||
|
*reply = Docker{vm}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Rpc() {
|
||||||
|
rpcServer, err := net.ResolveTCPAddr("tcp", "0.0.0.0:"+port)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(err)
|
||||||
|
}
|
||||||
|
inbound, err := net.ListenTCP("tcp", rpcServer)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(err)
|
||||||
|
}
|
||||||
|
listener := new(Listener)
|
||||||
|
rpc.Register(listener)
|
||||||
|
rpc.Accept(inbound)
|
||||||
|
}
|
||||||
134
server/server.go
134
server/server.go
@@ -1,7 +1,6 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
b64 "encoding/base64"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
|
"github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
|
||||||
@@ -16,13 +15,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Server() (*gin.Engine, error) {
|
func Server() error {
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
|
|
||||||
//Get Server port based on the config file
|
//Get Server port based on the config file
|
||||||
config, err := config.ConfigInit(nil, nil)
|
config, err := config.ConfigInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return 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
|
||||||
@@ -108,27 +107,14 @@ func Server() (*gin.Engine, error) {
|
|||||||
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", "")
|
||||||
BaseImage := c.DefaultQuery("BaseImage", "")
|
|
||||||
PublicKey := c.DefaultQuery("PublicKey", "")
|
|
||||||
var PortsInt int
|
var PortsInt int
|
||||||
|
|
||||||
if PublicKey == "" {
|
|
||||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", "Publickey not passed"))
|
|
||||||
}
|
|
||||||
|
|
||||||
PublicKeyDecoded, err := b64.StdEncoding.DecodeString(PublicKey)
|
|
||||||
if err != nil {
|
|
||||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert Get Request value to int
|
// Convert Get Request value to int
|
||||||
fmt.Sscanf(Ports, "%d", &PortsInt)
|
fmt.Sscanf(Ports, "%d", &PortsInt)
|
||||||
|
|
||||||
fmt.Println(string(PublicKeyDecoded[:]))
|
|
||||||
|
|
||||||
// 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, BaseImage, string(PublicKeyDecoded[:]))
|
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))
|
||||||
@@ -140,6 +126,7 @@ func Server() (*gin.Engine, error) {
|
|||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, resp)
|
c.JSON(http.StatusOK, resp)
|
||||||
@@ -173,16 +160,6 @@ func Server() (*gin.Engine, error) {
|
|||||||
c.String(http.StatusOK, strconv.Itoa(port))
|
c.String(http.StatusOK, strconv.Itoa(port))
|
||||||
})
|
})
|
||||||
|
|
||||||
r.GET("/MAPPort", func(c *gin.Context) {
|
|
||||||
Ports := c.DefaultQuery("port", "0")
|
|
||||||
url, _, err := MapPort(Ports)
|
|
||||||
if err != nil {
|
|
||||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
c.String(http.StatusOK, url)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 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" {
|
||||||
@@ -193,12 +170,9 @@ func Server() (*gin.Engine, error) {
|
|||||||
// 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" {
|
||||||
// Remove nodes currently not pingable
|
|
||||||
clientIPTable.RemoveOfflineNodes()
|
|
||||||
|
|
||||||
table, err := p2p.ReadIpTable()
|
table, err := p2p.ReadIpTable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var lowestLatency int64
|
var lowestLatency int64
|
||||||
@@ -208,7 +182,7 @@ func Server() (*gin.Engine, error) {
|
|||||||
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 && table.IpAddress[i].NAT != "" {
|
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]
|
||||||
}
|
}
|
||||||
@@ -218,14 +192,14 @@ func Server() (*gin.Engine, error) {
|
|||||||
if lowestLatency != 10000000 {
|
if lowestLatency != 10000000 {
|
||||||
serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort)
|
serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
// Create 3 second delay to allow FRP server to start
|
// Create 3 second delay to allow FRP server to start
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
// Starts FRP as a client with
|
// Starts FRP as a client with
|
||||||
proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, serverPort, config.ServerPort, "")
|
proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, serverPort, config.ServerPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// updating with the current proxy address
|
// updating with the current proxy address
|
||||||
@@ -235,99 +209,21 @@ func Server() (*gin.Engine, error) {
|
|||||||
ProxyIpAddr.NAT = "False"
|
ProxyIpAddr.NAT = "False"
|
||||||
ProxyIpAddr.EscapeImplementation = "FRP"
|
ProxyIpAddr.EscapeImplementation = "FRP"
|
||||||
|
|
||||||
// Sorry Jan it's a string
|
|
||||||
// Yes I could convert it
|
|
||||||
// to a boolean operator
|
|
||||||
// But I am way too tired
|
|
||||||
if config.BareMetal == "True" {
|
|
||||||
_, SSHPort, err := MapPort("22")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ProxyIpAddr.BareMetalSSHPort = SSHPort
|
|
||||||
}
|
|
||||||
|
|
||||||
//ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey)
|
|
||||||
|
|
||||||
// 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
|
||||||
err = table.WriteIpTable()
|
table.WriteIpTable()
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// update ip table
|
// update ip table
|
||||||
go func() error {
|
go clientIPTable.UpdateIpTableListClient()
|
||||||
err := clientIPTable.UpdateIpTableListClient()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run gin server on the specified port
|
// Run gin server on the specified port
|
||||||
go r.Run(":" + config.ServerPort)
|
err = r.Run(":" + config.ServerPort)
|
||||||
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func MapPort(port string) (string, string, error) {
|
|
||||||
//Get Server port based on the config file
|
|
||||||
config, err := config.ConfigInit(nil, nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// update IPTable with new port and ip address and update ip table
|
return nil
|
||||||
var ProxyIpAddr p2p.IpAddress
|
|
||||||
var lowestLatencyIpAddress p2p.IpAddress
|
|
||||||
|
|
||||||
clientIPTable.RemoveOfflineNodes()
|
|
||||||
|
|
||||||
table, err := p2p.ReadIpTable()
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var lowestLatency int64
|
|
||||||
// random large number
|
|
||||||
lowestLatency = 10000000
|
|
||||||
|
|
||||||
for i, _ := range table.IpAddress {
|
|
||||||
// Checks if the ping is the lowest and if the following node is acting as a proxy
|
|
||||||
//if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" {
|
|
||||||
if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].NAT != "" {
|
|
||||||
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
|
|
||||||
lowestLatencyIpAddress = table.IpAddress[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is an identified node
|
|
||||||
if lowestLatency != 10000000 {
|
|
||||||
serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
// Create 3 second delay to allow FRP server to start
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
// Starts FRP as a client with
|
|
||||||
proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, serverPort, port, "")
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// updating with the current proxy address
|
|
||||||
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
|
|
||||||
ProxyIpAddr.ServerPort = proxyPort
|
|
||||||
ProxyIpAddr.Name = config.MachineName
|
|
||||||
ProxyIpAddr.NAT = "False"
|
|
||||||
ProxyIpAddr.EscapeImplementation = "FRP"
|
|
||||||
//ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ProxyIpAddr.Ipv4 + ":" + ProxyIpAddr.ServerPort, ProxyIpAddr.ServerPort, nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user