Compare commits
4 Commits
master
...
simulation
| Author | SHA1 | Date | |
|---|---|---|---|
| 034f9e2896 | |||
| ece1e63fda | |||
| b88370cdb7 | |||
| 9f4cb9af02 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -31,7 +31,6 @@ server/docker/containers/
|
|||||||
|
|
||||||
# generic folder to ignore
|
# generic folder to ignore
|
||||||
export/
|
export/
|
||||||
exports/
|
|
||||||
|
|
||||||
# Any testing file
|
# Any testing file
|
||||||
*test
|
*test
|
||||||
@@ -50,3 +49,6 @@ venv
|
|||||||
# Nix and Nix flake files
|
# Nix and Nix flake files
|
||||||
result
|
result
|
||||||
result-*
|
result-*
|
||||||
|
|
||||||
|
# Ignore WASM generated files
|
||||||
|
*.wasm
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
//go:build cgo
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "C"
|
import "C"
|
||||||
@@ -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 ----------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|--------------|-----------------------------------------|
|
|--------------|-----------------------------------------|
|
||||||
| Copyright | Copyright (C) 2006-2024 John MacFarlane |
|
| Copyright | Copyright (C) 2006-2024 John MacFarlane |
|
||||||
| License | GNU GPL, version 2 or above |
|
| License | GNU GPL, version 2 or above |
|
||||||
|
| Maintainer | John MacFarlane \<jgm@berkeley.edu\> |
|
||||||
| Stability | alpha |
|
| Stability | alpha |
|
||||||
| Portability | portable |
|
| Portability | portable |
|
||||||
| Safe Haskell | Safe-Inferred |
|
| Safe Haskell | Safe-Inferred |
|
||||||
|
|||||||
66
Bindings/Haskell/flake.lock
generated
66
Bindings/Haskell/flake.lock
generated
@@ -18,41 +18,23 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-utils_2": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1731533236,
|
|
||||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"gomod2nix": {
|
"gomod2nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": [
|
"flake-utils": [
|
||||||
"p2prc-main",
|
"p2prc",
|
||||||
"flake-utils"
|
"flake-utils"
|
||||||
],
|
],
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"p2prc-main",
|
"p2prc",
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1745875161,
|
"lastModified": 1733668782,
|
||||||
"narHash": "sha256-0YkWCS13jpoo3+sX/3kcgdxBNt1VZTmvF+FhZb4rFKI=",
|
"narHash": "sha256-tPsqU00FhgdFr0JiQUiBMgPVbl1jbPCY5gbFiJycL3I=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "gomod2nix",
|
"repo": "gomod2nix",
|
||||||
"rev": "2cbd7fdd6eeab65c494cc426e18f4e4d2a5e35c0",
|
"rev": "514283ec89c39ad0079ff2f3b1437404e4cba608",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -75,11 +57,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1748026106,
|
"lastModified": 1735834308,
|
||||||
"narHash": "sha256-6m1Y3/4pVw1RWTsrkAK2VMYSzG4MMIj7sqUy7o8th1o=",
|
"narHash": "sha256-dklw3AXr3OGO4/XT1Tu3Xz9n/we8GctZZ75ZWVqAVhk=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "063f43f2dbdef86376cc29ad646c45c46e93234c",
|
"rev": "6df24922a1400241dae323af55f30e4318a6ca65",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -89,28 +71,28 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"p2prc-main": {
|
"p2prc": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils_2",
|
"flake-utils": "flake-utils",
|
||||||
"gomod2nix": "gomod2nix",
|
"gomod2nix": "gomod2nix",
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 0,
|
"lastModified": 0,
|
||||||
"narHash": "sha256-5qbaxawuLsg8iu9076zlAbLtTFSNJaTz7WERS5rWRxU=",
|
"narHash": "sha256-f4e4JcQzBS+R+8HqJbQVeecInm2ggInJuSSymj6gtQo=",
|
||||||
"path": "/nix/store/lg694r23fzc6v5ai3qqcszq1fp44djg2-source",
|
"path": "/nix/store/hmk8v0lxifsscll054qsdnzxqfql1998-source",
|
||||||
"type": "path"
|
"type": "path"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"path": "/nix/store/lg694r23fzc6v5ai3qqcszq1fp44djg2-source",
|
"path": "/nix/store/hmk8v0lxifsscll054qsdnzxqfql1998-source",
|
||||||
"type": "path"
|
"type": "path"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"p2prc-main": "p2prc-main"
|
"p2prc": "p2prc",
|
||||||
|
"utils": "utils"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
@@ -142,6 +124,24 @@
|
|||||||
"repo": "default",
|
"repo": "default",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|||||||
@@ -1,26 +1,22 @@
|
|||||||
{
|
{
|
||||||
description = "Nix flake for P2PRC Haskell library";
|
description = "Nix flake for P2PRC Haskell library";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
p2prc.url = "../../";
|
||||||
p2prc-main.url = "../../";
|
utils.url = "github:numtide/flake-utils";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { nixpkgs, flake-utils, p2prc-main, ... }:
|
outputs = { self, nixpkgs, utils, p2prc }: utils.lib.eachDefaultSystem (system:
|
||||||
flake-utils.lib.eachDefaultSystem (system:
|
|
||||||
let
|
let
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
||||||
packages.default = pkgs.haskellPackages.callPackage ./project.nix {};
|
|
||||||
|
|
||||||
devShell = pkgs.mkShell {
|
devShell = pkgs.mkShell {
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
cabal2nix
|
|
||||||
cabal-install
|
cabal-install
|
||||||
ghc
|
haskell.compiler.ghc96
|
||||||
zlib.dev
|
zlib.dev
|
||||||
p2prc-main.packages.${system}.default
|
p2prc.outputs.packages.${system}.default
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ module API
|
|||||||
( P2PRCapi(..)
|
( P2PRCapi(..)
|
||||||
, MapPortRequest(..)
|
, MapPortRequest(..)
|
||||||
, p2prcAPI
|
, p2prcAPI
|
||||||
, P2PRCommands(..)
|
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
@@ -14,7 +13,6 @@ import System.Process ( ProcessHandle )
|
|||||||
|
|
||||||
import Data.Aeson ( FromJSON )
|
import Data.Aeson ( FromJSON )
|
||||||
|
|
||||||
|
|
||||||
import Error
|
import Error
|
||||||
( IOEitherError
|
( IOEitherError
|
||||||
)
|
)
|
||||||
@@ -51,26 +49,15 @@ data P2PRCapi
|
|||||||
-- ^ List servers in network
|
-- ^ List servers in network
|
||||||
, execMapPort :: MapPortRequest -> IOEitherError MapPortResponse
|
, execMapPort :: MapPortRequest -> IOEitherError MapPortResponse
|
||||||
-- ^ Exposes and associates a local TCP port with a remote DNS address
|
-- ^ Exposes and associates a local TCP port with a remote DNS address
|
||||||
, execMaybeMapPortAndAddCustomInformation :: Maybe MapPortRequest -> PassCustomInformation -> IOEitherError String
|
|
||||||
, execAddCustomInformation :: PassCustomInformation -> IOEitherError String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- | This defines the request required to create an association between a TCP socket port and a DNS server in the network. If successful, it makes a resource available in the network.
|
-- | This defines the request required to create an association between a TCP socket port and a DNS server in the network. If successful, it makes a resource available in the network.
|
||||||
data MapPortRequest =
|
data MapPortRequest =
|
||||||
MkMapPortRequest -- ^ P2PRC's port allocation request value
|
MkMapPortRequest -- ^ P2PRC's port allocation request value
|
||||||
Int -- ^ TCP socket number
|
Int -- ^ TCP socket number
|
||||||
String -- ^ Network domain name
|
String -- ^ Network domain name
|
||||||
|
|
||||||
-- | This defined the custom information required to be passed through.
|
|
||||||
newtype PassCustomInformation =
|
|
||||||
MkAddCustomInformation
|
|
||||||
String
|
|
||||||
|
|
||||||
data P2PRCommands
|
|
||||||
= MapPort MapPortRequest
|
|
||||||
| CustomInformation PassCustomInformation
|
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
This function intiates a pure P2PRC runtime state and builds up a 'P2PRCapi' API instance. It allows a developer to create computing orchestration algorithms using the API primitives.
|
This function intiates a pure P2PRC runtime state and builds up a 'P2PRCapi' API instance. It allows a developer to create computing orchestration algorithms using the API primitives.
|
||||||
@@ -107,15 +94,9 @@ main =
|
|||||||
|
|
||||||
{-# WARNING p2prcAPI "This function is currently unstable because the configuration reading is dependent on the following issue: https://github.com/Akilan1999/p2p-rendering-computation/issues/120" #-}
|
{-# WARNING p2prcAPI "This function is currently unstable because the configuration reading is dependent on the following issue: https://github.com/Akilan1999/p2p-rendering-computation/issues/120" #-}
|
||||||
p2prcAPI :: P2PRCapi
|
p2prcAPI :: P2PRCapi
|
||||||
p2prcAPI = let
|
p2prcAPI =
|
||||||
|
|
||||||
execTemp :: Maybe MapPortRequest -> PassCustomInformation -> IOEitherError String
|
|
||||||
execTemp mp ci = undefined
|
|
||||||
|
|
||||||
|
|
||||||
in
|
|
||||||
MkP2PRCapi
|
MkP2PRCapi
|
||||||
{ startServer = spawnProcP2PRC p2prcCmdName [ MkOptAtomic "-s" ]
|
{ startServer = spawnProcP2PRC p2prcCmdName [ MkOptAtomic "--s" ]
|
||||||
|
|
||||||
, execListServers =
|
, execListServers =
|
||||||
execProcP2PRCParser [ MkOptAtomic "--ls" ] MkEmptyStdInput
|
execProcP2PRCParser [ MkOptAtomic "--ls" ] MkEmptyStdInput
|
||||||
@@ -134,9 +115,6 @@ p2prcAPI = let
|
|||||||
]
|
]
|
||||||
MkEmptyStdInput
|
MkEmptyStdInput
|
||||||
|
|
||||||
, execMaybeMapPortAndAddCustomInformation = execTemp
|
|
||||||
, execAddCustomInformation = execTemp Nothing
|
|
||||||
|
|
||||||
-- , execInitConfig = do
|
-- , execInitConfig = do
|
||||||
|
|
||||||
-- confInitRes <- execProcP2PRC [ MkOptAtomic "--dc" ] MkEmptyStdInput
|
-- confInitRes <- execProcP2PRC [ MkOptAtomic "--dc" ] MkEmptyStdInput
|
||||||
|
|||||||
@@ -116,5 +116,5 @@ 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"
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
module Engine
|
module Engine
|
||||||
( runP2PRC
|
( runP2PRC
|
||||||
, fn
|
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
@@ -19,7 +18,7 @@ import System.Process ( terminateProcess )
|
|||||||
import API
|
import API
|
||||||
( P2PRCapi(..)
|
( P2PRCapi(..)
|
||||||
, MapPortRequest(..)
|
, MapPortRequest(..)
|
||||||
, p2prcAPI, P2PRCommands
|
, p2prcAPI
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -59,10 +58,14 @@ import API
|
|||||||
@
|
@
|
||||||
-}
|
-}
|
||||||
runP2PRC
|
runP2PRC
|
||||||
:: [P2PRCommands] -- ^ TCP Port Request
|
:: MapPortRequest -- ^ TCP Port Request
|
||||||
-> IO ()
|
-> IO ()
|
||||||
runP2PRC [] = putStrLn ""
|
runP2PRC
|
||||||
runP2PRC nonEmpty@(_:_) =
|
( MkMapPortRequest
|
||||||
|
portNumber
|
||||||
|
domainName
|
||||||
|
)
|
||||||
|
=
|
||||||
let
|
let
|
||||||
|
|
||||||
--
|
--
|
||||||
@@ -95,7 +98,6 @@ runP2PRC nonEmpty@(_:_) =
|
|||||||
-- , execInitConfig = execInitConfig
|
-- , execInitConfig = execInitConfig
|
||||||
, execListServers = execListServers
|
, execListServers = execListServers
|
||||||
, execMapPort = execMapPort
|
, execMapPort = execMapPort
|
||||||
, execAddCustomInformation = _
|
|
||||||
}
|
}
|
||||||
) = p2prcAPI
|
) = p2prcAPI
|
||||||
|
|
||||||
@@ -114,8 +116,7 @@ runP2PRC nonEmpty@(_:_) =
|
|||||||
|
|
||||||
|
|
||||||
case eitherStartProcessHandle of
|
case eitherStartProcessHandle of
|
||||||
(Right startProcessHandle) ->
|
(Right startProcessHandle) -> do
|
||||||
do
|
|
||||||
|
|
||||||
let sleepNSecs i = threadDelay (i * 1000000)
|
let sleepNSecs i = threadDelay (i * 1000000)
|
||||||
|
|
||||||
@@ -124,8 +125,7 @@ runP2PRC nonEmpty@(_:_) =
|
|||||||
outputStr <- execListServers
|
outputStr <- execListServers
|
||||||
print outputStr
|
print outputStr
|
||||||
|
|
||||||
-- mapPortOut <- execMapPort $ MkMapPortRequest portNumber domainName
|
mapPortOut <- execMapPort $ MkMapPortRequest portNumber domainName
|
||||||
mapPortOut <- execMapPort $ MkMapPortRequest undefined undefined
|
|
||||||
|
|
||||||
case mapPortOut of
|
case mapPortOut of
|
||||||
(Right v) -> print v
|
(Right v) -> print v
|
||||||
@@ -159,7 +159,3 @@ runP2PRC nonEmpty@(_:_) =
|
|||||||
when (toLower c /= 'q') $ exitOnQ exitF
|
when (toLower c /= 'q') $ exitOnQ exitF
|
||||||
exitF
|
exitF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn :: undefined
|
|
||||||
fn = undefined
|
|
||||||
@@ -52,7 +52,6 @@ module P2PRC
|
|||||||
, P2PRCConfig(..)
|
, P2PRCConfig(..)
|
||||||
, MapPortRequest(..)
|
, MapPortRequest(..)
|
||||||
, MapPortResponse(..)
|
, MapPortResponse(..)
|
||||||
, P2PRCommands(..)
|
|
||||||
|
|
||||||
-- ** Primitive data types
|
-- ** Primitive data types
|
||||||
-- | These types represent the core data that is communicated between requests and the runtime.
|
-- | These types represent the core data that is communicated between requests and the runtime.
|
||||||
@@ -84,7 +83,6 @@ import API
|
|||||||
( MapPortRequest(..)
|
( MapPortRequest(..)
|
||||||
, P2PRCapi(..)
|
, P2PRCapi(..)
|
||||||
, p2prcAPI
|
, p2prcAPI
|
||||||
, P2PRCommands(..)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
{ mkDerivation, aeson, base, bytestring, directory, lib, process
|
|
||||||
, text
|
|
||||||
}:
|
|
||||||
mkDerivation {
|
|
||||||
pname = "p2prc";
|
|
||||||
version = "0.1.0.0";
|
|
||||||
src = ./.;
|
|
||||||
libraryHaskellDepends = [
|
|
||||||
aeson base bytestring directory process text
|
|
||||||
];
|
|
||||||
description = "P2PRC haskell library";
|
|
||||||
license = "unknown";
|
|
||||||
}
|
|
||||||
@@ -3,14 +3,10 @@ module Main where
|
|||||||
import P2PRC
|
import P2PRC
|
||||||
( runP2PRC
|
( runP2PRC
|
||||||
, MapPortRequest(MkMapPortRequest)
|
, MapPortRequest(MkMapPortRequest)
|
||||||
, P2PRCommands(MapPort)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main =let
|
main =
|
||||||
in
|
|
||||||
runP2PRC
|
runP2PRC
|
||||||
[
|
( MkMapPortRequest 8080 "jose.akilan.io"
|
||||||
( MapPort $ MkMapPortRequest 8080 "jose.akilan.io")
|
)
|
||||||
]
|
|
||||||
|
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
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
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
603
Docs/index.html
603
Docs/index.html
File diff suppressed because it is too large
Load Diff
177
Docs/index.org
177
Docs/index.org
@@ -182,110 +182,6 @@ GLOBAL OPTIONS:
|
|||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Nix Flake
|
|
||||||
|
|
||||||
Nix is a growing ecosystem that allows flexibility on how you develop, build and package software and configurations. It brings all programming languages (and all other tooling) to an equal footing, despite deep design differences. More importantly, integrates all the "packaging" into the context of a "pure" function.
|
|
||||||
|
|
||||||
|
|
||||||
P2PRC aims to become a utility that can be used in various flexible manners and having Nix support is a good alternative to accomplish this goal.
|
|
||||||
|
|
||||||
|
|
||||||
Nix Flake is a format, within the Nix ecosystem, intentionally designed to encourage a standard in packaging distribution. The current packaging assumes that you have "nix flake" installed because it is currently an experimental feature of Nix.
|
|
||||||
|
|
||||||
|
|
||||||
** P2PRC core Go language repo
|
|
||||||
|
|
||||||
In case you want to develop, build or integrate using nix, you just need to run either "nix develop" or "nix run" from the command line locally in a cloned git repository or by running "nix run github:akilan1999/p2p-rendering-computation -- --help"
|
|
||||||
|
|
||||||
|
|
||||||
P2PRC library also is ready to be imported into other nix flakes. To accomplish that please make sure to override the target nixpkgs environment in the following manner;
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
pkgs = import nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
overlays = [
|
|
||||||
p2prc-flake.overlays.default
|
|
||||||
];
|
|
||||||
};
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
|
|
||||||
This will make the p2prc executable available in the environment of any application you use.
|
|
||||||
|
|
||||||
** P2PRC Haskell library
|
|
||||||
|
|
||||||
*** Nix:
|
|
||||||
The project is structured to provide language bindings to any programming language. The first one being supported in this manner is the Haskell programming language. It provides a bootstrapping script for a new Cabal project with p2prc binary available in the environment and, more relevantly, the Haskell library bindings available in the virtual environment cabal environment.
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
nix run git+https://github.com/akilan1999/p2p-rendering-computation#initHaskellProject -- <PROJECT_NAME>
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
|
|
||||||
This will generate a new haskell project setup to automatically work with the p2prc development and running environment.
|
|
||||||
|
|
||||||
|
|
||||||
Once completed, you should go into the project directory and copy the nix flake template, necessary to define the project's environment.
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
nix flake init -t github:akilan1999/p2p-rendering-computation#haskell
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
The previous command sets up the flake environment and its dependencies. It will look like the following
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
{
|
|
||||||
description = "Start of Haskell P2PRC flake";
|
|
||||||
|
|
||||||
inputs =
|
|
||||||
{
|
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
||||||
|
|
||||||
flake-util.url = "github:numtide/flake-utils";
|
|
||||||
|
|
||||||
p2prc-flake.url = "github:akilan1999/p2p-rendering-computation";
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs = { nixpkgs, p2prc-flake, flake-utils, ... }:
|
|
||||||
(flake-utils.lib.eachDefaultSystem (system:
|
|
||||||
let
|
|
||||||
|
|
||||||
pkgs = import nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
overlays = [
|
|
||||||
p2prc-flake.overlays.default
|
|
||||||
p2prc-flake.overlays.bindings
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
in {
|
|
||||||
|
|
||||||
packages.default = pkgs.haskellPackages.callPackage ./cabal.nix { };
|
|
||||||
|
|
||||||
devShells.default = pkgs.haskellPackages.shellFor {
|
|
||||||
|
|
||||||
packages = p: [
|
|
||||||
(p.callPackage ./cabal.nix { })
|
|
||||||
];
|
|
||||||
|
|
||||||
buildInputs = with pkgs; [
|
|
||||||
p2prc-flake.packages.${system}.default
|
|
||||||
ghc
|
|
||||||
cabal2nix
|
|
||||||
cabal-install
|
|
||||||
];
|
|
||||||
|
|
||||||
shellHook = ''
|
|
||||||
cabal2nix . > ./cabal.nix
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
The template uses Cabal2Nix which manages the Haskell virtual environment automatically. It applies the system overlays, sets up the shell environment for the project (updating the Cabal2Nix configuration) and packages the main executable.
|
|
||||||
|
|
||||||
* Using basic commands
|
* Using basic commands
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: using-basic-commands
|
:CUSTOM_ID: using-basic-commands
|
||||||
@@ -772,24 +668,7 @@ called from other programming languages.
|
|||||||
P2PRC officially supports Haskell bindings and will further support
|
P2PRC officially supports Haskell bindings and will further support
|
||||||
project using Haskell to build orchestrators on top of P2PRC.
|
project using Haskell to build orchestrators on top of P2PRC.
|
||||||
|
|
||||||
**** Local machine without Nix
|
[[https://p2prc.akilan.io/Docs/haskell][Read more...]]
|
||||||
On the local machine we just create a folder as exports which copies the p2prc haskell bindings
|
|
||||||
and the latest build of the p2prc binary. After the binary is copied it runs the --dc in p2prc to setup the
|
|
||||||
basic p2prc configurations. To do the following just do:
|
|
||||||
#+begin_example
|
|
||||||
make haskell
|
|
||||||
#+end_example
|
|
||||||
**** Directory to enter into
|
|
||||||
#+begin_example
|
|
||||||
cd Bindings/Haskell/exports
|
|
||||||
#+end_example
|
|
||||||
**** Run
|
|
||||||
#+begin_example
|
|
||||||
- cabal build
|
|
||||||
- cabal run
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
[[https://p2prc.akilan.io/haskell][Read more...]]
|
|
||||||
|
|
||||||
* Config Implementation
|
* Config Implementation
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
@@ -811,28 +690,18 @@ configuration file was generated using JSON format.
|
|||||||
|
|
||||||
#+begin_src json
|
#+begin_src json
|
||||||
{
|
{
|
||||||
"MachineName": "Akilans-MacBook-Pro.local-975261X",
|
"MachineName": "pc-74-120.customer.ask4.lan",
|
||||||
"IPTable": "/Users/akilan/Documents/p2p-rendering-computation/p2p/iptable/ip_table.json",
|
"IPTable": "/Users/akilan/Documents/p2p-rendering-computation/p2p/iptable/ip_table.json",
|
||||||
"DockerContainers": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/",
|
"DockerContainers": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/",
|
||||||
"DefaultDockerFile": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/docker-ubuntu-sshd/",
|
"DefaultDockerFile": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/docker-ubuntu-sshd/",
|
||||||
"DockerRunLogs": "/tmp/",
|
|
||||||
"SpeedTestFile": "/Users/akilan/Documents/p2p-rendering-computation/p2p/50.bin",
|
"SpeedTestFile": "/Users/akilan/Documents/p2p-rendering-computation/p2p/50.bin",
|
||||||
"IPV6Address": "",
|
"IPV6Address": "",
|
||||||
"PluginPath": "/Users/akilan/Documents/p2p-rendering-computation/plugin/deploy",
|
"PluginPath": "/Users/akilan/Documents/p2p-rendering-computation/plugin/deploy",
|
||||||
"TrackContainersPath": "/Users/akilan/Documents/p2p-rendering-computation/client/trackcontainers/trackcontainers.json",
|
"TrackContainersPath": "/Users/akilan/Documents/p2p-rendering-computation/client/trackcontainers/trackcontainers.json",
|
||||||
"ServerPort": "8088",
|
"ServerPort": "8088",
|
||||||
"ProxyPort": "",
|
|
||||||
"GroupTrackContainersPath": "/Users/akilan/Documents/p2p-rendering-computation/client/trackcontainers/grouptrackcontainers.json",
|
"GroupTrackContainersPath": "/Users/akilan/Documents/p2p-rendering-computation/client/trackcontainers/grouptrackcontainers.json",
|
||||||
"FRPServerPort": true,
|
"FRPServerPort": "True",
|
||||||
"BehindNAT": true,
|
"BehindNAT": "True",
|
||||||
"IPTableKey": "QH3yQrGRe2X4",
|
|
||||||
"PublicKeyFile": "/Users/akilan/Documents/p2p-rendering-computation/p2prc.publicKey",
|
|
||||||
"PrivateKeyFile": "/Users/akilan/Documents/p2p-rendering-computation/p2prc.privateKey",
|
|
||||||
"PemFile": "/Users/akilan/Documents/p2p-rendering-computation/cert.pem",
|
|
||||||
"KeyFile": "/Users/akilan/Documents/p2p-rendering-computation/key.pem",
|
|
||||||
"BareMetal": false,
|
|
||||||
"UnsafeMode": false,
|
|
||||||
"Test": false,
|
|
||||||
"CustomConfig": null
|
"CustomConfig": null
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
@@ -914,48 +783,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
* Simulation
|
|
||||||
The simulation library is a really simple library to locally
|
|
||||||
run serveral instances of P2PRC to test the functionality
|
|
||||||
of sending information through the network and particularly
|
|
||||||
the Node discovery mechanism. There are current 5 commands
|
|
||||||
which can be used as shown below:
|
|
||||||
|
|
||||||
** Command
|
|
||||||
- ***P2PRC instances "number of instances"*** : Starts p2prc processes
|
|
||||||
based on the number of number instances provided. This includes
|
|
||||||
creating temporary folders with independent IPTables.
|
|
||||||
- ***Start all instances "number of instances"***: Starts the P2PRC instances
|
|
||||||
created. This function enters into the instance directory and runs
|
|
||||||
```p2prc -s &``` with a delay for approximately 3 seconds. This allows
|
|
||||||
each independent created node to learn about each other.
|
|
||||||
- ***IP Tables after Started number of instances"***: Prints the IPTable of
|
|
||||||
each independant node.
|
|
||||||
- ***Remove all test files***: Removes all test files created which needed for
|
|
||||||
testing the generated P2PRC instances.
|
|
||||||
- ***Kill all instances***: Kills all the background P2PRC instances created.
|
|
||||||
|
|
||||||
** Sample bash instructions
|
|
||||||
#+begin_src bash
|
|
||||||
# Unset default P2PRC env path
|
|
||||||
unset P2PRC
|
|
||||||
|
|
||||||
# Run with 2 nodes
|
|
||||||
P2PRC_instances 3
|
|
||||||
|
|
||||||
# Start instances
|
|
||||||
Start_all_instances 3
|
|
||||||
|
|
||||||
# List ip tables of nodes started
|
|
||||||
IP_Tables_after_Started 3
|
|
||||||
|
|
||||||
# Remove test files created
|
|
||||||
Remove_all_test_files
|
|
||||||
|
|
||||||
# Kill all instances
|
|
||||||
Kill_all_instances
|
|
||||||
#+end_src
|
|
||||||
Source code: https://github.com/Akilan1999/p2p-rendering-computation/blob/master/Simulation/simulation.sh
|
|
||||||
* Blog posts
|
* Blog posts
|
||||||
** Self host within 5 minutes any program
|
** Self host within 5 minutes any program
|
||||||
|
|
||||||
|
|||||||
3
Makefile
3
Makefile
@@ -14,9 +14,6 @@ sharedObjects:
|
|||||||
python:
|
python:
|
||||||
sh build-python-package.sh
|
sh build-python-package.sh
|
||||||
|
|
||||||
haskell:
|
|
||||||
sh build-haskell.sh
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
go clean -modcache
|
go clean -modcache
|
||||||
rm -fr .go-build vendor result*
|
rm -fr .go-build vendor result*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
> [!TIP]
|
> [!TIP]
|
||||||
> Haskell bindings supported!: [Bindings documentaton](https://p2prc.akilan.io/haskell/P2PRC.html)
|
> Haskell bindings supported!: [Bindings documentaton](https://p2prc.akilan.io/Docs/haskell/P2PRC.html)
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Fixing documentation to latest changes. If you have any questions setting up P2PRC either [create an issue](https://github.com/Akilan1999/p2p-rendering-computation/issues/new/choose) or send me an email (me AT akilan dot io).
|
> Fixing documentation to latest changes. If you have any questions setting up P2PRC either [create an issue](https://github.com/Akilan1999/p2p-rendering-computation/issues/new/choose) or send me an email (me AT akilan dot io).
|
||||||
@@ -57,7 +57,7 @@ alias p2prc='env P2PRC=<path you want the configs to exist in> nix run github:ak
|
|||||||
```bash
|
```bash
|
||||||
p2prc -h
|
p2prc -h
|
||||||
```
|
```
|
||||||
Read more on command usage: https://p2prc.akilan.io/#using-basic-commands
|
Read more on command usage: https://p2prc.akilan.io/Docs/#using-basic-commands
|
||||||
|
|
||||||
## Latest tutorial
|
## Latest tutorial
|
||||||
[](https://www.youtube.com/watch?v=OMwCpedu5cs")
|
[](https://www.youtube.com/watch?v=OMwCpedu5cs")
|
||||||
@@ -66,7 +66,7 @@ Read more on command usage: https://p2prc.akilan.io/#using-basic-commands
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
### We have documented to our best effort the basics of p2prc: [Link](https://p2prc.akilan.io/)
|
### We have documented to our best effort the basics of p2prc: [Link](https://p2prc.akilan.io/Docs/)
|
||||||
|
|
||||||
<!-- ## Table of contents in the current README -->
|
<!-- ## Table of contents in the current README -->
|
||||||
<!-- 1. [Introduction](#Introduction)
|
<!-- 1. [Introduction](#Introduction)
|
||||||
|
|||||||
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")
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
# Unset P2PRC
|
|
||||||
unset P2PRC
|
|
||||||
|
|
||||||
# Create P2PRC instances
|
|
||||||
# Parameters:
|
|
||||||
# 1. Number of nodes
|
|
||||||
P2PRC_instances() {
|
|
||||||
local rootPort=""
|
|
||||||
for (( counter=0; counter<$1; counter++ )); do
|
|
||||||
mkdir test-$counter/
|
|
||||||
cd test-$counter/
|
|
||||||
|
|
||||||
# Generate a new random port
|
|
||||||
NEW_PORT=$(shuf -i 2000-65000 -n 1)
|
|
||||||
|
|
||||||
# Initialize node
|
|
||||||
p2prc --dc
|
|
||||||
|
|
||||||
# Save rootPort from the first node
|
|
||||||
if [[ $counter -eq 0 ]]; then
|
|
||||||
rootPort=$NEW_PORT
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Root port: $rootPort"
|
|
||||||
echo "This node's port: $NEW_PORT"
|
|
||||||
|
|
||||||
# Set root port
|
|
||||||
p2prc --arn --ip 0.0.0.0 -p "$rootPort"
|
|
||||||
|
|
||||||
# add current node
|
|
||||||
p2prc --as 0.0.0.0 -p "$NEW_PORT"
|
|
||||||
|
|
||||||
# Replace the ServerPort in config
|
|
||||||
# test-$counter
|
|
||||||
sed -i.bak "s/\"ServerPort\": \"[0-9]*\"/\"ServerPort\": \"$NEW_PORT\"/" "./config.json"
|
|
||||||
sed -i.bak "s/\"Test\": false/\"Test\": true/" "./config.json"
|
|
||||||
sed -i.bak "s/\"BehindNAT\": true/\"BehindNAT\": false/" "./config.json"
|
|
||||||
# sed -i.bak "s/\"MachineName\": "Akilans-MacBook-Pro.local-J2UbbkF"/\"MachineName\": \"test-$counter\"/" "./config.json"
|
|
||||||
|
|
||||||
cat config.json
|
|
||||||
|
|
||||||
# List services
|
|
||||||
p2prc --ls
|
|
||||||
|
|
||||||
cd ..
|
|
||||||
done
|
|
||||||
|
|
||||||
# remove all instances after testing (optional — might want to comment this during testing)
|
|
||||||
# rm -rf test-*
|
|
||||||
}
|
|
||||||
|
|
||||||
# Arrays of process IDs
|
|
||||||
pids=()
|
|
||||||
|
|
||||||
# Calls all the P2PRC instances created for testing
|
|
||||||
Start_all_instances() {
|
|
||||||
for (( counter=0; counter<$1; counter++ )); do
|
|
||||||
cd test-$counter/
|
|
||||||
# Start P2PRC as background process
|
|
||||||
p2prc -s &
|
|
||||||
pids+=($!)
|
|
||||||
sleep 3
|
|
||||||
cd ..
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Kills all P2PRC instances
|
|
||||||
Kill_all_instances() {
|
|
||||||
for pid in "${pids[@]}"; do
|
|
||||||
kill "$pid"
|
|
||||||
echo "Killed process $pid"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Removes all test files created
|
|
||||||
Remove_all_test_files() {
|
|
||||||
rm -rf test-*
|
|
||||||
}
|
|
||||||
|
|
||||||
# List ip tables of all nodes started
|
|
||||||
IP_Tables_after_Started() {
|
|
||||||
for (( counter=0; counter<$1; counter++ )); do
|
|
||||||
cd test-$counter/
|
|
||||||
p2prc --ls
|
|
||||||
cd ..
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
Update_All_IP_Tables() {
|
|
||||||
for (( counter=0; counter<$1; counter++ )); do
|
|
||||||
cd test-$counter/
|
|
||||||
p2prc --us
|
|
||||||
cd ..
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test function for the root to custom information
|
|
||||||
# through the network
|
|
||||||
Send_Information() {
|
|
||||||
ls
|
|
||||||
cd test-2/
|
|
||||||
p2prc --amd "test message"
|
|
||||||
cd ..
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------- Work flow test ---------------
|
|
||||||
|
|
||||||
# Unset default P2PRC env path
|
|
||||||
unset P2PRC
|
|
||||||
|
|
||||||
# Run with 2 nodes
|
|
||||||
P2PRC_instances 3
|
|
||||||
|
|
||||||
## Start instances
|
|
||||||
Start_all_instances 3
|
|
||||||
|
|
||||||
|
|
||||||
# Send test information from node 1
|
|
||||||
sleep 10
|
|
||||||
Send_Information
|
|
||||||
|
|
||||||
sleep 10
|
|
||||||
## List ip tables of nodes started
|
|
||||||
IP_Tables_after_Started 3
|
|
||||||
#
|
|
||||||
## Remove test files created
|
|
||||||
Remove_all_test_files
|
|
||||||
|
|
||||||
## Kill all instances
|
|
||||||
Kill_all_instances
|
|
||||||
|
|
||||||
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")
|
||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"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"
|
||||||
)
|
)
|
||||||
@@ -56,17 +55,17 @@ func MapPort(port string, domainName string, serverAddress string) (response *cl
|
|||||||
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) {
|
||||||
|
|||||||
BIN
artwork/.DS_Store
vendored
BIN
artwork/.DS_Store
vendored
Binary file not shown.
BIN
artwork/p2prc-logos/.DS_Store
vendored
BIN
artwork/p2prc-logos/.DS_Store
vendored
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 922 KiB |
@@ -1,31 +0,0 @@
|
|||||||
# This bash script consists of the manaul build script of haskell
|
|
||||||
go build .
|
|
||||||
|
|
||||||
# Unset p2prc path
|
|
||||||
unset p2prc
|
|
||||||
|
|
||||||
# Enter the haskell project
|
|
||||||
cd Bindings/haskell
|
|
||||||
# Remove exsisting export build
|
|
||||||
rm -rf exports
|
|
||||||
# Create exports directory
|
|
||||||
mkdir exports
|
|
||||||
# Copy current haskell project into the folder
|
|
||||||
cp -rf . exports/
|
|
||||||
# Copy p2prc binary inside haskell folder
|
|
||||||
cp ../../p2p-rendering-computation exports/
|
|
||||||
|
|
||||||
cd exports
|
|
||||||
# remove exports directory copied inside exports
|
|
||||||
rm -rf exports/
|
|
||||||
|
|
||||||
# Set p2prc variable
|
|
||||||
echo export P2PRC=$PWD
|
|
||||||
|
|
||||||
export P2PRC=$PWD
|
|
||||||
|
|
||||||
./p2p-rendering-computation --dc
|
|
||||||
|
|
||||||
echo "Run the following commands in the directory: ${PWD}"
|
|
||||||
echo "To build: cabal build"
|
|
||||||
echo "To run sample program: cabal run"
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ func AddCustomInformationToIPTable(text string) error {
|
|||||||
if found {
|
if found {
|
||||||
table.WriteIpTable()
|
table.WriteIpTable()
|
||||||
// update IPTable after modified entry
|
// update IPTable after modified entry
|
||||||
UpdateIpTableListClient()
|
go UpdateIpTableListClient()
|
||||||
} else {
|
} else {
|
||||||
return errors.New("start server with p2prc -s as the server is currently not running")
|
return errors.New("start server with p2prc -s as the server is currently not running")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ func UpdateIpTableListClient() error {
|
|||||||
|
|
||||||
Exists := false
|
Exists := false
|
||||||
// If the address is local then add to the local list
|
// If the address is local then add to the local list
|
||||||
if (currentIPV4 == Addresses.IpAddress[j].Ipv4 && !Config.Test) && Addresses.IpAddress[j].ServerPort == Config.ServerPort {
|
if currentIPV4 == Addresses.IpAddress[j].Ipv4 && Addresses.IpAddress[j].ServerPort == Config.ServerPort {
|
||||||
Exists = true
|
Exists = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,12 +136,11 @@ func UpdateIpTableListClient() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
w.Add(1)
|
w.Add(1)
|
||||||
//if Addresses.IpAddress[j].Ipv6 != "" {
|
if Addresses.IpAddress[j].Ipv6 != "" {
|
||||||
// go UpdateIpTable(Addresses.IpAddress[j].Ipv6, Addresses.IpAddress[j].ServerPort, &w)
|
go UpdateIpTable(Addresses.IpAddress[j].Ipv6, Addresses.IpAddress[j].ServerPort, &w)
|
||||||
//} else if Addresses.IpAddress[j].Ipv4 != currentIPV4 {
|
} else if Addresses.IpAddress[j].Ipv4 != currentIPV4 {
|
||||||
// //go UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort, &w)
|
|
||||||
//}
|
|
||||||
go UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort, &w)
|
go UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort, &w)
|
||||||
|
}
|
||||||
w.Wait()
|
w.Wait()
|
||||||
|
|
||||||
//Appends server1 IP address to variable DoNotRead
|
//Appends server1 IP address to variable DoNotRead
|
||||||
|
|||||||
@@ -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"
|
|
||||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
serverPort = "8088"
|
|
||||||
client = http.Client{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// StartContainer Start container using REST api Implementation
|
|
||||||
// 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
|
|
||||||
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
|
|
||||||
//version := p2p.Ip4or6(IP)
|
|
||||||
//
|
//
|
||||||
////Get port number of the server
|
//// StartContainer Start container using REST api Implementation
|
||||||
//serverPort, err := GetServerPort(IP)
|
//// 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
|
||||||
|
//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
|
||||||
|
// //version := p2p.Ip4or6(IP)
|
||||||
|
// //
|
||||||
|
// ////Get port number of the server
|
||||||
|
// //serverPort, err := GetServerPort(IP)
|
||||||
|
// //if err != nil {
|
||||||
|
// // return nil, err
|
||||||
|
// //}
|
||||||
|
//
|
||||||
|
// //if version == "version 6" {
|
||||||
|
// // URL = "http://[" + IP + "]:" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
||||||
|
// //} else {
|
||||||
|
// // Get config information
|
||||||
|
// Config, err := config.ConfigInit(nil, nil)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return nil, err
|
// return nil, err
|
||||||
// }
|
// }
|
||||||
|
|
||||||
//if version == "version 6" {
|
|
||||||
// URL = "http://[" + IP + "]:" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
|
||||||
//} else {
|
|
||||||
// Get config information
|
|
||||||
Config, err := config.ConfigInit(nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get public key
|
|
||||||
PublicKey, err := Config.GetPublicKey()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used in URL to pass public key -> b64.StdEncoding.EncodeToString([]byte(PublicKey))
|
|
||||||
URL = `http://` + IP + `/startcontainer?ports=` + fmt.Sprint(NumPorts) + `&GPU=` + strconv.FormatBool(GPU) + `&ContainerName=` + ContainerName + `&BaseImage=` + baseImage + `&PublicKey=` + b64.StdEncoding.EncodeToString([]byte(PublicKey))
|
|
||||||
|
|
||||||
// Encode URL due to public key passed.
|
|
||||||
resp, err := http.Get(URL)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert response to byte value
|
|
||||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create variable for result response type
|
|
||||||
var dockerResult docker.DockerVM
|
|
||||||
|
|
||||||
// Adds byte value to docker.DockerVM struct
|
|
||||||
json.Unmarshal(byteValue, &dockerResult)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds the container to the tracked list
|
|
||||||
err = AddTrackContainer(&dockerResult, IP)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &dockerResult, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveContianer Stops and removes container from the server
|
|
||||||
func RemoveContianer(IP string, ID string) error {
|
|
||||||
var URL string
|
|
||||||
//version := p2p.Ip4or6(IP)
|
|
||||||
//
|
//
|
||||||
////Get port number of the server
|
// // Get public key
|
||||||
//serverPort, err := GetServerPort(IP)
|
// PublicKey, err := Config.GetPublicKey()
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Used in URL to pass public key -> b64.StdEncoding.EncodeToString([]byte(PublicKey))
|
||||||
|
// URL = `http://` + IP + `/startcontainer?ports=` + fmt.Sprint(NumPorts) + `&GPU=` + strconv.FormatBool(GPU) + `&ContainerName=` + ContainerName + `&BaseImage=` + baseImage + `&PublicKey=` + b64.StdEncoding.EncodeToString([]byte(PublicKey))
|
||||||
|
//
|
||||||
|
// // Encode URL due to public key passed.
|
||||||
|
// resp, err := http.Get(URL)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Convert response to byte value
|
||||||
|
// byteValue, err := ioutil.ReadAll(resp.Body)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Create variable for result response type
|
||||||
|
// var dockerResult docker.DockerVM
|
||||||
|
//
|
||||||
|
// // Adds byte value to docker.DockerVM struct
|
||||||
|
// json.Unmarshal(byteValue, &dockerResult)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Adds the container to the tracked list
|
||||||
|
// err = AddTrackContainer(&dockerResult, IP)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return &dockerResult, nil
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// RemoveContianer Stops and removes container from the server
|
||||||
|
//func RemoveContianer(IP string, ID string) error {
|
||||||
|
// var URL string
|
||||||
|
// //version := p2p.Ip4or6(IP)
|
||||||
|
// //
|
||||||
|
// ////Get port number of the server
|
||||||
|
// //serverPort, err := GetServerPort(IP)
|
||||||
|
// //if err != nil {
|
||||||
|
// // return err
|
||||||
|
// //}
|
||||||
|
//
|
||||||
|
// //if version == "version 6" {
|
||||||
|
// // URL = "http://[" + IP + "]:" + serverPort + "/RemoveContainer?id=" + ID
|
||||||
|
// //} else {
|
||||||
|
// URL = "http://" + IP + "/RemoveContainer?id=" + ID
|
||||||
|
// //}
|
||||||
|
// resp, err := http.Get(URL)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
|
|
||||||
//if version == "version 6" {
|
|
||||||
// URL = "http://[" + IP + "]:" + serverPort + "/RemoveContainer?id=" + ID
|
|
||||||
//} else {
|
|
||||||
URL = "http://" + IP + "/RemoveContainer?id=" + ID
|
|
||||||
//}
|
|
||||||
resp, err := http.Get(URL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert response to byte value
|
|
||||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks if success is returned in the body
|
|
||||||
if string(byteValue[:]) == "success" {
|
|
||||||
fmt.Println("success")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove container from groups it exists in
|
|
||||||
err = RemoveContainerGroups(ID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Remove container created from the tracked list
|
|
||||||
err = RemoveTrackedContainer(ID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ViewContainers This function displays all containers available on server side
|
|
||||||
func ViewContainers(IP string) (*docker.DockerContainers, error) {
|
|
||||||
// Passes URL with route /ShowImages
|
|
||||||
var URL string
|
|
||||||
//version := p2p.Ip4or6(IP)
|
|
||||||
//
|
//
|
||||||
////Get port number of the server
|
// // Convert response to byte value
|
||||||
//serverPort, err := GetServerPort(IP)
|
// byteValue, err := ioutil.ReadAll(resp.Body)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Checks if success is returned in the body
|
||||||
|
// if string(byteValue[:]) == "success" {
|
||||||
|
// fmt.Println("success")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Remove container from groups it exists in
|
||||||
|
// err = RemoveContainerGroups(ID)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// // Remove container created from the tracked list
|
||||||
|
// err = RemoveTrackedContainer(ID)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return nil
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// ViewContainers This function displays all containers available on server side
|
||||||
|
//func ViewContainers(IP string) (*docker.DockerContainers, error) {
|
||||||
|
// // Passes URL with route /ShowImages
|
||||||
|
// var URL string
|
||||||
|
// //version := p2p.Ip4or6(IP)
|
||||||
|
// //
|
||||||
|
// ////Get port number of the server
|
||||||
|
// //serverPort, err := GetServerPort(IP)
|
||||||
|
// //if err != nil {
|
||||||
|
// // return nil, err
|
||||||
|
// //}
|
||||||
|
//
|
||||||
|
// //if version == "version 6" {
|
||||||
|
// // URL = "http://[" + IP + "]:" + serverPort + "/ShowImages"
|
||||||
|
// //} else {
|
||||||
|
// URL = "http://" + IP + "/ShowImages"
|
||||||
|
// //}
|
||||||
|
// resp, err := http.Get(URL)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return nil, err
|
// return nil, err
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
//if version == "version 6" {
|
// // Convert response to byte value
|
||||||
// URL = "http://[" + IP + "]:" + serverPort + "/ShowImages"
|
// byteValue, err := ioutil.ReadAll(resp.Body)
|
||||||
//} else {
|
// if err != nil {
|
||||||
URL = "http://" + IP + "/ShowImages"
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Create variable for result response type
|
||||||
|
// var Result docker.DockerContainers
|
||||||
|
//
|
||||||
|
// // Adds byte value to docker.DockerContainers struct
|
||||||
|
// json.Unmarshal(byteValue, &Result)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return &Result, nil
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// GetServerPort Helper function to do find out server port information
|
||||||
|
//func GetServerPort(IpAddress string) (string, error) {
|
||||||
|
// // Getting information from the clients ip table
|
||||||
|
// ipTable, err := p2p.ReadIpTable()
|
||||||
|
// if err != nil {
|
||||||
|
// return "", err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 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
|
||||||
//}
|
//}
|
||||||
resp, err := http.Get(URL)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert response to byte value
|
|
||||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create variable for result response type
|
|
||||||
var Result docker.DockerContainers
|
|
||||||
|
|
||||||
// Adds byte value to docker.DockerContainers struct
|
|
||||||
json.Unmarshal(byteValue, &Result)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetServerPort Helper function to do find out server port information
|
|
||||||
func GetServerPort(IpAddress string) (string, error) {
|
|
||||||
// Getting information from the clients ip table
|
|
||||||
ipTable, err := p2p.ReadIpTable()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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){
|
||||||
|
|||||||
172
cmd/action.go
172
cmd/action.go
@@ -5,10 +5,8 @@ import (
|
|||||||
"github.com/Akilan1999/p2p-rendering-computation/abstractions"
|
"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"
|
||||||
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/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"
|
||||||
)
|
)
|
||||||
@@ -87,36 +85,36 @@ 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)
|
// standardOutput(err, imageRes)
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// Function called to stop and remove server from Docker
|
//// Function called to stop and remove server from Docker
|
||||||
if RemoveVM != "" {
|
//if RemoveVM != "" {
|
||||||
if ID == "" {
|
// if ID == "" {
|
||||||
fmt.Println("provide container ID via --ID or --id")
|
// fmt.Println("provide container ID via --ID or --id")
|
||||||
} else {
|
// } else {
|
||||||
err := client.RemoveContianer(RemoveVM, ID)
|
// err := client.RemoveContianer(RemoveVM, ID)
|
||||||
standardOutput(err, nil)
|
// standardOutput(err, nil)
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
//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)
|
||||||
|
//
|
||||||
standardOutput(err, imageRes)
|
// standardOutput(err, imageRes)
|
||||||
}
|
//}
|
||||||
|
|
||||||
//Call if specs flag is called
|
//Call if specs flag is called
|
||||||
if Specs != "" {
|
if Specs != "" {
|
||||||
@@ -139,83 +137,83 @@ var CliAction = func(ctx *cli.Context) error {
|
|||||||
|
|
||||||
// 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()
|
||||||
standardOutput(err, plugins)
|
// standardOutput(err, 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()
|
||||||
standardOutput(err, trackedContainers)
|
// standardOutput(err, 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)
|
||||||
standardOutput(err, nil)
|
// standardOutput(err, nil)
|
||||||
}
|
// }
|
||||||
//else {
|
// //else {
|
||||||
// fmt.Println("provide container ID via --ID or --id")
|
// // 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()
|
||||||
standardOutput(err, group)
|
// standardOutput(err, 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)
|
||||||
standardOutput(err, group)
|
// standardOutput(err, group)
|
||||||
} else if ID != "" { // Add container to group based on group ID provided
|
// } else if ID != "" { // Add container to group based on group ID provided
|
||||||
// --id <Container ID>
|
// // --id <Container ID>
|
||||||
group, err := client.AddContainerToGroup(ID, Group)
|
// group, err := client.AddContainerToGroup(ID, Group)
|
||||||
standardOutput(err, group)
|
// standardOutput(err, group)
|
||||||
} else { // View all information about current group
|
// } else { // View all information about current group
|
||||||
group, err := client.GetGroup(Group)
|
// group, err := client.GetGroup(Group)
|
||||||
standardOutput(err, group)
|
// standardOutput(err, 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)
|
||||||
standardOutput(err, nil)
|
// standardOutput(err, nil)
|
||||||
}
|
//}
|
||||||
|
|
||||||
// Execute Function to view all groups
|
// Execute Function to view all groups
|
||||||
if Groups {
|
//if Groups {
|
||||||
groups, err := client.ReadGroup()
|
// groups, err := client.ReadGroup()
|
||||||
standardOutput(err, groups)
|
// standardOutput(err, groups)
|
||||||
}
|
//}
|
||||||
|
|
||||||
//--------------------------------
|
//--------------------------------
|
||||||
|
|
||||||
if PullPlugin != "" {
|
//if PullPlugin != "" {
|
||||||
err := plugin.DownloadPlugin(PullPlugin)
|
// err := plugin.DownloadPlugin(PullPlugin)
|
||||||
standardOutput(err, nil)
|
// standardOutput(err, nil)
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
if RemovePlugin != "" {
|
//if RemovePlugin != "" {
|
||||||
err := plugin.DeletePlugin(RemovePlugin)
|
// err := plugin.DeletePlugin(RemovePlugin)
|
||||||
standardOutput(err, nil)
|
// standardOutput(err, nil)
|
||||||
}
|
//}
|
||||||
|
|
||||||
if AddMetaData != "" {
|
if AddMetaData != "" {
|
||||||
err := clientIPTable.AddCustomInformationToIPTable(AddMetaData)
|
err := clientIPTable.AddCustomInformationToIPTable(AddMetaData)
|
||||||
@@ -233,12 +231,6 @@ var CliAction = func(ctx *cli.Context) error {
|
|||||||
standardOutput(err, nil)
|
standardOutput(err, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// display configuration
|
|
||||||
if ViewConfig {
|
|
||||||
config, err := Config.ConfigInit(nil, nil)
|
|
||||||
standardOutput(err, config)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
276
cmd/flags.go
276
cmd/flags.go
@@ -43,7 +43,6 @@ var (
|
|||||||
AddMetaData string
|
AddMetaData string
|
||||||
AddRootNode bool
|
AddRootNode bool
|
||||||
IP string
|
IP string
|
||||||
ViewConfig bool
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var AppConfigFlags = []cli.Flag{
|
var AppConfigFlags = []cli.Flag{
|
||||||
@@ -75,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"},
|
||||||
@@ -124,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"},
|
||||||
@@ -152,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"},
|
||||||
@@ -232,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"},
|
||||||
@@ -254,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"},
|
||||||
@@ -289,11 +288,4 @@ var AppConfigFlags = []cli.Flag{
|
|||||||
EnvVars: []string{"IP"},
|
EnvVars: []string{"IP"},
|
||||||
Destination: &IP,
|
Destination: &IP,
|
||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "ViewConfig",
|
|
||||||
Aliases: []string{"vc"},
|
|
||||||
Usage: "View config file",
|
|
||||||
EnvVars: []string{"VC"},
|
|
||||||
Destination: &ViewConfig,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,9 +38,7 @@ type Config struct {
|
|||||||
KeyFile string
|
KeyFile string
|
||||||
BareMetal bool
|
BareMetal bool
|
||||||
UnsafeMode bool
|
UnsafeMode bool
|
||||||
Test bool
|
|
||||||
CustomConfig interface{}
|
CustomConfig interface{}
|
||||||
ConfigPath string
|
|
||||||
//NetworkInterface string
|
//NetworkInterface string
|
||||||
//NetworkInterfaceIPV6Index int
|
//NetworkInterfaceIPV6Index int
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,8 +95,6 @@ func SetDefaults(envName string, forceDefault bool, CustomConfig interface{}, No
|
|||||||
Defaults.PrivateKeyFile = defaultPath + "p2prc.privateKey"
|
Defaults.PrivateKeyFile = defaultPath + "p2prc.privateKey"
|
||||||
Defaults.BareMetal = false
|
Defaults.BareMetal = false
|
||||||
Defaults.UnsafeMode = false
|
Defaults.UnsafeMode = false
|
||||||
Defaults.Test = false
|
|
||||||
Defaults.ConfigPath = defaultPath + "config.json"
|
|
||||||
|
|
||||||
// Generate certificate files for SSL
|
// Generate certificate files for SSL
|
||||||
err = GenerateCertificate()
|
err = GenerateCertificate()
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||||
"log"
|
"log"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
@@ -53,8 +54,7 @@ func GenerateCertificate() error {
|
|||||||
|
|
||||||
//flag.Parse()
|
//flag.Parse()
|
||||||
|
|
||||||
//host, err = p2p.CurrentPublicIP()
|
host, err = p2p.CurrentPublicIP()
|
||||||
host = "0.0.0.0"
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
12
flake.lock
generated
12
flake.lock
generated
@@ -28,11 +28,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1745875161,
|
"lastModified": 1733668782,
|
||||||
"narHash": "sha256-0YkWCS13jpoo3+sX/3kcgdxBNt1VZTmvF+FhZb4rFKI=",
|
"narHash": "sha256-tPsqU00FhgdFr0JiQUiBMgPVbl1jbPCY5gbFiJycL3I=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "gomod2nix",
|
"repo": "gomod2nix",
|
||||||
"rev": "2cbd7fdd6eeab65c494cc426e18f4e4d2a5e35c0",
|
"rev": "514283ec89c39ad0079ff2f3b1437404e4cba608",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -43,11 +43,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1748460289,
|
"lastModified": 1735834308,
|
||||||
"narHash": "sha256-7doLyJBzCllvqX4gszYtmZUToxKvMUrg45EUWaUYmBg=",
|
"narHash": "sha256-dklw3AXr3OGO4/XT1Tu3Xz9n/we8GctZZ75ZWVqAVhk=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "96ec055edbe5ee227f28cdbc3f1ddf1df5965102",
|
"rev": "6df24922a1400241dae323af55f30e4318a6ca65",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
118
flake.nix
118
flake.nix
@@ -1,58 +1,30 @@
|
|||||||
{
|
{
|
||||||
description = "P2PRC nix flake";
|
description = "P2PRC nix flake";
|
||||||
|
|
||||||
inputs = {
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
inputs.gomod2nix.url = "github:nix-community/gomod2nix";
|
||||||
|
inputs.gomod2nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.gomod2nix.inputs.flake-utils.follows = "flake-utils";
|
||||||
|
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
outputs = { self, nixpkgs, flake-utils, gomod2nix }:
|
||||||
|
(flake-utils.lib.eachDefaultSystem
|
||||||
flake-utils = {
|
(system:
|
||||||
url = "github:numtide/flake-utils";
|
|
||||||
};
|
|
||||||
|
|
||||||
gomod2nix = {
|
|
||||||
url = "github:nix-community/gomod2nix";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
inputs.flake-utils.follows = "flake-utils";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs =
|
|
||||||
{
|
|
||||||
nixpkgs,
|
|
||||||
flake-utils,
|
|
||||||
gomod2nix,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
|
|
||||||
bindingsOverlay = import ./nix/overlays/bindings.nix;
|
|
||||||
coreOverlay = (final: prev: {
|
|
||||||
p2prc = final.callPackage ./. { };
|
|
||||||
});
|
|
||||||
|
|
||||||
in
|
|
||||||
(flake-utils.lib.eachDefaultSystem (system:
|
|
||||||
let
|
|
||||||
|
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays = [
|
overlays = [ gomod2nix.overlays.default ];
|
||||||
gomod2nix.overlays.default
|
|
||||||
coreOverlay
|
|
||||||
bindingsOverlay
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
|
||||||
# The current default sdk for macOS fails to compile go projects, so we use a newer one for now.
|
# The current default sdk for macOS fails to compile go projects, so we use a newer one for now.
|
||||||
# This has no effect on other platforms.
|
# This has no effect on other platforms.
|
||||||
callPackage = pkgs.darwin.apple_sdk_11_0.callPackage or pkgs.callPackage;
|
callPackage = pkgs.darwin.apple_sdk_11_0.callPackage or pkgs.callPackage;
|
||||||
|
|
||||||
p2prcDefault = callPackage ./. { };
|
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
packages.default = p2prcDefault;
|
|
||||||
|
packages.default = callPackage ./. { };
|
||||||
|
|
||||||
devShells.default = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
@@ -64,66 +36,6 @@
|
|||||||
sqlite-interactive
|
sqlite-interactive
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
})
|
||||||
packages.initHaskellProject = pkgs.writeShellApplication {
|
);
|
||||||
name = "initHaskellProject";
|
|
||||||
runtimeInputs = with pkgs; [
|
|
||||||
ghc
|
|
||||||
cabal2nix
|
|
||||||
cabal-install
|
|
||||||
git
|
|
||||||
p2prcDefault
|
|
||||||
];
|
|
||||||
text =
|
|
||||||
''
|
|
||||||
clear
|
|
||||||
|
|
||||||
if [ "$#" -eq 0 ]; then
|
|
||||||
echo "No arguments provided."
|
|
||||||
echo "Please provide the name of your project"
|
|
||||||
echo "nix run git+https://github:akilan1999/p2p-rendering-computation#initHaskellProject -- <NAME-PROJECT>"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
PROJECT_DIR="$1"
|
|
||||||
|
|
||||||
mkdir "$PROJECT_DIR"
|
|
||||||
|
|
||||||
cd "$PROJECT_DIR"
|
|
||||||
|
|
||||||
git init .
|
|
||||||
clear
|
|
||||||
|
|
||||||
cabal init --exe --simple
|
|
||||||
|
|
||||||
sed -i 's/base.*$/base, p2prc/' "$PROJECT_DIR".cabal
|
|
||||||
|
|
||||||
cabal2nix . > ./cabal.nix;
|
|
||||||
|
|
||||||
git add .
|
|
||||||
|
|
||||||
clear
|
|
||||||
|
|
||||||
echo -e "run the following commands to finish nix development and production environment:\n\n"
|
|
||||||
|
|
||||||
echo -e "cd $PROJECT_DIR"
|
|
||||||
echo -e "nix flake init -t github:akilan1999/p2p-rendering-computation#haskell"
|
|
||||||
echo -e "nix develop"
|
|
||||||
echo -e "nix run"
|
|
||||||
echo -e "\n\n"
|
|
||||||
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)) //
|
|
||||||
{
|
|
||||||
overlays = {
|
|
||||||
default = coreOverlay;
|
|
||||||
bindings = bindingsOverlay;
|
|
||||||
};
|
|
||||||
templates.haskell = {
|
|
||||||
path = ./nix/templates/haskell;
|
|
||||||
description = "Haskell Bindings to p2prc protocol";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
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,7 +0,0 @@
|
|||||||
final: prev: {
|
|
||||||
haskellPackages = prev.haskellPackages.override {
|
|
||||||
overrides = hfinal: hprev: {
|
|
||||||
p2prc = hfinal.callPackage ../../Bindings/Haskell/project.nix { };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
190
nix/templates/haskell/flake.lock
generated
190
nix/templates/haskell/flake.lock
generated
@@ -1,190 +0,0 @@
|
|||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"flake-util": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1731533236,
|
|
||||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1731533236,
|
|
||||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"id": "flake-utils",
|
|
||||||
"type": "indirect"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils_2": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems_3"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1731533236,
|
|
||||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"gomod2nix": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-utils": [
|
|
||||||
"p2prc-flake",
|
|
||||||
"flake-utils"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"p2prc-flake",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1745875161,
|
|
||||||
"narHash": "sha256-0YkWCS13jpoo3+sX/3kcgdxBNt1VZTmvF+FhZb4rFKI=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "gomod2nix",
|
|
||||||
"rev": "2cbd7fdd6eeab65c494cc426e18f4e4d2a5e35c0",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "gomod2nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1748460289,
|
|
||||||
"narHash": "sha256-7doLyJBzCllvqX4gszYtmZUToxKvMUrg45EUWaUYmBg=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "96ec055edbe5ee227f28cdbc3f1ddf1df5965102",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1748370509,
|
|
||||||
"narHash": "sha256-QlL8slIgc16W5UaI3w7xHQEP+Qmv/6vSNTpoZrrSlbk=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "4faa5f5321320e49a78ae7848582f684d64783e9",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"p2prc-flake": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-utils": "flake-utils_2",
|
|
||||||
"gomod2nix": "gomod2nix",
|
|
||||||
"nixpkgs": "nixpkgs_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1748646470,
|
|
||||||
"narHash": "sha256-7aZQQ+jHdlxUzFPXzEEYfH1oU3isSZlZnMC7HWUDHCk=",
|
|
||||||
"owner": "xecarlox94",
|
|
||||||
"repo": "p2p-rendering-computation",
|
|
||||||
"rev": "73a283a545d61754a0fe821287541c2cd412bc0e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "xecarlox94",
|
|
||||||
"ref": "nix",
|
|
||||||
"repo": "p2p-rendering-computation",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-util": "flake-util",
|
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"p2prc-flake": "p2prc-flake"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems_3": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
{
|
|
||||||
description = "Start of Haskell P2PRC flake";
|
|
||||||
|
|
||||||
inputs =
|
|
||||||
{
|
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
||||||
|
|
||||||
flake-util.url = "github:numtide/flake-utils";
|
|
||||||
|
|
||||||
p2prc-flake.url = "github:akilan1999/p2p-rendering-computation";
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs = { nixpkgs, p2prc-flake, flake-utils, ... }:
|
|
||||||
(flake-utils.lib.eachDefaultSystem (system:
|
|
||||||
let
|
|
||||||
|
|
||||||
pkgs = import nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
overlays = [
|
|
||||||
p2prc-flake.overlays.default
|
|
||||||
p2prc-flake.overlays.bindings
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
in {
|
|
||||||
|
|
||||||
packages.default = pkgs.haskellPackages.callPackage ./cabal.nix { };
|
|
||||||
|
|
||||||
devShells.default = pkgs.haskellPackages.shellFor {
|
|
||||||
|
|
||||||
packages = p: [
|
|
||||||
(p.callPackage ./cabal.nix { })
|
|
||||||
];
|
|
||||||
|
|
||||||
buildInputs = with pkgs; [
|
|
||||||
p2prc-flake.packages.${system}.default
|
|
||||||
ghc
|
|
||||||
cabal2nix
|
|
||||||
cabal-install
|
|
||||||
];
|
|
||||||
|
|
||||||
shellHook = ''
|
|
||||||
cabal2nix . > ./cabal.nix
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
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
|
||||||
@@ -87,57 +85,57 @@ func StartFRPClientForServer(ipaddress string, port string, localport string, re
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
|||||||
@@ -42,8 +42,6 @@ type IP struct {
|
|||||||
Query string
|
Query string
|
||||||
}
|
}
|
||||||
|
|
||||||
var Test = false
|
|
||||||
|
|
||||||
// ReadIpTable Read data from Ip tables from json file
|
// ReadIpTable Read data from Ip tables from json file
|
||||||
func ReadIpTable() (*IpAddresses, error) {
|
func ReadIpTable() (*IpAddresses, error) {
|
||||||
// Get Path from config
|
// Get Path from config
|
||||||
@@ -180,16 +178,6 @@ func (table *IpAddresses) RemoveDuplicates() error {
|
|||||||
|
|
||||||
// CurrentPublicIP Get Current Public IP address
|
// CurrentPublicIP Get Current Public IP address
|
||||||
func CurrentPublicIP() (string, error) {
|
func CurrentPublicIP() (string, error) {
|
||||||
// Get configs
|
|
||||||
Config, err := config.ConfigInit(nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
// If test mode is on then return local address
|
|
||||||
if Config.Test {
|
|
||||||
return "0.0.0.0", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.Get("http://ip-api.com/json/")
|
req, err := http.Get("http://ip-api.com/json/")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@@ -205,7 +193,6 @@ func CurrentPublicIP() (string, error) {
|
|||||||
json.Unmarshal(body, &ip)
|
json.Unmarshal(body, &ip)
|
||||||
|
|
||||||
return ip.Query, nil
|
return ip.Query, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentIPV6 gets the current IPV6 address based on the interface
|
// GetCurrentIPV6 gets the current IPV6 address based on the interface
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ func (ip *IpAddresses) SpeedTestUpdatedIPTable() error {
|
|||||||
// and look upon later on.
|
// and look upon later on.
|
||||||
AddAuthorisationKey(ip.IpAddress[k].PublicKey)
|
AddAuthorisationKey(ip.IpAddress[k].PublicKey)
|
||||||
}
|
}
|
||||||
targets.IpAddress[i].CustomInformation = ip.IpAddress[k].CustomInformation
|
|
||||||
// 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) || (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) {
|
||||||
|
|||||||
@@ -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
|
|
||||||
115
server/server.go
115
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,63 +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)
|
||||||
|
//
|
||||||
// Creates container and returns-back result to
|
// fmt.Println(string(PublicKeyDecoded[:]))
|
||||||
// access container
|
//
|
||||||
resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName, BaseImage, string(PublicKeyDecoded[:]))
|
// // Creates container and returns-back result to
|
||||||
|
// // access container
|
||||||
if err != nil {
|
// resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName, BaseImage, string(PublicKeyDecoded[:]))
|
||||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
//
|
||||||
}
|
// if err != nil {
|
||||||
|
// c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||||
// Ensures that FRP is triggered only if a proxy address is provided
|
// }
|
||||||
if ProxyIpAddr.Ipv4 != "" && c.Request.Host != "localhost:"+config.ServerPort && c.Request.Host != "0.0.0.0:"+config.ServerPort {
|
//
|
||||||
resp, err = frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, lowestLatencyIpAddress.ServerPort, resp)
|
// // Ensures that FRP is triggered only if a proxy address is provided
|
||||||
if err != nil {
|
// if ProxyIpAddr.Ipv4 != "" && c.Request.Host != "localhost:"+config.ServerPort && c.Request.Host != "0.0.0.0:"+config.ServerPort {
|
||||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
// resp, err = frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, lowestLatencyIpAddress.ServerPort, resp)
|
||||||
}
|
// if err != nil {
|
||||||
}
|
// 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) {
|
||||||
@@ -310,7 +310,6 @@ func Server() (*gin.Engine, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ProxyIpAddr.ServerPort = config.ServerPort
|
ProxyIpAddr.ServerPort = config.ServerPort
|
||||||
ProxyIpAddr.Name = config.MachineName
|
ProxyIpAddr.Name = config.MachineName
|
||||||
ProxyIpAddr.NAT = false
|
ProxyIpAddr.NAT = false
|
||||||
|
|||||||
BIN
wasm/p2prc.wasm
BIN
wasm/p2prc.wasm
Binary file not shown.
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