Compare commits
19 Commits
python-add
...
simulation
| Author | SHA1 | Date | |
|---|---|---|---|
| 034f9e2896 | |||
| ece1e63fda | |||
| b88370cdb7 | |||
| 9f4cb9af02 | |||
| d79c28c32f | |||
|
|
7b0d36873b | ||
| 2283736cc6 | |||
| 51b253df15 | |||
| b9f5dec9de | |||
| 30b464449c | |||
| ffd711f448 | |||
| 0d01d70c2b | |||
| 6b1edd3d8a | |||
| 5cf1e144aa | |||
|
|
f605e2e06b | ||
| 873caa911c | |||
| 73a470e201 | |||
| 805514edfa | |||
|
|
5e3a4e8b7a |
49
.github/workflows/pages.yml
vendored
49
.github/workflows/pages.yml
vendored
@@ -1,49 +0,0 @@
|
|||||||
name: Deploy Jekyll with GitHub Pages dependencies preinstalled
|
|
||||||
|
|
||||||
on:
|
|
||||||
# Runs on pushes targeting the default branch
|
|
||||||
push:
|
|
||||||
branches: ["main", "master"]
|
|
||||||
|
|
||||||
# Allows you to run this workflow manually from the Actions tab
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pages: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
# Allow one concurrent deployment
|
|
||||||
concurrency:
|
|
||||||
group: "pages"
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
# Build job
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Setup Pages
|
|
||||||
uses: actions/configure-pages@v2
|
|
||||||
- name: Build with Jekyll
|
|
||||||
uses: actions/jekyll-build-pages@v1
|
|
||||||
with:
|
|
||||||
source: ./
|
|
||||||
destination: ./_site
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-pages-artifact@v1
|
|
||||||
|
|
||||||
# Deployment job
|
|
||||||
deploy:
|
|
||||||
environment:
|
|
||||||
name: github-pages
|
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: build
|
|
||||||
steps:
|
|
||||||
- name: Deploy to GitHub Pages
|
|
||||||
id: deployment
|
|
||||||
uses: actions/deploy-pages@v1
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -49,3 +49,6 @@ venv
|
|||||||
# Nix and Nix flake files
|
# Nix and Nix flake files
|
||||||
result
|
result
|
||||||
result-*
|
result-*
|
||||||
|
|
||||||
|
# Ignore WASM generated files
|
||||||
|
*.wasm
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
|
//go:build cgo
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/abstractions"
|
"github.com/Akilan1999/p2p-rendering-computation/abstractions"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
|
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The Client package where data-types
|
// The Client package where data-types
|
||||||
@@ -16,23 +18,23 @@ import (
|
|||||||
|
|
||||||
// --------------------------------- Container Control ----------------------------------------
|
// --------------------------------- Container Control ----------------------------------------
|
||||||
|
|
||||||
//export StartContainer
|
////export StartContainer
|
||||||
func StartContainer(IP string) (output *C.char) {
|
//func StartContainer(IP string) (output *C.char) {
|
||||||
container, err := abstractions.StartContainer(IP)
|
// container, err := abstractions.StartContainer(IP)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return C.CString(err.Error())
|
// return C.CString(err.Error())
|
||||||
}
|
// }
|
||||||
return ConvertStructToJSONString(container)
|
// return ConvertStructToJSONString(container)
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
//export RemoveContainer
|
////export RemoveContainer
|
||||||
func RemoveContainer(IP string, ID string) (output *C.char) {
|
//func RemoveContainer(IP string, ID string) (output *C.char) {
|
||||||
err := abstractions.RemoveContainer(IP, ID)
|
// err := abstractions.RemoveContainer(IP, ID)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return C.CString(err.Error())
|
// return C.CString(err.Error())
|
||||||
}
|
// }
|
||||||
return C.CString("Success")
|
// return C.CString("Success")
|
||||||
}
|
//}
|
||||||
|
|
||||||
// --------------------------------- Plugin Control ----------------------------------------
|
// --------------------------------- Plugin Control ----------------------------------------
|
||||||
|
|
||||||
@@ -77,20 +79,20 @@ func RemoveContainer(IP string, ID string) (output *C.char) {
|
|||||||
|
|
||||||
//export GetSpecs
|
//export GetSpecs
|
||||||
func GetSpecs(IP string) (output *C.char) {
|
func GetSpecs(IP string) (output *C.char) {
|
||||||
specs, err := abstractions.GetSpecs(IP)
|
specs, err := abstractions.GetSpecs(IP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(err.Error())
|
return C.CString(err.Error())
|
||||||
}
|
}
|
||||||
return ConvertStructToJSONString(specs)
|
return ConvertStructToJSONString(specs)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export Init
|
//export Init
|
||||||
func Init(customConfig string) (output *C.char) {
|
func Init(customConfig string) (output *C.char) {
|
||||||
init, err := abstractions.Init(customConfig)
|
init, err := abstractions.Init(customConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(err.Error())
|
return C.CString(err.Error())
|
||||||
}
|
}
|
||||||
return ConvertStructToJSONString(init)
|
return ConvertStructToJSONString(init)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,81 +100,90 @@ func Init(customConfig string) (output *C.char) {
|
|||||||
|
|
||||||
//export ViewIPTable
|
//export ViewIPTable
|
||||||
func ViewIPTable() (output *C.char) {
|
func ViewIPTable() (output *C.char) {
|
||||||
table, err := abstractions.ViewIPTable()
|
table, err := abstractions.ViewIPTable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(err.Error())
|
return C.CString(err.Error())
|
||||||
}
|
}
|
||||||
return ConvertStructToJSONString(table)
|
return ConvertStructToJSONString(table)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export UpdateIPTable
|
//export UpdateIPTable
|
||||||
func UpdateIPTable() (output *C.char) {
|
func UpdateIPTable() (output *C.char) {
|
||||||
err := abstractions.UpdateIPTable()
|
err := abstractions.UpdateIPTable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(err.Error())
|
return C.CString(err.Error())
|
||||||
}
|
}
|
||||||
return C.CString("Success")
|
return C.CString("Success")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export EscapeFirewall
|
//export EscapeFirewall
|
||||||
func EscapeFirewall(HostOutsideNATIP string, HostOutsideNATPort string, internalPort string) (output *C.char) {
|
func EscapeFirewall(HostOutsideNATIP string, HostOutsideNATPort string, internalPort string) (output *C.char) {
|
||||||
// Get free port from P2PRC server node
|
// Get free port from P2PRC server node
|
||||||
serverPort, err := frp.GetFRPServerPort("http://" + HostOutsideNATIP + ":" + HostOutsideNATPort)
|
serverPort, err := frp.GetFRPServerPort("http://" + HostOutsideNATIP + ":" + HostOutsideNATPort)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(err.Error())
|
return C.CString(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
|
|
||||||
ExposedPort, err := frp.StartFRPClientForServer(HostOutsideNATIP+":"+HostOutsideNATPort, serverPort, internalPort, "")
|
ExposedPort, err := frp.StartFRPClientForServer(HostOutsideNATIP+":"+HostOutsideNATPort, serverPort, internalPort, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(err.Error())
|
return C.CString(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return C.CString(ExposedPort)
|
return C.CString(ExposedPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export MapPort
|
//export MapPort
|
||||||
func MapPort(Port string, DomainName string, ServerAddress string) *C.char {
|
func MapPort(Port string, DomainName string, ServerAddress string) *C.char {
|
||||||
Address, err := abstractions.MapPort(Port, DomainName, ServerAddress)
|
Address, err := abstractions.MapPort(Port, DomainName, ServerAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(err.Error())
|
return C.CString(err.Error())
|
||||||
}
|
}
|
||||||
return C.CString(Address.EntireAddress)
|
return C.CString(Address.EntireAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export CustomInformation
|
//export CustomInformation
|
||||||
func CustomInformation(CustomInformation string) *C.char {
|
func CustomInformation(CustomInformation string) *C.char {
|
||||||
err := abstractions.AddCustomInformation(CustomInformation)
|
err := abstractions.AddCustomInformation(CustomInformation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(err.Error())
|
return C.CString(err.Error())
|
||||||
}
|
}
|
||||||
return C.CString("Success")
|
return C.CString("Success")
|
||||||
|
}
|
||||||
|
|
||||||
|
//export AddRootNode
|
||||||
|
func AddRootNode(IP string, Port string) *C.char {
|
||||||
|
err := abstractions.AddRootNode(IP, Port)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
return C.CString("Success")
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------- Controlling Server ----------------------------------------
|
// --------------------------------- Controlling Server ----------------------------------------
|
||||||
|
|
||||||
//export Server
|
//export Server
|
||||||
func Server() (output *C.char) {
|
func Server() (output *C.char) {
|
||||||
_, err := abstractions.Start()
|
_, err := abstractions.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(err.Error())
|
return C.CString(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return ConvertStructToJSONString("")
|
return ConvertStructToJSONString("")
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------- Helper Functions ----------------------------------------
|
// --------------------------------- Helper Functions ----------------------------------------
|
||||||
|
|
||||||
func ConvertStructToJSONString(Struct interface{}) *C.char {
|
func ConvertStructToJSONString(Struct interface{}) *C.char {
|
||||||
jsonBytes, err := json.Marshal(Struct)
|
jsonBytes, err := json.Marshal(Struct)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(err.Error())
|
return C.CString(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the JSON bytes to a string
|
// Convert the JSON bytes to a string
|
||||||
return C.CString(string(jsonBytes))
|
return C.CString(string(jsonBytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {}
|
func main() {}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
module Paths_p2prc where
|
|
||||||
import Data.Version
|
|
||||||
version :: Version; version = makeVersion [0,1,0,0]
|
|
||||||
getDataDir :: IO FilePath; getDataDir = return "/Users/akilan/.mcabal/mhs-0.12.3.0/packages/p2prc-0.1.0.0/data"
|
|
||||||
@@ -20,19 +20,21 @@ import Error
|
|||||||
import JSON
|
import JSON
|
||||||
( IPAddressTable(..)
|
( IPAddressTable(..)
|
||||||
, MapPortResponse(..)
|
, MapPortResponse(..)
|
||||||
, P2prcConfig
|
, P2PRCConfig
|
||||||
)
|
)
|
||||||
|
|
||||||
import CLI
|
import CLI
|
||||||
( StdInput(..)
|
( StdInput(..)
|
||||||
, CLIOpt(..)
|
, CLIOpt(..)
|
||||||
, eitherErrDecode
|
, eitherErrDecode
|
||||||
, p2PrcCmdName
|
, p2prcCmdName
|
||||||
, eitherExecProcess
|
, eitherExecProcess
|
||||||
, eitherExecProcessParser
|
, eitherExecProcessParser
|
||||||
, spawnProcP2Prc
|
, spawnProcP2PRC
|
||||||
)
|
)
|
||||||
|
|
||||||
|
-- import System.Environment (lookupEnv)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- | Lower level P2PRC Haskell api that exposes basic functionality necessary to joint the network.
|
-- | Lower level P2PRC Haskell api that exposes basic functionality necessary to joint the network.
|
||||||
@@ -41,7 +43,7 @@ data P2PRCapi
|
|||||||
= MkP2PRCapi
|
= MkP2PRCapi
|
||||||
{ startServer :: IOEitherError ProcessHandle
|
{ startServer :: IOEitherError ProcessHandle
|
||||||
-- ^ Start server
|
-- ^ Start server
|
||||||
, execInitConfig :: IOEitherError P2prcConfig
|
-- , execInitConfig :: IOEitherError P2PRCConfig
|
||||||
-- ^ Instantiate server configuration
|
-- ^ Instantiate server configuration
|
||||||
, execListServers :: IOEitherError IPAddressTable
|
, execListServers :: IOEitherError IPAddressTable
|
||||||
-- ^ List servers in network
|
-- ^ List servers in network
|
||||||
@@ -94,14 +96,14 @@ main =
|
|||||||
p2prcAPI :: P2PRCapi
|
p2prcAPI :: P2PRCapi
|
||||||
p2prcAPI =
|
p2prcAPI =
|
||||||
MkP2PRCapi
|
MkP2PRCapi
|
||||||
{ startServer = spawnProcP2Prc p2PrcCmdName [ MkOptAtomic "--s" ]
|
{ startServer = spawnProcP2PRC p2prcCmdName [ MkOptAtomic "--s" ]
|
||||||
|
|
||||||
, execListServers =
|
, execListServers =
|
||||||
execProcP2PrcParser [ MkOptAtomic "--ls" ] MkEmptyStdInput
|
execProcP2PRCParser [ MkOptAtomic "--ls" ] MkEmptyStdInput
|
||||||
|
|
||||||
, execMapPort =
|
, execMapPort =
|
||||||
\ (MkMapPortRequest portNumber domainName) ->
|
\ (MkMapPortRequest portNumber domainName) ->
|
||||||
execProcP2PrcParser
|
execProcP2PRCParser
|
||||||
[ MkOptTuple
|
[ MkOptTuple
|
||||||
( "--mp"
|
( "--mp"
|
||||||
, show portNumber
|
, show portNumber
|
||||||
@@ -113,39 +115,41 @@ p2prcAPI =
|
|||||||
]
|
]
|
||||||
MkEmptyStdInput
|
MkEmptyStdInput
|
||||||
|
|
||||||
, execInitConfig = do
|
-- , execInitConfig = do
|
||||||
|
|
||||||
confInitRes <- execProcP2Prc [ MkOptAtomic "--dc" ] MkEmptyStdInput
|
-- confInitRes <- execProcP2PRC [ MkOptAtomic "--dc" ] MkEmptyStdInput
|
||||||
|
|
||||||
case confInitRes of
|
-- case confInitRes of
|
||||||
(Right _) -> do
|
-- (Right _) -> do
|
||||||
|
|
||||||
-- TODO: get config file name dynamically
|
-- maybeValue <- lookupEnv "P2PRC"
|
||||||
--
|
|
||||||
currDirectory <- getCurrentDirectory
|
|
||||||
|
|
||||||
-- TODO: change values before loading file
|
-- -- TODO: get config file name dynamically
|
||||||
let fname = currDirectory ++ "/config.json" :: FilePath
|
-- --
|
||||||
|
-- currDirectory <- getCurrentDirectory
|
||||||
|
|
||||||
|
-- -- TODO: change values before loading file
|
||||||
|
-- let fname = currDirectory ++ "/config.json" :: FilePath
|
||||||
|
|
||||||
|
|
||||||
-- TODO: read config check if file exists
|
-- -- TODO: read config check if file exists
|
||||||
configContent <- readFile fname
|
-- configContent <- readFile fname
|
||||||
|
|
||||||
pure $ eitherErrDecode configContent
|
-- pure $ eitherErrDecode configContent
|
||||||
|
|
||||||
(Left err) -> pure $ Left err
|
-- (Left err) -> pure $ Left err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
execProcP2PrcParser ::
|
execProcP2PRCParser ::
|
||||||
FromJSON a =>
|
FromJSON a =>
|
||||||
[CLIOpt] -> StdInput -> IOEitherError a
|
[CLIOpt] -> StdInput -> IOEitherError a
|
||||||
|
|
||||||
execProcP2PrcParser = eitherExecProcessParser p2PrcCmdName
|
execProcP2PRCParser = eitherExecProcessParser p2prcCmdName
|
||||||
-- TODO: GHC question, why does it scope down instead staying generic
|
-- TODO: GHC question, why does it scope down instead staying generic
|
||||||
|
|
||||||
execProcP2Prc = eitherExecProcess p2PrcCmdName
|
-- execProcP2PRC = eitherExecProcess p2prcCmdName
|
||||||
|
|
||||||
|
|||||||
@@ -87,8 +87,8 @@ optsToCLI = concatMap _optToCLI
|
|||||||
_optToCLI (MkOptTuple (o, v)) = [o, v]
|
_optToCLI (MkOptTuple (o, v)) = [o, v]
|
||||||
|
|
||||||
|
|
||||||
spawnProcP2Prc :: CLICmd -> [CLIOpt] -> IOEitherError ProcessHandle
|
spawnProcP2PRC :: CLICmd -> [CLIOpt] -> IOEitherError ProcessHandle
|
||||||
spawnProcP2Prc cmd opts =
|
spawnProcP2PRC cmd opts =
|
||||||
do
|
do
|
||||||
let prc = proc cmd $ optsToCLI opts
|
let prc = proc cmd $ optsToCLI opts
|
||||||
|
|
||||||
@@ -115,6 +115,6 @@ eitherErrorDecode esa =
|
|||||||
|
|
||||||
-- assumes the program is ran inside the haskell module in p2prc's repo
|
-- assumes the program is ran inside the haskell module in p2prc's repo
|
||||||
-- assumes that last path segment is "haskell" and that p2prc binary's name is "p2p-rendering-computation"
|
-- assumes that last path segment is "haskell" and that p2prc binary's name is "p2p-rendering-computation"
|
||||||
p2PrcCmdName :: String
|
p2prcCmdName :: String
|
||||||
p2PrcCmdName = "p2p-rendering-computation"
|
p2prcCmdName = "p2prc"
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ runP2PRC
|
|||||||
|
|
||||||
( MkP2PRCapi
|
( MkP2PRCapi
|
||||||
{ startServer = startServer
|
{ startServer = startServer
|
||||||
, execInitConfig = execInitConfig
|
-- , execInitConfig = execInitConfig
|
||||||
, execListServers = execListServers
|
, execListServers = execListServers
|
||||||
, execMapPort = execMapPort
|
, execMapPort = execMapPort
|
||||||
}
|
}
|
||||||
@@ -105,12 +105,12 @@ runP2PRC
|
|||||||
let
|
let
|
||||||
|
|
||||||
|
|
||||||
configValue <- execInitConfig
|
-- configValue <- execInitConfig
|
||||||
|
|
||||||
-- TODO: get name of host server from config json
|
-- TODO: get name of host server from config json
|
||||||
|
|
||||||
print configValue
|
-- print configValue
|
||||||
putStrLn "\n\n\n"
|
-- putStrLn "\n\n\n"
|
||||||
|
|
||||||
eitherStartProcessHandle <- startServer
|
eitherStartProcessHandle <- startServer
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
module JSON
|
module JSON
|
||||||
( P2prcConfig(..)
|
( P2PRCConfig(..)
|
||||||
, IPAddressTable(..)
|
, IPAddressTable(..)
|
||||||
, IPAddress(..)
|
, IPAddress(..)
|
||||||
, ServerInfo(..)
|
, ServerInfo(..)
|
||||||
@@ -38,11 +38,11 @@ instance FromJSON MapPortResponse where
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
{-# WARNING P2prcConfig "This type is unstable at the moment due to the P2PRC's library error handling bug. For more information visit: https://github.com/Akilan1999/p2p-rendering-computation/issues/114#issuecomment-2474737015" #-}
|
{-# WARNING P2PRCConfig "This type is unstable at the moment due to the P2PRC's library error handling bug. For more information visit: https://github.com/Akilan1999/p2p-rendering-computation/issues/114#issuecomment-2474737015" #-}
|
||||||
|
|
||||||
-- | This represents the server configuration that defines its attributes and behaviours in the network, as well as, the location of the runtime persistence artifacts.
|
-- | This represents the server configuration that defines its attributes and behaviours in the network, as well as, the location of the runtime persistence artifacts.
|
||||||
newtype P2prcConfig
|
newtype P2PRCConfig
|
||||||
= MkP2prConfig
|
= MkP2PRCConfig
|
||||||
{ machineName :: String -- ^ Machine Name
|
{ machineName :: String -- ^ Machine Name
|
||||||
} deriving Show
|
} deriving Show
|
||||||
|
|
||||||
@@ -96,13 +96,13 @@ newtype P2prcConfig
|
|||||||
-- to have a dedicated port field
|
-- to have a dedicated port field
|
||||||
|
|
||||||
|
|
||||||
instance FromJSON P2prcConfig where
|
instance FromJSON P2PRCConfig where
|
||||||
parseJSON (Object o) = do
|
parseJSON (Object o) = do
|
||||||
|
|
||||||
machineName <- o .: "MachineName"
|
machineName <- o .: "MachineName"
|
||||||
|
|
||||||
pure
|
pure
|
||||||
$ MkP2prConfig
|
$ MkP2PRCConfig
|
||||||
{ machineName=machineName
|
{ machineName=machineName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ module P2PRC
|
|||||||
-- ** Interface data types
|
-- ** Interface data types
|
||||||
-- | This section gives an overview on the runtime and host machine interfaces.
|
-- | This section gives an overview on the runtime and host machine interfaces.
|
||||||
, P2PRCapi(..)
|
, P2PRCapi(..)
|
||||||
, P2prcConfig(..)
|
, P2PRCConfig(..)
|
||||||
, MapPortRequest(..)
|
, MapPortRequest(..)
|
||||||
, MapPortResponse(..)
|
, MapPortResponse(..)
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ import JSON
|
|||||||
, ServerInfo(..)
|
, ServerInfo(..)
|
||||||
, IPAddress(..)
|
, IPAddress(..)
|
||||||
, MapPortResponse(..)
|
, MapPortResponse(..)
|
||||||
, P2prcConfig(..)
|
, P2PRCConfig(..)
|
||||||
)
|
)
|
||||||
|
|
||||||
import API
|
import API
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
z
|
|
||||||
@@ -44,9 +44,9 @@ class Node:
|
|||||||
Upload: int
|
Upload: int
|
||||||
ServerPort: str
|
ServerPort: str
|
||||||
BareMetalSSHPort: str
|
BareMetalSSHPort: str
|
||||||
NAT: str
|
NAT: bool
|
||||||
EscapeImplementation: str
|
EscapeImplementation: str
|
||||||
ProxyServer: str
|
ProxyServer: bool
|
||||||
UnSafeMode: bool
|
UnSafeMode: bool
|
||||||
PublicKey: str
|
PublicKey: str
|
||||||
CustomInformation: str
|
CustomInformation: str
|
||||||
@@ -64,6 +64,9 @@ def StartServer():
|
|||||||
# Starting P2PRC as a server mode
|
# Starting P2PRC as a server mode
|
||||||
p2prc.Server()
|
p2prc.Server()
|
||||||
|
|
||||||
|
def Init():
|
||||||
|
p2prc.Init("")
|
||||||
|
|
||||||
# Class to create string to pass as string function
|
# Class to create string to pass as string function
|
||||||
# parameter to shared object file
|
# parameter to shared object file
|
||||||
class go_string(Structure):
|
class go_string(Structure):
|
||||||
@@ -98,6 +101,21 @@ def ListNodes():
|
|||||||
dat: IPAddress = dacite.from_dict(IPAddress,ipTableObject)
|
dat: IPAddress = dacite.from_dict(IPAddress,ipTableObject)
|
||||||
return dat
|
return dat
|
||||||
|
|
||||||
|
# Add a root node to P2RRC and overwrites all other nodes.
|
||||||
|
# To be only added before the network started and with
|
||||||
|
# the intention of a fresh protocol.
|
||||||
|
def AddRootNode(ip="", port="") -> bool:
|
||||||
|
ip = go_string(c_char_p(ip.encode('utf-8')), len(ip))
|
||||||
|
port = go_string(c_char_p(port.encode('utf-8')), len(port))
|
||||||
|
|
||||||
|
p2prc.AddRootNode.restype = c_char_p
|
||||||
|
res = p2prc.AddRootNode(ip, port)
|
||||||
|
if str(res).strip("b'") == "Success":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# python function to pass-through custom
|
# python function to pass-through custom
|
||||||
# information to interpret which can be
|
# information to interpret which can be
|
||||||
# interpreted as a DSL.
|
# interpreted as a DSL.
|
||||||
|
|||||||
@@ -9,3 +9,6 @@ if __name__ == "__main__":
|
|||||||
# Add custom information to the network
|
# Add custom information to the network
|
||||||
if AddCustomInformation("Test"):
|
if AddCustomInformation("Test"):
|
||||||
print("It worked")
|
print("It worked")
|
||||||
|
|
||||||
|
if AddRootNode("0.0.0.0", "8081"):
|
||||||
|
print("It worked for adding root node")
|
||||||
|
|||||||
BIN
Docs/Colored-On-Light-Image.png
Normal file
BIN
Docs/Colored-On-Light-Image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 276 KiB |
14
Docs/android-setup.txt
Normal file
14
Docs/android-setup.txt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
This is a temporary android setup instruction:
|
||||||
|
|
||||||
|
1. Instruction to run from ADB with termux
|
||||||
|
'''
|
||||||
|
run-as com.termux files/usr/bin/bash -lic 'export PATH=/data/data/com.termux/files/usr/bin:$PATH; export LD_PRELOAD=/data/data/com.termux/files/usr/lib/libtermux-exec.so; bash -i'
|
||||||
|
'''
|
||||||
|
|
||||||
|
2. Install golang
|
||||||
|
'''
|
||||||
|
pkg install golang
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
563
Docs/index.html
563
Docs/index.html
File diff suppressed because it is too large
Load Diff
@@ -3,16 +3,20 @@
|
|||||||
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="https://fniessen.github.io/org-html-themes/src/readtheorg_theme/css/search.css"/>
|
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="https://fniessen.github.io/org-html-themes/src/readtheorg_theme/css/search.css"/>
|
||||||
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="style.css"/>
|
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="style.css"/>
|
||||||
|
|
||||||
|
#+attr_html: :width 300px
|
||||||
|
[[./Colored-On-Light-Image.png]]
|
||||||
|
|
||||||
|
* Guide through video
|
||||||
|
*** The video below shows the setup and usage of P2PRC.
|
||||||
|
#+attr_html: :class video
|
||||||
|
[[https://www.youtube.com/watch?v=OMwCpedu5cs][https://i3.ytimg.com/vi/OMwCpedu5cs/maxresdefault.jpg]]
|
||||||
|
|
||||||
|
*** Source code: https://github.com/Akilan1999/p2p-rendering-computation
|
||||||
|
|
||||||
* Introduction
|
* Introduction
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: chapter1-introduction
|
:CUSTOM_ID: chapter1-introduction
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
** Abstract
|
|
||||||
:PROPERTIES:
|
|
||||||
:CUSTOM_ID: abstract
|
|
||||||
:END:
|
|
||||||
This project focuses on creating a framework for running heavy computational tasks that a regular
|
This project focuses on creating a framework for running heavy computational tasks that a regular
|
||||||
computer cannot handle easily. These tasks may include graphically demanding video games, rendering
|
computer cannot handle easily. These tasks may include graphically demanding video games, rendering
|
||||||
3D animations, and performing complex protein folding simulations. The major focus of this project
|
3D animations, and performing complex protein folding simulations. The major focus of this project
|
||||||
@@ -352,6 +356,14 @@ p2prc --mp <port no to map> --dn <domain name to link Mapped port against> --ra
|
|||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
*** Add root node
|
||||||
|
Adds a root node to P2RRC and overwrites all other nodes in the ip table.
|
||||||
|
To be only added before the network is started and with
|
||||||
|
the intention of a fresh instance.
|
||||||
|
#+begin_example
|
||||||
|
p2prc --arn --ip <root node ip address> -p <root node port no>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
* P2P Module Implementation
|
* P2P Module Implementation
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: p2p-module-implementation
|
:CUSTOM_ID: p2p-module-implementation
|
||||||
@@ -363,7 +375,7 @@ to determine upload and download speeds. This valuable information enables users
|
|||||||
servers with optimal performance, enhancing their overall network experience.
|
servers with optimal performance, enhancing their overall network experience.
|
||||||
|
|
||||||
#+caption: UML diagram of P2P module
|
#+caption: UML diagram of P2P module
|
||||||
[[file:images/p2pmoduleArch.png]]
|
[[file:./images/p2pmoduleArch.png]
|
||||||
|
|
||||||
The peer to peer implementation was built from scratch. This is because
|
The peer to peer implementation was built from scratch. This is because
|
||||||
other peer to peer libraries were on the implementation of the
|
other peer to peer libraries were on the implementation of the
|
||||||
@@ -783,6 +795,7 @@ func main() {
|
|||||||
|
|
||||||
|
|
||||||
- Video tutorial:
|
- Video tutorial:
|
||||||
|
#+attr_html: :class video
|
||||||
[[https://youtu.be/rN4SiVowg5E][https://i3.ytimg.com/vi/rN4SiVowg5E/maxresdefault.jpg]]
|
[[https://youtu.be/rN4SiVowg5E][https://i3.ytimg.com/vi/rN4SiVowg5E/maxresdefault.jpg]]
|
||||||
|
|
||||||
This is a fun expirement for anyone to try to quickly run a server and
|
This is a fun expirement for anyone to try to quickly run a server and
|
||||||
|
|||||||
1
Docs/kill-docs.sh
Normal file
1
Docs/kill-docs.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
kill -9 $(lsof -t -i:8083)
|
||||||
1
Docs/run-docs.sh
Normal file
1
Docs/run-docs.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
go run staticServer.go &
|
||||||
28
Docs/staticServer.go
Normal file
28
Docs/staticServer.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
Serve is a very simple static file server in go
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
-p="8100": port to serve on
|
||||||
|
-d=".": the directory of static files to host
|
||||||
|
|
||||||
|
Navigating to http://localhost:8100 will display the index.html or directory
|
||||||
|
listing file.
|
||||||
|
*/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
port := flag.String("p", "8083", "port to serve on")
|
||||||
|
directory := flag.String("d", ".", "the directory of static file to host")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
http.Handle("/", http.FileServer(http.Dir(*directory)))
|
||||||
|
|
||||||
|
log.Printf("Serving %s on HTTP port: %s\n", *directory, *port)
|
||||||
|
log.Fatal(http.ListenAndServe(":"+*port, nil))
|
||||||
|
}
|
||||||
@@ -23,3 +23,7 @@ h4,h5,h6{
|
|||||||
color: #b96c29;
|
color: #b96c29;
|
||||||
font-weight:300;
|
font-weight:300;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.video {
|
||||||
|
box-shadow: 10px 10px 25px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|||||||
BIN
Simulation/__pycache__/library.cpython-313.pyc
Normal file
BIN
Simulation/__pycache__/library.cpython-313.pyc
Normal file
Binary file not shown.
143
Simulation/library.py
Normal file
143
Simulation/library.py
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
import ctypes
|
||||||
|
from ctypes import Structure, c_char_p, c_int, cdll
|
||||||
|
from dataclasses import dataclass, astuple
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
from typing import List
|
||||||
|
import subprocess
|
||||||
|
import uuid
|
||||||
|
import dacite
|
||||||
|
import os
|
||||||
|
import sqlalchemy
|
||||||
|
import dataclasses
|
||||||
|
from typing import Union
|
||||||
|
import schedule
|
||||||
|
import threading
|
||||||
|
import requests
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
# p2prc.Init("")
|
||||||
|
|
||||||
|
# Start running schedule
|
||||||
|
schedule.run_pending()
|
||||||
|
|
||||||
|
# # Create Sqlite database to track processes
|
||||||
|
# engine=sqlalchemy.create_engine(f'sqlite:///homeserver.db')
|
||||||
|
|
||||||
|
# Global variable
|
||||||
|
# A global variable will be populated on runtime.
|
||||||
|
# It is read from P2PRC directly or from a local
|
||||||
|
# database.
|
||||||
|
|
||||||
|
# Node information
|
||||||
|
# Generated using: https://jsonformatter.org/json-to-python
|
||||||
|
@dataclass
|
||||||
|
class Node:
|
||||||
|
Name: str
|
||||||
|
MachineUsername: str
|
||||||
|
IPV4: str
|
||||||
|
IPV6: str
|
||||||
|
Latency: int
|
||||||
|
Download: int
|
||||||
|
Upload: int
|
||||||
|
ServerPort: str
|
||||||
|
BareMetalSSHPort: str
|
||||||
|
NAT: bool
|
||||||
|
EscapeImplementation: str
|
||||||
|
ProxyServer: bool
|
||||||
|
UnSafeMode: bool
|
||||||
|
PublicKey: str
|
||||||
|
CustomInformation: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class IPAddress:
|
||||||
|
ip_address: List[Node]
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# ----------------------------- Helper functions -----------------------------
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
p2prc = None
|
||||||
|
|
||||||
|
def LoadDLL(envPath=""):
|
||||||
|
global p2prc
|
||||||
|
# os.environ["P2PRC"] = envPath
|
||||||
|
print(envPath)
|
||||||
|
# env = "P2PRC=" + envPath
|
||||||
|
os.system("sh setEnv.sh " + envPath)
|
||||||
|
# subprocess.call("sh setEnv.sh " + envPath)
|
||||||
|
p2prc = ctypes.CDLL("SharedObjects/p2prc.so")
|
||||||
|
|
||||||
|
|
||||||
|
def StartServer():
|
||||||
|
# Starting P2PRC as a server mode
|
||||||
|
p2prc.Server()
|
||||||
|
|
||||||
|
def Init():
|
||||||
|
p2prc.Init("")
|
||||||
|
|
||||||
|
# Class to create string to pass as string function
|
||||||
|
# parameter to shared object file
|
||||||
|
class go_string(Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("p", c_char_p),
|
||||||
|
("n", c_int)]
|
||||||
|
|
||||||
|
# Ensuring local port can escape NAT and responds
|
||||||
|
# with the public ip and port no.
|
||||||
|
# If the domain name is specified then the public IP
|
||||||
|
# can be used as an A name entry.
|
||||||
|
def P2PRCMapPort(port="",domainname="",serveraddress=""):
|
||||||
|
port = go_string(c_char_p(port.encode('utf-8')), len(port))
|
||||||
|
domainname = go_string(c_char_p(domainname.encode('utf-8')), len(domainname))
|
||||||
|
serveraddress = go_string(c_char_p(serveraddress.encode('utf-8')), len(serveraddress))
|
||||||
|
|
||||||
|
# Defining the response type of the GoLang function
|
||||||
|
# function
|
||||||
|
p2prc.MapPort.restype = c_char_p
|
||||||
|
# Calling the Go function
|
||||||
|
address = p2prc.MapPort(port,domainname,serveraddress)
|
||||||
|
res = str(address).strip("b'")
|
||||||
|
return res
|
||||||
|
|
||||||
|
# Lists all avaliable nodes in the network
|
||||||
|
def ListNodes():
|
||||||
|
# View IP Table information
|
||||||
|
p2prc.ViewIPTable.restype = c_char_p
|
||||||
|
ipTable = p2prc.ViewIPTable()
|
||||||
|
# View IP Table as
|
||||||
|
ipTableObject = json.loads((str(ipTable).strip("b'")))
|
||||||
|
dat: IPAddress = dacite.from_dict(IPAddress,ipTableObject)
|
||||||
|
return dat
|
||||||
|
|
||||||
|
# Add a root node to P2RRC and overwrites all other nodes.
|
||||||
|
# To be only added before the network started and with
|
||||||
|
# the intention of a fresh protocol.
|
||||||
|
def AddRootNode(ip="", port="") -> bool:
|
||||||
|
ip = go_string(c_char_p(ip.encode('utf-8')), len(ip))
|
||||||
|
port = go_string(c_char_p(port.encode('utf-8')), len(port))
|
||||||
|
|
||||||
|
p2prc.AddRootNode.restype = c_char_p
|
||||||
|
res = p2prc.AddRootNode(ip, port)
|
||||||
|
if str(res).strip("b'") == "Success":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# python function to pass-through custom
|
||||||
|
# information to interpret which can be
|
||||||
|
# interpreted as a DSL.
|
||||||
|
def AddCustomInformation(message="") -> bool:
|
||||||
|
message = go_string(c_char_p(message.encode('utf-8')), len(message))
|
||||||
|
|
||||||
|
p2prc.CustomInformation.restype = c_char_p
|
||||||
|
status = p2prc.CustomInformation(message)
|
||||||
|
if str(status).strip("b'") == "Success":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
6
Simulation/requests
Normal file
6
Simulation/requests
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
dacite
|
||||||
|
schedule
|
||||||
|
sqlalchemy
|
||||||
|
dacite
|
||||||
|
schedule
|
||||||
|
sqlalchemy
|
||||||
4
Simulation/requirements.txt
Normal file
4
Simulation/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
dacite
|
||||||
|
schedule
|
||||||
|
sqlalchemy
|
||||||
|
requests
|
||||||
1
Simulation/setEnv.sh
Normal file
1
Simulation/setEnv.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export P2PRC=$1
|
||||||
145
Simulation/simulation.py
Normal file
145
Simulation/simulation.py
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
# This repo consists of the P2PRC simulation to ensure
|
||||||
|
# that we can test various nodes locally with just processes.
|
||||||
|
# Note: This implementation is for local nodes only.
|
||||||
|
|
||||||
|
from library import *
|
||||||
|
import os
|
||||||
|
import socket
|
||||||
|
from contextlib import closing
|
||||||
|
|
||||||
|
# Stores the base information
|
||||||
|
# required to know about a P2PRC node
|
||||||
|
@dataclass
|
||||||
|
class P2PRCNode:
|
||||||
|
Name: str
|
||||||
|
ConfigLocation: str
|
||||||
|
ServerPort: str
|
||||||
|
RunningState: bool
|
||||||
|
RootNodePort: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class P2PRCNodes:
|
||||||
|
P2PRCNodes: List[P2PRCNode]
|
||||||
|
|
||||||
|
# Tracker for P2PRC nodes
|
||||||
|
PublicP2PRCNodes: Union[P2PRCNodes, None] = None
|
||||||
|
|
||||||
|
# Tracker of root Node
|
||||||
|
RootNode: P2PRCNode
|
||||||
|
|
||||||
|
# Sets up P2PRC with default configuration
|
||||||
|
def SetupP2PRCNode(name=""):
|
||||||
|
# Unset environment variables
|
||||||
|
os.environ.pop('P2PRC', None)
|
||||||
|
# Create Test folder
|
||||||
|
Dirname = "P2PRC-Test-" + name
|
||||||
|
try:
|
||||||
|
os.mkdir(Dirname)
|
||||||
|
print(f"Directory '{Dirname}' created successfully.")
|
||||||
|
except FileExistsError:
|
||||||
|
print(f"Directory '{Dirname}' already exists.")
|
||||||
|
KillProcedure()
|
||||||
|
|
||||||
|
# Set env variable for session
|
||||||
|
envPath = os.path.abspath(os.getcwd()) + "/" + Dirname
|
||||||
|
LoadDLL(envPath)
|
||||||
|
|
||||||
|
# Generate random 4
|
||||||
|
ServerPortNo = str(find_free_port())
|
||||||
|
|
||||||
|
# Initialise data class
|
||||||
|
p2prcNode = P2PRCNode(
|
||||||
|
Name = name,
|
||||||
|
ConfigLocation = envPath,
|
||||||
|
ServerPort = ServerPortNo,
|
||||||
|
RunningState = True,
|
||||||
|
RootNodePort = "",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Adds P2PRC node to memory
|
||||||
|
AddP2PRCNodeToMemory(p2prcNode)
|
||||||
|
|
||||||
|
# Initialise P2PRC instance
|
||||||
|
Init()
|
||||||
|
|
||||||
|
# Add root node to ip table
|
||||||
|
AddRootNode("0.0.0.0",ServerPortNo)
|
||||||
|
|
||||||
|
# Change server port no on Config
|
||||||
|
ChangeFileValue(envPath + "/config.json", "ServerPort", ServerPortNo)
|
||||||
|
|
||||||
|
thread = threading.Thread(target = StartServer)
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
|
||||||
|
# Find free TCP port avaliable
|
||||||
|
# Source: https://stackoverflow.com/questions/1365265/on-localhost-how-do-i-pick-a-free-port-number
|
||||||
|
def find_free_port():
|
||||||
|
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
|
||||||
|
s.bind(('', 0))
|
||||||
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
return s.getsockname()[1]
|
||||||
|
|
||||||
|
# Standard function called after
|
||||||
|
# a simulation is terminated or
|
||||||
|
# when error exception is called
|
||||||
|
def KillProcedure():
|
||||||
|
RemoveAllP2PRCNodesFromMemoryAndConfigFile()
|
||||||
|
|
||||||
|
# -------------------------- helper functions -----------------------
|
||||||
|
def ChangeFileValue(file_path, key, new_value):
|
||||||
|
"""
|
||||||
|
Reads a JSON file, updates a key with a new value, and writes it back.
|
||||||
|
|
||||||
|
:param file_path: Path to the JSON file
|
||||||
|
:param key: Key in the JSON to update
|
||||||
|
:param new_value: New value to assign to the key
|
||||||
|
"""
|
||||||
|
# Read from the JSON file
|
||||||
|
with open(file_path, 'r') as file:
|
||||||
|
data = json.load(file)
|
||||||
|
|
||||||
|
# Update the key with the new value
|
||||||
|
data[key] = new_value
|
||||||
|
|
||||||
|
# Write the updated data back to the JSON file
|
||||||
|
with open(file_path, 'w') as file:
|
||||||
|
json.dump(data, file, indent=4)
|
||||||
|
|
||||||
|
# Adds the process dataclass the to
|
||||||
|
# the global variable PublicProcess.
|
||||||
|
def AddP2PRCNodeToMemory(p2prcNode: P2PRCNode):
|
||||||
|
global PublicP2PRCNodes
|
||||||
|
global RootNode
|
||||||
|
if PublicP2PRCNodes == None:
|
||||||
|
PublicP2PRCNodes = P2PRCNodes(P2PRCNodes=[p2prcNode])
|
||||||
|
p2prcNode.RootNodePort = p2prcNode.ServerPort
|
||||||
|
RootNode = p2prcNode
|
||||||
|
else:
|
||||||
|
p2prcNode.RootNodePort = RootNode.ServerPort
|
||||||
|
PublicP2PRCNodes.P2PRCNodes.append(p2prcNode)
|
||||||
|
|
||||||
|
# Remove all nodes test nodes generated
|
||||||
|
def RemoveAllP2PRCNodesFromMemoryAndConfigFile():
|
||||||
|
global PublicP2PRCNodes
|
||||||
|
if PublicP2PRCNodes is not None:
|
||||||
|
for node in PublicP2PRCNodes.P2PRCNodes:
|
||||||
|
config_path = node.ConfigLocation
|
||||||
|
# Safely remove the folder if it exists
|
||||||
|
if os.path.exists(config_path) and os.path.isdir(config_path):
|
||||||
|
try:
|
||||||
|
shutil.rmtree(config_path)
|
||||||
|
print(f"Deleted folder: {config_path}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to delete {config_path}: {e}")
|
||||||
|
# Clear the node list
|
||||||
|
PublicP2PRCNodes = None
|
||||||
|
print("All P2PRC nodes removed from memory.")
|
||||||
|
else:
|
||||||
|
print("No P2PRC nodes to remove.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Setting up 2 P2PRC nodes
|
||||||
|
SetupP2PRCNode(name="Test")
|
||||||
|
SetupP2PRCNode(name="Test1")
|
||||||
14
Simulation/test.py
Normal file
14
Simulation/test.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from library import *
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
P2PRCNodes = ListNodes()
|
||||||
|
# Print nodes in the network
|
||||||
|
print(P2PRCNodes)
|
||||||
|
|
||||||
|
# Add custom information to the network
|
||||||
|
if AddCustomInformation("Test"):
|
||||||
|
print("It worked")
|
||||||
|
|
||||||
|
if AddRootNode("0.0.0.0", "8081"):
|
||||||
|
print("It worked for adding root node")
|
||||||
@@ -1,95 +1,107 @@
|
|||||||
package abstractions
|
package abstractions
|
||||||
|
|
||||||
import "C"
|
|
||||||
import (
|
import (
|
||||||
"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"
|
||||||
Config "github.com/Akilan1999/p2p-rendering-computation/config"
|
Config "github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config/generate"
|
"github.com/Akilan1999/p2p-rendering-computation/config/generate"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/server"
|
"github.com/Akilan1999/p2p-rendering-computation/server"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gin-gonic/gin"
|
"os"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Init Initialises p2prc
|
// Init Initialises p2prc
|
||||||
func Init(customConfig interface{}) (config *Config.Config, err error) {
|
func Init(customConfig interface{}) (config *Config.Config, err error) {
|
||||||
|
|
||||||
// Get config file path
|
// Get config file path
|
||||||
// Checks P2PRC path initially
|
// Checks P2PRC path initially
|
||||||
// - Get PATH if environment varaible
|
// - Get PATH if environment varaible
|
||||||
path, err := Config.GetPathP2PRC("P2PRC")
|
path, err := Config.GetPathP2PRC("P2PRC")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// check if the config file exists
|
// check if the config file exists
|
||||||
if _, err = os.Stat(path + "config.json"); err != nil {
|
if _, err = os.Stat(path + "config.json"); err != nil {
|
||||||
// Initialize with base p2prc config files
|
// Initialize with base p2prc config files
|
||||||
// set the config file with default paths
|
// set the config file with default paths
|
||||||
config, err = generate.SetDefaults("P2PRC", false, customConfig, false)
|
config, err = generate.SetDefaults("P2PRC", false, customConfig, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If the configs are available then use them over generating new ones.
|
// If the configs are available then use them over generating new ones.
|
||||||
config, err = Config.ConfigInit(nil, nil)
|
config, err = Config.ConfigInit(nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start p2prc in a server mode
|
// Start p2prc in a server mode
|
||||||
func Start() (*gin.Engine, error) {
|
func Start() (*gin.Engine, error) {
|
||||||
engine, err := server.Server()
|
engine, err := server.Server()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return engine, nil
|
return engine, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MapPort Creates a reverse proxy connection and maps the appropriate port
|
// MapPort Creates a reverse proxy connection and maps the appropriate port
|
||||||
func MapPort(port string, domainName string, serverAddress string) (response *client.ResponseMAPPort, err error) {
|
func MapPort(port string, domainName string, serverAddress string) (response *client.ResponseMAPPort, err error) {
|
||||||
response, err = client.MAPPort(port, domainName, serverAddress)
|
response, err = client.MAPPort(port, domainName, serverAddress)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartContainer Starts docker container on the remote machine
|
//// StartContainer Starts docker container on the remote machine
|
||||||
func StartContainer(IP string) (container *docker.DockerVM, err error) {
|
//func StartContainer(IP string) (container *docker.DockerVM, err error) {
|
||||||
container, err = client.StartContainer(IP, 0, false, "", "")
|
// container, err = client.StartContainer(IP, 0, false, "", "")
|
||||||
return
|
// return
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// RemoveContainer Removes docker container based on the IP address and ID
|
//// RemoveContainer Removes docker container based on the IP address and ID
|
||||||
// provided
|
//// provided
|
||||||
func RemoveContainer(IP string, ID string) error {
|
//func RemoveContainer(IP string, ID string) error {
|
||||||
return client.RemoveContianer(IP, ID)
|
// return client.RemoveContianer(IP, ID)
|
||||||
}
|
//}
|
||||||
|
|
||||||
// GetSpecs Get spec information about the remote server
|
// GetSpecs Get spec information about the remote server
|
||||||
func GetSpecs(IP string) (specs *server.SysInfo, err error) {
|
func GetSpecs(IP string) (specs *server.SysInfo, err error) {
|
||||||
specs, err = client.GetSpecs(IP)
|
specs, err = client.GetSpecs(IP)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ViewIPTable View information of nodes in the network
|
// ViewIPTable View information of nodes in the network
|
||||||
func ViewIPTable() (table *p2p.IpAddresses, err error) {
|
func ViewIPTable() (table *p2p.IpAddresses, err error) {
|
||||||
table, err = p2p.ReadIpTable()
|
table, err = p2p.ReadIpTable()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateIPTable Force updates IP tables based on new
|
// UpdateIPTable Force updates IP tables based on new
|
||||||
// new nodes discovered in the network
|
// new nodes discovered in the network
|
||||||
func UpdateIPTable() (err error) {
|
func UpdateIPTable() (err error) {
|
||||||
return clientIPTable.UpdateIpTableListClient()
|
return clientIPTable.UpdateIpTableListClient()
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddCustomInformation allows to pass custom information
|
// AddCustomInformation allows to pass custom information
|
||||||
// through the network to which can be listened on
|
// through the network to which can be listened on
|
||||||
// all peers in the network to execute a task.
|
// all peers in the network to execute a task.
|
||||||
func AddCustomInformation(information string) error {
|
func AddCustomInformation(information string) error {
|
||||||
return clientIPTable.AddCustomInformationToIPTable(information)
|
return clientIPTable.AddCustomInformationToIPTable(information)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddRootNode Adds root node to the network by using defaults except for
|
||||||
|
// ip address and port no. Supports only IPV4 as of now.
|
||||||
|
func AddRootNode(rootIP string, portNo string) error {
|
||||||
|
var rootNode []p2p.IpAddress
|
||||||
|
|
||||||
|
rootNode = append(rootNode, p2p.IpAddress{
|
||||||
|
Name: "",
|
||||||
|
Ipv4: rootIP,
|
||||||
|
ServerPort: portNo,
|
||||||
|
NAT: false,
|
||||||
|
})
|
||||||
|
return generate.GenerateIPTableFile(rootNode)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,310 +1,301 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"io/ioutil"
|
|
||||||
"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(nil, nil)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
jsonFile, err := os.Open(config.GroupTrackContainersPath)
|
// jsonFile, err := os.Open(config.GroupTrackContainersPath)
|
||||||
// if we os.Open returns an error then handle it
|
// // if we os.Open returns an error then handle it
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
// defer the closing of our jsonFile so that we can parse it later on
|
// // defer the closing of our jsonFile so that we can parse it later on
|
||||||
defer jsonFile.Close()
|
// defer jsonFile.Close()
|
||||||
// read our opened xmlFile as a byte array.
|
// // read our opened xmlFile as a byte array.
|
||||||
byteValue, _ := ioutil.ReadAll(jsonFile)
|
// byteValue, _ := ioutil.ReadAll(jsonFile)
|
||||||
// we initialize our Users array
|
// // we initialize our Users array
|
||||||
var groups Groups
|
// var groups Groups
|
||||||
// we unmarshal our byteArray which contains our
|
// // we unmarshal our byteArray which contains our
|
||||||
// jsonFile's content into 'users' which we defined above
|
// // jsonFile's content into 'users' which we defined above
|
||||||
json.Unmarshal(byteValue, &groups)
|
// json.Unmarshal(byteValue, &groups)
|
||||||
return &groups, nil
|
// return &groups, nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// WriteGroup Function to write type Groups to the grouptrackcontainers.json file
|
//// WriteGroup Function to write type Groups to the grouptrackcontainers.json file
|
||||||
func (grp *Groups) WriteGroup() error {
|
//func (grp *Groups) WriteGroup() error {
|
||||||
file, err := json.MarshalIndent(grp, "", " ")
|
// file, err := json.MarshalIndent(grp, "", " ")
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
// Get Path from config
|
// // Get Path from config
|
||||||
config, err := config.ConfigInit(nil, nil)
|
// config, err := config.ConfigInit(nil, nil)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
// Writes to the appropriate file
|
// // Writes to the appropriate file
|
||||||
err = ioutil.WriteFile(config.GroupTrackContainersPath, file, 0644)
|
// err = ioutil.WriteFile(config.GroupTrackContainersPath, file, 0644)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// AddContainer Adds a container to the Tracked container list of the group
|
//// AddContainer Adds a container to the Tracked container list of the group
|
||||||
func (grp *Group) AddContainer(Container *TrackContainer) error {
|
//func (grp *Group) AddContainer(Container *TrackContainer) error {
|
||||||
grp.TrackContainerList = append(grp.TrackContainerList, Container)
|
// grp.TrackContainerList = append(grp.TrackContainerList, Container)
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// RemoveContainerGroup Removes container information from the group
|
//// RemoveContainerGroup Removes container information from the group
|
||||||
func (grp *Group) RemoveContainerGroup(Container *TrackContainer) error {
|
//func (grp *Group) RemoveContainerGroup(Container *TrackContainer) error {
|
||||||
// Iterating through all container in the Group of Tracked Container
|
// // Iterating through all container in the Group of Tracked Container
|
||||||
for i, container := range grp.TrackContainerList {
|
// for i, container := range grp.TrackContainerList {
|
||||||
// If the container ID matches then remove the container from the group
|
// // If the container ID matches then remove the container from the group
|
||||||
if container.Id == Container.Id {
|
// if container.Id == Container.Id {
|
||||||
grp.TrackContainerList = append(grp.TrackContainerList[:i], grp.TrackContainerList[i+1:]...)
|
// grp.TrackContainerList = append(grp.TrackContainerList[:i], grp.TrackContainerList[i+1:]...)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// RemoveContainerGroups removes container found in all groups
|
//// RemoveContainerGroups removes container found in all groups
|
||||||
func (grp *Groups) RemoveContainerGroups(Container *TrackContainer) error {
|
//func (grp *Groups) RemoveContainerGroups(Container *TrackContainer) error {
|
||||||
// Iterating through all groups
|
// // Iterating through all groups
|
||||||
for i, group := range grp.GroupList {
|
// for i, group := range grp.GroupList {
|
||||||
// Removes the container in the following group
|
// // Removes the container in the following group
|
||||||
// if it exists
|
// // if it exists
|
||||||
err := group.RemoveContainerGroup(Container)
|
// err := group.RemoveContainerGroup(Container)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
// Set group information to list groups
|
// // Set group information to list groups
|
||||||
grp.GroupList[i] = group
|
// grp.GroupList[i] = group
|
||||||
}
|
// }
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// ModifyContainerGroups Modifies container information is all groups
|
//// ModifyContainerGroups Modifies container information is all groups
|
||||||
// available
|
//// available
|
||||||
func (TC *TrackContainer) ModifyContainerGroups() error {
|
//func (TC *TrackContainer) ModifyContainerGroups() error {
|
||||||
group, err := ReadGroup()
|
// group, err := ReadGroup()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
// Iterate though all groups and modify the container
|
// // Iterate though all groups and modify the container
|
||||||
// information in groups where the modified container
|
// // information in groups where the modified container
|
||||||
// ID matches
|
// // ID matches
|
||||||
for i, _ := range group.GroupList {
|
// for i, _ := range group.GroupList {
|
||||||
// Checking in each group if the modified container ID exists
|
// // Checking in each group if the modified container ID exists
|
||||||
for j, _ := range group.GroupList[i].TrackContainerList {
|
// for j, _ := range group.GroupList[i].TrackContainerList {
|
||||||
// If there is match then change them
|
// // If there is match then change them
|
||||||
if group.GroupList[i].TrackContainerList[j].Id == TC.Id {
|
// if group.GroupList[i].TrackContainerList[j].Id == TC.Id {
|
||||||
group.GroupList[i].TrackContainerList[j] = TC
|
// group.GroupList[i].TrackContainerList[j] = TC
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Write modified result to the Groups track container JSON file
|
// // Write modified result to the Groups track container JSON file
|
||||||
err = group.WriteGroup()
|
// err = group.WriteGroup()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -1,220 +1,210 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
//// TrackContainers This struct stores arrays of current containers running
|
||||||
"encoding/json"
|
//type TrackContainers struct {
|
||||||
"errors"
|
// TrackContainerList []TrackContainer `json:"TrackContainer"`
|
||||||
"fmt"
|
//}
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
//
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
//// TrackContainer Stores information of current containers
|
||||||
"io/ioutil"
|
//type TrackContainer struct {
|
||||||
"os"
|
// Id string `json:"ID"`
|
||||||
)
|
// Container *docker.DockerVM `json:"Container"`
|
||||||
|
// IpAddress string `json:"IpAddress"`
|
||||||
// TrackContainers This struct stores arrays of current containers running
|
//}
|
||||||
type TrackContainers struct {
|
//
|
||||||
TrackContainerList []TrackContainer `json:"TrackContainer"`
|
//// AddTrackContainer Adds new container which has been added to the track container
|
||||||
}
|
//func AddTrackContainer(d *docker.DockerVM, ipAddress string) error {
|
||||||
|
// // Checking if pointer d is null
|
||||||
// TrackContainer Stores information of current containers
|
// if d == nil {
|
||||||
type TrackContainer struct {
|
// return errors.New("d is nil")
|
||||||
Id string `json:"ID"`
|
// }
|
||||||
Container *docker.DockerVM `json:"Container"`
|
// //Get config information to derive paths for track containers json file
|
||||||
IpAddress string `json:"IpAddress"`
|
// config, err := config.ConfigInit(nil, nil)
|
||||||
}
|
// if err != nil {
|
||||||
|
// return err
|
||||||
// AddTrackContainer Adds new container which has been added to the track container
|
// }
|
||||||
func AddTrackContainer(d *docker.DockerVM, ipAddress string) error {
|
//
|
||||||
// Checking if pointer d is null
|
// // Getting information about the file trackcontainers.json file
|
||||||
if d == nil {
|
// stat, err := os.Stat(config.TrackContainersPath)
|
||||||
return errors.New("d is nil")
|
// if err != nil {
|
||||||
}
|
// return err
|
||||||
//Get config information to derive paths for track containers json file
|
// }
|
||||||
config, err := config.ConfigInit(nil, nil)
|
// // Initialize variable for TrackContainers
|
||||||
if err != nil {
|
// var trackContainers TrackContainers
|
||||||
return err
|
// // If the trackcontainers.json file is not empty then
|
||||||
}
|
// // Read from that file
|
||||||
|
// if stat.Size() != 0 {
|
||||||
// Getting information about the file trackcontainers.json file
|
// // Reads tracked container file
|
||||||
stat, err := os.Stat(config.TrackContainersPath)
|
// trackContainersFile, err := ReadTrackContainers(config.TrackContainersPath)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
// Initialize variable for TrackContainers
|
// trackContainers = *trackContainersFile
|
||||||
var trackContainers TrackContainers
|
// }
|
||||||
// If the trackcontainers.json file is not empty then
|
//
|
||||||
// Read from that file
|
// // Initialize new variable with type struct TrackContainers and
|
||||||
if stat.Size() != 0 {
|
// // add container struct and ip address
|
||||||
// Reads tracked container file
|
// var trackContainer TrackContainer
|
||||||
trackContainersFile, err := ReadTrackContainers(config.TrackContainersPath)
|
// trackContainer.Id = d.ID
|
||||||
if err != nil {
|
// trackContainer.Container = d
|
||||||
return err
|
// trackContainer.IpAddress = ipAddress
|
||||||
}
|
//
|
||||||
trackContainers = *trackContainersFile
|
// // Adds new container as passed in the parameter to the struct
|
||||||
}
|
// if &trackContainer == nil {
|
||||||
|
// return errors.New("trackContainer variable is nil")
|
||||||
// Initialize new variable with type struct TrackContainers and
|
// }
|
||||||
// add container struct and ip address
|
// trackContainers.TrackContainerList = append(trackContainers.TrackContainerList, trackContainer)
|
||||||
var trackContainer TrackContainer
|
//
|
||||||
trackContainer.Id = d.ID
|
// // write modified information to the tracked json file
|
||||||
trackContainer.Container = d
|
// data, err := json.MarshalIndent(trackContainers, "", "\t")
|
||||||
trackContainer.IpAddress = ipAddress
|
// if err != nil {
|
||||||
|
// return err
|
||||||
// Adds new container as passed in the parameter to the struct
|
// }
|
||||||
if &trackContainer == nil {
|
// err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
||||||
return errors.New("trackContainer variable is nil")
|
// if err != nil {
|
||||||
}
|
// return err
|
||||||
trackContainers.TrackContainerList = append(trackContainers.TrackContainerList, trackContainer)
|
// }
|
||||||
|
//
|
||||||
// write modified information to the tracked json file
|
// return nil
|
||||||
data, err := json.MarshalIndent(trackContainers, "", "\t")
|
//}
|
||||||
if err != nil {
|
//
|
||||||
return err
|
//// RemoveTrackedContainer This function removos tracked container from the trackcontainer JSON file
|
||||||
}
|
//func RemoveTrackedContainer(id string) error {
|
||||||
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
// //Get config information to derive paths for track containers json file
|
||||||
if err != nil {
|
// config, err := config.ConfigInit(nil, nil)
|
||||||
return err
|
// if err != nil {
|
||||||
}
|
// return err
|
||||||
|
// }
|
||||||
return nil
|
// // Getting tracked container struct
|
||||||
}
|
// trackedContainers, err := ReadTrackContainers(config.TrackContainersPath)
|
||||||
|
// // Storing index of element to remove
|
||||||
// RemoveTrackedContainer This function removos tracked container from the trackcontainer JSON file
|
// var removeElement int
|
||||||
func RemoveTrackedContainer(id string) error {
|
// removeElement = -1
|
||||||
//Get config information to derive paths for track containers json file
|
// for i := range trackedContainers.TrackContainerList {
|
||||||
config, err := config.ConfigInit(nil, nil)
|
// if trackedContainers.TrackContainerList[i].Id == id {
|
||||||
if err != nil {
|
// removeElement = i
|
||||||
return err
|
// break
|
||||||
}
|
// }
|
||||||
// Getting tracked container struct
|
// }
|
||||||
trackedContainers, err := ReadTrackContainers(config.TrackContainersPath)
|
// // Checks if the element to be removed has been detected
|
||||||
// Storing index of element to remove
|
// if removeElement == -1 {
|
||||||
var removeElement int
|
// return errors.New("Container ID not found in the tracked list")
|
||||||
removeElement = -1
|
// }
|
||||||
for i := range trackedContainers.TrackContainerList {
|
// // Remove the detected element from the struct
|
||||||
if trackedContainers.TrackContainerList[i].Id == id {
|
// trackedContainers.TrackContainerList = append(trackedContainers.TrackContainerList[:removeElement], trackedContainers.TrackContainerList[removeElement+1:]...)
|
||||||
removeElement = i
|
//
|
||||||
break
|
// // write modified information to the tracked json file
|
||||||
}
|
// data, err := json.MarshalIndent(trackedContainers, "", "\t")
|
||||||
}
|
// if err != nil {
|
||||||
// Checks if the element to be removed has been detected
|
// return err
|
||||||
if removeElement == -1 {
|
// }
|
||||||
return errors.New("Container ID not found in the tracked list")
|
// err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
||||||
}
|
// if err != nil {
|
||||||
// Remove the detected element from the struct
|
// return err
|
||||||
trackedContainers.TrackContainerList = append(trackedContainers.TrackContainerList[:removeElement], trackedContainers.TrackContainerList[removeElement+1:]...)
|
// }
|
||||||
|
//
|
||||||
// write modified information to the tracked json file
|
// return nil
|
||||||
data, err := json.MarshalIndent(trackedContainers, "", "\t")
|
//}
|
||||||
if err != nil {
|
//
|
||||||
return err
|
//// ViewTrackedContainers View Containers currently tracked
|
||||||
}
|
//func ViewTrackedContainers() (error, *TrackContainers) {
|
||||||
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
// config, err := config.ConfigInit(nil, nil)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err, nil
|
||||||
}
|
// }
|
||||||
|
// trackedContianers, err := ReadTrackContainers(config.TrackContainersPath)
|
||||||
return nil
|
// if err != nil {
|
||||||
}
|
// return err, nil
|
||||||
|
// }
|
||||||
// ViewTrackedContainers View Containers currently tracked
|
//
|
||||||
func ViewTrackedContainers() (error, *TrackContainers) {
|
// return nil, trackedContianers
|
||||||
config, err := config.ConfigInit(nil, nil)
|
//}
|
||||||
if err != nil {
|
//
|
||||||
return err, nil
|
//// ReadTrackContainers Reads containers which are currently tracked
|
||||||
}
|
//func ReadTrackContainers(filename string) (*TrackContainers, error) {
|
||||||
trackedContianers, err := ReadTrackContainers(config.TrackContainersPath)
|
// buf, err := ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err, nil
|
// return nil, err
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return nil, trackedContianers
|
// c := &TrackContainers{}
|
||||||
}
|
// err = json.Unmarshal(buf, c)
|
||||||
|
// if err != nil {
|
||||||
// ReadTrackContainers Reads containers which are currently tracked
|
// return nil, fmt.Errorf("in file %q: %v", filename, err)
|
||||||
func ReadTrackContainers(filename string) (*TrackContainers, error) {
|
// }
|
||||||
buf, err := ioutil.ReadFile(filename)
|
//
|
||||||
if err != nil {
|
// return c, nil
|
||||||
return nil, err
|
//}
|
||||||
}
|
//
|
||||||
|
////func ModifyTrackContainers()
|
||||||
c := &TrackContainers{}
|
//
|
||||||
err = json.Unmarshal(buf, c)
|
//// GetContainerInformation gets information about container based on
|
||||||
if err != nil {
|
//// container ID provided
|
||||||
return nil, fmt.Errorf("in file %q: %v", filename, err)
|
//func GetContainerInformation(ID string) (*TrackContainer, error) {
|
||||||
}
|
// // Getting the current containers
|
||||||
|
// err, CurrentContainers := ViewTrackedContainers()
|
||||||
return c, nil
|
// if err != nil {
|
||||||
}
|
// return nil, err
|
||||||
|
// }
|
||||||
//func ModifyTrackContainers()
|
// // Iterating through all tracked containers to get the container information
|
||||||
|
// // of the ID passed through the function parameter
|
||||||
// GetContainerInformation gets information about container based on
|
// for _, container := range CurrentContainers.TrackContainerList {
|
||||||
// container ID provided
|
// if container.Container.ID == ID {
|
||||||
func GetContainerInformation(ID string) (*TrackContainer, error) {
|
// return &container, nil
|
||||||
// Getting the current containers
|
// }
|
||||||
err, CurrentContainers := ViewTrackedContainers()
|
// }
|
||||||
if err != nil {
|
// return nil, errors.New("Container not found. ")
|
||||||
return nil, err
|
//}
|
||||||
}
|
//
|
||||||
// Iterating through all tracked containers to get the container information
|
//// ModifyContainerInformation Modifies information inside the container
|
||||||
// of the ID passed through the function parameter
|
//func (TC *TrackContainer) ModifyContainerInformation() error {
|
||||||
for _, container := range CurrentContainers.TrackContainerList {
|
// // Gets all the information of tracker containers
|
||||||
if container.Container.ID == ID {
|
// err, t := ViewTrackedContainers()
|
||||||
return &container, nil
|
// if err != nil {
|
||||||
}
|
// return err
|
||||||
}
|
// }
|
||||||
return nil, errors.New("Container not found. ")
|
// // Find the element where the containers match and
|
||||||
}
|
// // change them
|
||||||
|
// for i, container := range t.TrackContainerList {
|
||||||
// ModifyContainerInformation Modifies information inside the container
|
// if TC.Id == container.Id {
|
||||||
func (TC *TrackContainer) ModifyContainerInformation() error {
|
// t.TrackContainerList[i] = *TC
|
||||||
// Gets all the information of tracker containers
|
// break
|
||||||
err, t := ViewTrackedContainers()
|
// }
|
||||||
if err != nil {
|
// }
|
||||||
return err
|
// // Write the modified information to the file
|
||||||
}
|
// // write modified information to the tracked json file
|
||||||
// Find the element where the containers match and
|
// err = t.WriteContainers()
|
||||||
// change them
|
// if err != nil {
|
||||||
for i, container := range t.TrackContainerList {
|
// return err
|
||||||
if TC.Id == container.Id {
|
// }
|
||||||
t.TrackContainerList[i] = *TC
|
//
|
||||||
break
|
// return nil
|
||||||
}
|
//}
|
||||||
}
|
//
|
||||||
// Write the modified information to the file
|
//// WriteContainers Write information back to the config file
|
||||||
// write modified information to the tracked json file
|
//func (TC *TrackContainers) WriteContainers() error {
|
||||||
err = t.WriteContainers()
|
// // Initialize config file
|
||||||
if err != nil {
|
// config, err := config.ConfigInit(nil, nil)
|
||||||
return err
|
// // write modified information to the tracked json file
|
||||||
}
|
// data, err := json.MarshalIndent(TC, "", "\t")
|
||||||
|
// if err != nil {
|
||||||
return nil
|
// return err
|
||||||
}
|
// }
|
||||||
|
// err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
||||||
// WriteContainers Write information back to the config file
|
// if err != nil {
|
||||||
func (TC *TrackContainers) WriteContainers() error {
|
// return err
|
||||||
// Initialize config file
|
// }
|
||||||
config, err := config.ConfigInit(nil, nil)
|
//
|
||||||
// write modified information to the tracked json file
|
// return nil
|
||||||
data, err := json.MarshalIndent(TC, "", "\t")
|
//}
|
||||||
if err != nil {
|
//
|
||||||
return err
|
//// CheckID Checks if the ID belongs to a group or a single container
|
||||||
}
|
//func CheckID(ID string) (string, error) {
|
||||||
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
// // For group checks if the 1st characters is "grp"
|
||||||
if err != nil {
|
// if ID[0:3] == "grp" {
|
||||||
return err
|
// return "group", nil
|
||||||
}
|
// } else {
|
||||||
|
// return "container", nil
|
||||||
return nil
|
// }
|
||||||
}
|
// return "", nil
|
||||||
|
//}
|
||||||
// CheckID Checks if the ID belongs to a group or a single container
|
|
||||||
func CheckID(ID string) (string, error) {
|
|
||||||
// For group checks if the 1st characters is "grp"
|
|
||||||
if ID[0:3] == "grp" {
|
|
||||||
return "group", nil
|
|
||||||
} else {
|
|
||||||
return "container", nil
|
|
||||||
}
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,192 +1,180 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
//var (
|
||||||
b64 "encoding/base64"
|
// serverPort = "8088"
|
||||||
"encoding/json"
|
// client = http.Client{}
|
||||||
"fmt"
|
//)
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
//
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
//// StartContainer Start container using REST api Implementation
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
//// From the selected server IP address
|
||||||
"io/ioutil"
|
//// TODO: Test cases for this function
|
||||||
"net/http"
|
//// Calls URL ex: http://0.0.0.0:8088/startcontainer?ports=0&GPU=false&ContainerName=docker-ubuntu-sshd
|
||||||
"strconv"
|
//func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string, baseImage string) (*docker.DockerVM, error) {
|
||||||
)
|
// // Passes URL with number of TCP ports to allocated and to give GPU access to the docker container
|
||||||
|
// var URL string
|
||||||
var (
|
// //version := p2p.Ip4or6(IP)
|
||||||
serverPort = "8088"
|
// //
|
||||||
client = http.Client{}
|
// ////Get port number of the server
|
||||||
)
|
// //serverPort, err := GetServerPort(IP)
|
||||||
|
// //if err != nil {
|
||||||
// StartContainer Start container using REST api Implementation
|
// // return nil, err
|
||||||
// From the selected server IP address
|
// //}
|
||||||
// TODO: Test cases for this function
|
//
|
||||||
// Calls URL ex: http://0.0.0.0:8088/startcontainer?ports=0&GPU=false&ContainerName=docker-ubuntu-sshd
|
// //if version == "version 6" {
|
||||||
func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string, baseImage string) (*docker.DockerVM, error) {
|
// // URL = "http://[" + IP + "]:" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
||||||
// Passes URL with number of TCP ports to allocated and to give GPU access to the docker container
|
// //} else {
|
||||||
var URL string
|
// // Get config information
|
||||||
//version := p2p.Ip4or6(IP)
|
// Config, err := config.ConfigInit(nil, nil)
|
||||||
//
|
// if err != nil {
|
||||||
////Get port number of the server
|
// return nil, err
|
||||||
//serverPort, err := GetServerPort(IP)
|
// }
|
||||||
//if err != nil {
|
//
|
||||||
// return nil, err
|
// // Get public key
|
||||||
//}
|
// PublicKey, err := Config.GetPublicKey()
|
||||||
|
// if err != nil {
|
||||||
//if version == "version 6" {
|
// return nil, err
|
||||||
// URL = "http://[" + IP + "]:" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
// }
|
||||||
//} else {
|
//
|
||||||
// Get config information
|
// // Used in URL to pass public key -> b64.StdEncoding.EncodeToString([]byte(PublicKey))
|
||||||
Config, err := config.ConfigInit(nil, nil)
|
// URL = `http://` + IP + `/startcontainer?ports=` + fmt.Sprint(NumPorts) + `&GPU=` + strconv.FormatBool(GPU) + `&ContainerName=` + ContainerName + `&BaseImage=` + baseImage + `&PublicKey=` + b64.StdEncoding.EncodeToString([]byte(PublicKey))
|
||||||
if err != nil {
|
//
|
||||||
return nil, err
|
// // Encode URL due to public key passed.
|
||||||
}
|
// resp, err := http.Get(URL)
|
||||||
|
// if err != nil {
|
||||||
// Get public key
|
// return nil, err
|
||||||
PublicKey, err := Config.GetPublicKey()
|
// }
|
||||||
if err != nil {
|
//
|
||||||
return nil, err
|
// // Convert response to byte value
|
||||||
}
|
// byteValue, err := ioutil.ReadAll(resp.Body)
|
||||||
|
// if err != nil {
|
||||||
// Used in URL to pass public key -> b64.StdEncoding.EncodeToString([]byte(PublicKey))
|
// return nil, err
|
||||||
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.
|
// // Create variable for result response type
|
||||||
resp, err := http.Get(URL)
|
// var dockerResult docker.DockerVM
|
||||||
if err != nil {
|
//
|
||||||
return nil, err
|
// // Adds byte value to docker.DockerVM struct
|
||||||
}
|
// json.Unmarshal(byteValue, &dockerResult)
|
||||||
|
// if err != nil {
|
||||||
// Convert response to byte value
|
// return nil, err
|
||||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
// }
|
||||||
if err != nil {
|
//
|
||||||
return nil, err
|
// // Adds the container to the tracked list
|
||||||
}
|
// err = AddTrackContainer(&dockerResult, IP)
|
||||||
|
// if err != nil {
|
||||||
// Create variable for result response type
|
// return nil, err
|
||||||
var dockerResult docker.DockerVM
|
// }
|
||||||
|
//
|
||||||
// Adds byte value to docker.DockerVM struct
|
// return &dockerResult, nil
|
||||||
json.Unmarshal(byteValue, &dockerResult)
|
//}
|
||||||
if err != nil {
|
//
|
||||||
return nil, err
|
//// RemoveContianer Stops and removes container from the server
|
||||||
}
|
//func RemoveContianer(IP string, ID string) error {
|
||||||
|
// var URL string
|
||||||
// Adds the container to the tracked list
|
// //version := p2p.Ip4or6(IP)
|
||||||
err = AddTrackContainer(&dockerResult, IP)
|
// //
|
||||||
if err != nil {
|
// ////Get port number of the server
|
||||||
return nil, err
|
// //serverPort, err := GetServerPort(IP)
|
||||||
}
|
// //if err != nil {
|
||||||
|
// // return err
|
||||||
return &dockerResult, nil
|
// //}
|
||||||
}
|
//
|
||||||
|
// //if version == "version 6" {
|
||||||
// RemoveContianer Stops and removes container from the server
|
// // URL = "http://[" + IP + "]:" + serverPort + "/RemoveContainer?id=" + ID
|
||||||
func RemoveContianer(IP string, ID string) error {
|
// //} else {
|
||||||
var URL string
|
// URL = "http://" + IP + "/RemoveContainer?id=" + ID
|
||||||
//version := p2p.Ip4or6(IP)
|
// //}
|
||||||
//
|
// resp, err := http.Get(URL)
|
||||||
////Get port number of the server
|
// if err != nil {
|
||||||
//serverPort, err := GetServerPort(IP)
|
// return err
|
||||||
//if err != nil {
|
// }
|
||||||
// return err
|
//
|
||||||
//}
|
// // Convert response to byte value
|
||||||
|
// byteValue, err := ioutil.ReadAll(resp.Body)
|
||||||
//if version == "version 6" {
|
// if err != nil {
|
||||||
// URL = "http://[" + IP + "]:" + serverPort + "/RemoveContainer?id=" + ID
|
// return err
|
||||||
//} else {
|
// }
|
||||||
URL = "http://" + IP + "/RemoveContainer?id=" + ID
|
//
|
||||||
//}
|
// // Checks if success is returned in the body
|
||||||
resp, err := http.Get(URL)
|
// if string(byteValue[:]) == "success" {
|
||||||
if err != nil {
|
// fmt.Println("success")
|
||||||
return err
|
// }
|
||||||
}
|
//
|
||||||
|
// // Remove container from groups it exists in
|
||||||
// Convert response to byte value
|
// err = RemoveContainerGroups(ID)
|
||||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
// if err != nil {
|
||||||
if err != nil {
|
// return err
|
||||||
return err
|
// }
|
||||||
}
|
// // Remove container created from the tracked list
|
||||||
|
// err = RemoveTrackedContainer(ID)
|
||||||
// Checks if success is returned in the body
|
// if err != nil {
|
||||||
if string(byteValue[:]) == "success" {
|
// return err
|
||||||
fmt.Println("success")
|
// }
|
||||||
}
|
//
|
||||||
|
// return nil
|
||||||
// Remove container from groups it exists in
|
//}
|
||||||
err = RemoveContainerGroups(ID)
|
//
|
||||||
if err != nil {
|
//// ViewContainers This function displays all containers available on server side
|
||||||
return err
|
//func ViewContainers(IP string) (*docker.DockerContainers, error) {
|
||||||
}
|
// // Passes URL with route /ShowImages
|
||||||
// Remove container created from the tracked list
|
// var URL string
|
||||||
err = RemoveTrackedContainer(ID)
|
// //version := p2p.Ip4or6(IP)
|
||||||
if err != nil {
|
// //
|
||||||
return err
|
// ////Get port number of the server
|
||||||
}
|
// //serverPort, err := GetServerPort(IP)
|
||||||
|
// //if err != nil {
|
||||||
return nil
|
// // return nil, err
|
||||||
}
|
// //}
|
||||||
|
//
|
||||||
// ViewContainers This function displays all containers available on server side
|
// //if version == "version 6" {
|
||||||
func ViewContainers(IP string) (*docker.DockerContainers, error) {
|
// // URL = "http://[" + IP + "]:" + serverPort + "/ShowImages"
|
||||||
// Passes URL with route /ShowImages
|
// //} else {
|
||||||
var URL string
|
// URL = "http://" + IP + "/ShowImages"
|
||||||
//version := p2p.Ip4or6(IP)
|
// //}
|
||||||
//
|
// resp, err := http.Get(URL)
|
||||||
////Get port number of the server
|
// if err != nil {
|
||||||
//serverPort, err := GetServerPort(IP)
|
// return nil, err
|
||||||
//if err != nil {
|
// }
|
||||||
// return nil, err
|
//
|
||||||
//}
|
// // Convert response to byte value
|
||||||
|
// byteValue, err := ioutil.ReadAll(resp.Body)
|
||||||
//if version == "version 6" {
|
// if err != nil {
|
||||||
// URL = "http://[" + IP + "]:" + serverPort + "/ShowImages"
|
// return nil, err
|
||||||
//} else {
|
// }
|
||||||
URL = "http://" + IP + "/ShowImages"
|
//
|
||||||
//}
|
// // Create variable for result response type
|
||||||
resp, err := http.Get(URL)
|
// var Result docker.DockerContainers
|
||||||
if err != nil {
|
//
|
||||||
return nil, err
|
// // Adds byte value to docker.DockerContainers struct
|
||||||
}
|
// json.Unmarshal(byteValue, &Result)
|
||||||
|
// if err != nil {
|
||||||
// Convert response to byte value
|
// return nil, err
|
||||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
// }
|
||||||
if err != nil {
|
//
|
||||||
return nil, err
|
// return &Result, nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// Create variable for result response type
|
//// GetServerPort Helper function to do find out server port information
|
||||||
var Result docker.DockerContainers
|
//func GetServerPort(IpAddress string) (string, error) {
|
||||||
|
// // Getting information from the clients ip table
|
||||||
// Adds byte value to docker.DockerContainers struct
|
// ipTable, err := p2p.ReadIpTable()
|
||||||
json.Unmarshal(byteValue, &Result)
|
// if err != nil {
|
||||||
if err != nil {
|
// return "", err
|
||||||
return nil, err
|
// }
|
||||||
}
|
//
|
||||||
|
// // Iterate thorough ip table struct and find
|
||||||
return &Result, nil
|
// // out which port is for the ip address provided
|
||||||
}
|
// // in the parameter of the function
|
||||||
|
// for _, address := range ipTable.IpAddress {
|
||||||
// GetServerPort Helper function to do find out server port information
|
// // If we found a match then return a port
|
||||||
func GetServerPort(IpAddress string) (string, error) {
|
// if address.Ipv4 == IpAddress || address.Ipv6 == IpAddress {
|
||||||
// Getting information from the clients ip table
|
// return address.ServerPort, nil
|
||||||
ipTable, err := p2p.ReadIpTable()
|
// }
|
||||||
if err != nil {
|
// }
|
||||||
return "", err
|
//
|
||||||
}
|
// // We return default port
|
||||||
|
// return "8088", nil
|
||||||
// Iterate thorough ip table struct and find
|
//}
|
||||||
// out which port is for the ip address provided
|
|
||||||
// in the parameter of the function
|
|
||||||
for _, address := range ipTable.IpAddress {
|
|
||||||
// If we found a match then return a port
|
|
||||||
if address.Ipv4 == IpAddress || address.Ipv6 == IpAddress {
|
|
||||||
return address.ServerPort, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We return default port
|
|
||||||
return "8088", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrintStartContainer Prints results Generated container
|
// PrintStartContainer Prints results Generated container
|
||||||
//func PrintStartContainer(d *docker.DockerVM){
|
//func PrintStartContainer(d *docker.DockerVM){
|
||||||
|
|||||||
263
cmd/action.go
263
cmd/action.go
@@ -2,11 +2,11 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/abstractions"
|
||||||
"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/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/server"
|
"github.com/Akilan1999/p2p-rendering-computation/server"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
@@ -85,214 +85,161 @@ var CliAction = func(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Displays all images available on the server side
|
// Displays all images available on the server side
|
||||||
if ViewImages != "" {
|
//if ViewImages != "" {
|
||||||
imageRes, err := client.ViewContainers(ViewImages)
|
// imageRes, err := client.ViewContainers(ViewImages)
|
||||||
|
// standardOutput(err, imageRes)
|
||||||
if err != nil {
|
//}
|
||||||
fmt.Print(err)
|
//
|
||||||
}
|
//// Function called to stop and remove server from Docker
|
||||||
client.PrettyPrint(imageRes)
|
//if RemoveVM != "" {
|
||||||
}
|
// if ID == "" {
|
||||||
|
// fmt.Println("provide container ID via --ID or --id")
|
||||||
// Function called to stop and remove server from Docker
|
// } else {
|
||||||
if RemoveVM != "" {
|
// err := client.RemoveContianer(RemoveVM, ID)
|
||||||
if ID == "" {
|
// standardOutput(err, nil)
|
||||||
fmt.Println("provide container ID via --ID or --id")
|
// }
|
||||||
} else {
|
//}
|
||||||
err := client.RemoveContianer(RemoveVM, ID)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Print(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Call function to create Docker container
|
//Call function to create Docker container
|
||||||
if CreateVM != "" {
|
//if CreateVM != "" {
|
||||||
|
//
|
||||||
var PortsInt int
|
// var PortsInt int
|
||||||
|
//
|
||||||
if Ports != "" {
|
// if Ports != "" {
|
||||||
// Convert Get Request value to int
|
// // Convert Get Request value to int
|
||||||
fmt.Sscanf(Ports, "%d", &PortsInt)
|
// fmt.Sscanf(Ports, "%d", &PortsInt)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 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, BaseImage)
|
||||||
|
//
|
||||||
if err != nil {
|
// standardOutput(err, imageRes)
|
||||||
fmt.Print(err)
|
//}
|
||||||
}
|
|
||||||
client.PrettyPrint(imageRes)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Call if specs flag is called
|
//Call if specs flag is called
|
||||||
if Specs != "" {
|
if Specs != "" {
|
||||||
specs, err := client.GetSpecs(Specs)
|
specs, err := client.GetSpecs(Specs)
|
||||||
if err != nil {
|
standardOutput(err, specs)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pretty print
|
|
||||||
client.PrettyPrint(specs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//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 := generate.SetDefaults("P2PRC", false, nil, false)
|
||||||
if err != nil {
|
standardOutput(err, nil)
|
||||||
fmt.Print(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//If the network interface flag is called
|
//If the network interface flag is called
|
||||||
// Then all the network interfaces are displayed
|
// Then all the network interfaces are displayed
|
||||||
if NetworkInterface {
|
if NetworkInterface {
|
||||||
err := p2p.ViewNetworkInterface()
|
err := p2p.ViewNetworkInterface()
|
||||||
if err != nil {
|
standardOutput(err, nil)
|
||||||
fmt.Print(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the view plugin flag is called then display all
|
// If the view plugin flag is called then display all
|
||||||
// plugins available
|
// plugins available
|
||||||
if ViewPlugin {
|
//if ViewPlugin {
|
||||||
plugins, err := plugin.DetectPlugins()
|
// plugins, err := plugin.DetectPlugins()
|
||||||
if err != nil {
|
// standardOutput(err, plugins)
|
||||||
fmt.Print(err)
|
//}
|
||||||
}
|
|
||||||
client.PrettyPrint(plugins)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the flag Tracked Container is called or the flag
|
// If the flag Tracked Container is called or the flag
|
||||||
// --tc
|
// --tc
|
||||||
if TrackedContainers {
|
//if TrackedContainers {
|
||||||
err, trackedContainers := client.ViewTrackedContainers()
|
// err, trackedContainers := client.ViewTrackedContainers()
|
||||||
if err != nil {
|
// standardOutput(err, trackedContainers)
|
||||||
fmt.Print(err)
|
//}
|
||||||
}
|
|
||||||
client.PrettyPrint(trackedContainers)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Executing plugin when the plugin flag is called
|
//Executing plugin when the plugin flag is called
|
||||||
// --plugin
|
// --plugin
|
||||||
if ExecutePlugin != "" {
|
//if ExecutePlugin != "" {
|
||||||
// To execute plugin requires the container ID or group ID provided when being executed
|
// // To execute plugin requires the container ID or group ID provided when being executed
|
||||||
if ID != "" {
|
// if ID != "" {
|
||||||
err := plugin.CheckRunPlugin(ExecutePlugin, ID)
|
// err := plugin.CheckRunPlugin(ExecutePlugin, ID)
|
||||||
if err != nil {
|
// standardOutput(err, nil)
|
||||||
fmt.Println(err)
|
// }
|
||||||
} else {
|
// //else {
|
||||||
fmt.Println("Success")
|
// // fmt.Println("provide container ID via --ID or --id")
|
||||||
}
|
// //}
|
||||||
} else {
|
//
|
||||||
fmt.Println("provide container ID via --ID or --id")
|
//}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Executing function to create new group
|
// Executing function to create new group
|
||||||
// Creates new group and outputs JSON file
|
// Creates new group and outputs JSON file
|
||||||
if CreateGroup {
|
//if CreateGroup {
|
||||||
group, err := client.CreateGroup()
|
// group, err := client.CreateGroup()
|
||||||
if err != nil {
|
// standardOutput(err, group)
|
||||||
return err
|
//}
|
||||||
}
|
|
||||||
client.PrettyPrint(group)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actions to be performed when the
|
// Actions to be performed when the
|
||||||
// group flag is called
|
// group flag is called
|
||||||
// --group <Group ID>
|
// --group <Group ID>
|
||||||
if Group != "" {
|
//if Group != "" {
|
||||||
// Remove container from group based on group ID provided
|
// // Remove container from group based on group ID provided
|
||||||
// --rmcgroup --id <contianer id>
|
// // --rmcgroup --id <contianer id>
|
||||||
if RemoveContainerGroup && ID != "" {
|
// if RemoveContainerGroup && ID != "" {
|
||||||
group, err := client.RemoveContainerGroup(ID, Group)
|
// group, err := client.RemoveContainerGroup(ID, Group)
|
||||||
if err != nil {
|
// standardOutput(err, group)
|
||||||
fmt.Println(err)
|
// } else if ID != "" { // Add container to group based on group ID provided
|
||||||
} else {
|
// // --id <Container ID>
|
||||||
client.PrettyPrint(group)
|
// group, err := client.AddContainerToGroup(ID, Group)
|
||||||
}
|
// standardOutput(err, group)
|
||||||
} else if ID != "" { // Add container to group based on group ID provided
|
// } else { // View all information about current group
|
||||||
// --id <Container ID>
|
// group, err := client.GetGroup(Group)
|
||||||
group, err := client.AddContainerToGroup(ID, Group)
|
// standardOutput(err, group)
|
||||||
if err != nil {
|
// }
|
||||||
fmt.Println(err)
|
//}
|
||||||
} else {
|
|
||||||
client.PrettyPrint(group)
|
|
||||||
}
|
|
||||||
} else { // View all information about current group
|
|
||||||
group, err := client.GetGroup(Group)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
} else {
|
|
||||||
client.PrettyPrint(group)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute function to remove entire group
|
// Execute function to remove entire group
|
||||||
// when remove group flag is called
|
// when remove group flag is called
|
||||||
// --rmgroup
|
// --rmgroup
|
||||||
if RemoveGroup != "" {
|
//if RemoveGroup != "" {
|
||||||
err := client.RemoveGroup(RemoveGroup)
|
// err := client.RemoveGroup(RemoveGroup)
|
||||||
if err != nil {
|
// standardOutput(err, nil)
|
||||||
fmt.Println(err)
|
//}
|
||||||
} else {
|
|
||||||
fmt.Println("Group Removed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute Function to view all groups
|
// Execute Function to view all groups
|
||||||
if Groups {
|
//if Groups {
|
||||||
groups, err := client.ReadGroup()
|
// groups, err := client.ReadGroup()
|
||||||
if err != nil {
|
// standardOutput(err, groups)
|
||||||
fmt.Println(err)
|
//}
|
||||||
} else {
|
|
||||||
client.PrettyPrint(groups)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------
|
//--------------------------------
|
||||||
|
|
||||||
if PullPlugin != "" {
|
//if PullPlugin != "" {
|
||||||
err := plugin.DownloadPlugin(PullPlugin)
|
// err := plugin.DownloadPlugin(PullPlugin)
|
||||||
if err != nil {
|
// standardOutput(err, nil)
|
||||||
fmt.Println(err)
|
//}
|
||||||
} else {
|
//
|
||||||
fmt.Println("Success")
|
//if RemovePlugin != "" {
|
||||||
}
|
// err := plugin.DeletePlugin(RemovePlugin)
|
||||||
}
|
// standardOutput(err, nil)
|
||||||
|
//}
|
||||||
if RemovePlugin != "" {
|
|
||||||
err := plugin.DeletePlugin(RemovePlugin)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
} else {
|
|
||||||
fmt.Println("Success")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if AddMetaData != "" {
|
if AddMetaData != "" {
|
||||||
err := clientIPTable.AddCustomInformationToIPTable(AddMetaData)
|
err := clientIPTable.AddCustomInformationToIPTable(AddMetaData)
|
||||||
if err != nil {
|
standardOutput(err, nil)
|
||||||
fmt.Println(err)
|
|
||||||
} else {
|
|
||||||
fmt.Println("Success")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if MAPPort != "" {
|
if MAPPort != "" {
|
||||||
address, err := client.MAPPort(MAPPort, DomainName, RemoteAddress)
|
address, err := client.MAPPort(MAPPort, DomainName, RemoteAddress)
|
||||||
if err != nil {
|
standardOutput(err, address)
|
||||||
return err
|
}
|
||||||
}
|
|
||||||
if err != nil {
|
// Action called to add root node to network
|
||||||
fmt.Println(err)
|
if AddRootNode && IP != "" && Ports != "" {
|
||||||
} else {
|
err := abstractions.AddRootNode(IP, Ports)
|
||||||
client.PrettyPrint(address)
|
standardOutput(err, nil)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func standardOutput(err error, i interface{}) {
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else if i == nil {
|
||||||
|
fmt.Println("Success")
|
||||||
|
} else {
|
||||||
|
client.PrettyPrint(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
284
cmd/flags.go
284
cmd/flags.go
@@ -41,6 +41,8 @@ var (
|
|||||||
PullPlugin string
|
PullPlugin string
|
||||||
RemovePlugin string
|
RemovePlugin string
|
||||||
AddMetaData string
|
AddMetaData string
|
||||||
|
AddRootNode bool
|
||||||
|
IP string
|
||||||
)
|
)
|
||||||
|
|
||||||
var AppConfigFlags = []cli.Flag{
|
var AppConfigFlags = []cli.Flag{
|
||||||
@@ -72,48 +74,48 @@ var AppConfigFlags = []cli.Flag{
|
|||||||
EnvVars: []string{"ADD_SERVER"},
|
EnvVars: []string{"ADD_SERVER"},
|
||||||
Destination: &AddServer,
|
Destination: &AddServer,
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
Name: "ViewImages",
|
// Name: "ViewImages",
|
||||||
Aliases: []string{"vi"},
|
// Aliases: []string{"vi"},
|
||||||
Usage: "View images available on the server IP address",
|
// Usage: "View images available on the server IP address",
|
||||||
EnvVars: []string{"VIEW_IMAGES"},
|
// EnvVars: []string{"VIEW_IMAGES"},
|
||||||
Destination: &ViewImages,
|
// Destination: &ViewImages,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
Name: "CreateVM",
|
// Name: "CreateVM",
|
||||||
Aliases: []string{"touch"},
|
// Aliases: []string{"touch"},
|
||||||
Usage: "Creates Docker container on the selected server",
|
// Usage: "Creates Docker container on the selected server",
|
||||||
EnvVars: []string{"CREATE_VM"},
|
// EnvVars: []string{"CREATE_VM"},
|
||||||
Destination: &CreateVM,
|
// Destination: &CreateVM,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
Name: "ContainerName",
|
// Name: "ContainerName",
|
||||||
Aliases: []string{"cn"},
|
// Aliases: []string{"cn"},
|
||||||
Usage: "Specifying the container run on the server side",
|
// Usage: "Specifying the container run on the server side",
|
||||||
EnvVars: []string{"CONTAINER_NAME"},
|
// EnvVars: []string{"CONTAINER_NAME"},
|
||||||
Destination: &ContainerName,
|
// Destination: &ContainerName,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
Name: "BaseImage",
|
// Name: "BaseImage",
|
||||||
Aliases: []string{"bi"},
|
// Aliases: []string{"bi"},
|
||||||
Usage: "Specifying the docker base image to template the dockerfile",
|
// Usage: "Specifying the docker base image to template the dockerfile",
|
||||||
EnvVars: []string{"CONTAINER_NAME"},
|
// EnvVars: []string{"CONTAINER_NAME"},
|
||||||
Destination: &BaseImage,
|
// 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 (IP:port) accompanied by container ID via --ID or --id",
|
||||||
EnvVars: []string{"REMOVE_VM"},
|
// EnvVars: []string{"REMOVE_VM"},
|
||||||
Destination: &RemoveVM,
|
// Destination: &RemoveVM,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
Name: "ID",
|
// Name: "ID",
|
||||||
Aliases: []string{"id"},
|
// Aliases: []string{"id"},
|
||||||
Usage: "Docker Container ID",
|
// Usage: "Docker Container ID",
|
||||||
EnvVars: []string{"ID"},
|
// EnvVars: []string{"ID"},
|
||||||
Destination: &ID,
|
// Destination: &ID,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "Ports",
|
Name: "Ports",
|
||||||
Aliases: []string{"p"},
|
Aliases: []string{"p"},
|
||||||
@@ -121,13 +123,13 @@ var AppConfigFlags = []cli.Flag{
|
|||||||
EnvVars: []string{"NUM_PORTS"},
|
EnvVars: []string{"NUM_PORTS"},
|
||||||
Destination: &Ports,
|
Destination: &Ports,
|
||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
//&cli.BoolFlag{
|
||||||
Name: "GPU",
|
// Name: "GPU",
|
||||||
Aliases: []string{"gpu"},
|
// Aliases: []string{"gpu"},
|
||||||
Usage: "Create Docker Containers to access GPU",
|
// Usage: "Create Docker Containers to access GPU",
|
||||||
EnvVars: []string{"USE_GPU"},
|
// EnvVars: []string{"USE_GPU"},
|
||||||
Destination: &GPU,
|
// Destination: &GPU,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "Specification",
|
Name: "Specification",
|
||||||
Aliases: []string{"specs"},
|
Aliases: []string{"specs"},
|
||||||
@@ -149,63 +151,63 @@ var AppConfigFlags = []cli.Flag{
|
|||||||
EnvVars: []string{"NETWORK_INTERFACE"},
|
EnvVars: []string{"NETWORK_INTERFACE"},
|
||||||
Destination: &NetworkInterface,
|
Destination: &NetworkInterface,
|
||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
//&cli.BoolFlag{
|
||||||
Name: "ViewPlugins",
|
// Name: "ViewPlugins",
|
||||||
Aliases: []string{"vp"},
|
// Aliases: []string{"vp"},
|
||||||
Usage: "Shows plugins available to be executed",
|
// Usage: "Shows plugins available to be executed",
|
||||||
EnvVars: []string{"VIEW_PLUGIN"},
|
// EnvVars: []string{"VIEW_PLUGIN"},
|
||||||
Destination: &ViewPlugin,
|
// Destination: &ViewPlugin,
|
||||||
},
|
//},
|
||||||
&cli.BoolFlag{
|
//&cli.BoolFlag{
|
||||||
Name: "TrackedContainers",
|
// Name: "TrackedContainers",
|
||||||
Aliases: []string{"tc"},
|
// Aliases: []string{"tc"},
|
||||||
Usage: "View (currently running) containers which have " +
|
// Usage: "View (currently running) containers which have " +
|
||||||
"been created from the client side ",
|
// "been created from the client side ",
|
||||||
EnvVars: []string{"TRACKED_CONTAINERS"},
|
// EnvVars: []string{"TRACKED_CONTAINERS"},
|
||||||
Destination: &TrackedContainers,
|
// Destination: &TrackedContainers,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
Name: "ExecutePlugin",
|
// Name: "ExecutePlugin",
|
||||||
Aliases: []string{"plugin"},
|
// Aliases: []string{"plugin"},
|
||||||
Usage: "Plugin which needs to be executed",
|
// Usage: "Plugin which needs to be executed",
|
||||||
EnvVars: []string{"EXECUTE_PLUGIN"},
|
// EnvVars: []string{"EXECUTE_PLUGIN"},
|
||||||
Destination: &ExecutePlugin,
|
// Destination: &ExecutePlugin,
|
||||||
},
|
//},
|
||||||
&cli.BoolFlag{
|
//&cli.BoolFlag{
|
||||||
Name: "CreateGroup",
|
// Name: "CreateGroup",
|
||||||
Aliases: []string{"cgroup"},
|
// Aliases: []string{"cgroup"},
|
||||||
Usage: "Creates a new group",
|
// Usage: "Creates a new group",
|
||||||
EnvVars: []string{"CREATE_GROUP"},
|
// EnvVars: []string{"CREATE_GROUP"},
|
||||||
Destination: &CreateGroup,
|
// Destination: &CreateGroup,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
Name: "Group",
|
// Name: "Group",
|
||||||
Aliases: []string{"group"},
|
// Aliases: []string{"group"},
|
||||||
Usage: "group flag with argument group ID",
|
// Usage: "group flag with argument group ID",
|
||||||
EnvVars: []string{"GROUP"},
|
// EnvVars: []string{"GROUP"},
|
||||||
Destination: &Group,
|
// Destination: &Group,
|
||||||
},
|
//},
|
||||||
&cli.BoolFlag{
|
//&cli.BoolFlag{
|
||||||
Name: "Groups",
|
// Name: "Groups",
|
||||||
Aliases: []string{"groups"},
|
// Aliases: []string{"groups"},
|
||||||
Usage: "View all groups",
|
// Usage: "View all groups",
|
||||||
EnvVars: []string{"GROUPS"},
|
// EnvVars: []string{"GROUPS"},
|
||||||
Destination: &Groups,
|
// Destination: &Groups,
|
||||||
},
|
//},
|
||||||
&cli.BoolFlag{
|
//&cli.BoolFlag{
|
||||||
Name: "RemoveContainerGroup",
|
// Name: "RemoveContainerGroup",
|
||||||
Aliases: []string{"rmcgroup"},
|
// Aliases: []string{"rmcgroup"},
|
||||||
Usage: "Remove specific container in the group",
|
// Usage: "Remove specific container in the group",
|
||||||
EnvVars: []string{"REMOVE_CONTAINER_GROUP"},
|
// EnvVars: []string{"REMOVE_CONTAINER_GROUP"},
|
||||||
Destination: &RemoveContainerGroup,
|
// Destination: &RemoveContainerGroup,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
Name: "RemoveGroup",
|
// Name: "RemoveGroup",
|
||||||
Aliases: []string{"rmgroup"},
|
// Aliases: []string{"rmgroup"},
|
||||||
Usage: "Removes the entire group",
|
// Usage: "Removes the entire group",
|
||||||
EnvVars: []string{"REMOVE_GROUP"},
|
// EnvVars: []string{"REMOVE_GROUP"},
|
||||||
Destination: &RemoveGroup,
|
// Destination: &RemoveGroup,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "MAPPort",
|
Name: "MAPPort",
|
||||||
Aliases: []string{"mp"},
|
Aliases: []string{"mp"},
|
||||||
@@ -229,20 +231,20 @@ var AppConfigFlags = []cli.Flag{
|
|||||||
},
|
},
|
||||||
// Generate only allowed in dev release
|
// Generate only allowed in dev release
|
||||||
// -- REMOVE ON REGULAR RELEASE --
|
// -- REMOVE ON REGULAR RELEASE --
|
||||||
&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
Name: "Generate",
|
// Name: "Generate",
|
||||||
Aliases: []string{"gen"},
|
// Aliases: []string{"gen"},
|
||||||
Usage: "Generates a new copy of P2PRC which can be modified based on your needs",
|
// Usage: "Generates a new copy of P2PRC which can be modified based on your needs",
|
||||||
EnvVars: []string{"GENERATE"},
|
// EnvVars: []string{"GENERATE"},
|
||||||
Destination: &Generate,
|
// Destination: &Generate,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
Name: "ModuleName",
|
// Name: "ModuleName",
|
||||||
Aliases: []string{"mod"},
|
// Aliases: []string{"mod"},
|
||||||
Usage: "New go project module name",
|
// Usage: "New go project module name",
|
||||||
EnvVars: []string{"MODULENAME"},
|
// EnvVars: []string{"MODULENAME"},
|
||||||
Destination: &Modulename,
|
// Destination: &Modulename,
|
||||||
},
|
//},
|
||||||
//&cli.BoolFlag{
|
//&cli.BoolFlag{
|
||||||
// Name: "FRPServerProxy",
|
// Name: "FRPServerProxy",
|
||||||
// Aliases: []string{"proxy"},
|
// Aliases: []string{"proxy"},
|
||||||
@@ -251,20 +253,20 @@ var AppConfigFlags = []cli.Flag{
|
|||||||
// Destination: &FRPProxy,
|
// Destination: &FRPProxy,
|
||||||
//},
|
//},
|
||||||
//--------------------------------
|
//--------------------------------
|
||||||
&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
Name: "PullPlugin",
|
// Name: "PullPlugin",
|
||||||
Aliases: []string{"pp"},
|
// Aliases: []string{"pp"},
|
||||||
Usage: "Pulls plugin from git repos",
|
// Usage: "Pulls plugin from git repos",
|
||||||
EnvVars: []string{"PULLPLUGIN"},
|
// EnvVars: []string{"PULLPLUGIN"},
|
||||||
Destination: &PullPlugin,
|
// Destination: &PullPlugin,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
Name: "RemovePlugin",
|
// Name: "RemovePlugin",
|
||||||
Aliases: []string{"rp"},
|
// Aliases: []string{"rp"},
|
||||||
Usage: "Removes plugin",
|
// Usage: "Removes plugin",
|
||||||
EnvVars: []string{"REMOVEPLUGIN"},
|
// EnvVars: []string{"REMOVEPLUGIN"},
|
||||||
Destination: &RemovePlugin,
|
// Destination: &RemovePlugin,
|
||||||
},
|
//},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "AddMetaData",
|
Name: "AddMetaData",
|
||||||
Aliases: []string{"amd"},
|
Aliases: []string{"amd"},
|
||||||
@@ -272,4 +274,18 @@ var AppConfigFlags = []cli.Flag{
|
|||||||
EnvVars: []string{"ADDMETADATA"},
|
EnvVars: []string{"ADDMETADATA"},
|
||||||
Destination: &AddMetaData,
|
Destination: &AddMetaData,
|
||||||
},
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "AddRootNode",
|
||||||
|
Aliases: []string{"arn"},
|
||||||
|
Usage: "Adds initial root node to talk to",
|
||||||
|
EnvVars: []string{"ADDROOTNODE"},
|
||||||
|
Destination: &AddRootNode,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "IPAddress",
|
||||||
|
Aliases: []string{"ip"},
|
||||||
|
Usage: "IP address",
|
||||||
|
EnvVars: []string{"IP"},
|
||||||
|
Destination: &IP,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ type Config struct {
|
|||||||
ServerPort string
|
ServerPort string
|
||||||
ProxyPort string
|
ProxyPort string
|
||||||
GroupTrackContainersPath string
|
GroupTrackContainersPath string
|
||||||
FRPServerPort string
|
FRPServerPort bool
|
||||||
BehindNAT string
|
BehindNAT bool
|
||||||
IPTableKey string
|
IPTableKey string
|
||||||
PublicKeyFile string
|
PublicKeyFile string
|
||||||
PrivateKeyFile string
|
PrivateKeyFile string
|
||||||
|
|||||||
@@ -78,9 +78,9 @@ func SetDefaults(envName string, forceDefault bool, CustomConfig interface{}, No
|
|||||||
Defaults.GroupTrackContainersPath = defaultPath + "client/trackcontainers/grouptrackcontainers.json"
|
Defaults.GroupTrackContainersPath = defaultPath + "client/trackcontainers/grouptrackcontainers.json"
|
||||||
Defaults.ServerPort = "8088"
|
Defaults.ServerPort = "8088"
|
||||||
Defaults.ProxyPort = ""
|
Defaults.ProxyPort = ""
|
||||||
Defaults.FRPServerPort = "True"
|
Defaults.FRPServerPort = true
|
||||||
Defaults.CustomConfig = CustomConfig
|
Defaults.CustomConfig = CustomConfig
|
||||||
Defaults.BehindNAT = "True"
|
Defaults.BehindNAT = true
|
||||||
Defaults.DockerRunLogs = "/tmp/"
|
Defaults.DockerRunLogs = "/tmp/"
|
||||||
// Generate a random key to be added to IPTable
|
// Generate a random key to be added to IPTable
|
||||||
Defaults.IPTableKey = String(12)
|
Defaults.IPTableKey = String(12)
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ func GenerateIPTableFile(rootNodes []p2p.IpAddress) (err error) {
|
|||||||
if len(rootNodes) <= 0 {
|
if len(rootNodes) <= 0 {
|
||||||
rootnode.Name = "Node1"
|
rootnode.Name = "Node1"
|
||||||
rootnode.ServerPort = "8078"
|
rootnode.ServerPort = "8078"
|
||||||
rootnode.NAT = "False"
|
rootnode.NAT = false
|
||||||
rootnode.Ipv4 = "217.76.63.222"
|
rootnode.Ipv4 = "217.76.63.222"
|
||||||
rootnode.ProxyServer = "True"
|
rootnode.ProxyServer = true
|
||||||
|
|
||||||
rootnodes.IpAddress = append(rootnodes.IpAddress, rootnode)
|
rootnodes.IpAddress = append(rootnodes.IpAddress, rootnode)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
5
go.mod
5
go.mod
@@ -3,7 +3,6 @@ module github.com/Akilan1999/p2p-rendering-computation
|
|||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/apenella/go-ansible v1.1.0
|
|
||||||
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/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
|
||||||
@@ -16,7 +15,6 @@ require (
|
|||||||
github.com/urfave/cli/v2 v2.3.0
|
github.com/urfave/cli/v2 v2.3.0
|
||||||
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/crypto v0.16.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -24,8 +22,6 @@ require (
|
|||||||
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3 // indirect
|
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3 // indirect
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
|
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
|
||||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||||
github.com/apenella/go-common-utils v0.1.1 // indirect
|
|
||||||
github.com/apenella/go-common-utils/error v0.0.0-20200917063805-34b0ed3c4ce1 // indirect
|
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 // indirect
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
@@ -100,5 +96,6 @@ require (
|
|||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/square/go-jose.v2 v2.4.1 // indirect
|
gopkg.in/square/go-jose.v2 v2.4.1 // indirect
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gotest.tools/v3 v3.0.3 // indirect
|
gotest.tools/v3 v3.0.3 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
36
go.sum
36
go.sum
@@ -63,7 +63,6 @@ github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg3
|
|||||||
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/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/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
|
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
@@ -79,13 +78,6 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5
|
|||||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
github.com/apenella/go-ansible v1.1.0 h1:wWqaZBvoDxPjvtwXc2fXbDj546uBj/Kv2PL7PW82EfY=
|
|
||||||
github.com/apenella/go-ansible v1.1.0/go.mod h1:tHqFBSwWXF9k2hkLQWfq6oxMQZHslySQqttkA2siyqE=
|
|
||||||
github.com/apenella/go-common-utils v0.1.1 h1:dJA2tY22z6mYB5a+EogfiS7NxZsR/Ld3TWnZcS3JPa0=
|
|
||||||
github.com/apenella/go-common-utils v0.1.1/go.mod h1:E7RUbl9B1vdLkTIapoTE2W6pIgW7dTSJOxL3pf4gV6g=
|
|
||||||
github.com/apenella/go-common-utils/error v0.0.0-20200917063805-34b0ed3c4ce1 h1:lw/fwF65AaJVxyUTJShtBiZfaiafKde3QkR4im1glzQ=
|
|
||||||
github.com/apenella/go-common-utils/error v0.0.0-20200917063805-34b0ed3c4ce1/go.mod h1:Hj3S/BcSHKfv9VDMcrY7lsm9hGnb7cd70alSkl/Sv+4=
|
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||||
@@ -106,7 +98,6 @@ github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8n
|
|||||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
@@ -167,8 +158,6 @@ github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ
|
|||||||
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||||
github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
|
github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
|
||||||
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
|
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
|
||||||
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||||
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
|
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
|
||||||
@@ -200,7 +189,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||||
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
|
||||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||||
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
@@ -240,7 +228,6 @@ github.com/fatedier/golib v0.1.1-0.20220321042308-c306138b83ac/go.mod h1:fLV0TLw
|
|||||||
github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible h1:ssXat9YXFvigNge/IkkZvFMn8yeYKFX+uI6wn2mLJ74=
|
github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible h1:ssXat9YXFvigNge/IkkZvFMn8yeYKFX+uI6wn2mLJ74=
|
||||||
github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible/go.mod h1:YpCOaxj7vvMThhIQ9AfTOPW2sfztQR5WDfs7AflSy4s=
|
github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible/go.mod h1:YpCOaxj7vvMThhIQ9AfTOPW2sfztQR5WDfs7AflSy4s=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
|
||||||
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=
|
||||||
@@ -314,7 +301,6 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
|||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/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-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=
|
||||||
@@ -385,13 +371,10 @@ github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
|
|||||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
@@ -399,7 +382,6 @@ github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:
|
|||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||||
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/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
|
||||||
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
||||||
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
@@ -462,7 +444,6 @@ github.com/lithammer/shortuuid v3.0.0+incompatible h1:NcD0xWW/MZYXEHa6ITy6kaXN5n
|
|||||||
github.com/lithammer/shortuuid v3.0.0+incompatible/go.mod h1:FR74pbAuElzOUuenUHTK2Tciko1/vKuIKS9dSkDrA4w=
|
github.com/lithammer/shortuuid v3.0.0+incompatible/go.mod h1:FR74pbAuElzOUuenUHTK2Tciko1/vKuIKS9dSkDrA4w=
|
||||||
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/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=
|
||||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||||
@@ -470,7 +451,6 @@ github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHef
|
|||||||
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
||||||
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
|
||||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
@@ -506,7 +486,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
|
|||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
|
||||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
@@ -547,7 +526,6 @@ github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6
|
|||||||
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
|
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
|
||||||
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/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-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
|
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
|
||||||
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
|
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
|
||||||
@@ -568,7 +546,6 @@ github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAm
|
|||||||
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||||
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||||
@@ -583,8 +560,6 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
|
|||||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
|
||||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
@@ -594,7 +569,6 @@ github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8
|
|||||||
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
|
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
|
||||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
@@ -606,7 +580,6 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
|
|||||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
||||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
@@ -635,20 +608,14 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
|
|||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
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/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
|
||||||
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/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/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/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/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=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
@@ -681,7 +648,6 @@ github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//
|
|||||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
|
||||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||||
@@ -703,7 +669,6 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2
|
|||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
|
||||||
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
|
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
@@ -718,7 +683,6 @@ gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40 h1:dizWJqTWj
|
|||||||
gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40/go.mod h1:rOnSnoRyxMI3fe/7KIbVcsHRGxe30OONv8dEgo+vCfA=
|
gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40/go.mod h1:rOnSnoRyxMI3fe/7KIbVcsHRGxe30OONv8dEgo+vCfA=
|
||||||
gitlab.com/NebulousLabs/go-upnp v0.0.0-20181011194642-3a71999ed0d3 h1:qXqiXDgeQxspR3reot1pWme00CX1pXbxesdzND+EjbU=
|
gitlab.com/NebulousLabs/go-upnp v0.0.0-20181011194642-3a71999ed0d3 h1:qXqiXDgeQxspR3reot1pWme00CX1pXbxesdzND+EjbU=
|
||||||
gitlab.com/NebulousLabs/go-upnp v0.0.0-20181011194642-3a71999ed0d3/go.mod h1:sleOmkovWsDEQVYXmOJhx69qheoMTmCuPYyiCFCihlg=
|
gitlab.com/NebulousLabs/go-upnp v0.0.0-20181011194642-3a71999ed0d3/go.mod h1:sleOmkovWsDEQVYXmOJhx69qheoMTmCuPYyiCFCihlg=
|
||||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
|
||||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
||||||
|
|||||||
909
index.org~
Normal file
909
index.org~
Normal file
@@ -0,0 +1,909 @@
|
|||||||
|
#+SETUPFILE: https://fniessen.github.io/org-html-themes/org/theme-readtheorg.setup
|
||||||
|
|
||||||
|
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="https://fniessen.github.io/org-html-themes/src/readtheorg_theme/css/search.css"/>
|
||||||
|
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="style.css"/>
|
||||||
|
|
||||||
|
#+attr_html: :width 300px :align center
|
||||||
|
[[./artwork/p2prc-logos/Colored-On-Light-Image.png]]
|
||||||
|
|
||||||
|
* Guide through video
|
||||||
|
*** The video below shows the setup and usage of P2PRC.
|
||||||
|
#+attr_html: :class video
|
||||||
|
[[https://www.youtube.com/watch?v=OMwCpedu5cs][https://i3.ytimg.com/vi/OMwCpedu5cs/maxresdefault.jpg]]
|
||||||
|
|
||||||
|
* Introduction
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: chapter1-introduction
|
||||||
|
:END:
|
||||||
|
This project focuses on creating a framework for running heavy computational tasks that a regular
|
||||||
|
computer cannot handle easily. These tasks may include graphically demanding video games, rendering
|
||||||
|
3D animations, and performing complex protein folding simulations. The major focus of this project
|
||||||
|
is not on financial incentives but rather on building a robust and efficient peer-to-peer (P2P)
|
||||||
|
network to decentralise task execution and increase the computational bandwidth available for
|
||||||
|
such tasks.
|
||||||
|
|
||||||
|
The P2PRC framework serves as a foundation for decentralised rendering and computation,
|
||||||
|
providing insights into how tasks can be distributed efficiently across a network of peers.
|
||||||
|
Leveraging the P2PRC approach, this project extends its capabilities to handle a
|
||||||
|
wider range of computationally intensive tasks.
|
||||||
|
|
||||||
|
** Motivation
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: motivation
|
||||||
|
:END:
|
||||||
|
Many of the users rely on our PC / Laptop or servers that belong to a
|
||||||
|
server farm to run heavy tasks and with the demand of high creativity
|
||||||
|
requires higher computing power. Buying a powerful computer every few
|
||||||
|
years to run a bunch of heavy tasks which are not executed as frequently
|
||||||
|
to reap the benefits can be inefficient utilization of hardware. On the
|
||||||
|
other end, renting servers to run these heavy tasks can be really
|
||||||
|
useful. Ethically speaking this is leading to monopolisation of
|
||||||
|
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 the client and
|
||||||
|
server.
|
||||||
|
|
||||||
|
* Installation
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: installation
|
||||||
|
:END:
|
||||||
|
|
||||||
|
Over here we will cover the basic steps to get the server and client
|
||||||
|
side running.
|
||||||
|
|
||||||
|
** Latest release install
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: latest-release-install
|
||||||
|
:END:
|
||||||
|
https://github.com/Akilan1999/p2p-rendering-computation/releases
|
||||||
|
|
||||||
|
** Install from Github master branch
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: install-from-github-master-branch
|
||||||
|
:END:
|
||||||
|
*** Install Go lang
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: install-go-lang
|
||||||
|
:END:
|
||||||
|
The entire the implementation of this project is done using Go lang.
|
||||||
|
Thus, we need go lang to compile to code to a binary file.
|
||||||
|
[[https://golang.org/doc/install][Instructions to install Go lang]]
|
||||||
|
|
||||||
|
*** Install Docker
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: install-docker
|
||||||
|
:END:
|
||||||
|
In this project the choice of virtualization is Docker due to it's wide
|
||||||
|
usage in the developer community. In the server module we use the Docker
|
||||||
|
Go API to create and interact with the containers.
|
||||||
|
|
||||||
|
[[https://docs.docker.com/get-docker/][Instructions to install docker]]
|
||||||
|
|
||||||
|
[[https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker][Instructions
|
||||||
|
to install docker GPU]]
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
// Do ensure that the docker command does not need sudo to run
|
||||||
|
sudo chmod 666 /var/run/docker.sock
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Build Project and install project
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: build-project-and-install-project
|
||||||
|
:END:
|
||||||
|
To set up the internal dependencies and build the entire go code into a
|
||||||
|
single binary
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
make
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
**** For Windows
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: for-windows
|
||||||
|
:END:
|
||||||
|
To set up P2PRC on Windows, simply run this batch file. *Make sure you
|
||||||
|
are not in admin mode when running this.*
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
.\install.bat
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Add appropriate paths to =.bashrc=
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: add-appropriate-paths-to-.bashrc
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
export P2PRC=/<PATH>/p2p-rendering-computation
|
||||||
|
export PATH=/<PATH>/p2p-rendering-computation:${PATH}
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Test if binary works
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: test-if-binary-works
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --help
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
**** Output:
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: output
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
NAME:
|
||||||
|
p2p-rendering-computation - p2p cli application to create and access VMs in other servers
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
p2prc [global options] command [command options] [arguments...]
|
||||||
|
|
||||||
|
VERSION:
|
||||||
|
2.0.0
|
||||||
|
|
||||||
|
COMMANDS:
|
||||||
|
help, h Shows a list of commands or help for one command
|
||||||
|
|
||||||
|
GLOBAL OPTIONS:
|
||||||
|
--Server, -s Starts server (default: false) [$SERVER]
|
||||||
|
--UpdateServerList, --us Update List of Server available based on servers iptables (default: false) [$UPDATE_SERVER_LIST]
|
||||||
|
--ListServers, --ls List servers which can render tasks (default: false) [$LIST_SERVERS]
|
||||||
|
--AddServer value, --as value Adds server IP address to iptables [$ADD_SERVER]
|
||||||
|
--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]
|
||||||
|
--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 (IP:port) accompanied by container ID via --ID or --id [$REMOVE_VM]
|
||||||
|
--ID value, --id value Docker Container ID [$ID]
|
||||||
|
--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]
|
||||||
|
--Specification value, --specs value Specs of the server node [$SPECS]
|
||||||
|
--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]
|
||||||
|
--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]
|
||||||
|
--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)
|
||||||
|
--version, -v print the version (default: false)
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* Using basic commands
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: using-basic-commands
|
||||||
|
:END:
|
||||||
|
*** Start as a server
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: start-as-a-server
|
||||||
|
:END:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
p2prc -s
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** View server Specification
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: view-server-specification
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --specs=<ip address>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Run container
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: run-container
|
||||||
|
:END:
|
||||||
|
use the =--gpu= if you know the other machine has a gpu.
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
p2prc --touch=<server ip address> -p <number of ports> --gpu
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Remove container
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: remove-container
|
||||||
|
:END:
|
||||||
|
The docker id is present in the output where you create a container
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
p2prc --rm=<server ip address> --id=<docker container id>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Adding servers to ip table
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: adding-servers-to-ip-table
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --as=<server ip address you want to add>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Update ip table
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: update-ip-table
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --us
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** List Servers
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: list-servers
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --ls
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** View Network interfaces
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: view-network-interfaces
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --ni
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Viewing Containers created Client side
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: viewing-containers-created-client-side
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --tc
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Running plugin
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: running-plugin
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --plugin <plugin name> --id <container id or group id>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Create group
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: create-group
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --cgroup
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Add container to group
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: add-container-to-group
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --group <group id> --id <container id>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** View groups
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: view-groups
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --groups
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** View specific group
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: view-specific-group
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --group <group id>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Delete container from group
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: delete-container-from-group
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --rmcgroup --group <group id> --id <container id>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Delete entire group
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: delete-entire-group
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --rmgroup <group id>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Pulling plugin from a remote repo
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: pulling-plugin-from-a-remote-repo
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --pp <repo link>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Deleting plugin from the plugin directory
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: deleting-plugin-from-the-plugin-directory
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --rp <plugin name>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** Added custom metadata about the current node
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: added-custom-metadata-about-the-current-node
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
p2prc --amd "custom metadata"
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** MapPort and link to domain name
|
||||||
|
Allows to expose remote ports from a machine in the P2P network.
|
||||||
|
#+begin_example
|
||||||
|
p2prc --mp <port no to map> --dn <domain name to link Mapped port against>
|
||||||
|
#+end_example
|
||||||
|
**** MapPort in remote machine
|
||||||
|
This is to ensure ports on remote machines on the P2PRC can be easily opened.
|
||||||
|
#+begin_example
|
||||||
|
p2prc --mp <port no to map> --dn <domain name to link Mapped port against> --ra <remote server address>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* P2P Module Implementation
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: p2p-module-implementation
|
||||||
|
:END:
|
||||||
|
The P2P module is for managing server information within the network.
|
||||||
|
It maintains and updates the IP table, ensuring accuracy by preventing duplicates and removing
|
||||||
|
entries for unreachable servers. Furthermore, the module conducts speed tests on the listed servers
|
||||||
|
to determine upload and download speeds. This valuable information enables users to identify nearby
|
||||||
|
servers with optimal performance, enhancing their overall network experience.
|
||||||
|
|
||||||
|
#+caption: UML diagram of P2P module
|
||||||
|
[[file:Docs/images/p2pmoduleArch.png]
|
||||||
|
|
||||||
|
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 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 server. 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
|
||||||
|
implementations of each functionality in depth.
|
||||||
|
|
||||||
|
** IP Table
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: ip-table
|
||||||
|
:END:
|
||||||
|
The ip table file is a json as the format with a list of servers ip
|
||||||
|
addresses, latencies, downloads and uploads speeds. The functions
|
||||||
|
implemented include read file, write file and remove duplicate IP
|
||||||
|
addresses. The remove duplicate IP address function exists because
|
||||||
|
sometimes servers IP tables can have the same ip addresses as what the
|
||||||
|
client has. The path of the IP table json file is received from the
|
||||||
|
configuration module.
|
||||||
|
|
||||||
|
#+begin_src json
|
||||||
|
{
|
||||||
|
"ip_address": [
|
||||||
|
{
|
||||||
|
"Name": "<hostname of the machine>",
|
||||||
|
"MachineUsername": "<machine username>",
|
||||||
|
"IPV4": "<ipv4 address>",
|
||||||
|
"IPV6": "<ipv6 address (Not used)>",
|
||||||
|
"Latency": <latency to the server>,
|
||||||
|
"Download": <download speed (Not used)>,
|
||||||
|
"Upload": <upload speed (Not used)>,
|
||||||
|
"ServerPort": "<server port no>",
|
||||||
|
"BareMetalSSHPort": "<Baremetal ssh port no>",
|
||||||
|
"NAT": "<boolean representing if the node is behind NAT or not>",
|
||||||
|
"EscapeImplementation": "<NAT traversal implementation>",
|
||||||
|
"ProxyServer": "<If the node listed is acting as a proxy server>",
|
||||||
|
"UnSafeMode": <Unsafe mode if turned on will allow all nodes in the network public keys to be
|
||||||
|
added to that particular node>",
|
||||||
|
"PublicKey": "<Public key of that particular node>",
|
||||||
|
"CustomInformation": "<custom information passed in through all the nodes in the network>"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
*** Latency
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: latency
|
||||||
|
:END:
|
||||||
|
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.
|
||||||
|
|
||||||
|
** NAT Traversal
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: nat-traversal
|
||||||
|
:END:
|
||||||
|
P2PRC currently supports TURN for NAT traversal.
|
||||||
|
|
||||||
|
** TURN
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: turn
|
||||||
|
:END:
|
||||||
|
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
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: client-mode
|
||||||
|
:END:
|
||||||
|
- Call =/FRPPort=
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
http://<turn server ip>:<server port no>/FRPport
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
- Call the TURN server in the following manner. The following is a
|
||||||
|
sample code snippet below.
|
||||||
|
|
||||||
|
#+begin_src 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* Language Bindings
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: language-bindings
|
||||||
|
:END:
|
||||||
|
[[https://en.wikipedia.org/wiki/Language_binding][Language bindings]]
|
||||||
|
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.
|
||||||
|
|
||||||
|
** How to build shared object files
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: how-to-build-shared-object-files
|
||||||
|
:END:
|
||||||
|
**** The easier way
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: the-easier-way
|
||||||
|
:END:
|
||||||
|
#+begin_src sh
|
||||||
|
# Run
|
||||||
|
make sharedObjects
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
**** Or the direct way
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: or-the-direct-way
|
||||||
|
:END:
|
||||||
|
#+begin_src sh
|
||||||
|
# Run
|
||||||
|
cd Bindings && go build -buildmode=c-shared -o p2prc.so
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
**** If successfully built:
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: if-successfully-built
|
||||||
|
:END:
|
||||||
|
#+begin_src sh
|
||||||
|
# Enter into the Bindings directory
|
||||||
|
cd Bindings
|
||||||
|
# List files
|
||||||
|
ls
|
||||||
|
# Find files
|
||||||
|
p2prc.h p2prc.so
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Workings under the hood
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: workings-under-the-hood
|
||||||
|
:END:
|
||||||
|
Below are a sample set of commands to open the bindings implementation.
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
# run
|
||||||
|
cd Bindings/
|
||||||
|
# list files
|
||||||
|
ls
|
||||||
|
# search for file
|
||||||
|
Client.go
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
*** In Client go
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: in-client-go
|
||||||
|
:END:
|
||||||
|
There a few things to notice which are different from your standard Go
|
||||||
|
programs:
|
||||||
|
|
||||||
|
**** 1. We import "C" which means [[https://pkg.go.dev/cmd/cgo][Cgo]] is required.
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: we-import-c-which-means-cgo-is-required.
|
||||||
|
:END:
|
||||||
|
#+begin_src go
|
||||||
|
import "C"
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
**** 2. All functions which are required to be called from other programming languages have comment such as.
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: all-functions-which-are-required-to-be-called-from-other-programming-languages-have-comment-such-as.
|
||||||
|
:END:
|
||||||
|
#+begin_src 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)
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
**** 3. While looking through the file (If 2 files are compared it is pretty trivial to notice a common structure).
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: while-looking-through-the-file-if-2-files-are-compared-it-is-pretty-trivial-to-notice-a-common-structure.
|
||||||
|
:END:
|
||||||
|
#+begin_src 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)
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
**** It is easy to notice that:
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: it-is-easy-to-notice-that
|
||||||
|
:END:
|
||||||
|
- =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:
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: a-pseudo-code-to-refer-to-the-common-function-implementation-shape-could-be-represented-as
|
||||||
|
:END:
|
||||||
|
#+begin_example
|
||||||
|
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>)
|
||||||
|
}
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
** Current languages supported
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: current-languages-supported
|
||||||
|
:END:
|
||||||
|
*** Python
|
||||||
|
|
||||||
|
**** Build sample python program
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: build-sample-python-program
|
||||||
|
:END:
|
||||||
|
The easier way
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
|
# Run
|
||||||
|
make python
|
||||||
|
# Expected ouput
|
||||||
|
Output is in the Directory Bindings/python/export/
|
||||||
|
# Run
|
||||||
|
cd Bindings/python/export/
|
||||||
|
# list files
|
||||||
|
ls
|
||||||
|
# Expected output
|
||||||
|
SharedObjects/ library.py requirements.txt
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
*** Haskell
|
||||||
|
P2PRC officially supports Haskell bindings and will further support
|
||||||
|
project using Haskell to build orchestrators on top of P2PRC.
|
||||||
|
|
||||||
|
[[https://p2prc.akilan.io/Docs/haskell][Read more...]]
|
||||||
|
|
||||||
|
* Config Implementation
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: config-implementation
|
||||||
|
:END:
|
||||||
|
The configuration module is responsible to store basic information of
|
||||||
|
absolute paths of files being called in the Go code. In a full-fledged
|
||||||
|
Cli the configuration file can be found in the directory /etc/ and from
|
||||||
|
there points to location such as where the IP table file is located. In
|
||||||
|
the future implementation the config file will have information such as
|
||||||
|
number of hops and other parameters to tweak and to improve the
|
||||||
|
effectiveness of the peer to peer network. The configuration module was
|
||||||
|
implemented using the library Viper. The Viper library automates
|
||||||
|
features such as searching in default paths to find out if the
|
||||||
|
configuration file is present. If the configuration file is not present
|
||||||
|
in the default paths then it auto generates the configuration file. The
|
||||||
|
configurations file can be in any format. In this project the
|
||||||
|
configuration file was generated using JSON format.
|
||||||
|
|
||||||
|
#+begin_src json
|
||||||
|
{
|
||||||
|
"MachineName": "pc-74-120.customer.ask4.lan",
|
||||||
|
"IPTable": "/Users/akilan/Documents/p2p-rendering-computation/p2p/iptable/ip_table.json",
|
||||||
|
"DockerContainers": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/",
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* Abstractions
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: abstractions
|
||||||
|
:END:
|
||||||
|
|
||||||
|
The Abstractions package consists of black-boxed functions for P2PRC.
|
||||||
|
|
||||||
|
** Functions
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: functions
|
||||||
|
:END:
|
||||||
|
- =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.
|
||||||
|
|
||||||
|
* NAT Traversal
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: nat-traversal
|
||||||
|
:END:
|
||||||
|
P2PRC currently supports TURN for NAT traversal.
|
||||||
|
|
||||||
|
** TURN
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: turn
|
||||||
|
:END:
|
||||||
|
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
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: client-mode
|
||||||
|
:END:
|
||||||
|
- Call =/FRPPort=
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
http://<turn server ip>:<server port no>/FRPport
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
- Call the TURN server in the following manner. The following is a
|
||||||
|
sample code snippet below.
|
||||||
|
|
||||||
|
#+begin_src 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* Blog posts
|
||||||
|
** Self host within 5 minutes any program
|
||||||
|
|
||||||
|
- Author: [[http://akilan.io/][Akilan Selvacoumar]]
|
||||||
|
- Date: 28-01-2025
|
||||||
|
|
||||||
|
|
||||||
|
- Video tutorial:
|
||||||
|
[[https://youtu.be/rN4SiVowg5E][https://i3.ytimg.com/vi/rN4SiVowg5E/maxresdefault.jpg]]
|
||||||
|
|
||||||
|
This is a fun expirement for anyone to try to quickly run a server and
|
||||||
|
quickly do a map port and domain name mapping in a single command.
|
||||||
|
|
||||||
|
*** 1. Find a program you want to run
|
||||||
|
Let's try to setup a really easy program (Let's do with Linkwarden
|
||||||
|
with docker compose :) ). This is under the assumption you have docker
|
||||||
|
compose installed on your local machine.
|
||||||
|
|
||||||
|
**** Let's run Linkwarden using docker compose and P2PRC
|
||||||
|
[[https://docs.linkwarden.app/self-hosting/installation][Installation instructions]]:
|
||||||
|
#+BEGIN_SRC
|
||||||
|
mkdir linkwarden && cd linkwarden
|
||||||
|
curl -O https://raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml
|
||||||
|
curl -L https://raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env"
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Environment configuration
|
||||||
|
#+BEGIN_SRC
|
||||||
|
vim .env
|
||||||
|
|
||||||
|
# Change values
|
||||||
|
NEXTAUTH_URL=https://<DOMAIN NAME>/api/v1/auth
|
||||||
|
NEXTAUTH_SECRET=VERY_SENSITIVE_SECRET
|
||||||
|
POSTGRES_PASSWORD=CUSTOM_POSTGRES_PASSWORD
|
||||||
|
#+END_SRC
|
||||||
|
Run linkwarden!
|
||||||
|
#+BEGIN_SRC
|
||||||
|
docker compose up
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
If setup correctly linkwarden should
|
||||||
|
be running.
|
||||||
|
Local link: http://localhost:3000
|
||||||
|
|
||||||
|
Time to setup P2PRC
|
||||||
|
[[https://p2prc.akilan.io/Docs/#build-project-and-install-project][Installation Instructions]]
|
||||||
|
|
||||||
|
Run p2prc as a background
|
||||||
|
#+BEGIN_SRC
|
||||||
|
p2prc -s &
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Run map port and domain mapping
|
||||||
|
#+BEGIN_SRC
|
||||||
|
p2prc --mp 3000 --dn <DOMAIN NAME>
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Sample response
|
||||||
|
#+BEGIN_SRC
|
||||||
|
{
|
||||||
|
"IPAddress": "217.76.63.222",
|
||||||
|
"PortNo": "61582",
|
||||||
|
"EntireAddress": "217.76.63.222:61582"
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Add DNS entry
|
||||||
|
#+BEGIN_SRC
|
||||||
|
A entry 217.76.63.222
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Your done now just head to the DOMAIN NAME you added.
|
||||||
|
ex: https://linkwarden.akilan.io
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* Ideas for future potencial features
|
||||||
|
Consists of personal loideas for the future of P2PRC.
|
||||||
|
At moment only has main contributors writiing to this.
|
||||||
|
|
||||||
|
** To support hetrogenous set of Nodes that cannot run P2PRC
|
||||||
|
This stems from a personal issue I have when doing research
|
||||||
|
on [[https://github.com/CTSRD-CHERI/cheribsd][CheriBSD]] kernel. For my research I am using the ARM morello
|
||||||
|
which is a 128bit ARMv8 processor. At the moment Go programs
|
||||||
|
can cannot compile and run inside the CPU. This means I cannot
|
||||||
|
run P2PRC at the moment inside the ARM morello to remotely access
|
||||||
|
it when it's behind NAT using P2PRC. This would indeed be a common
|
||||||
|
problem when running against various Architectures that do not
|
||||||
|
support running P2PRC. As you will see soon this also creates
|
||||||
|
oppurtunity space to scale faster to nodes in a local network
|
||||||
|
and would introduce a new layer fault tolerance within a local
|
||||||
|
network nodes.
|
||||||
|
|
||||||
|
*** Assumptions:
|
||||||
|
- I have a Morello board that cannot run P2PRC
|
||||||
|
- The Morello has a local IP address (ex: 192.168.0.10)
|
||||||
|
- I have 2 laptops running P2PRC in that local network.
|
||||||
|
- This means I have 2 ways to access the Morello board: Which is to SSH
|
||||||
|
into either 2 laptops and then SSH into 192.168.0.10 to gain access
|
||||||
|
to the board. Wouldn't it be great to automate this whole layer and
|
||||||
|
as well look into custom tasks into the hetrogenous hardware.
|
||||||
|
*** Set of interesting possible:
|
||||||
|
We build a cool set possibilities before and use this to build up the implementation
|
||||||
|
plan.
|
||||||
|
- We can use P2PRC access the morello board remotely in a single command.
|
||||||
|
- We can use the P2PRC protocol to run servers inside the morello board via traversed
|
||||||
|
node locally which can access that Node.
|
||||||
|
- Spin servers on node not running P2PRC using the P2PRC standard abstractions.
|
||||||
|
- Auto-setup P2PRC nodes with just SSH access via potencially a DSL.
|
||||||
|
- A neat use case for CHERI for instance would be use the architecture to run light
|
||||||
|
weight hypervisors.
|
||||||
|
*** Implementation
|
||||||
|
- To use implementations similar to [[https://linux.die.net/man/1/socat][socat]] to ensure we can bind address of local
|
||||||
|
nodes to a node running P2PRC and the node running P2PRC can do a local map port.
|
||||||
|
- We are working on hardening the implementation of the --mp (Map port) to even
|
||||||
|
map ports to machines which remotely running P2PRC. This means of instance I
|
||||||
|
can issue a command to the Morello board without the morello board being in
|
||||||
|
my local network.
|
||||||
|
- We would want to implement the exsisting P2PRC public key mechanism as well so that
|
||||||
|
other nodes can access the Morello board who have permission access.
|
||||||
|
|
||||||
|
#+CAPTION: Implementation idea (To be improved upon)
|
||||||
|
[[./Docs/images/P2PRCRemoteNodes.png]]
|
||||||
35
main.go
35
main.go
@@ -1,13 +1,10 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/cmd"
|
"github.com/Akilan1999/p2p-rendering-computation/cmd"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VERSION specifies the version of the platform
|
// VERSION specifies the version of the platform
|
||||||
@@ -19,20 +16,20 @@ var OS, Pull_location, Run_script string
|
|||||||
var List_servers, Ip_table bool
|
var List_servers, Ip_table bool
|
||||||
|
|
||||||
// To be implemented later on
|
// To be implemented later on
|
||||||
func getFireSignalsChannel() chan os.Signal {
|
//func getFireSignalsChannel() chan os.Signal {
|
||||||
|
//
|
||||||
c := make(chan os.Signal, 1)
|
// c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c,
|
// signal.Notify(c,
|
||||||
// https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html
|
// // https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html
|
||||||
syscall.SIGTERM, // "the normal way to politely ask a program to terminate"
|
// syscall.SIGTERM, // "the normal way to politely ask a program to terminate"
|
||||||
syscall.SIGINT, // Ctrl+C
|
// syscall.SIGINT, // Ctrl+C
|
||||||
syscall.SIGQUIT, // Ctrl-\
|
// syscall.SIGQUIT, // Ctrl-\
|
||||||
syscall.SIGKILL, // "always fatal", "SIGKILL and SIGSTOP may not be caught by a program"
|
// syscall.SIGKILL, // "always fatal", "SIGKILL and SIGSTOP may not be caught by a program"
|
||||||
syscall.SIGHUP, // "terminal is disconnected"
|
// syscall.SIGHUP, // "terminal is disconnected"
|
||||||
)
|
// )
|
||||||
return c
|
// return c
|
||||||
|
//
|
||||||
}
|
//}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
|
|||||||
@@ -1,30 +1,28 @@
|
|||||||
package frp
|
package frp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
"github.com/fatedier/frp/client"
|
||||||
"github.com/fatedier/frp/client"
|
"github.com/fatedier/frp/pkg/config"
|
||||||
"github.com/fatedier/frp/pkg/config"
|
"github.com/phayes/freeport"
|
||||||
"github.com/phayes/freeport"
|
"math/rand"
|
||||||
"math/rand"
|
"strconv"
|
||||||
"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
|
||||||
@@ -33,154 +31,154 @@ type ClientMapping struct {
|
|||||||
// to open. This under the assumption the user knows the
|
// to open. This under the assumption the user knows the
|
||||||
// exact port available in server doing the TURN connection.
|
// exact port available in server doing the TURN connection.
|
||||||
func StartFRPClientForServer(ipaddress string, port string, localport string, remoteport string) (string, error) {
|
func StartFRPClientForServer(ipaddress string, port string, localport string, remoteport string) (string, error) {
|
||||||
// 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 "", err
|
return "", 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
|
||||||
|
|
||||||
// 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
|
var OpenPorts []int
|
||||||
// if the remote port is
|
// if the remote port is
|
||||||
// not empty then set the remote port to that.
|
// not empty then set the remote port to that.
|
||||||
if remoteport != "" {
|
if remoteport != "" {
|
||||||
// converts localport to int
|
// converts localport to int
|
||||||
portIntRemote, err := strconv.Atoi(remoteport)
|
portIntRemote, err := strconv.Atoi(remoteport)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
OpenPorts = append(OpenPorts, portIntRemote)
|
OpenPorts = append(OpenPorts, portIntRemote)
|
||||||
} else {
|
} else {
|
||||||
//random port
|
//random port
|
||||||
//randPort := rangeIn(10000, 99999)
|
//randPort := rangeIn(10000, 99999)
|
||||||
OpenPorts, err = freeport.GetFreePorts(1)
|
OpenPorts, err = freeport.GetFreePorts(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.ClientMappings = []ClientMapping{
|
c.ClientMappings = []ClientMapping{
|
||||||
{
|
{
|
||||||
LocalIP: "localhost",
|
LocalIP: "localhost",
|
||||||
LocalPort: portInt,
|
LocalPort: portInt,
|
||||||
RemotePort: OpenPorts[0],
|
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 {
|
// for i, _ := range Docker.Ports.PortSet {
|
||||||
portMap := Docker.Ports.PortSet[i].ExternalPort
|
// portMap := Docker.Ports.PortSet[i].ExternalPort
|
||||||
|
//
|
||||||
serverPort, err := GetFRPServerPort("http://" + ipaddress + ":" + port)
|
// serverPort, err := GetFRPServerPort("http://" + ipaddress + ":" + port)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
//delay to allow the FRP server to start
|
// //delay to allow the FRP server to start
|
||||||
time.Sleep(1 * time.Second)
|
// time.Sleep(1 * time.Second)
|
||||||
|
//
|
||||||
proxyPort, err := StartFRPClientForServer(ipaddress, serverPort, strconv.Itoa(portMap), "")
|
// proxyPort, err := StartFRPClientForServer(ipaddress, serverPort, strconv.Itoa(portMap), "")
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
portInt, err = strconv.Atoi(proxyPort)
|
// portInt, err = strconv.Atoi(proxyPort)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
Docker.Ports.PortSet[i].ExternalPort = portInt
|
// Docker.Ports.PortSet[i].ExternalPort = portInt
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return Docker, nil
|
// return Docker, nil
|
||||||
|
//
|
||||||
}
|
//}
|
||||||
|
|
||||||
// StartFRPClient Starts FRP client
|
// StartFRPClient Starts FRP client
|
||||||
func (c *Client) StartFRPClient() error {
|
func (c *Client) StartFRPClient() error {
|
||||||
|
|
||||||
cfg := config.GetDefaultClientConf()
|
cfg := config.GetDefaultClientConf()
|
||||||
|
|
||||||
//Config, err := defaultConfig.ConfigInit(nil, nil)
|
//Config, err := defaultConfig.ConfigInit(nil, nil)
|
||||||
//if err != nil {
|
//if err != nil {
|
||||||
// return err
|
// return err
|
||||||
//}
|
//}
|
||||||
|
|
||||||
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
|
||||||
//cfg.TLSEnable = true
|
//cfg.TLSEnable = true
|
||||||
//cfg.TLSKeyFile = Config.KeyFile
|
//cfg.TLSKeyFile = Config.KeyFile
|
||||||
//cfg.TLSCertFile = Config.PemFile
|
//cfg.TLSCertFile = Config.PemFile
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ type IpAddress struct {
|
|||||||
Upload float64 `json:"Upload"`
|
Upload float64 `json:"Upload"`
|
||||||
ServerPort string `json:"ServerPort"`
|
ServerPort string `json:"ServerPort"`
|
||||||
BareMetalSSHPort string `json:"BareMetalSSHPort"`
|
BareMetalSSHPort string `json:"BareMetalSSHPort"`
|
||||||
NAT string `json:"NAT"`
|
NAT bool `json:"NAT"`
|
||||||
EscapeImplementation string `json:"EscapeImplementation"`
|
EscapeImplementation string `json:"EscapeImplementation"`
|
||||||
ProxyServer string `json:"ProxyServer"`
|
ProxyServer bool `json:"ProxyServer"`
|
||||||
UnSafeMode bool `json:"UnSafeMode"`
|
UnSafeMode bool `json:"UnSafeMode"`
|
||||||
PublicKey string `json:"PublicKey"`
|
PublicKey string `json:"PublicKey"`
|
||||||
CustomInformation string `json:"CustomInformation"`
|
CustomInformation string `json:"CustomInformation"`
|
||||||
@@ -161,7 +161,7 @@ func (table *IpAddresses) RemoveDuplicates() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if table.IpAddress[i].NAT == "True" && table.IpAddress[i].EscapeImplementation == "None" {
|
if table.IpAddress[i].NAT && table.IpAddress[i].EscapeImplementation == "None" {
|
||||||
Exists = true
|
Exists = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ func (ip *IpAddresses) SpeedTestUpdatedIPTable() error {
|
|||||||
}
|
}
|
||||||
// Checks if both the IPV4 addresses are the same or the IPV6 address is not
|
// Checks if both the IPV4 addresses are the same or the IPV6 address is not
|
||||||
// an empty string and IPV6 address are the same
|
// an empty string and IPV6 address are the same
|
||||||
if (ip.IpAddress[k].Ipv4 == targets.IpAddress[i].Ipv4 && targets.IpAddress[i].NAT == "True") || (targets.IpAddress[i].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) {
|
if (ip.IpAddress[k].Ipv4 == targets.IpAddress[i].Ipv4 && targets.IpAddress[i].NAT) || (targets.IpAddress[i].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) {
|
||||||
Exists = true
|
Exists = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
.idea
|
|
||||||
.DS_Store
|
|
||||||
Dockerfile
|
|
||||||
2
plugin/.gitignore
vendored
2
plugin/.gitignore
vendored
@@ -1,2 +0,0 @@
|
|||||||
.idea
|
|
||||||
.DS_Store
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Test if it's detected
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
all:
|
|
||||||
vars:
|
|
||||||
ansible_python_interpreter: /usr/bin/python3
|
|
||||||
main:
|
|
||||||
hosts:
|
|
||||||
host1:
|
|
||||||
ansible_host: 0.0.0.0 # Replace with your remote IP
|
|
||||||
ansible_port: 44003 # Replace with your remote SSH port
|
|
||||||
ansible_user: master # Replace wtih your username
|
|
||||||
ansible_ssh_pass: password
|
|
||||||
ansible_sudo_pass: password
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- hosts: all
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: simple-ansibleplaybook
|
|
||||||
debug:
|
|
||||||
msg: Your are running 'simple-ansibleplaybook' example
|
|
||||||
224
plugin/docs.md
224
plugin/docs.md
@@ -1,224 +0,0 @@
|
|||||||
<!-- Code generated by gomarkdoc. DO NOT EDIT -->
|
|
||||||
|
|
||||||
# plugin
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "github.com/Akilan1999/p2p-rendering-computation/plugin"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Index
|
|
||||||
|
|
||||||
- [func CheckRunPlugin\(PluginName string, ID string\) error](<#CheckRunPlugin>)
|
|
||||||
- [func DeletePlugin\(pluginname string\) error](<#DeletePlugin>)
|
|
||||||
- [func DownloadPlugin\(pluginurl string\) error](<#DownloadPlugin>)
|
|
||||||
- [func RunPluginContainer\(PluginName string, ContainerID string\) error](<#RunPluginContainer>)
|
|
||||||
- [type ExecuteIP](<#ExecuteIP>)
|
|
||||||
- [func \(e \*ExecuteIP\) ModifyHost\(p \*Plugin\) error](<#ExecuteIP.ModifyHost>)
|
|
||||||
- [func \(e \*ExecuteIP\) RunAnsible\(p \*Plugin\) error](<#ExecuteIP.RunAnsible>)
|
|
||||||
- [type Host](<#Host>)
|
|
||||||
- [func ReadHost\(filename string\) \(\*Host, error\)](<#ReadHost>)
|
|
||||||
- [type Plugin](<#Plugin>)
|
|
||||||
- [func RunPlugin\(pluginName string, IPAddresses \[\]\*ExecuteIP\) \(\*Plugin, error\)](<#RunPlugin>)
|
|
||||||
- [func SearchPlugin\(pluginname string\) \(\*Plugin, error\)](<#SearchPlugin>)
|
|
||||||
- [func \(p \*Plugin\) AutoSetPorts\(containerID string\) error](<#Plugin.AutoSetPorts>)
|
|
||||||
- [func \(p \*Plugin\) CopyToTmpPlugin\(\) error](<#Plugin.CopyToTmpPlugin>)
|
|
||||||
- [func \(p \*Plugin\) ExecutePlugin\(\) error](<#Plugin.ExecutePlugin>)
|
|
||||||
- [func \(p \*Plugin\) NumPorts\(\) error](<#Plugin.NumPorts>)
|
|
||||||
- [type Plugins](<#Plugins>)
|
|
||||||
- [func DetectPlugins\(\) \(\*Plugins, error\)](<#DetectPlugins>)
|
|
||||||
|
|
||||||
|
|
||||||
<a name="CheckRunPlugin"></a>
|
|
||||||
## func [CheckRunPlugin](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L330>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func CheckRunPlugin(PluginName string, ID string) error
|
|
||||||
```
|
|
||||||
|
|
||||||
CheckRunPlugin Checks if the ID belongs to the group or container calls the plugin function the appropriate amount of times
|
|
||||||
|
|
||||||
<a name="DeletePlugin"></a>
|
|
||||||
## func [DeletePlugin](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/packageManager.go#L46>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func DeletePlugin(pluginname string) error
|
|
||||||
```
|
|
||||||
|
|
||||||
DeletePlugin The following function deletes a plugin based on the plugin name provided.
|
|
||||||
|
|
||||||
<a name="DownloadPlugin"></a>
|
|
||||||
## func [DownloadPlugin](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/packageManager.go#L13>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func DownloadPlugin(pluginurl string) error
|
|
||||||
```
|
|
||||||
|
|
||||||
DownloadPlugin This functions downloads package from a git repo.
|
|
||||||
|
|
||||||
<a name="RunPluginContainer"></a>
|
|
||||||
## func [RunPluginContainer](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L284>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func RunPluginContainer(PluginName string, ContainerID string) error
|
|
||||||
```
|
|
||||||
|
|
||||||
RunPluginContainer Runs ansible plugin based on plugin name and container name which is derived from the tracked containers file We pass in the group ID as a parameter because when we modify the ports taken
|
|
||||||
|
|
||||||
<a name="ExecuteIP"></a>
|
|
||||||
## type [ExecuteIP](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L40-L45>)
|
|
||||||
|
|
||||||
ExecuteIP IP Address to execute Ansible instruction
|
|
||||||
|
|
||||||
```go
|
|
||||||
type ExecuteIP struct {
|
|
||||||
ContainerID string
|
|
||||||
IPAddress string
|
|
||||||
SSHPortNo string
|
|
||||||
Success bool
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<a name="ExecuteIP.ModifyHost"></a>
|
|
||||||
### func \(\*ExecuteIP\) [ModifyHost](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L234>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (e *ExecuteIP) ModifyHost(p *Plugin) error
|
|
||||||
```
|
|
||||||
|
|
||||||
ModifyHost adds IP address , port no to the config file
|
|
||||||
|
|
||||||
<a name="ExecuteIP.RunAnsible"></a>
|
|
||||||
### func \(\*ExecuteIP\) [RunAnsible](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L199>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (e *ExecuteIP) RunAnsible(p *Plugin) error
|
|
||||||
```
|
|
||||||
|
|
||||||
RunAnsible Executes based on credentials on the struct
|
|
||||||
|
|
||||||
<a name="Host"></a>
|
|
||||||
## type [Host](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L49-L66>)
|
|
||||||
|
|
||||||
Host Struct for ansible host Generated from https://zhwt.github.io/yaml-to-go/
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Host struct {
|
|
||||||
All struct {
|
|
||||||
Vars struct {
|
|
||||||
AnsiblePythonInterpreter string `yaml:"ansible_python_interpreter"`
|
|
||||||
} `yaml:"vars"`
|
|
||||||
} `yaml:"all"`
|
|
||||||
Main struct {
|
|
||||||
Hosts struct {
|
|
||||||
Host1 struct {
|
|
||||||
AnsibleHost string `yaml:"ansible_host"`
|
|
||||||
AnsiblePort int `yaml:"ansible_port"`
|
|
||||||
AnsibleUser string `yaml:"ansible_user"`
|
|
||||||
AnsibleSSHPass string `yaml:"ansible_ssh_pass"`
|
|
||||||
AnsibleSudoPass string `yaml:"ansible_sudo_pass"`
|
|
||||||
} `yaml:"host1"`
|
|
||||||
} `yaml:"hosts"`
|
|
||||||
} `yaml:"main"`
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<a name="ReadHost"></a>
|
|
||||||
### func [ReadHost](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L266>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func ReadHost(filename string) (*Host, error)
|
|
||||||
```
|
|
||||||
|
|
||||||
ReadHost Reads host file and adds
|
|
||||||
|
|
||||||
<a name="Plugin"></a>
|
|
||||||
## type [Plugin](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L31-L37>)
|
|
||||||
|
|
||||||
Plugin Information about the plugins available
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Plugin struct {
|
|
||||||
FolderName string
|
|
||||||
PluginDescription string
|
|
||||||
|
|
||||||
Execute []*ExecuteIP
|
|
||||||
NumOfPorts int
|
|
||||||
// contains filtered or unexported fields
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<a name="RunPlugin"></a>
|
|
||||||
### func [RunPlugin](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L131>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func RunPlugin(pluginName string, IPAddresses []*ExecuteIP) (*Plugin, error)
|
|
||||||
```
|
|
||||||
|
|
||||||
RunPlugin Executes plugins based on the plugin name provided
|
|
||||||
|
|
||||||
<a name="SearchPlugin"></a>
|
|
||||||
### func [SearchPlugin](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L114>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func SearchPlugin(pluginname string) (*Plugin, error)
|
|
||||||
```
|
|
||||||
|
|
||||||
SearchPlugin Detects plugin information based on the name provided on the parameter
|
|
||||||
|
|
||||||
<a name="Plugin.AutoSetPorts"></a>
|
|
||||||
### func \(\*Plugin\) [AutoSetPorts](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L383>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (p *Plugin) AutoSetPorts(containerID string) error
|
|
||||||
```
|
|
||||||
|
|
||||||
AutoSetPorts Automatically maps free ports to site.yml file
|
|
||||||
|
|
||||||
<a name="Plugin.CopyToTmpPlugin"></a>
|
|
||||||
### func \(\*Plugin\) [CopyToTmpPlugin](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L366>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (p *Plugin) CopyToTmpPlugin() error
|
|
||||||
```
|
|
||||||
|
|
||||||
CopyToTmpPlugin This function would ensure that we create a copy of the plugin in the tmp directory, and it would be executed from there. This due to the reason of automating port allocation when running plugins
|
|
||||||
|
|
||||||
<a name="Plugin.ExecutePlugin"></a>
|
|
||||||
### func \(\*Plugin\) [ExecutePlugin](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L174>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (p *Plugin) ExecutePlugin() error
|
|
||||||
```
|
|
||||||
|
|
||||||
ExecutePlugin Function to execute plugins that are called
|
|
||||||
|
|
||||||
<a name="Plugin.NumPorts"></a>
|
|
||||||
### func \(\*Plugin\) [NumPorts](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L446>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (p *Plugin) NumPorts() error
|
|
||||||
```
|
|
||||||
|
|
||||||
NumPorts Gets the Number the ports the plugin requires
|
|
||||||
|
|
||||||
<a name="Plugins"></a>
|
|
||||||
## type [Plugins](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L26-L28>)
|
|
||||||
|
|
||||||
Plugins Array of all plugins detected
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Plugins struct {
|
|
||||||
PluginsDetected []*Plugin
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<a name="DetectPlugins"></a>
|
|
||||||
### func [DetectPlugins](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/plugin/plugin.go#L69>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func DetectPlugins() (*Plugins, error)
|
|
||||||
```
|
|
||||||
|
|
||||||
DetectPlugins Detects all the plugins available
|
|
||||||
|
|
||||||
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
cp -r plugin/TestAnsible/ plugin/deploy/
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
package plugin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
|
||||||
"github.com/go-git/go-git/v5"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DownloadPlugin This functions downloads package from
|
|
||||||
// a git repo.
|
|
||||||
func DownloadPlugin(pluginurl string) error {
|
|
||||||
// paring plugin url
|
|
||||||
u, err := url.Parse(pluginurl)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
path := u.Path
|
|
||||||
// Trim first character of the string
|
|
||||||
path = path[1:]
|
|
||||||
// trim last element of the string
|
|
||||||
path = path[:len(path)-1]
|
|
||||||
// Replaces / with _
|
|
||||||
folder := strings.Replace(path, "/", "_", -1)
|
|
||||||
// Reads plugin path from the config path
|
|
||||||
config, err := config.ConfigInit(nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// clones a repo and stores it at the plugin directory
|
|
||||||
_, err = git.PlainClone(config.PluginPath+"/"+folder, false, &git.CloneOptions{
|
|
||||||
URL: pluginurl,
|
|
||||||
Progress: os.Stdout,
|
|
||||||
})
|
|
||||||
// returns error if raised
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeletePlugin The following function deletes a plugin based on
|
|
||||||
// the plugin name provided.
|
|
||||||
func DeletePlugin(pluginname string) error {
|
|
||||||
config, err := config.ConfigInit(nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin, err := SearchPlugin(pluginname)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the directory holding the plugin
|
|
||||||
err = os.RemoveAll(config.PluginPath + "/" + plugin.FolderName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
464
plugin/plugin.go
464
plugin/plugin.go
@@ -1,464 +0,0 @@
|
|||||||
package plugin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/client"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"gopkg.in/yaml.v2"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/apenella/go-ansible/pkg/execute"
|
|
||||||
"github.com/apenella/go-ansible/pkg/options"
|
|
||||||
"github.com/apenella/go-ansible/pkg/playbook"
|
|
||||||
"github.com/apenella/go-ansible/pkg/stdoutcallback/results"
|
|
||||||
"github.com/otiai10/copy"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Plugins Array of all plugins detected
|
|
||||||
type Plugins struct {
|
|
||||||
PluginsDetected []*Plugin
|
|
||||||
}
|
|
||||||
|
|
||||||
// Plugin Information about the plugins available
|
|
||||||
type Plugin struct {
|
|
||||||
FolderName string
|
|
||||||
PluginDescription string
|
|
||||||
path string
|
|
||||||
Execute []*ExecuteIP
|
|
||||||
NumOfPorts int
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExecuteIP IP Address to execute Ansible instruction
|
|
||||||
type ExecuteIP struct {
|
|
||||||
ContainerID string
|
|
||||||
IPAddress string
|
|
||||||
SSHPortNo string
|
|
||||||
Success bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Host Struct for ansible host
|
|
||||||
// Generated from https://zhwt.github.io/yaml-to-go/
|
|
||||||
type Host struct {
|
|
||||||
All struct {
|
|
||||||
Vars struct {
|
|
||||||
AnsiblePythonInterpreter string `yaml:"ansible_python_interpreter"`
|
|
||||||
} `yaml:"vars"`
|
|
||||||
} `yaml:"all"`
|
|
||||||
Main struct {
|
|
||||||
Hosts struct {
|
|
||||||
Host1 struct {
|
|
||||||
AnsibleHost string `yaml:"ansible_host"`
|
|
||||||
AnsiblePort int `yaml:"ansible_port"`
|
|
||||||
AnsibleUser string `yaml:"ansible_user"`
|
|
||||||
AnsibleSSHPass string `yaml:"ansible_ssh_pass"`
|
|
||||||
AnsibleSudoPass string `yaml:"ansible_sudo_pass"`
|
|
||||||
} `yaml:"host1"`
|
|
||||||
} `yaml:"hosts"`
|
|
||||||
} `yaml:"main"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DetectPlugins Detects all the plugins available
|
|
||||||
func DetectPlugins() (*Plugins, error) {
|
|
||||||
config, err := config.ConfigInit(nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
folders, err := ioutil.ReadDir(config.PluginPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var plugins *Plugins = new(Plugins)
|
|
||||||
|
|
||||||
for _, f := range folders {
|
|
||||||
if f.IsDir() {
|
|
||||||
//Declare variable plugin of type Plugin
|
|
||||||
var plugin Plugin
|
|
||||||
|
|
||||||
// Setting name of folder to plugin
|
|
||||||
plugin.FolderName = f.Name()
|
|
||||||
// Getting Description from file description.txt
|
|
||||||
Description, err := ioutil.ReadFile(config.PluginPath + "/" + plugin.FolderName + "/description.txt")
|
|
||||||
// if we os.Open returns an error then handle it
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Description from description.txt
|
|
||||||
plugin.PluginDescription = string(Description)
|
|
||||||
// Set plugin path
|
|
||||||
plugin.path = config.PluginPath + "/" + plugin.FolderName
|
|
||||||
|
|
||||||
plugins.PluginsDetected = append(plugins.PluginsDetected, &plugin)
|
|
||||||
// Get the number of ports the plugin needs
|
|
||||||
err = plugin.NumPorts()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return plugins, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SearchPlugin Detects plugin information based on the
|
|
||||||
// name provided on the parameter
|
|
||||||
func SearchPlugin(pluginname string) (*Plugin, error) {
|
|
||||||
plugins, err := DetectPlugins()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop ot find the plugin name that matches
|
|
||||||
for _, plugin := range plugins.PluginsDetected {
|
|
||||||
if pluginname == plugin.FolderName {
|
|
||||||
return plugin, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, errors.New("plugin not detected")
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunPlugin Executes plugins based on the plugin name provided
|
|
||||||
func RunPlugin(pluginName string, IPAddresses []*ExecuteIP) (*Plugin, error) {
|
|
||||||
plugins, err := DetectPlugins()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variable to store struct information about the plugin
|
|
||||||
var plugindetected *Plugin
|
|
||||||
for _, plugin := range plugins.PluginsDetected {
|
|
||||||
if plugin.FolderName == pluginName {
|
|
||||||
plugindetected = plugin
|
|
||||||
plugindetected.Execute = IPAddresses
|
|
||||||
// Get Execute plugin path from config file
|
|
||||||
config, err := config.ConfigInit(nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
plugindetected.path = config.PluginPath
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if plugindetected == nil {
|
|
||||||
return nil, errors.New("Plugin not detected")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create copy of the plugin the tmp directory
|
|
||||||
// To ensure we execute the plugin from there
|
|
||||||
err = plugindetected.CopyToTmpPlugin()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Executing the plugin
|
|
||||||
err = plugindetected.ExecutePlugin()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return plugindetected, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExecutePlugin Function to execute plugins that are called
|
|
||||||
func (p *Plugin) ExecutePlugin() error {
|
|
||||||
|
|
||||||
// Run ip address to execute ansible inside
|
|
||||||
for _, execute := range p.Execute {
|
|
||||||
// Modify ansible hosts before executing
|
|
||||||
err := execute.ModifyHost(p)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// sets the ports to the plugin folder
|
|
||||||
err = p.AutoSetPorts(execute.ContainerID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = execute.RunAnsible(p)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// If ran successfully then change success flag to true
|
|
||||||
execute.Success = true
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunAnsible Executes based on credentials on the struct
|
|
||||||
func (e *ExecuteIP) RunAnsible(p *Plugin) error {
|
|
||||||
ansiblePlaybookConnectionOptions := &options.AnsibleConnectionOptions{
|
|
||||||
User: "master",
|
|
||||||
}
|
|
||||||
|
|
||||||
ansiblePlaybookOptions := &playbook.AnsiblePlaybookOptions{
|
|
||||||
Inventory: p.path + "/" + p.FolderName + "/hosts",
|
|
||||||
ExtraVars: map[string]interface{}{"ansible_ssh_common_args": "-o StrictHostKeyChecking=no"},
|
|
||||||
}
|
|
||||||
|
|
||||||
ansiblePlaybookPrivilegeEscalationOptions := &options.AnsiblePrivilegeEscalationOptions{
|
|
||||||
Become: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
playbook := &playbook.AnsiblePlaybookCmd{
|
|
||||||
Playbooks: []string{p.path + "/" + p.FolderName + "/site.yml"},
|
|
||||||
ConnectionOptions: ansiblePlaybookConnectionOptions,
|
|
||||||
PrivilegeEscalationOptions: ansiblePlaybookPrivilegeEscalationOptions,
|
|
||||||
Options: ansiblePlaybookOptions,
|
|
||||||
Exec: execute.NewDefaultExecute(
|
|
||||||
execute.WithTransformers(
|
|
||||||
results.Prepend("success"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := playbook.Run(context.TODO())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ModifyHost adds IP address , port no to the config file
|
|
||||||
func (e *ExecuteIP) ModifyHost(p *Plugin) error {
|
|
||||||
host, err := ReadHost(p.path + "/" + p.FolderName + "/hosts")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Setting ansible host
|
|
||||||
host.Main.Hosts.Host1.AnsibleHost = e.IPAddress
|
|
||||||
// Setting SSH port no
|
|
||||||
host.Main.Hosts.Host1.AnsiblePort, err = strconv.Atoi(e.SSHPortNo)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Setting SSH user name
|
|
||||||
host.Main.Hosts.Host1.AnsibleUser = "master"
|
|
||||||
// Setting SSH password
|
|
||||||
host.Main.Hosts.Host1.AnsibleSSHPass = "password"
|
|
||||||
// Setting SSH sudo password
|
|
||||||
host.Main.Hosts.Host1.AnsibleSudoPass = "password"
|
|
||||||
|
|
||||||
// write modified information to the hosts yaml file
|
|
||||||
data, err := yaml.Marshal(host)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = ioutil.WriteFile(p.path+"/"+p.FolderName+"/hosts", data, 0777)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadHost Reads host file and adds
|
|
||||||
func ReadHost(filename string) (*Host, error) {
|
|
||||||
buf, err := ioutil.ReadFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
c := &Host{}
|
|
||||||
err = yaml.Unmarshal(buf, c)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("in file %q: %v", filename, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunPluginContainer Runs ansible plugin based on plugin name and container name which
|
|
||||||
// is derived from the tracked containers file
|
|
||||||
// We pass in the group ID as a parameter because when we modify the ports taken
|
|
||||||
func RunPluginContainer(PluginName string, ContainerID string) error {
|
|
||||||
// Gets container information based on container ID
|
|
||||||
ContainerInformation, err := client.GetContainerInformation(ContainerID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setting Up IP's for which the plugins will be executed
|
|
||||||
var ExecuteIPs []*ExecuteIP
|
|
||||||
var ExecuteIP ExecuteIP
|
|
||||||
// Getting port no of SSH port
|
|
||||||
for _, port := range ContainerInformation.Container.Ports.PortSet {
|
|
||||||
if port.PortName == "SSH" {
|
|
||||||
ExecuteIP.SSHPortNo = fmt.Sprint(port.ExternalPort)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Handle error if SSH port is not provided
|
|
||||||
if ExecuteIP.SSHPortNo == "" {
|
|
||||||
return errors.New("SSH port not found")
|
|
||||||
}
|
|
||||||
// Split the port no from ip address since current the IP address
|
|
||||||
// field is populated as
|
|
||||||
// <ip address>:<port no>
|
|
||||||
|
|
||||||
host, _, err := net.SplitHostPort(ContainerInformation.IpAddress)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// IP address of the container
|
|
||||||
ExecuteIP.IPAddress = host
|
|
||||||
// Set container ID to ExecutorIP
|
|
||||||
ExecuteIP.ContainerID = ContainerInformation.Id
|
|
||||||
// Append IP to list of executor IP
|
|
||||||
ExecuteIPs = append(ExecuteIPs, &ExecuteIP)
|
|
||||||
// Run plugin to execute plugin
|
|
||||||
_, err = RunPlugin(PluginName, ExecuteIPs)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckRunPlugin Checks if the ID belongs to the group or container
|
|
||||||
// calls the plugin function the appropriate amount of times
|
|
||||||
func CheckRunPlugin(PluginName string, ID string) error {
|
|
||||||
// Check if the ID belongs to the group or container ID
|
|
||||||
id, err := client.CheckID(ID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// When the ID belongs to a group
|
|
||||||
if id == "group" {
|
|
||||||
// gets the group information
|
|
||||||
group, err := client.GetGroup(ID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Iterate through each container information in the group
|
|
||||||
// and run the plugin in each of them
|
|
||||||
for _, container := range group.TrackContainerList {
|
|
||||||
// runs plugin for each container
|
|
||||||
err := RunPluginContainer(PluginName, container.Id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { // This means the following ID is a container ID
|
|
||||||
err := RunPluginContainer(PluginName, ID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyToTmpPlugin This function would ensure that we create a copy of the
|
|
||||||
// plugin in the tmp directory, and it would be executed
|
|
||||||
// from there. This due to the reason of automating port allocation
|
|
||||||
// when running plugins
|
|
||||||
func (p *Plugin) CopyToTmpPlugin() 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(p.path+"/"+p.FolderName, "/tmp/"+id.String()+"_"+p.FolderName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the plugin execution to the tmp location
|
|
||||||
p.path = "/tmp"
|
|
||||||
p.FolderName = id.String() + "_" + p.FolderName
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AutoSetPorts Automatically maps free ports to site.yml file
|
|
||||||
func (p *Plugin) AutoSetPorts(containerID string) error {
|
|
||||||
container, err := client.GetContainerInformation(containerID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// variable that would have a list of ports
|
|
||||||
// to be allocated to the plugin system
|
|
||||||
var ports []int
|
|
||||||
// Counted that increments when a port is taken
|
|
||||||
PortTaken := 0
|
|
||||||
// setting all external ports available in an array
|
|
||||||
for i, port := range container.Container.Ports.PortSet {
|
|
||||||
if port.IsUsed == false {
|
|
||||||
// Ensuring we break outside the loop once the ports
|
|
||||||
// are set.
|
|
||||||
if PortTaken >= p.NumOfPorts {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// Setting the following port flag to true
|
|
||||||
container.Container.Ports.PortSet[i].IsUsed = true
|
|
||||||
// Incrementing the variable PortTaken
|
|
||||||
PortTaken++
|
|
||||||
// Maps to internal since
|
|
||||||
// Inside the machine
|
|
||||||
// internal port -> (maps) same internal port
|
|
||||||
// TURN (i.e FRP) based approach (internal port -> maps to different external port)
|
|
||||||
ports = append(ports, port.InternalPort)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// parses the site.yml file in the tmp directory
|
|
||||||
t, err := template.ParseFiles(p.path + "/" + p.FolderName + "/site.yml")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// opens the output file
|
|
||||||
f, err := os.Create(p.path + "/" + p.FolderName + "/site.yml")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// sends the ports to the site.yml file to populate them
|
|
||||||
err = t.Execute(f, ports)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Once the following is done set port to taken
|
|
||||||
// n tracked container list
|
|
||||||
err = container.ModifyContainerInformation()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Once the following is done set port to taken
|
|
||||||
// I(Groups)
|
|
||||||
err = container.ModifyContainerGroups()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NumPorts Gets the Number the ports the
|
|
||||||
// plugin requires
|
|
||||||
func (p *Plugin) NumPorts() error {
|
|
||||||
jsonFile, err := os.Open(p.path + "/ports.json")
|
|
||||||
// if we os.Open returns an error then handle it
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// defer the closing of our jsonFile so that we can parse it later on
|
|
||||||
defer jsonFile.Close()
|
|
||||||
|
|
||||||
// read our opened xmlFile as a byte array.
|
|
||||||
byteValue, _ := ioutil.ReadAll(jsonFile)
|
|
||||||
|
|
||||||
// we unmarshal our byteArray which contains our
|
|
||||||
// jsonFile's content into 'users' which we defined above
|
|
||||||
json.Unmarshal(byteValue, &p)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,257 +0,0 @@
|
|||||||
package plugin
|
|
||||||
|
|
||||||
// import (
|
|
||||||
// "fmt"
|
|
||||||
// "github.com/Akilan1999/p2p-rendering-computation/client"
|
|
||||||
// "github.com/Akilan1999/p2p-rendering-computation/config"
|
|
||||||
// "github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
|
||||||
// "net"
|
|
||||||
// "strconv"
|
|
||||||
// "testing"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// // Test if the dummy plugin added is detected
|
|
||||||
// func TestDetectPlugins(t *testing.T) {
|
|
||||||
// _, err := DetectPlugins()
|
|
||||||
// if err != nil {
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Test ensures that the ansible are executed inside local containers
|
|
||||||
// func TestRunPlugin(t *testing.T) {
|
|
||||||
// var testips []*ExecuteIP
|
|
||||||
// var testip1, testip2 ExecuteIP
|
|
||||||
//
|
|
||||||
// // Create docker container and get SSH port
|
|
||||||
// container1, err := docker.BuildRunContainer(0, "false", "")
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// //Test IP 1 configuration
|
|
||||||
// testip1.IPAddress = "0.0.0.0"
|
|
||||||
// testip1.SSHPortNo = strconv.Itoa(container1.Ports.PortSet[0].ExternalPort)
|
|
||||||
//
|
|
||||||
// // Create docker container and get SSH port
|
|
||||||
// container2, err := docker.BuildRunContainer(0, "false", "")
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
// //Test IP 2 configuration
|
|
||||||
// testip2.IPAddress = "0.0.0.0"
|
|
||||||
// testip2.SSHPortNo = strconv.Itoa(container2.Ports.PortSet[0].ExternalPort)
|
|
||||||
//
|
|
||||||
// testips = append(testips, &testip1)
|
|
||||||
// testips = append(testips, &testip2)
|
|
||||||
//
|
|
||||||
// _, err = RunPlugin("TestAnsible", testips)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Removing container1 after Ansible is executed
|
|
||||||
// err = docker.StopAndRemoveContainer(container1.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// err = docker.StopAndRemoveContainer(container2.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Test to ensure that the ansible host file is modified to
|
|
||||||
// // the appropriate IP
|
|
||||||
// func TestExecuteIP_ModifyHost(t *testing.T) {
|
|
||||||
// var plugin Plugin
|
|
||||||
// var testip ExecuteIP
|
|
||||||
//
|
|
||||||
// // Get plugin path from config file
|
|
||||||
// Config, err := config.ConfigInit(nil, nil)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
// //Set plugin name
|
|
||||||
// plugin.FolderName = "TestAnsible"
|
|
||||||
// plugin.path = Config.PluginPath
|
|
||||||
//
|
|
||||||
// //Test IP 1 configuration
|
|
||||||
// testip.IPAddress = "0.0.0.0"
|
|
||||||
// testip.SSHPortNo = "41289"
|
|
||||||
//
|
|
||||||
// err = testip.ModifyHost(&plugin)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Test to ensure the cli function runs as intended and executes
|
|
||||||
// // the test ansible script
|
|
||||||
// func TestRunPluginContainer(t *testing.T) {
|
|
||||||
// // Create docker container and get SSH port
|
|
||||||
// container1, err := docker.BuildRunContainer(0, "false", "")
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Ensuring created container is the added to the tracked list
|
|
||||||
// err = client.AddTrackContainer(container1, "0.0.0.0")
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Running test Ansible script
|
|
||||||
// err = RunPluginContainer("TestAnsible", container1.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Removes container information from the tracker IP addresses
|
|
||||||
// err = client.RemoveTrackedContainer(container1.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Removing container1 after Ansible is executed
|
|
||||||
// err = docker.StopAndRemoveContainer(container1.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Testing the function can plugin can run with
|
|
||||||
// // group ID and container ID
|
|
||||||
// func TestCheckRunPlugin(t *testing.T) {
|
|
||||||
// // Create docker container and get SSH port
|
|
||||||
// container1, err := docker.BuildRunContainer(0, "false", "")
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
// // Create docker container and get SSH port
|
|
||||||
// container2, err := docker.BuildRunContainer(0, "false", "")
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Ensuring created container1 is the added to the tracked list
|
|
||||||
// err = client.AddTrackContainer(container1, "0.0.0.0")
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
// // Ensuring created container2 is the added to the tracked list
|
|
||||||
// err = client.AddTrackContainer(container2, "0.0.0.0")
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Create group to add created containers
|
|
||||||
// group, err := client.CreateGroup()
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Add container 1 to the group
|
|
||||||
// _, err = client.AddContainerToGroup(container1.ID, group.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Add container 2 to the group
|
|
||||||
// _, err = client.AddContainerToGroup(container2.ID, group.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // -------------------------- Main test cases -------------------------------
|
|
||||||
//
|
|
||||||
// // Checking function against container ID
|
|
||||||
// err = CheckRunPlugin("TestAnsible", container1.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Checking function against group ID
|
|
||||||
// err = CheckRunPlugin("TestAnsible", group.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // ----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// // Remove created group
|
|
||||||
// err = client.RemoveGroup(group.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Removes container1 information from the tracker IP addresses
|
|
||||||
// err = client.RemoveTrackedContainer(container1.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Removing container1 after Ansible is executed
|
|
||||||
// err = docker.StopAndRemoveContainer(container1.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Removes container2 information from the tracker IP addresses
|
|
||||||
// err = client.RemoveTrackedContainer(container2.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Removing container2 after Ansible is executed
|
|
||||||
// err = docker.StopAndRemoveContainer(container2.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// t.Fail()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func TestDownloadPlugin(t *testing.T) {
|
|
||||||
// err := DownloadPlugin("https://github.com/Akilan1999/laplace/")
|
|
||||||
// if err != nil {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Simple test case implemented to the test if
|
|
||||||
// // the port no can be extracted from the IP address.
|
|
||||||
// func TestParseIP(t *testing.T) {
|
|
||||||
// host, port, err := net.SplitHostPort("12.34.23.13:5432")
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Printf("Error: %v\n", err)
|
|
||||||
// } else {
|
|
||||||
// fmt.Printf("Host: %s\nPort: %s\n", host, port)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
BIN
server/docker/.DS_Store
vendored
BIN
server/docker/.DS_Store
vendored
Binary file not shown.
@@ -1,12 +0,0 @@
|
|||||||
SHELL := /bin/bash
|
|
||||||
|
|
||||||
.PHONY: set_virtualenv,install_docker_requirements,dockerproc
|
|
||||||
|
|
||||||
set_virtualenv:
|
|
||||||
virtualenv env
|
|
||||||
|
|
||||||
install_docker_requirements:
|
|
||||||
source env/bin/activate && pip install -r requirements.txt
|
|
||||||
|
|
||||||
dockerproc:
|
|
||||||
ADMIN_USER=admin ADMIN_PASSWORD=admin docker-compose -f dockprom/docker-compose.yml up -d
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
Docker Module P2P-rendering-computation
|
|
||||||
========================================
|
|
||||||
|
|
||||||
This module is incharge to spin up docker contaianers , create
|
|
||||||
SSH server and VNC server. This module is implemented using
|
|
||||||
python.
|
|
||||||
@@ -1,508 +0,0 @@
|
|||||||
package docker
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
|
||||||
"github.com/docker/docker/client"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/lithammer/shortuuid"
|
|
||||||
"github.com/otiai10/copy"
|
|
||||||
"github.com/phayes/freeport"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"text/template"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DockerVM struct {
|
|
||||||
SSHUsername string `json:"SSHUsername"`
|
|
||||||
SSHPublcKey string `json:"SSHPublicKey"`
|
|
||||||
ID string `json:"ID"`
|
|
||||||
TagName string `json:"TagName"`
|
|
||||||
ImagePath string `json:"ImagePath"`
|
|
||||||
Ports Ports `json:"Ports"`
|
|
||||||
GPU string `json:"GPU"`
|
|
||||||
TempPath string
|
|
||||||
BaseImage string
|
|
||||||
LogsPath string
|
|
||||||
SSHCommand string `json:"SSHCommand"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DockerContainers struct {
|
|
||||||
DockerContainer []DockerContainer `json:"DockerContainer"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DockerContainer struct {
|
|
||||||
ContainerName string `json:"DockerContainerName"`
|
|
||||||
ContainerDescription string `json:"ContainerDescription"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Ports struct {
|
|
||||||
PortSet []Port `json:"Port"`
|
|
||||||
}
|
|
||||||
type Port struct {
|
|
||||||
PortName string `json:"PortName"`
|
|
||||||
InternalPort int `json:"InternalPort"`
|
|
||||||
Type string `json:"Type"`
|
|
||||||
ExternalPort int `json:"ExternalPort"`
|
|
||||||
IsUsed bool `json:"IsUsed"`
|
|
||||||
Description string `json:"Description"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ErrorLine struct {
|
|
||||||
Error string `json:"error"`
|
|
||||||
ErrorDetail ErrorDetail `json:"errorDetail"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ErrorDetail struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var dockerRegistryUserID = ""
|
|
||||||
|
|
||||||
// BuildRunContainer Function is incharge to invoke building and running contianer and also allocating external
|
|
||||||
// ports
|
|
||||||
func BuildRunContainer(NumPorts int, GPU string, ContainerName string, baseImage string, publicKey string) (*DockerVM, error) {
|
|
||||||
//Docker Struct Variable
|
|
||||||
var RespDocker *DockerVM = new(DockerVM)
|
|
||||||
|
|
||||||
// Sets if GPU is selected or not
|
|
||||||
RespDocker.GPU = GPU
|
|
||||||
|
|
||||||
// Get config informatopn
|
|
||||||
|
|
||||||
// Sets Free port to Struct
|
|
||||||
//RespDocker.SSHPort = Ports[0]
|
|
||||||
//RespDocker.VNCPort = Ports[1]
|
|
||||||
// Sets appropriate username and password to the
|
|
||||||
// variables in the struct
|
|
||||||
RespDocker.SSHUsername = "root"
|
|
||||||
//RespDocker.BaseImage = "ubuntu:20.04"
|
|
||||||
//RespDocker.VNCPassword = "vncpassword"
|
|
||||||
|
|
||||||
//Default parameters
|
|
||||||
RespDocker.TagName = "p2p-ubuntu"
|
|
||||||
// Get Path from config
|
|
||||||
config, err := config.ConfigInit(nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
RespDocker.ImagePath = config.DefaultDockerFile
|
|
||||||
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
|
|
||||||
// which is docker-ubuntu-sshd
|
|
||||||
if ContainerName != "" && ContainerName != "docker-ubuntu-sshd" {
|
|
||||||
Containers, err := ViewAllContainers()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, dockerContainer := range Containers.DockerContainer {
|
|
||||||
if dockerContainer.ContainerName == ContainerName {
|
|
||||||
RespDocker.ImagePath = config.DockerContainers + ContainerName + "/"
|
|
||||||
RespDocker.TagName = ContainerName
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if RespDocker.ImagePath == config.DefaultDockerFile {
|
|
||||||
return nil, errors.New("Container " + ContainerName + " does not exist in the server")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checking if the base image is provided
|
|
||||||
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 {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Number of perts we want to open + number of ports required inside the
|
|
||||||
// docker container
|
|
||||||
count := NumPorts + len(PortsInformation.PortSet)
|
|
||||||
// Creates number of ports
|
|
||||||
OpenPorts, err := freeport.GetFreePorts(count)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// Allocate external ports to ports available in the ports.json file
|
|
||||||
for i := range PortsInformation.PortSet {
|
|
||||||
// Setting external ports
|
|
||||||
PortsInformation.PortSet[i].ExternalPort = OpenPorts[i]
|
|
||||||
PortsInformation.PortSet[i].IsUsed = true
|
|
||||||
}
|
|
||||||
//Length of Ports allocated from thr port file
|
|
||||||
portFileLength := len(PortsInformation.PortSet)
|
|
||||||
// Allocate New ports the user wants to generate
|
|
||||||
for i := 0; i < NumPorts; i++ {
|
|
||||||
var TempPort Port
|
|
||||||
TempPort.PortName = "AutoGen Port"
|
|
||||||
TempPort.Type = "tcp"
|
|
||||||
TempPort.InternalPort = OpenPorts[portFileLength+i]
|
|
||||||
TempPort.ExternalPort = OpenPorts[portFileLength+i]
|
|
||||||
TempPort.Description = "Auto generated TCP port"
|
|
||||||
TempPort.IsUsed = false
|
|
||||||
//Append temp port to port information
|
|
||||||
PortsInformation.PortSet = append(PortsInformation.PortSet, TempPort)
|
|
||||||
}
|
|
||||||
// Setting ports to the docker VM struct
|
|
||||||
RespDocker.Ports = *PortsInformation
|
|
||||||
|
|
||||||
// Gets docker information from env variables
|
|
||||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds docker image
|
|
||||||
err = RespDocker.imageBuild(cli)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Runs docker contianer
|
|
||||||
err = RespDocker.runContainer(cli)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return RespDocker, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds docker image (TODO: relative path for Dockerfile deploy)
|
|
||||||
func (d *DockerVM) imageBuild(dockerClient *client.Client) error {
|
|
||||||
//ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
|
|
||||||
//defer cancel()
|
|
||||||
|
|
||||||
var cmd bytes.Buffer
|
|
||||||
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 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
//tar, err := archive.TarWithOptions(d.ImagePath+"/"+d.TagName, &archive.TarOptions{})
|
|
||||||
//if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//opts := types.ImageBuildOptions{
|
|
||||||
// Dockerfile: "Dockerfile",
|
|
||||||
// Tags: []string{d.TagName},
|
|
||||||
// Remove: true,
|
|
||||||
//}
|
|
||||||
//res, err := dockerClient.ImageBuild(ctx, tar, opts)
|
|
||||||
//if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//defer res.Body.Close()
|
|
||||||
//
|
|
||||||
//err = print(res.Body)
|
|
||||||
//if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Starts container and assigns port numbers
|
|
||||||
// Sample Docker run Command
|
|
||||||
// docker run -d=true --name=Test123 --restart=always --gpus all
|
|
||||||
// -p 3443:6901 -p 3453:22 -p 3434:3434 -p 3245:3245 -v=/opt/data:/data
|
|
||||||
// p2p-ubuntu /start > /dev/null
|
|
||||||
func (d *DockerVM) runContainer(dockerClient *client.Client) error {
|
|
||||||
//ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
|
|
||||||
|
|
||||||
// The first mode runs using the Docker Api. As the API supports using
|
|
||||||
// CPU and uses a shell script for GPU call because till this point of
|
|
||||||
// implementation docker api does not support the flag "--gpu all"
|
|
||||||
//if d.GPU != "true" {
|
|
||||||
// //Exposed ports for docker config file
|
|
||||||
// var ExposedPort nat.PortSet
|
|
||||||
//
|
|
||||||
// ExposedPort = nat.PortSet{
|
|
||||||
// "22/tcp": struct{}{},
|
|
||||||
// //"6901/tcp": struct{}{},
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Port forwarding for VNC and SSH ports
|
|
||||||
// PortForwarding := nat.PortMap{
|
|
||||||
// //"22/tcp": []nat.PortBinding{
|
|
||||||
// // {
|
|
||||||
// // HostIP: "0.0.0.0",
|
|
||||||
// // HostPort: fmt.Sprint(d.SSHPort),
|
|
||||||
// // },
|
|
||||||
// //},
|
|
||||||
// //"6901/tcp": []nat.PortBinding{
|
|
||||||
// // {
|
|
||||||
// // HostIP: "0.0.0.0",
|
|
||||||
// // HostPort: fmt.Sprint(d.VNCPort),
|
|
||||||
// // },
|
|
||||||
// //},
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for i := range d.Ports.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 ")
|
|
||||||
if d.GPU == "true" {
|
|
||||||
cmd.WriteString("--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=/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
|
|
||||||
}
|
|
||||||
|
|
||||||
// StopAndRemoveContainer
|
|
||||||
// Stop and remove a container
|
|
||||||
// Reference (https://gist.github.com/frikky/e2efcea6c733ea8d8d015b7fe8a91bf6)
|
|
||||||
func StopAndRemoveContainer(containername string) error {
|
|
||||||
//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
|
|
||||||
var stop bytes.Buffer
|
|
||||||
stop.WriteString("docker stop " + containername)
|
|
||||||
|
|
||||||
cmdStr := stop.String()
|
|
||||||
_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove docker container
|
|
||||||
var remove bytes.Buffer
|
|
||||||
remove.WriteString("docker remove " + containername)
|
|
||||||
|
|
||||||
cmdStr = remove.String()
|
|
||||||
|
|
||||||
_, err = exec.Command("/bin/sh", "-c", cmdStr).Output()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ViewAllContainers returns all containers runnable and which can be built
|
|
||||||
func ViewAllContainers() (*DockerContainers, error) {
|
|
||||||
// Traverse the deploy path as per given in the config file
|
|
||||||
config, err := config.ConfigInit(nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
folders, err := ioutil.ReadDir(config.DockerContainers)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
//Declare variable DockerContainers of type struct
|
|
||||||
var Containers *DockerContainers = new(DockerContainers)
|
|
||||||
|
|
||||||
for _, f := range folders {
|
|
||||||
if f.IsDir() {
|
|
||||||
//Declare variable DockerContainer of type struct
|
|
||||||
var Container DockerContainer
|
|
||||||
|
|
||||||
// Setting container name to deploy name
|
|
||||||
Container.ContainerName = f.Name()
|
|
||||||
// Getting Description from file description.txt
|
|
||||||
Description, err := ioutil.ReadFile(config.DockerContainers + "/" + Container.ContainerName + "/description.txt")
|
|
||||||
// if we os.Open returns an error then handle it
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Description from description.txt
|
|
||||||
Container.ContainerDescription = string(Description)
|
|
||||||
|
|
||||||
Containers.DockerContainer = append(Containers.DockerContainer, Container)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Containers, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func print(rd io.Reader) error {
|
|
||||||
var lastLine string
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(rd)
|
|
||||||
for scanner.Scan() {
|
|
||||||
lastLine = scanner.Text()
|
|
||||||
}
|
|
||||||
|
|
||||||
errLine := &ErrorLine{}
|
|
||||||
json.Unmarshal([]byte(lastLine), errLine)
|
|
||||||
if errLine.Error != "" {
|
|
||||||
return errors.New(errLine.Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := scanner.Err(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func OpenPortsFile(filename string) (*Ports, error) {
|
|
||||||
buf, err := ioutil.ReadFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
c := &Ports{}
|
|
||||||
err = json.Unmarshal(buf, c)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("in file %q: %v", filename, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package docker
|
|
||||||
|
|
||||||
// import (
|
|
||||||
// "testing"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// func TestDockerUbuntuSSHDProvided(t *testing.T) {
|
|
||||||
// // Testing by providing default container name
|
|
||||||
// _,err := BuildRunContainer(2,"false","docker-ubuntu-sshd")
|
|
||||||
//
|
|
||||||
// if err != nil {
|
|
||||||
// t.Error(err)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func TestDockerDefaultContainer(t *testing.T) {
|
|
||||||
// // Testing by providing without providing default container name
|
|
||||||
// _,err := BuildRunContainer(2,"false","")
|
|
||||||
//
|
|
||||||
// if err != nil {
|
|
||||||
// t.Error(err)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func TestContainerHorovod(t *testing.T) {
|
|
||||||
// // Testing by providing the horovod cpu image
|
|
||||||
// _,err := BuildRunContainer(2,"false","cpuhorovod")
|
|
||||||
//
|
|
||||||
// if err != nil {
|
|
||||||
// t.Error(err)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func TestViewAllContainers(t *testing.T) {
|
|
||||||
// _,err := ViewAllContainers()
|
|
||||||
//
|
|
||||||
// if err != nil {
|
|
||||||
// t.Error(err)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2016 Stefan Prodan
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -1,353 +0,0 @@
|
|||||||
dockprom
|
|
||||||
========
|
|
||||||
|
|
||||||
A monitoring solution for Docker hosts and containers with [Prometheus](https://prometheus.io/), [Grafana](http://grafana.org/), [cAdvisor](https://github.com/google/cadvisor),
|
|
||||||
[NodeExporter](https://github.com/prometheus/node_exporter) and alerting with [AlertManager](https://github.com/prometheus/alertmanager).
|
|
||||||
|
|
||||||
***If you're looking for the Docker Swarm version please go to [stefanprodan/swarmprom](https://github.com/stefanprodan/swarmprom)***
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
Clone this repository on your Docker host, cd into dockprom directory and run compose up:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/stefanprodan/dockprom
|
|
||||||
cd dockprom
|
|
||||||
|
|
||||||
ADMIN_USER=admin ADMIN_PASSWORD=admin docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
Prerequisites:
|
|
||||||
|
|
||||||
* Docker Engine >= 1.13
|
|
||||||
* Docker Compose >= 1.11
|
|
||||||
|
|
||||||
Containers:
|
|
||||||
|
|
||||||
* Prometheus (metrics database) `http://<host-ip>:9090`
|
|
||||||
* Prometheus-Pushgateway (push acceptor for ephemeral and batch jobs) `http://<host-ip>:9091`
|
|
||||||
* AlertManager (alerts management) `http://<host-ip>:9093`
|
|
||||||
* Grafana (visualize metrics) `http://<host-ip>:3000`
|
|
||||||
* NodeExporter (host metrics collector)
|
|
||||||
* cAdvisor (containers metrics collector)
|
|
||||||
* Caddy (reverse proxy and basic auth provider for prometheus and alertmanager)
|
|
||||||
|
|
||||||
## Setup Grafana
|
|
||||||
|
|
||||||
Navigate to `http://<host-ip>:3000` and login with user ***admin*** password ***admin***. You can change the credentials in the compose file or by supplying the `ADMIN_USER` and `ADMIN_PASSWORD` environment variables on compose up. The config file can be added directly in grafana part like this
|
|
||||||
```
|
|
||||||
grafana:
|
|
||||||
image: grafana/grafana:7.2.0
|
|
||||||
env_file:
|
|
||||||
- config
|
|
||||||
|
|
||||||
```
|
|
||||||
and the config file format should have this content
|
|
||||||
```
|
|
||||||
GF_SECURITY_ADMIN_USER=admin
|
|
||||||
GF_SECURITY_ADMIN_PASSWORD=changeme
|
|
||||||
GF_USERS_ALLOW_SIGN_UP=false
|
|
||||||
```
|
|
||||||
If you want to change the password, you have to remove this entry, otherwise the change will not take effect
|
|
||||||
```
|
|
||||||
- grafana_data:/var/lib/grafana
|
|
||||||
```
|
|
||||||
|
|
||||||
Grafana is preconfigured with dashboards and Prometheus as the default data source:
|
|
||||||
|
|
||||||
* Name: Prometheus
|
|
||||||
* Type: Prometheus
|
|
||||||
* Url: http://prometheus:9090
|
|
||||||
* Access: proxy
|
|
||||||
|
|
||||||
***Docker Host Dashboard***
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
The Docker Host Dashboard shows key metrics for monitoring the resource usage of your server:
|
|
||||||
|
|
||||||
* Server uptime, CPU idle percent, number of CPU cores, available memory, swap and storage
|
|
||||||
* System load average graph, running and blocked by IO processes graph, interrupts graph
|
|
||||||
* CPU usage graph by mode (guest, idle, iowait, irq, nice, softirq, steal, system, user)
|
|
||||||
* Memory usage graph by distribution (used, free, buffers, cached)
|
|
||||||
* IO usage graph (read Bps, read Bps and IO time)
|
|
||||||
* Network usage graph by device (inbound Bps, Outbound Bps)
|
|
||||||
* Swap usage and activity graphs
|
|
||||||
|
|
||||||
For storage and particularly Free Storage graph, you have to specify the fstype in grafana graph request.
|
|
||||||
You can find it in `grafana/dashboards/docker_host.json`, at line 480 :
|
|
||||||
|
|
||||||
"expr": "sum(node_filesystem_free_bytes{fstype=\"btrfs\"})",
|
|
||||||
|
|
||||||
I work on BTRFS, so i need to change `aufs` to `btrfs`.
|
|
||||||
|
|
||||||
You can find right value for your system in Prometheus `http://<host-ip>:9090` launching this request :
|
|
||||||
|
|
||||||
node_filesystem_free_bytes
|
|
||||||
|
|
||||||
***Docker Containers Dashboard***
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
The Docker Containers Dashboard shows key metrics for monitoring running containers:
|
|
||||||
|
|
||||||
* Total containers CPU load, memory and storage usage
|
|
||||||
* Running containers graph, system load graph, IO usage graph
|
|
||||||
* Container CPU usage graph
|
|
||||||
* Container memory usage graph
|
|
||||||
* Container cached memory usage graph
|
|
||||||
* Container network inbound usage graph
|
|
||||||
* Container network outbound usage graph
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> This dashboard doesn't show the containers that are part of the monitoring stack.
|
|
||||||
|
|
||||||
***Monitor Services Dashboard***
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
The Monitor Services Dashboard shows key metrics for monitoring the containers that make up the monitoring stack:
|
|
||||||
|
|
||||||
* Prometheus container uptime, monitoring stack total memory usage, Prometheus local storage memory chunks and series
|
|
||||||
* Container CPU usage graph
|
|
||||||
* Container memory usage graph
|
|
||||||
* Prometheus chunks to persist and persistence urgency graphs
|
|
||||||
* Prometheus chunks ops and checkpoint duration graphs
|
|
||||||
* Prometheus samples ingested rate, target scrapes and scrape duration graphs
|
|
||||||
* Prometheus HTTP requests graph
|
|
||||||
* Prometheus alerts graph
|
|
||||||
|
|
||||||
## Define alerts
|
|
||||||
|
|
||||||
Three alert groups have been setup within the [alert.rules](https://github.com/stefanprodan/dockprom/blob/master/prometheus/alert.rules) configuration file:
|
|
||||||
|
|
||||||
* Monitoring services alerts [targets](https://github.com/stefanprodan/dockprom/blob/master/prometheus/alert.rules#L2-L11)
|
|
||||||
* Docker Host alerts [host](https://github.com/stefanprodan/dockprom/blob/master/prometheus/alert.rules#L13-L40)
|
|
||||||
* Docker Containers alerts [containers](https://github.com/stefanprodan/dockprom/blob/master/prometheus/alert.rules#L42-L69)
|
|
||||||
|
|
||||||
You can modify the alert rules and reload them by making a HTTP POST call to Prometheus:
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -X POST http://admin:admin@<host-ip>:9090/-/reload
|
|
||||||
```
|
|
||||||
|
|
||||||
***Monitoring services alerts***
|
|
||||||
|
|
||||||
Trigger an alert if any of the monitoring targets (node-exporter and cAdvisor) are down for more than 30 seconds:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- alert: monitor_service_down
|
|
||||||
expr: up == 0
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: critical
|
|
||||||
annotations:
|
|
||||||
summary: "Monitor service non-operational"
|
|
||||||
description: "Service {{ $labels.instance }} is down."
|
|
||||||
```
|
|
||||||
|
|
||||||
***Docker Host alerts***
|
|
||||||
|
|
||||||
Trigger an alert if the Docker host CPU is under high load for more than 30 seconds:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- alert: high_cpu_load
|
|
||||||
expr: node_load1 > 1.5
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "Server under high load"
|
|
||||||
description: "Docker host is under high load, the avg load 1m is at {{ $value}}. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}."
|
|
||||||
```
|
|
||||||
|
|
||||||
Modify the load threshold based on your CPU cores.
|
|
||||||
|
|
||||||
Trigger an alert if the Docker host memory is almost full:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- alert: high_memory_load
|
|
||||||
expr: (sum(node_memory_MemTotal_bytes) - sum(node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes) ) / sum(node_memory_MemTotal_bytes) * 100 > 85
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "Server memory is almost full"
|
|
||||||
description: "Docker host memory usage is {{ humanize $value}}%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}."
|
|
||||||
```
|
|
||||||
|
|
||||||
Trigger an alert if the Docker host storage is almost full:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- alert: high_storage_load
|
|
||||||
expr: (node_filesystem_size_bytes{fstype="aufs"} - node_filesystem_free_bytes{fstype="aufs"}) / node_filesystem_size_bytes{fstype="aufs"} * 100 > 85
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "Server storage is almost full"
|
|
||||||
description: "Docker host storage usage is {{ humanize $value}}%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}."
|
|
||||||
```
|
|
||||||
|
|
||||||
***Docker Containers alerts***
|
|
||||||
|
|
||||||
Trigger an alert if a container is down for more than 30 seconds:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- alert: jenkins_down
|
|
||||||
expr: absent(container_memory_usage_bytes{name="jenkins"})
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: critical
|
|
||||||
annotations:
|
|
||||||
summary: "Jenkins down"
|
|
||||||
description: "Jenkins container is down for more than 30 seconds."
|
|
||||||
```
|
|
||||||
|
|
||||||
Trigger an alert if a container is using more than 10% of total CPU cores for more than 30 seconds:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- alert: jenkins_high_cpu
|
|
||||||
expr: sum(rate(container_cpu_usage_seconds_total{name="jenkins"}[1m])) / count(node_cpu_seconds_total{mode="system"}) * 100 > 10
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "Jenkins high CPU usage"
|
|
||||||
description: "Jenkins CPU usage is {{ humanize $value}}%."
|
|
||||||
```
|
|
||||||
|
|
||||||
Trigger an alert if a container is using more than 1.2GB of RAM for more than 30 seconds:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- alert: jenkins_high_memory
|
|
||||||
expr: sum(container_memory_usage_bytes{name="jenkins"}) > 1200000000
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "Jenkins high memory usage"
|
|
||||||
description: "Jenkins memory consumption is at {{ humanize $value}}."
|
|
||||||
```
|
|
||||||
|
|
||||||
## Setup alerting
|
|
||||||
|
|
||||||
The AlertManager service is responsible for handling alerts sent by Prometheus server.
|
|
||||||
AlertManager can send notifications via email, Pushover, Slack, HipChat or any other system that exposes a webhook interface.
|
|
||||||
A complete list of integrations can be found [here](https://prometheus.io/docs/alerting/configuration).
|
|
||||||
|
|
||||||
You can view and silence notifications by accessing `http://<host-ip>:9093`.
|
|
||||||
|
|
||||||
The notification receivers can be configured in [alertmanager/config.yml](https://github.com/stefanprodan/dockprom/blob/master/alertmanager/config.yml) file.
|
|
||||||
|
|
||||||
To receive alerts via Slack you need to make a custom integration by choose ***incoming web hooks*** in your Slack team app page.
|
|
||||||
You can find more details on setting up Slack integration [here](http://www.robustperception.io/using-slack-with-the-alertmanager/).
|
|
||||||
|
|
||||||
Copy the Slack Webhook URL into the ***api_url*** field and specify a Slack ***channel***.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
route:
|
|
||||||
receiver: 'slack'
|
|
||||||
|
|
||||||
receivers:
|
|
||||||
- name: 'slack'
|
|
||||||
slack_configs:
|
|
||||||
- send_resolved: true
|
|
||||||
text: "{{ .CommonAnnotations.description }}"
|
|
||||||
username: 'Prometheus'
|
|
||||||
channel: '#<channel>'
|
|
||||||
api_url: 'https://hooks.slack.com/services/<webhook-id>'
|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Sending metrics to the Pushgateway
|
|
||||||
|
|
||||||
The [pushgateway](https://github.com/prometheus/pushgateway) is used to collect data from batch jobs or from services.
|
|
||||||
|
|
||||||
To push data, simply execute:
|
|
||||||
|
|
||||||
echo "some_metric 3.14" | curl --data-binary @- http://user:password@localhost:9091/metrics/job/some_job
|
|
||||||
|
|
||||||
Please replace the `user:password` part with your user and password set in the initial configuration (default: `admin:admin`).
|
|
||||||
|
|
||||||
## Updating Grafana to v5.2.2
|
|
||||||
|
|
||||||
[In Grafana versions >= 5.1 the id of the grafana user has been changed](http://docs.grafana.org/installation/docker/#migration-from-a-previous-version-of-the-docker-container-to-5-1-or-later). Unfortunately this means that files created prior to 5.1 won’t have the correct permissions for later versions.
|
|
||||||
|
|
||||||
| Version | User | User ID |
|
|
||||||
|:-------:|:-------:|:-------:|
|
|
||||||
| < 5.1 | grafana | 104 |
|
|
||||||
| \>= 5.1 | grafana | 472 |
|
|
||||||
|
|
||||||
There are two possible solutions to this problem.
|
|
||||||
- Change ownership from 104 to 472
|
|
||||||
- Start the upgraded container as user 104
|
|
||||||
|
|
||||||
##### Specifying a user in docker-compose.yml
|
|
||||||
|
|
||||||
To change ownership of the files run your grafana container as root and modify the permissions.
|
|
||||||
|
|
||||||
First perform a `docker-compose down` then modify your docker-compose.yml to include the `user: root` option:
|
|
||||||
|
|
||||||
```
|
|
||||||
grafana:
|
|
||||||
image: grafana/grafana:5.2.2
|
|
||||||
container_name: grafana
|
|
||||||
volumes:
|
|
||||||
- grafana_data:/var/lib/grafana
|
|
||||||
- ./grafana/datasources:/etc/grafana/datasources
|
|
||||||
- ./grafana/dashboards:/etc/grafana/dashboards
|
|
||||||
- ./grafana/setup.sh:/setup.sh
|
|
||||||
entrypoint: /setup.sh
|
|
||||||
user: root
|
|
||||||
environment:
|
|
||||||
- GF_SECURITY_ADMIN_USER=${ADMIN_USER:-admin}
|
|
||||||
- GF_SECURITY_ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin}
|
|
||||||
- GF_USERS_ALLOW_SIGN_UP=false
|
|
||||||
restart: unless-stopped
|
|
||||||
expose:
|
|
||||||
- 3000
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
labels:
|
|
||||||
org.label-schema.group: "monitoring"
|
|
||||||
```
|
|
||||||
|
|
||||||
Perform a `docker-compose up -d` and then issue the following commands:
|
|
||||||
|
|
||||||
```
|
|
||||||
docker exec -it --user root grafana bash
|
|
||||||
|
|
||||||
# in the container you just started:
|
|
||||||
chown -R root:root /etc/grafana && \
|
|
||||||
chmod -R a+r /etc/grafana && \
|
|
||||||
chown -R grafana:grafana /var/lib/grafana && \
|
|
||||||
chown -R grafana:grafana /usr/share/grafana
|
|
||||||
```
|
|
||||||
|
|
||||||
To run the grafana container as `user: 104` change your `docker-compose.yml` like such:
|
|
||||||
|
|
||||||
```
|
|
||||||
grafana:
|
|
||||||
image: grafana/grafana:5.2.2
|
|
||||||
container_name: grafana
|
|
||||||
volumes:
|
|
||||||
- grafana_data:/var/lib/grafana
|
|
||||||
- ./grafana/datasources:/etc/grafana/datasources
|
|
||||||
- ./grafana/dashboards:/etc/grafana/dashboards
|
|
||||||
- ./grafana/setup.sh:/setup.sh
|
|
||||||
entrypoint: /setup.sh
|
|
||||||
user: "104"
|
|
||||||
environment:
|
|
||||||
- GF_SECURITY_ADMIN_USER=${ADMIN_USER:-admin}
|
|
||||||
- GF_SECURITY_ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin}
|
|
||||||
- GF_USERS_ALLOW_SIGN_UP=false
|
|
||||||
restart: unless-stopped
|
|
||||||
expose:
|
|
||||||
- 3000
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
labels:
|
|
||||||
org.label-schema.group: "monitoring"
|
|
||||||
```
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
route:
|
|
||||||
receiver: 'slack'
|
|
||||||
|
|
||||||
receivers:
|
|
||||||
- name: 'slack'
|
|
||||||
slack_configs:
|
|
||||||
- send_resolved: true
|
|
||||||
text: "{{ .CommonAnnotations.description }}"
|
|
||||||
username: 'Prometheus'
|
|
||||||
channel: '#<channel-name>'
|
|
||||||
api_url: 'https://hooks.slack.com/services/<webhook-id>'
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
:9090 {
|
|
||||||
proxy / prometheus:9090 {
|
|
||||||
transparent
|
|
||||||
}
|
|
||||||
|
|
||||||
errors stderr
|
|
||||||
tls off
|
|
||||||
}
|
|
||||||
|
|
||||||
:9093 {
|
|
||||||
proxy / alertmanager:9093 {
|
|
||||||
transparent
|
|
||||||
}
|
|
||||||
|
|
||||||
errors stderr
|
|
||||||
tls off
|
|
||||||
}
|
|
||||||
|
|
||||||
:9091 {
|
|
||||||
proxy / pushgateway:9091 {
|
|
||||||
transparent
|
|
||||||
}
|
|
||||||
|
|
||||||
errors stderr
|
|
||||||
tls off
|
|
||||||
}
|
|
||||||
|
|
||||||
:3000 {
|
|
||||||
proxy / grafana:3000 {
|
|
||||||
transparent
|
|
||||||
websocket
|
|
||||||
}
|
|
||||||
|
|
||||||
errors stderr
|
|
||||||
tls off
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
GF_SECURITY_ADMIN_USER=admin
|
|
||||||
GF_SECURITY_ADMIN_PASSWORD=changeme
|
|
||||||
GF_USERS_ALLOW_SIGN_UP=false
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
version: '2.1'
|
|
||||||
|
|
||||||
services:
|
|
||||||
|
|
||||||
nodeexporter:
|
|
||||||
image: prom/node-exporter:v1.0.1
|
|
||||||
container_name: nodeexporter
|
|
||||||
volumes:
|
|
||||||
- /proc:/host/proc:ro
|
|
||||||
- /sys:/host/sys:ro
|
|
||||||
- /:/rootfs:ro
|
|
||||||
command:
|
|
||||||
- '--path.procfs=/host/proc'
|
|
||||||
- '--path.rootfs=/rootfs'
|
|
||||||
- '--path.sysfs=/host/sys'
|
|
||||||
- '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'
|
|
||||||
restart: unless-stopped
|
|
||||||
network_mode: host
|
|
||||||
labels:
|
|
||||||
org.label-schema.group: "monitoring"
|
|
||||||
|
|
||||||
cadvisor:
|
|
||||||
image: gcr.io/cadvisor/cadvisor:v0.38.7
|
|
||||||
container_name: cadvisor
|
|
||||||
volumes:
|
|
||||||
- /:/rootfs:ro
|
|
||||||
- /var/run:/var/run:rw
|
|
||||||
- /sys:/sys:ro
|
|
||||||
- /var/lib/docker/:/var/lib/docker:ro
|
|
||||||
- /cgroup:/cgroup:ro
|
|
||||||
restart: unless-stopped
|
|
||||||
network_mode: host
|
|
||||||
labels:
|
|
||||||
org.label-schema.group: "monitoring"
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
version: '2.1'
|
|
||||||
|
|
||||||
networks:
|
|
||||||
monitor-net:
|
|
||||||
driver: bridge
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
prometheus_data: {}
|
|
||||||
grafana_data: {}
|
|
||||||
|
|
||||||
services:
|
|
||||||
|
|
||||||
prometheus:
|
|
||||||
image: prom/prometheus:v2.24.1
|
|
||||||
container_name: prometheus
|
|
||||||
volumes:
|
|
||||||
- ./prometheus:/etc/prometheus
|
|
||||||
- prometheus_data:/prometheus
|
|
||||||
command:
|
|
||||||
- '--config.file=/etc/prometheus/prometheus.yml'
|
|
||||||
- '--storage.tsdb.path=/prometheus'
|
|
||||||
- '--web.console.libraries=/etc/prometheus/console_libraries'
|
|
||||||
- '--web.console.templates=/etc/prometheus/consoles'
|
|
||||||
- '--storage.tsdb.retention.time=200h'
|
|
||||||
- '--web.enable-lifecycle'
|
|
||||||
restart: unless-stopped
|
|
||||||
expose:
|
|
||||||
- 9090
|
|
||||||
ports:
|
|
||||||
- "9090:9090"
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
labels:
|
|
||||||
org.label-schema.group: "monitoring"
|
|
||||||
|
|
||||||
alertmanager:
|
|
||||||
image: prom/alertmanager:v0.21.0
|
|
||||||
container_name: alertmanager
|
|
||||||
volumes:
|
|
||||||
- ./alertmanager:/etc/alertmanager
|
|
||||||
command:
|
|
||||||
- '--config.file=/etc/alertmanager/config.yml'
|
|
||||||
- '--storage.path=/alertmanager'
|
|
||||||
restart: unless-stopped
|
|
||||||
expose:
|
|
||||||
- 9093
|
|
||||||
ports:
|
|
||||||
- "9093:9093"
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
labels:
|
|
||||||
org.label-schema.group: "monitoring"
|
|
||||||
|
|
||||||
nodeexporter:
|
|
||||||
image: prom/node-exporter:v1.0.1
|
|
||||||
container_name: nodeexporter
|
|
||||||
volumes:
|
|
||||||
- /proc:/host/proc:ro
|
|
||||||
- /sys:/host/sys:ro
|
|
||||||
- /:/rootfs:ro
|
|
||||||
command:
|
|
||||||
- '--path.procfs=/host/proc'
|
|
||||||
- '--path.rootfs=/rootfs'
|
|
||||||
- '--path.sysfs=/host/sys'
|
|
||||||
- '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'
|
|
||||||
restart: unless-stopped
|
|
||||||
expose:
|
|
||||||
- 9100
|
|
||||||
ports:
|
|
||||||
- "9100:9100"
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
labels:
|
|
||||||
org.label-schema.group: "monitoring"
|
|
||||||
|
|
||||||
cadvisor:
|
|
||||||
image: gcr.io/cadvisor/cadvisor:v0.38.7
|
|
||||||
container_name: cadvisor
|
|
||||||
volumes:
|
|
||||||
- /:/rootfs:ro
|
|
||||||
- /var/run:/var/run:rw
|
|
||||||
- /sys:/sys:ro
|
|
||||||
- /var/lib/docker:/var/lib/docker:ro
|
|
||||||
#- /cgroup:/cgroup:ro #doesn't work on MacOS only for Linux
|
|
||||||
restart: unless-stopped
|
|
||||||
expose:
|
|
||||||
- 8080
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
labels:
|
|
||||||
org.label-schema.group: "monitoring"
|
|
||||||
|
|
||||||
grafana:
|
|
||||||
image: grafana/grafana:7.3.7
|
|
||||||
container_name: grafana
|
|
||||||
volumes:
|
|
||||||
- grafana_data:/var/lib/grafana
|
|
||||||
- ./grafana/provisioning/dashboards:/etc/grafana/provisioning/dashboards
|
|
||||||
- ./grafana/provisioning/datasources:/etc/grafana/provisioning/datasources
|
|
||||||
environment:
|
|
||||||
- GF_SECURITY_ADMIN_USER=${ADMIN_USER:-admin}
|
|
||||||
- GF_SECURITY_ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin}
|
|
||||||
- GF_USERS_ALLOW_SIGN_UP=false
|
|
||||||
restart: unless-stopped
|
|
||||||
expose:
|
|
||||||
- 3000
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
labels:
|
|
||||||
org.label-schema.group: "monitoring"
|
|
||||||
|
|
||||||
pushgateway:
|
|
||||||
image: prom/pushgateway:v1.4.0
|
|
||||||
container_name: pushgateway
|
|
||||||
restart: unless-stopped
|
|
||||||
expose:
|
|
||||||
- 9091
|
|
||||||
ports:
|
|
||||||
- "9091:9091"
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
labels:
|
|
||||||
org.label-schema.group: "monitoring"
|
|
||||||
|
|
||||||
caddy:
|
|
||||||
image: caddy:2.3.0-alpine
|
|
||||||
container_name: caddy
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
- "9090:9090"
|
|
||||||
- "9093:9093"
|
|
||||||
- "9091:9091"
|
|
||||||
volumes:
|
|
||||||
- ./caddy:/etc/caddy
|
|
||||||
environment:
|
|
||||||
- ADMIN_USER=${ADMIN_USER:-admin}
|
|
||||||
- ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin}
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
labels:
|
|
||||||
org.label-schema.group: "monitoring"
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
apiVersion: 1
|
|
||||||
|
|
||||||
providers:
|
|
||||||
- name: 'Prometheus'
|
|
||||||
orgId: 1
|
|
||||||
folder: ''
|
|
||||||
type: file
|
|
||||||
disableDeletion: false
|
|
||||||
editable: true
|
|
||||||
allowUiUpdates: true
|
|
||||||
options:
|
|
||||||
path: /etc/grafana/provisioning/dashboards
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,398 +0,0 @@
|
|||||||
{
|
|
||||||
"id": null,
|
|
||||||
"title": "Nginx",
|
|
||||||
"description": "Nginx exporter metrics",
|
|
||||||
"tags": [
|
|
||||||
"nginx"
|
|
||||||
],
|
|
||||||
"style": "dark",
|
|
||||||
"timezone": "browser",
|
|
||||||
"editable": true,
|
|
||||||
"hideControls": false,
|
|
||||||
"sharedCrosshair": true,
|
|
||||||
"rows": [
|
|
||||||
{
|
|
||||||
"collapse": false,
|
|
||||||
"editable": true,
|
|
||||||
"height": "250px",
|
|
||||||
"panels": [
|
|
||||||
{
|
|
||||||
"aliasColors": {},
|
|
||||||
"bars": false,
|
|
||||||
"datasource": "Prometheus",
|
|
||||||
"decimals": 2,
|
|
||||||
"editable": true,
|
|
||||||
"error": false,
|
|
||||||
"fill": 1,
|
|
||||||
"grid": {
|
|
||||||
"threshold1": null,
|
|
||||||
"threshold1Color": "rgba(216, 200, 27, 0.27)",
|
|
||||||
"threshold2": null,
|
|
||||||
"threshold2Color": "rgba(234, 112, 112, 0.22)"
|
|
||||||
},
|
|
||||||
"id": 3,
|
|
||||||
"isNew": true,
|
|
||||||
"legend": {
|
|
||||||
"alignAsTable": true,
|
|
||||||
"avg": true,
|
|
||||||
"current": true,
|
|
||||||
"max": true,
|
|
||||||
"min": true,
|
|
||||||
"rightSide": true,
|
|
||||||
"show": true,
|
|
||||||
"total": false,
|
|
||||||
"values": true
|
|
||||||
},
|
|
||||||
"lines": true,
|
|
||||||
"linewidth": 2,
|
|
||||||
"links": [],
|
|
||||||
"nullPointMode": "connected",
|
|
||||||
"percentage": false,
|
|
||||||
"pointradius": 5,
|
|
||||||
"points": false,
|
|
||||||
"renderer": "flot",
|
|
||||||
"seriesOverrides": [],
|
|
||||||
"span": 12,
|
|
||||||
"stack": false,
|
|
||||||
"steppedLine": false,
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "sum(irate(nginx_connections_processed_total{stage=\"any\"}[5m])) by (stage)",
|
|
||||||
"hide": false,
|
|
||||||
"interval": "",
|
|
||||||
"intervalFactor": 10,
|
|
||||||
"legendFormat": "requests",
|
|
||||||
"metric": "",
|
|
||||||
"refId": "B",
|
|
||||||
"step": 10
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"timeFrom": null,
|
|
||||||
"timeShift": null,
|
|
||||||
"title": "Requests/sec",
|
|
||||||
"tooltip": {
|
|
||||||
"msResolution": false,
|
|
||||||
"shared": true,
|
|
||||||
"sort": 0,
|
|
||||||
"value_type": "cumulative"
|
|
||||||
},
|
|
||||||
"type": "graph",
|
|
||||||
"xaxis": {
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
"yaxes": [
|
|
||||||
{
|
|
||||||
"format": "short",
|
|
||||||
"label": null,
|
|
||||||
"logBase": 1,
|
|
||||||
"max": null,
|
|
||||||
"min": 0,
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"format": "short",
|
|
||||||
"label": null,
|
|
||||||
"logBase": 1,
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"show": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"aliasColors": {},
|
|
||||||
"bars": false,
|
|
||||||
"datasource": "Prometheus",
|
|
||||||
"decimals": 2,
|
|
||||||
"editable": true,
|
|
||||||
"error": false,
|
|
||||||
"fill": 1,
|
|
||||||
"grid": {
|
|
||||||
"threshold1": null,
|
|
||||||
"threshold1Color": "rgba(216, 200, 27, 0.27)",
|
|
||||||
"threshold2": null,
|
|
||||||
"threshold2Color": "rgba(234, 112, 112, 0.22)"
|
|
||||||
},
|
|
||||||
"id": 2,
|
|
||||||
"isNew": true,
|
|
||||||
"legend": {
|
|
||||||
"alignAsTable": true,
|
|
||||||
"avg": true,
|
|
||||||
"current": true,
|
|
||||||
"max": true,
|
|
||||||
"min": true,
|
|
||||||
"rightSide": true,
|
|
||||||
"show": true,
|
|
||||||
"total": false,
|
|
||||||
"values": true
|
|
||||||
},
|
|
||||||
"lines": true,
|
|
||||||
"linewidth": 2,
|
|
||||||
"links": [],
|
|
||||||
"nullPointMode": "connected",
|
|
||||||
"percentage": false,
|
|
||||||
"pointradius": 5,
|
|
||||||
"points": false,
|
|
||||||
"renderer": "flot",
|
|
||||||
"seriesOverrides": [],
|
|
||||||
"span": 12,
|
|
||||||
"stack": false,
|
|
||||||
"steppedLine": false,
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "sum(nginx_connections_current) by (state)",
|
|
||||||
"interval": "",
|
|
||||||
"intervalFactor": 2,
|
|
||||||
"legendFormat": "{{state}}",
|
|
||||||
"metric": "",
|
|
||||||
"refId": "A",
|
|
||||||
"step": 2
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"timeFrom": null,
|
|
||||||
"timeShift": null,
|
|
||||||
"title": "Connections",
|
|
||||||
"tooltip": {
|
|
||||||
"msResolution": false,
|
|
||||||
"shared": true,
|
|
||||||
"sort": 0,
|
|
||||||
"value_type": "cumulative"
|
|
||||||
},
|
|
||||||
"type": "graph",
|
|
||||||
"xaxis": {
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
"yaxes": [
|
|
||||||
{
|
|
||||||
"format": "short",
|
|
||||||
"label": null,
|
|
||||||
"logBase": 1,
|
|
||||||
"max": null,
|
|
||||||
"min": 0,
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"format": "short",
|
|
||||||
"label": null,
|
|
||||||
"logBase": 1,
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"show": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"aliasColors": {},
|
|
||||||
"bars": false,
|
|
||||||
"datasource": "Prometheus",
|
|
||||||
"decimals": 2,
|
|
||||||
"editable": true,
|
|
||||||
"error": false,
|
|
||||||
"fill": 1,
|
|
||||||
"grid": {
|
|
||||||
"threshold1": null,
|
|
||||||
"threshold1Color": "rgba(216, 200, 27, 0.27)",
|
|
||||||
"threshold2": null,
|
|
||||||
"threshold2Color": "rgba(234, 112, 112, 0.22)"
|
|
||||||
},
|
|
||||||
"id": 1,
|
|
||||||
"isNew": true,
|
|
||||||
"legend": {
|
|
||||||
"alignAsTable": true,
|
|
||||||
"avg": true,
|
|
||||||
"current": true,
|
|
||||||
"max": true,
|
|
||||||
"min": true,
|
|
||||||
"rightSide": true,
|
|
||||||
"show": true,
|
|
||||||
"total": false,
|
|
||||||
"values": true
|
|
||||||
},
|
|
||||||
"lines": true,
|
|
||||||
"linewidth": 2,
|
|
||||||
"links": [],
|
|
||||||
"nullPointMode": "connected",
|
|
||||||
"percentage": false,
|
|
||||||
"pointradius": 5,
|
|
||||||
"points": false,
|
|
||||||
"renderer": "flot",
|
|
||||||
"seriesOverrides": [],
|
|
||||||
"span": 12,
|
|
||||||
"stack": false,
|
|
||||||
"steppedLine": false,
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "sum(irate(nginx_connections_processed_total{stage!=\"any\"}[5m])) by (stage)",
|
|
||||||
"hide": false,
|
|
||||||
"interval": "",
|
|
||||||
"intervalFactor": 10,
|
|
||||||
"legendFormat": "{{stage}}",
|
|
||||||
"metric": "",
|
|
||||||
"refId": "B",
|
|
||||||
"step": 10
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"timeFrom": null,
|
|
||||||
"timeShift": null,
|
|
||||||
"title": "Connections rate",
|
|
||||||
"tooltip": {
|
|
||||||
"msResolution": false,
|
|
||||||
"shared": true,
|
|
||||||
"sort": 0,
|
|
||||||
"value_type": "cumulative"
|
|
||||||
},
|
|
||||||
"type": "graph",
|
|
||||||
"xaxis": {
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
"yaxes": [
|
|
||||||
{
|
|
||||||
"format": "short",
|
|
||||||
"label": null,
|
|
||||||
"logBase": 1,
|
|
||||||
"max": null,
|
|
||||||
"min": 0,
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"format": "short",
|
|
||||||
"label": null,
|
|
||||||
"logBase": 1,
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"show": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"title": "Nginx exporter metrics"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collapse": false,
|
|
||||||
"editable": true,
|
|
||||||
"height": "250px",
|
|
||||||
"panels": [
|
|
||||||
{
|
|
||||||
"aliasColors": {},
|
|
||||||
"bars": false,
|
|
||||||
"datasource": null,
|
|
||||||
"editable": true,
|
|
||||||
"error": false,
|
|
||||||
"fill": 1,
|
|
||||||
"grid": {
|
|
||||||
"threshold1": null,
|
|
||||||
"threshold1Color": "rgba(216, 200, 27, 0.27)",
|
|
||||||
"threshold2": null,
|
|
||||||
"threshold2Color": "rgba(234, 112, 112, 0.22)"
|
|
||||||
},
|
|
||||||
"id": 4,
|
|
||||||
"isNew": true,
|
|
||||||
"legend": {
|
|
||||||
"alignAsTable": true,
|
|
||||||
"avg": true,
|
|
||||||
"current": true,
|
|
||||||
"max": true,
|
|
||||||
"min": true,
|
|
||||||
"rightSide": true,
|
|
||||||
"show": true,
|
|
||||||
"total": false,
|
|
||||||
"values": true
|
|
||||||
},
|
|
||||||
"lines": true,
|
|
||||||
"linewidth": 2,
|
|
||||||
"links": [],
|
|
||||||
"nullPointMode": "connected",
|
|
||||||
"percentage": false,
|
|
||||||
"pointradius": 5,
|
|
||||||
"points": false,
|
|
||||||
"renderer": "flot",
|
|
||||||
"seriesOverrides": [],
|
|
||||||
"span": 12,
|
|
||||||
"stack": false,
|
|
||||||
"steppedLine": false,
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "sum(rate(container_cpu_usage_seconds_total{name=~\"nginx\"}[5m])) / count(node_cpu_seconds_total{mode=\"system\"}) * 100",
|
|
||||||
"intervalFactor": 2,
|
|
||||||
"legendFormat": "nginx",
|
|
||||||
"refId": "A",
|
|
||||||
"step": 2
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"timeFrom": null,
|
|
||||||
"timeShift": null,
|
|
||||||
"title": "CPU usage",
|
|
||||||
"tooltip": {
|
|
||||||
"msResolution": false,
|
|
||||||
"shared": true,
|
|
||||||
"sort": 0,
|
|
||||||
"value_type": "cumulative"
|
|
||||||
},
|
|
||||||
"type": "graph",
|
|
||||||
"xaxis": {
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
"yaxes": [
|
|
||||||
{
|
|
||||||
"format": "short",
|
|
||||||
"label": null,
|
|
||||||
"logBase": 1,
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"format": "short",
|
|
||||||
"label": null,
|
|
||||||
"logBase": 1,
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"show": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"title": "Nginx container metrics"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": {
|
|
||||||
"from": "now-15m",
|
|
||||||
"to": "now"
|
|
||||||
},
|
|
||||||
"timepicker": {
|
|
||||||
"refresh_intervals": [
|
|
||||||
"5s",
|
|
||||||
"10s",
|
|
||||||
"30s",
|
|
||||||
"1m",
|
|
||||||
"5m",
|
|
||||||
"15m",
|
|
||||||
"30m",
|
|
||||||
"1h",
|
|
||||||
"2h",
|
|
||||||
"1d"
|
|
||||||
],
|
|
||||||
"time_options": [
|
|
||||||
"5m",
|
|
||||||
"15m",
|
|
||||||
"1h",
|
|
||||||
"6h",
|
|
||||||
"12h",
|
|
||||||
"24h",
|
|
||||||
"2d",
|
|
||||||
"7d",
|
|
||||||
"30d"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"templating": {
|
|
||||||
"list": []
|
|
||||||
},
|
|
||||||
"annotations": {
|
|
||||||
"list": []
|
|
||||||
},
|
|
||||||
"refresh": "10s",
|
|
||||||
"schemaVersion": 12,
|
|
||||||
"version": 9,
|
|
||||||
"links": [],
|
|
||||||
"gnetId": null
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
apiVersion: 1
|
|
||||||
|
|
||||||
datasources:
|
|
||||||
- name: Prometheus
|
|
||||||
type: prometheus
|
|
||||||
access: proxy
|
|
||||||
orgId: 1
|
|
||||||
url: http://prometheus:9090
|
|
||||||
basicAuth: false
|
|
||||||
isDefault: true
|
|
||||||
editable: true
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
# Prometheus on EC2 & ECS:
|
|
||||||
|
|
||||||
Some helpers for anyone configuring Prometheus on ECS and AWS EC2.
|
|
||||||
|
|
||||||
To get started on AWS ECS and EC2:
|
|
||||||
|
|
||||||
*For EC2/ECS nodes*:
|
|
||||||
- Import the ecs task definition and add cadvisor and node-exporter service/task definition and run them on each host you want to be monitored
|
|
||||||
- Any hosts which have "Monitoring: On" tag will be automatically added in the targets
|
|
||||||
- Expose ports 9100 and 9191 to your Prometheus host
|
|
||||||
|
|
||||||
*For Prometheus host*:
|
|
||||||
|
|
||||||
- Copy prometheus.yml configuration present here to base prometheus configuration to enable EC2 service discovery
|
|
||||||
- `docker compose up -d`
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> Set query.staleness-delta to 1m make metrics more realtime
|
|
||||||
|
|
||||||
|
|
||||||
### TODO
|
|
||||||
- [ ] Add alerting rules based on ECS
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
{
|
|
||||||
"family": "cadvisor",
|
|
||||||
"containerDefinitions": [
|
|
||||||
{
|
|
||||||
"name": "cadvisor",
|
|
||||||
"image": "google/cadvisor",
|
|
||||||
"cpu": 10,
|
|
||||||
"memory": 300,
|
|
||||||
"portMappings": [
|
|
||||||
{
|
|
||||||
"containerPort": 9191,
|
|
||||||
"hostPort": 9191
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"essential": true,
|
|
||||||
"privileged": true,
|
|
||||||
"mountPoints": [
|
|
||||||
{
|
|
||||||
"sourceVolume": "root",
|
|
||||||
"containerPath": "/rootfs",
|
|
||||||
"readOnly": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolume": "var_run",
|
|
||||||
"containerPath": "/var/run",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolume": "sys",
|
|
||||||
"containerPath": "/sys",
|
|
||||||
"readOnly": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolume": "var_lib_docker",
|
|
||||||
"containerPath": "/var/lib/docker",
|
|
||||||
"readOnly": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolume": "cgroup",
|
|
||||||
"containerPath": "/cgroup",
|
|
||||||
"readOnly": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"volumes": [
|
|
||||||
{
|
|
||||||
"name": "root",
|
|
||||||
"host": {
|
|
||||||
"sourcePath": "/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "var_run",
|
|
||||||
"host": {
|
|
||||||
"sourcePath": "/var/run"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sys",
|
|
||||||
"host": {
|
|
||||||
"sourcePath": "/sys"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "var_lib_docker",
|
|
||||||
"host": {
|
|
||||||
"sourcePath": "/var/lib/docker/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "cgroup",
|
|
||||||
"host": {
|
|
||||||
"sourcePath": "/cgroup"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"family": "prometheus",
|
|
||||||
"containerDefinitions": [
|
|
||||||
{
|
|
||||||
"portMappings": [
|
|
||||||
{
|
|
||||||
"hostPort": 9100,
|
|
||||||
"containerPort": 9100,
|
|
||||||
"protocol": "tcp"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"essential": true,
|
|
||||||
"name": "node_exporter",
|
|
||||||
"image": "prom/node-exporter",
|
|
||||||
"cpu": 0,
|
|
||||||
"privileged": null,
|
|
||||||
"memoryReservation": 150
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"volumes": [],
|
|
||||||
"networkMode": "host"
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
global:
|
|
||||||
scrape_interval: 15s
|
|
||||||
evaluation_interval: 15s
|
|
||||||
|
|
||||||
# Attach these labels to any time series or alerts when communicating with
|
|
||||||
# external systems (federation, remote storage, Alertmanager).
|
|
||||||
external_labels:
|
|
||||||
monitor: 'docker-host-alpha'
|
|
||||||
|
|
||||||
# Load and evaluate rules in this file every 'evaluation_interval' seconds.
|
|
||||||
rule_files:
|
|
||||||
- "targets.rules"
|
|
||||||
- "hosts.rules"
|
|
||||||
- "containers.rules"
|
|
||||||
|
|
||||||
# A scrape configuration containing exactly one endpoint to scrape.
|
|
||||||
scrape_configs:
|
|
||||||
- job_name: 'nodeexporter'
|
|
||||||
scrape_interval: 5s
|
|
||||||
static_configs:
|
|
||||||
- targets: ['nodeexporter:9100']
|
|
||||||
|
|
||||||
- job_name: 'cadvisor'
|
|
||||||
scrape_interval: 5s
|
|
||||||
static_configs:
|
|
||||||
- targets: ['cadvisor:8080']
|
|
||||||
|
|
||||||
- job_name: 'prometheus'
|
|
||||||
scrape_interval: 10s
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9090']
|
|
||||||
|
|
||||||
|
|
||||||
# sample scrape configuration for AWS EC2
|
|
||||||
- job_name: 'nodeexporter'
|
|
||||||
ec2_sd_configs:
|
|
||||||
- region: us-east-1
|
|
||||||
port: 9100
|
|
||||||
relabel_configs:
|
|
||||||
# Only monitor instances which have a tag called Monitoring "Monitoring"
|
|
||||||
- source_labels: [__meta_ec2_tag_Monitoring]
|
|
||||||
regex: On
|
|
||||||
action: keep
|
|
||||||
|
|
||||||
- job_name: 'cadvisor'
|
|
||||||
ec2_sd_configs:
|
|
||||||
- region: us-east-1
|
|
||||||
port: 9010
|
|
||||||
relabel_configs:
|
|
||||||
# Only monitor instances which have a tag called Monitoring "Monitoring"
|
|
||||||
- source_labels: [__meta_ec2_tag_Monitoring]
|
|
||||||
regex: On
|
|
||||||
action: keep
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
groups:
|
|
||||||
- name: targets
|
|
||||||
rules:
|
|
||||||
- alert: monitor_service_down
|
|
||||||
expr: up == 0
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: critical
|
|
||||||
annotations:
|
|
||||||
summary: "Monitor service non-operational"
|
|
||||||
description: "Service {{ $labels.instance }} is down."
|
|
||||||
|
|
||||||
- name: host
|
|
||||||
rules:
|
|
||||||
- alert: high_cpu_load
|
|
||||||
expr: node_load1 > 1.5
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "Server under high load"
|
|
||||||
description: "Docker host is under high load, the avg load 1m is at {{ $value}}. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}."
|
|
||||||
|
|
||||||
- alert: high_memory_load
|
|
||||||
expr: (sum(node_memory_MemTotal_bytes) - sum(node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes) ) / sum(node_memory_MemTotal_bytes) * 100 > 85
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "Server memory is almost full"
|
|
||||||
description: "Docker host memory usage is {{ humanize $value}}%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}."
|
|
||||||
|
|
||||||
- alert: high_storage_load
|
|
||||||
expr: (node_filesystem_size_bytes{fstype="aufs"} - node_filesystem_free_bytes{fstype="aufs"}) / node_filesystem_size_bytes{fstype="aufs"} * 100 > 85
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "Server storage is almost full"
|
|
||||||
description: "Docker host storage usage is {{ humanize $value}}%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}."
|
|
||||||
|
|
||||||
- name: containers
|
|
||||||
rules:
|
|
||||||
- alert: jenkins_down
|
|
||||||
expr: absent(container_memory_usage_bytes{name="jenkins"})
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: critical
|
|
||||||
annotations:
|
|
||||||
summary: "Jenkins down"
|
|
||||||
description: "Jenkins container is down for more than 30 seconds."
|
|
||||||
|
|
||||||
- alert: jenkins_high_cpu
|
|
||||||
expr: sum(rate(container_cpu_usage_seconds_total{name="jenkins"}[1m])) / count(node_cpu_seconds_total{mode="system"}) * 100 > 10
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "Jenkins high CPU usage"
|
|
||||||
description: "Jenkins CPU usage is {{ humanize $value}}%."
|
|
||||||
|
|
||||||
- alert: jenkins_high_memory
|
|
||||||
expr: sum(container_memory_usage_bytes{name="jenkins"}) > 1200000000
|
|
||||||
for: 30s
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "Jenkins high memory usage"
|
|
||||||
description: "Jenkins memory consumption is at {{ humanize $value}}."
|
|
||||||
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
global:
|
|
||||||
scrape_interval: 15s
|
|
||||||
evaluation_interval: 15s
|
|
||||||
|
|
||||||
# Attach these labels to any time series or alerts when communicating with
|
|
||||||
# external systems (federation, remote storage, Alertmanager).
|
|
||||||
external_labels:
|
|
||||||
monitor: 'docker-host-alpha'
|
|
||||||
|
|
||||||
# Load and evaluate rules in this file every 'evaluation_interval' seconds.
|
|
||||||
rule_files:
|
|
||||||
- "alert.rules"
|
|
||||||
|
|
||||||
# A scrape configuration containing exactly one endpoint to scrape.
|
|
||||||
scrape_configs:
|
|
||||||
- job_name: 'nodeexporter'
|
|
||||||
scrape_interval: 5s
|
|
||||||
static_configs:
|
|
||||||
- targets: ['nodeexporter:9100']
|
|
||||||
|
|
||||||
- job_name: 'cadvisor'
|
|
||||||
scrape_interval: 5s
|
|
||||||
static_configs:
|
|
||||||
- targets: ['cadvisor:8080']
|
|
||||||
|
|
||||||
- job_name: 'prometheus'
|
|
||||||
scrape_interval: 10s
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9090']
|
|
||||||
|
|
||||||
- job_name: 'pushgateway'
|
|
||||||
scrape_interval: 10s
|
|
||||||
honor_labels: true
|
|
||||||
static_configs:
|
|
||||||
- targets: ['pushgateway:9091']
|
|
||||||
|
|
||||||
|
|
||||||
alerting:
|
|
||||||
alertmanagers:
|
|
||||||
- scheme: http
|
|
||||||
static_configs:
|
|
||||||
- targets:
|
|
||||||
- 'alertmanager:9093'
|
|
||||||
|
|
||||||
# - job_name: 'nginx'
|
|
||||||
# scrape_interval: 10s
|
|
||||||
# static_configs:
|
|
||||||
# - targets: ['nginxexporter:9113']
|
|
||||||
|
|
||||||
# - job_name: 'aspnetcore'
|
|
||||||
# scrape_interval: 10s
|
|
||||||
# static_configs:
|
|
||||||
# - targets: ['eventlog-proxy:5000', 'eventlog:5000']
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 270 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 247 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 501 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 39 KiB |
@@ -1,174 +0,0 @@
|
|||||||
<!-- Code generated by gomarkdoc. DO NOT EDIT -->
|
|
||||||
|
|
||||||
# docker
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Index
|
|
||||||
|
|
||||||
- [func StopAndRemoveContainer\(containername string\) error](<#StopAndRemoveContainer>)
|
|
||||||
- [type DockerContainer](<#DockerContainer>)
|
|
||||||
- [type DockerContainers](<#DockerContainers>)
|
|
||||||
- [func ViewAllContainers\(\) \(\*DockerContainers, error\)](<#ViewAllContainers>)
|
|
||||||
- [type DockerVM](<#DockerVM>)
|
|
||||||
- [func BuildRunContainer\(NumPorts int, GPU string, ContainerName string, baseImage string, publicKey string\) \(\*DockerVM, error\)](<#BuildRunContainer>)
|
|
||||||
- [func \(d \*DockerVM\) CopyToTmpContainer\(\) error](<#DockerVM.CopyToTmpContainer>)
|
|
||||||
- [func \(d \*DockerVM\) TemplateDockerContainer\(\) error](<#DockerVM.TemplateDockerContainer>)
|
|
||||||
- [type ErrorDetail](<#ErrorDetail>)
|
|
||||||
- [type ErrorLine](<#ErrorLine>)
|
|
||||||
- [type Port](<#Port>)
|
|
||||||
- [type Ports](<#Ports>)
|
|
||||||
- [func OpenPortsFile\(filename string\) \(\*Ports, error\)](<#OpenPortsFile>)
|
|
||||||
|
|
||||||
|
|
||||||
<a name="StopAndRemoveContainer"></a>
|
|
||||||
## func [StopAndRemoveContainer](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L340>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func StopAndRemoveContainer(containername string) error
|
|
||||||
```
|
|
||||||
|
|
||||||
StopAndRemoveContainer Stop and remove a container Reference \(https://gist.github.com/frikky/e2efcea6c733ea8d8d015b7fe8a91bf6\)
|
|
||||||
|
|
||||||
<a name="DockerContainer"></a>
|
|
||||||
## type [DockerContainer](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L40-L43>)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```go
|
|
||||||
type DockerContainer struct {
|
|
||||||
ContainerName string `json:"DockerContainerName"`
|
|
||||||
ContainerDescription string `json:"ContainerDescription"`
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<a name="DockerContainers"></a>
|
|
||||||
## type [DockerContainers](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L36-L38>)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```go
|
|
||||||
type DockerContainers struct {
|
|
||||||
DockerContainer []DockerContainer `json:"DockerContainer"`
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<a name="ViewAllContainers"></a>
|
|
||||||
### func [ViewAllContainers](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L387>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func ViewAllContainers() (*DockerContainers, error)
|
|
||||||
```
|
|
||||||
|
|
||||||
ViewAllContainers returns all containers runnable and which can be built
|
|
||||||
|
|
||||||
<a name="DockerVM"></a>
|
|
||||||
## type [DockerVM](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L22-L34>)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```go
|
|
||||||
type DockerVM struct {
|
|
||||||
SSHUsername string `json:"SSHUsername"`
|
|
||||||
SSHPublcKey string `json:"SSHPublicKey"`
|
|
||||||
ID string `json:"ID"`
|
|
||||||
TagName string `json:"TagName"`
|
|
||||||
ImagePath string `json:"ImagePath"`
|
|
||||||
Ports Ports `json:"Ports"`
|
|
||||||
GPU string `json:"GPU"`
|
|
||||||
TempPath string
|
|
||||||
BaseImage string
|
|
||||||
LogsPath string
|
|
||||||
SSHCommand string `json:"SSHCommand"`
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<a name="BuildRunContainer"></a>
|
|
||||||
### func [BuildRunContainer](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L70>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func BuildRunContainer(NumPorts int, GPU string, ContainerName string, baseImage string, publicKey string) (*DockerVM, error)
|
|
||||||
```
|
|
||||||
|
|
||||||
BuildRunContainer Function is incharge to invoke building and running contianer and also allocating external ports
|
|
||||||
|
|
||||||
<a name="DockerVM.CopyToTmpContainer"></a>
|
|
||||||
### func \(\*DockerVM\) [CopyToTmpContainer](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L493>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (d *DockerVM) CopyToTmpContainer() error
|
|
||||||
```
|
|
||||||
|
|
||||||
CopyToTmpContainer Creates a copy of the docker folder
|
|
||||||
|
|
||||||
<a name="DockerVM.TemplateDockerContainer"></a>
|
|
||||||
### func \(\*DockerVM\) [TemplateDockerContainer](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L464>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (d *DockerVM) TemplateDockerContainer() error
|
|
||||||
```
|
|
||||||
|
|
||||||
TemplateDockerContainer This function templates the docker container with the base docker image to use
|
|
||||||
|
|
||||||
<a name="ErrorDetail"></a>
|
|
||||||
## type [ErrorDetail](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L62-L64>)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```go
|
|
||||||
type ErrorDetail struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<a name="ErrorLine"></a>
|
|
||||||
## type [ErrorLine](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L57-L60>)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```go
|
|
||||||
type ErrorLine struct {
|
|
||||||
Error string `json:"error"`
|
|
||||||
ErrorDetail ErrorDetail `json:"errorDetail"`
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<a name="Port"></a>
|
|
||||||
## type [Port](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L48-L55>)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Port struct {
|
|
||||||
PortName string `json:"PortName"`
|
|
||||||
InternalPort int `json:"InternalPort"`
|
|
||||||
Type string `json:"Type"`
|
|
||||||
ExternalPort int `json:"ExternalPort"`
|
|
||||||
IsUsed bool `json:"IsUsed"`
|
|
||||||
Description string `json:"Description"`
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<a name="Ports"></a>
|
|
||||||
## type [Ports](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L45-L47>)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Ports struct {
|
|
||||||
PortSet []Port `json:"Port"`
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<a name="OpenPortsFile"></a>
|
|
||||||
### func [OpenPortsFile](<https://github.com/Akilan1999/p2p-rendering-computation/blob/master/server/docker/docker.go#L447>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func OpenPortsFile(filename string) (*Ports, error)
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
docker kill $(docker ps -q)\
|
|
||||||
docker rm $(docker ps -a -q)
|
|
||||||
docker rmi $(docker images -q) --force
|
|
||||||
docker system prune --all
|
|
||||||
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"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -9,7 +8,6 @@ import (
|
|||||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
|
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -120,65 +118,65 @@ func Server() (*gin.Engine, error) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Starts docker container in server
|
// Starts docker container in server
|
||||||
r.GET("/startcontainer", func(c *gin.Context) {
|
//r.GET("/startcontainer", func(c *gin.Context) {
|
||||||
// Get Number of ports to open and whether to use GPU or not
|
// // Get Number of ports to open and whether to use GPU or not
|
||||||
Ports := c.DefaultQuery("ports", "0")
|
// Ports := c.DefaultQuery("ports", "0")
|
||||||
GPU := c.DefaultQuery("GPU", "false")
|
// GPU := c.DefaultQuery("GPU", "false")
|
||||||
ContainerName := c.DefaultQuery("ContainerName", "")
|
// ContainerName := c.DefaultQuery("ContainerName", "")
|
||||||
BaseImage := c.DefaultQuery("BaseImage", "")
|
// BaseImage := c.DefaultQuery("BaseImage", "")
|
||||||
PublicKey := c.DefaultQuery("PublicKey", "")
|
// PublicKey := c.DefaultQuery("PublicKey", "")
|
||||||
var PortsInt int
|
// var PortsInt int
|
||||||
|
//
|
||||||
if PublicKey == "" {
|
// if PublicKey == "" {
|
||||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", "Publickey not passed"))
|
// c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", "Publickey not passed"))
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
PublicKeyDecoded, err := b64.StdEncoding.DecodeString(PublicKey)
|
// PublicKeyDecoded, err := b64.StdEncoding.DecodeString(PublicKey)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
// 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[:]))
|
// 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, BaseImage, string(PublicKeyDecoded[:]))
|
||||||
|
//
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
// c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Ensures that FRP is triggered only if a proxy address is provided
|
// // Ensures that FRP is triggered only if a proxy address is provided
|
||||||
if ProxyIpAddr.Ipv4 != "" && c.Request.Host != "localhost:"+config.ServerPort && c.Request.Host != "0.0.0.0:"+config.ServerPort {
|
// if ProxyIpAddr.Ipv4 != "" && c.Request.Host != "localhost:"+config.ServerPort && c.Request.Host != "0.0.0.0:"+config.ServerPort {
|
||||||
resp, err = frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, lowestLatencyIpAddress.ServerPort, resp)
|
// resp, err = frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, lowestLatencyIpAddress.ServerPort, resp)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
// c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
c.JSON(http.StatusOK, resp)
|
// c.JSON(http.StatusOK, resp)
|
||||||
})
|
//})
|
||||||
|
|
||||||
//Remove container
|
//Remove container
|
||||||
r.GET("/RemoveContainer", func(c *gin.Context) {
|
//r.GET("/RemoveContainer", func(c *gin.Context) {
|
||||||
ID := c.DefaultQuery("id", "0")
|
// ID := c.DefaultQuery("id", "0")
|
||||||
if err := docker.StopAndRemoveContainer(ID); err != nil {
|
// if err := docker.StopAndRemoveContainer(ID); err != nil {
|
||||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
// c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||||
}
|
// }
|
||||||
c.String(http.StatusOK, "success")
|
// c.String(http.StatusOK, "success")
|
||||||
})
|
//})
|
||||||
|
//
|
||||||
//Show images available
|
////Show images available
|
||||||
r.GET("/ShowImages", func(c *gin.Context) {
|
//r.GET("/ShowImages", func(c *gin.Context) {
|
||||||
resp, err := docker.ViewAllContainers()
|
// resp, err := docker.ViewAllContainers()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
// c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||||
}
|
// }
|
||||||
c.JSON(http.StatusOK, resp)
|
// c.JSON(http.StatusOK, resp)
|
||||||
})
|
//})
|
||||||
|
|
||||||
// Request for port no from Server with address
|
// Request for port no from Server with address
|
||||||
r.GET("/FRPPort", func(c *gin.Context) {
|
r.GET("/FRPPort", func(c *gin.Context) {
|
||||||
@@ -255,7 +253,7 @@ func Server() (*gin.Engine, error) {
|
|||||||
// TODO check if IPV6 or Proxy port is specified
|
// TODO check if IPV6 or Proxy port is specified
|
||||||
// if not update current entry as proxy address
|
// if not update current entry as proxy address
|
||||||
// with appropriate port on IP Table
|
// with appropriate port on IP Table
|
||||||
if config.BehindNAT == "True" {
|
if config.BehindNAT {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -267,7 +265,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 && !table.IpAddress[i].NAT {
|
||||||
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
|
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
|
||||||
lowestLatencyIpAddress = table.IpAddress[i]
|
lowestLatencyIpAddress = table.IpAddress[i]
|
||||||
}
|
}
|
||||||
@@ -291,8 +289,8 @@ func Server() (*gin.Engine, error) {
|
|||||||
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
|
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
|
||||||
ProxyIpAddr.ServerPort = proxyPort
|
ProxyIpAddr.ServerPort = proxyPort
|
||||||
ProxyIpAddr.Name = config.MachineName
|
ProxyIpAddr.Name = config.MachineName
|
||||||
ProxyIpAddr.NAT = "False"
|
ProxyIpAddr.NAT = false
|
||||||
ProxyIpAddr.ProxyServer = "False"
|
ProxyIpAddr.ProxyServer = false
|
||||||
ProxyIpAddr.EscapeImplementation = "FRP"
|
ProxyIpAddr.EscapeImplementation = "FRP"
|
||||||
|
|
||||||
if config.BareMetal {
|
if config.BareMetal {
|
||||||
@@ -314,9 +312,9 @@ func Server() (*gin.Engine, error) {
|
|||||||
}
|
}
|
||||||
ProxyIpAddr.ServerPort = config.ServerPort
|
ProxyIpAddr.ServerPort = config.ServerPort
|
||||||
ProxyIpAddr.Name = config.MachineName
|
ProxyIpAddr.Name = config.MachineName
|
||||||
ProxyIpAddr.NAT = "False"
|
ProxyIpAddr.NAT = false
|
||||||
if config.ProxyPort != "" {
|
if config.ProxyPort != "" {
|
||||||
ProxyIpAddr.ProxyServer = "True"
|
ProxyIpAddr.ProxyServer = true
|
||||||
}
|
}
|
||||||
ProxyIpAddr.EscapeImplementation = ""
|
ProxyIpAddr.EscapeImplementation = ""
|
||||||
if config.BareMetal {
|
if config.BareMetal {
|
||||||
@@ -425,9 +423,9 @@ func MapPort(port string, domainName string) (string, string, 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 && !table.IpAddress[i].NAT {
|
||||||
// Filter based on nodes with proxy enabled
|
// Filter based on nodes with proxy enabled
|
||||||
if domainName != "" && table.IpAddress[i].ProxyServer == "True" {
|
if domainName != "" && table.IpAddress[i].ProxyServer {
|
||||||
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
|
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
|
||||||
lowestLatencyIpAddress = table.IpAddress[i]
|
lowestLatencyIpAddress = table.IpAddress[i]
|
||||||
continue
|
continue
|
||||||
@@ -466,7 +464,7 @@ func MapPort(port string, domainName string) (string, string, error) {
|
|||||||
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
|
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
|
||||||
ProxyIpAddr.ServerPort = proxyPort
|
ProxyIpAddr.ServerPort = proxyPort
|
||||||
ProxyIpAddr.Name = config.MachineName
|
ProxyIpAddr.Name = config.MachineName
|
||||||
ProxyIpAddr.NAT = "False"
|
ProxyIpAddr.NAT = false
|
||||||
ProxyIpAddr.EscapeImplementation = "FRP"
|
ProxyIpAddr.EscapeImplementation = "FRP"
|
||||||
|
|
||||||
//ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey)
|
//ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey)
|
||||||
|
|||||||
32
style.css
32
style.css
@@ -1,32 +0,0 @@
|
|||||||
body {
|
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
span#discordJoin {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dark mode */
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
/* General Page Changing */
|
|
||||||
body {
|
|
||||||
background: #121212; /* Background Color */
|
|
||||||
color: #FFFFFF; /* Text Color */
|
|
||||||
}
|
|
||||||
|
|
||||||
a:link{ /* Unvisited Link */
|
|
||||||
color: #03DAC5;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:visited { /* Visited Link */
|
|
||||||
color: #BB86FC;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover { /* Mouse over Link */
|
|
||||||
color: #018786;
|
|
||||||
}
|
|
||||||
|
|
||||||
span#discordJoin { /* Text Color Change */
|
|
||||||
color: #cc0227;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
156
wasm/wasm.go
Normal file
156
wasm/wasm.go
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"syscall/js"
|
||||||
|
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/abstractions"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Register functions
|
||||||
|
js.Global().Set("getSpecs", js.FuncOf(getSpecs))
|
||||||
|
js.Global().Set("initConfig", js.FuncOf(initConfig))
|
||||||
|
js.Global().Set("viewIPTable", js.FuncOf(viewIPTable))
|
||||||
|
js.Global().Set("updateIPTable", js.FuncOf(updateIPTable))
|
||||||
|
js.Global().Set("escapeFirewall", js.FuncOf(escapeFirewall))
|
||||||
|
js.Global().Set("mapPort", js.FuncOf(mapPort))
|
||||||
|
js.Global().Set("customInformation", js.FuncOf(customInformation))
|
||||||
|
js.Global().Set("addRootNode", js.FuncOf(addRootNode))
|
||||||
|
js.Global().Set("startServer", js.FuncOf(startServer))
|
||||||
|
|
||||||
|
// Prevent Go program from exiting
|
||||||
|
select {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------- Helpers ----------------------------------------
|
||||||
|
|
||||||
|
func convertToJSValue(value interface{}) js.Value {
|
||||||
|
jsonBytes, err := json.Marshal(value)
|
||||||
|
if err != nil {
|
||||||
|
return js.ValueOf(map[string]interface{}{"error": err.Error()})
|
||||||
|
}
|
||||||
|
return js.ValueOf(string(jsonBytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
func returnError(err error) js.Value {
|
||||||
|
return js.ValueOf(map[string]interface{}{"error": err.Error()})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------- WASM Functions ----------------------------------------
|
||||||
|
|
||||||
|
func getSpecs(this js.Value, args []js.Value) any {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return returnError(jsError("Missing IP argument"))
|
||||||
|
}
|
||||||
|
specs, err := abstractions.GetSpecs(args[0].String())
|
||||||
|
if err != nil {
|
||||||
|
return returnError(err)
|
||||||
|
}
|
||||||
|
return convertToJSValue(specs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initConfig(this js.Value, args []js.Value) any {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return returnError(jsError("Missing config argument"))
|
||||||
|
}
|
||||||
|
initData, err := abstractions.Init(args[0].String())
|
||||||
|
if err != nil {
|
||||||
|
return returnError(err)
|
||||||
|
}
|
||||||
|
return convertToJSValue(initData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func viewIPTable(this js.Value, args []js.Value) any {
|
||||||
|
table, err := abstractions.ViewIPTable()
|
||||||
|
if err != nil {
|
||||||
|
return returnError(err)
|
||||||
|
}
|
||||||
|
return convertToJSValue(table)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateIPTable(this js.Value, args []js.Value) any {
|
||||||
|
err := abstractions.UpdateIPTable()
|
||||||
|
if err != nil {
|
||||||
|
return returnError(err)
|
||||||
|
}
|
||||||
|
return js.ValueOf("Success")
|
||||||
|
}
|
||||||
|
|
||||||
|
func escapeFirewall(this js.Value, args []js.Value) any {
|
||||||
|
if len(args) < 3 {
|
||||||
|
return returnError(jsError("Expected 3 arguments"))
|
||||||
|
}
|
||||||
|
host := args[0].String()
|
||||||
|
port := args[1].String()
|
||||||
|
internalPort := args[2].String()
|
||||||
|
|
||||||
|
serverPort, err := frp.GetFRPServerPort("http://" + host + ":" + port)
|
||||||
|
if err != nil {
|
||||||
|
return returnError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
|
||||||
|
exposedPort, err := frp.StartFRPClientForServer(host+":"+port, serverPort, internalPort, "")
|
||||||
|
if err != nil {
|
||||||
|
return returnError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return js.ValueOf(exposedPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapPort(this js.Value, args []js.Value) any {
|
||||||
|
if len(args) < 3 {
|
||||||
|
return returnError(jsError("Expected 3 arguments"))
|
||||||
|
}
|
||||||
|
port := args[0].String()
|
||||||
|
domain := args[1].String()
|
||||||
|
server := args[2].String()
|
||||||
|
|
||||||
|
addr, err := abstractions.MapPort(port, domain, server)
|
||||||
|
if err != nil {
|
||||||
|
return returnError(err)
|
||||||
|
}
|
||||||
|
return js.ValueOf(addr.EntireAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
func customInformation(this js.Value, args []js.Value) any {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return returnError(jsError("Missing custom information"))
|
||||||
|
}
|
||||||
|
err := abstractions.AddCustomInformation(args[0].String())
|
||||||
|
if err != nil {
|
||||||
|
return returnError(err)
|
||||||
|
}
|
||||||
|
return js.ValueOf("Success")
|
||||||
|
}
|
||||||
|
|
||||||
|
func addRootNode(this js.Value, args []js.Value) any {
|
||||||
|
if len(args) < 2 {
|
||||||
|
return returnError(jsError("Expected 2 arguments"))
|
||||||
|
}
|
||||||
|
err := abstractions.AddRootNode(args[0].String(), args[1].String())
|
||||||
|
if err != nil {
|
||||||
|
return returnError(err)
|
||||||
|
}
|
||||||
|
return js.ValueOf("Success")
|
||||||
|
}
|
||||||
|
|
||||||
|
func startServer(this js.Value, args []js.Value) any {
|
||||||
|
_, err := abstractions.Start()
|
||||||
|
if err != nil {
|
||||||
|
return returnError(err)
|
||||||
|
}
|
||||||
|
return js.ValueOf("Server started")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------- Utility ----------------------------------------
|
||||||
|
|
||||||
|
func jsError(msg string) error {
|
||||||
|
return errors.New("WASM error: " + msg)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user