Compare commits
376 Commits
sample-run
...
setup-bare
| Author | SHA1 | Date | |
|---|---|---|---|
| 277259a65a | |||
| 22c8fefd8d | |||
| 623d7b93e0 | |||
| eb0a7d6b34 | |||
| 2bd39cc450 | |||
| afacc339ec | |||
| b3f5d63e16 | |||
| f833eba32b | |||
| b55134d194 | |||
| 0b0ae2df06 | |||
| ff105bf9e0 | |||
| 7a86bb29c9 | |||
| 71b23b1e0d | |||
|
|
64f8d77a65 | ||
| 5a5985a573 | |||
| 0a13327551 | |||
| 00317008a2 | |||
| ecd6b0cbf3 | |||
| dabba14741 | |||
| fc7ad63c06 | |||
| ac8a3dcdca | |||
| 447834b556 | |||
| 883b3a5cde | |||
| 2c8ef44bd8 | |||
| 63d079f71d | |||
| a4cd96c72f | |||
| 07dea4ff27 | |||
| a37f81a47f | |||
| 0c1e6edcbc | |||
| 9192901e25 | |||
| 5d20e688a8 | |||
| 505ef3b982 | |||
| 9d9e385909 | |||
| aa4b18f39d | |||
| f9fb225b91 | |||
| 7a5cb2f1e3 | |||
|
|
8ff61422d7 | ||
|
|
0c86c6e673 | ||
|
|
00629b604f | ||
| 72484da67b | |||
| 7f1e9cbbae | |||
|
|
c14a0521c9 | ||
| 504cdb41cf | |||
| c815ed34d7 | |||
| 60c4bba380 | |||
| 3a2cb47b6e | |||
| 8c708c6f11 | |||
| 83653866e6 | |||
|
|
9c94f20ea8 | ||
|
|
18ae29946d | ||
|
|
05936a5486 | ||
|
|
7d5e5cb619 | ||
|
|
04eea717a6 | ||
|
|
b6db9147c8 | ||
|
|
599f7ba2c6 | ||
|
|
38a05d6ab5 | ||
|
|
ea08b5c3ea | ||
|
|
1c496d8be1 | ||
|
|
a4b9634dc2 | ||
|
|
65b90d7ce9 | ||
|
|
95ab45bf62 | ||
| 751f1b15a6 | |||
| 8ccdcaefb5 | |||
| 213838715b | |||
|
|
f899b4e6bb | ||
| 2704caa5e4 | |||
| 2b6c7a5963 | |||
| b78c009f9f | |||
| 708eacd1db | |||
| 979e856272 | |||
| 614a3412c5 | |||
| ea90348fd2 | |||
|
|
a07c91c888 | ||
| 636646b0a1 | |||
| 3933b29979 | |||
| 96e755bc19 | |||
|
|
7f0a43625b | ||
| 29eff7a3af | |||
| 7ed25ef4b3 | |||
| 6b287f2cf1 | |||
| dfa8713aea | |||
| 263275d80c | |||
| 9caf6cde07 | |||
| d71bd991b0 | |||
| e21465b1eb | |||
| fb606cf4ff | |||
| 136243d6a5 | |||
|
|
2f6116993b | ||
|
|
0665a82815 | ||
|
|
a7d741909c | ||
|
|
232c13aca0 | ||
|
|
70aa82a946 | ||
|
|
8f4c2623e3 | ||
|
|
a038bf9f20 | ||
|
|
683e20953b | ||
|
|
8e6a6e246c | ||
|
|
06e5e1e67f | ||
|
|
2b191af951 | ||
|
|
85ac36d51b | ||
|
|
64225b85b7 | ||
|
|
66b26c5ea2 | ||
| 4d2b903a0f | |||
|
|
5ac033403f | ||
| d52aca3d14 | |||
| 05c9f52e6d | |||
| 732b31fafa | |||
| 5edf1f801b | |||
| 4e025bdc70 | |||
| 3bcba8a3e2 | |||
|
|
97d10918b1 | ||
|
|
d3181d272e | ||
|
|
0550a35df1 | ||
|
|
7984f72db1 | ||
|
|
806b499e72 | ||
|
|
cf1e7c6d6f | ||
|
|
86aaba23c4 | ||
|
|
53bef115b0 | ||
|
|
fbbb23c13a | ||
|
|
f0496f8184 | ||
| 69c0aa5cb1 | |||
|
|
88dddd0230 | ||
| c9f007a652 | |||
| 3b70ff5879 | |||
|
|
6161b0afa3 | ||
| 4268b5a637 | |||
|
|
60a00cbb57 | ||
| 35b9e7ea33 | |||
|
|
e965adf798 | ||
| 1428d324b1 | |||
| c646a1389e | |||
| be9de346e5 | |||
| 73e62ba0fa | |||
| 60500620db | |||
| 4dac4234ad | |||
| c7a665fdc8 | |||
| e1debe8f53 | |||
| ba0e562fd7 | |||
| afe4105e3a | |||
|
|
c42bf002de | ||
| 256998d964 | |||
| f82f5f9ec8 | |||
|
|
1bc62cc2d1 | ||
| 8f12781928 | |||
| 280091f7b1 | |||
| 8106277956 | |||
| f6c7a21601 | |||
| f7a3b72287 | |||
| 160f544b8b | |||
| 52d9dd1b16 | |||
| 15df4f45d5 | |||
| 6f4fdf1a8e | |||
| b8820ff150 | |||
| 67199a35ba | |||
| dd2bf2e104 | |||
| c5a7f85941 | |||
| 1fb248d12d | |||
| add0ae7fb6 | |||
| c6ff05a9cb | |||
| 1cd4fa87d7 | |||
| 120654a901 | |||
| f959b70ab9 | |||
| 713500413c | |||
| fb01428507 | |||
| 4deff38c07 | |||
| ede9674a08 | |||
|
|
8a58aa6869 | ||
|
|
9f5c75c4ef | ||
|
|
f6da22733a | ||
|
|
a9f0488c4b | ||
|
|
dec52e497c | ||
|
|
002235cf00 | ||
| 2138ee2d5d | |||
| 4921a6345d | |||
| 7c0ddc79c9 | |||
| fbfa0e47fa | |||
|
|
80033e759a | ||
|
|
f1ed6c0e45 | ||
|
|
9e0b28bde5 | ||
|
|
f5c505160b | ||
|
|
0700f68543 | ||
|
|
b5d77a1b72 | ||
|
|
536672a582 | ||
|
|
97292009dd | ||
|
|
4338adc9d5 | ||
|
|
a555c30db1 | ||
|
|
9994847f90 | ||
|
|
7531f678c6 | ||
|
|
6a25e540b2 | ||
| b82d56b8d0 | |||
|
|
9d99875cb8 | ||
| f63696d9da | |||
| 0144e59d71 | |||
|
|
8be15ca19b | ||
|
|
c5efee3932 | ||
|
|
b325b848d1 | ||
|
|
57cf1f984b | ||
|
|
d7b7e6b84b | ||
| eb1644367e | |||
| ab2a0b28f9 | |||
| 9f304d26c1 | |||
| 56be275759 | |||
| a06e1be2bc | |||
| d45bc99be7 | |||
|
|
dec76d254f | ||
| 91b15e3bd7 | |||
| 9d8303d66c | |||
| 2a7d8e154d | |||
|
|
519801d2c0 | ||
| fc5e834552 | |||
|
|
be985942b9 | ||
| 1ca73faaed | |||
|
|
5da700a9d0 | ||
|
|
86a266b017 | ||
| e9cc304d02 | |||
| 6b43d94e8d | |||
|
|
64580fade0 | ||
|
|
ddf0879f90 | ||
|
|
e9ce832893 | ||
|
|
24b1a1f8b6 | ||
|
|
f781cc28fc | ||
|
|
c83ebbe149 | ||
| 9d69aed8ce | |||
| 65de9dda17 | |||
| c3a3a21132 | |||
|
|
f0bdb44e7c | ||
| ce5b7aa1af | |||
| e4b1aaf208 | |||
| 5823cf2028 | |||
| 5c2b36c086 | |||
| 8fd9ccfa2d | |||
| 85bf56ec01 | |||
| e5334cbd3c | |||
|
|
fd9d5e1419 | ||
|
|
111c5ef93c | ||
|
|
1a7035164b | ||
| 554b08d6be | |||
| 8b95d05986 | |||
| ab2bcb393b | |||
| 4ed2e10ac3 | |||
|
|
8a278239ba | ||
|
|
51e9e38122 | ||
|
|
a047c630d7 | ||
| 6b4b028b6f | |||
| dab82ae3cf | |||
| e3088a36e1 | |||
| 7a9a6b7ac5 | |||
| c7985ed318 | |||
| a920ff749b | |||
| 1fe5db06c0 | |||
| d288d1f2d6 | |||
| e2f8df9dcb | |||
| 707592195a | |||
| 10e5c72c90 | |||
|
|
fa61b70d41 | ||
|
|
b8aa24d49e | ||
|
|
7f3e0a466f | ||
|
|
7fd33ceb4c | ||
|
|
4c43ab77bb | ||
| 4e133ed789 | |||
| 5ff6702d9c | |||
|
|
af4b129bee | ||
|
|
b776b3e1e1 | ||
|
|
47dc49867b | ||
|
|
340177e992 | ||
|
|
e893674180 | ||
|
|
b8e2a0047f | ||
|
|
7f48b7fb3d | ||
| 116cd7e0bd | |||
|
|
3e6c3b8a18 | ||
| 1411a5c0da | |||
|
|
1063fa5fd7 | ||
| 2aea584f8b | |||
| 088c9c5ba4 | |||
|
|
3ca75a540b | ||
| 4e0fd09d73 | |||
|
|
c3647c2fe7 | ||
| a9f3d39bbb | |||
| fc87d95753 | |||
| c22f73ad28 | |||
| e98f4119da | |||
|
|
c42725743d | ||
|
|
1877420fc6 | ||
|
|
decb1c0e10 | ||
| a416578702 | |||
| 489ffd6d0c | |||
| 51110c235b | |||
| 726292a77d | |||
| 92cd9fe1ab | |||
|
|
739c7305a8 | ||
| 75a4bed9d1 | |||
| 0131ce5765 | |||
| 326ebe1697 | |||
| b6d757d5e3 | |||
| 022558f740 | |||
| 58b8af4b6e | |||
| ef031c5b68 | |||
| de14a5fb06 | |||
| 1a0184406d | |||
| 0069308a2a | |||
| 378c8bb75e | |||
|
|
a73469155f | ||
|
|
0a28f22c76 | ||
| a3ddad6aca | |||
|
|
08f58a00c5 | ||
| 0ecd8355b5 | |||
| 63f570bb4f | |||
| 02f72209dc | |||
|
|
68228a6013 | ||
| ae2500ed4b | |||
|
|
5be8778652 | ||
| 6dde485de1 | |||
| c0f70e87f4 | |||
|
|
6df72c4abb | ||
|
|
26e6fd4ec2 | ||
| aabac388ba | |||
|
|
655c5de4ec | ||
| 3e8a99b435 | |||
|
|
5e7f540802 | ||
| 28620b61ad | |||
|
|
6f6072f598 | ||
| f7bae1100a | |||
| a0b63fa2ec | |||
|
|
5b90bf3168 | ||
|
|
d7780a916b | ||
| 10f37a60a4 | |||
|
|
2b76c16215 | ||
| f4bd08b6bf | |||
|
|
680f703326 | ||
| 2caa9d0aac | |||
| 657577f583 | |||
| 21b9efc3a6 | |||
| 9f8e6a1f04 | |||
| 1eac752fa7 | |||
|
|
fbb3748fe4 | ||
| 0bdcaca087 | |||
| 4f10936664 | |||
|
|
1f5d9e0af8 | ||
| ca222af710 | |||
|
|
28ed412cdf | ||
| 2765f4e81e | |||
| c9e6206a89 | |||
| 29176b16ec | |||
|
|
0bf44cff4e | ||
|
|
2e9a5599b5 | ||
|
|
6e089961bb | ||
|
|
4ee45ebabd | ||
|
|
c5d8769b17 | ||
| 4c8d6ae28f | |||
| 02ca82084b | |||
|
|
9d03b08450 | ||
| 1730a58e53 | |||
| c9b35ac790 | |||
|
|
afab95db65 | ||
| af46493aa9 | |||
| 435f553889 | |||
|
|
0495a49f90 | ||
| ad9a1c9699 | |||
| 14bceec3cc | |||
| 8466e2d1ca | |||
|
|
4141f1c575 | ||
| 84be0012a1 | |||
|
|
370544958d | ||
|
|
2cef7b4b35 | ||
| a46a7983c5 | |||
|
|
8fbc644f72 | ||
|
|
49088aa44e | ||
|
|
0ae7546e05 | ||
|
|
de308898df | ||
|
|
dc890e2a67 | ||
|
|
bc643ba4a9 | ||
|
|
36b759d930 | ||
|
|
d1ee000ce7 | ||
|
|
780fcb119e | ||
|
|
cc2b3fb879 | ||
|
|
cdb2a194d5 | ||
|
|
9d28f07ad2 |
12
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||||
|
patreon: # Replace with a single Patreon username
|
||||||
|
open_collective: # Replace with a single Open Collective username
|
||||||
|
ko_fi: akilan1999
|
||||||
|
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||||
|
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||||
|
liberapay: # Replace with a single Liberapay username
|
||||||
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
|
otechie: # Replace with a single Otechie username
|
||||||
|
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||||
62
.github/release-drafter.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
name: Release Drafter
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
# branches to consider in the event; optional, defaults to all
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
# pull_request event is required only for autolabeler
|
||||||
|
pull_request:
|
||||||
|
# Only following types are handled by the action, but one can default to all as well
|
||||||
|
types: [opened, reopened, synchronize]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update_release_draft:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
# (Optional) GitHub Enterprise requires GHE_HOST variable set
|
||||||
|
#- name: Set GHE_HOST
|
||||||
|
# run: |
|
||||||
|
# echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# Drafts your next Release notes as Pull Requests are merged into "master"
|
||||||
|
- uses: release-drafter/release-drafter@v5
|
||||||
|
# (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml
|
||||||
|
# with:
|
||||||
|
# config-name: my-config.yml
|
||||||
|
# disable-autolabeler: true
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
name-template: 'v$RESOLVED_VERSION'
|
||||||
|
tag-template: 'v$RESOLVED_VERSION'
|
||||||
|
categories:
|
||||||
|
- title: '🚀 Features'
|
||||||
|
labels:
|
||||||
|
- 'feature'
|
||||||
|
- 'enhancement'
|
||||||
|
- title: '🐛 Bug Fixes'
|
||||||
|
labels:
|
||||||
|
- 'fix'
|
||||||
|
- 'bugfix'
|
||||||
|
- 'bug'
|
||||||
|
- title: '🧰 Maintenance'
|
||||||
|
label: 'chore'
|
||||||
|
|
||||||
|
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
|
||||||
|
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
|
||||||
|
version-resolver:
|
||||||
|
major:
|
||||||
|
labels:
|
||||||
|
- 'major'
|
||||||
|
minor:
|
||||||
|
labels:
|
||||||
|
- 'minor'
|
||||||
|
patch:
|
||||||
|
labels:
|
||||||
|
- 'patch'
|
||||||
|
default: patch
|
||||||
|
template: |
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
$CHANGES
|
||||||
49
.github/workflows/pages.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
name: Deploy Jekyll with GitHub Pages dependencies preinstalled
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Runs on pushes targeting the default branch
|
||||||
|
push:
|
||||||
|
branches: ["main", "master"]
|
||||||
|
|
||||||
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
# Allow one concurrent deployment
|
||||||
|
concurrency:
|
||||||
|
group: "pages"
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Build job
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Setup Pages
|
||||||
|
uses: actions/configure-pages@v2
|
||||||
|
- name: Build with Jekyll
|
||||||
|
uses: actions/jekyll-build-pages@v1
|
||||||
|
with:
|
||||||
|
source: ./
|
||||||
|
destination: ./_site
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-pages-artifact@v1
|
||||||
|
|
||||||
|
# Deployment job
|
||||||
|
deploy:
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
steps:
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
id: deployment
|
||||||
|
uses: actions/deploy-pages@v1
|
||||||
33
.gitignore
vendored
@@ -8,3 +8,36 @@ p2p-rendering-computation
|
|||||||
p2prc
|
p2prc
|
||||||
config.json
|
config.json
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
#ignore generated iptables
|
||||||
|
p2p/iptable/
|
||||||
|
#ignore plugins added
|
||||||
|
plugin/deploy/
|
||||||
|
#ignore track container file
|
||||||
|
client/trackcontainers/
|
||||||
|
# Test generated files
|
||||||
|
generate/p2prctest
|
||||||
|
generate/Test
|
||||||
|
#ignore windows exe files
|
||||||
|
*.exe
|
||||||
|
dist/
|
||||||
|
# Ignore any sort of logs
|
||||||
|
logs/
|
||||||
|
|
||||||
|
# ignore docker image files
|
||||||
|
server/docker/containers/
|
||||||
|
*.h
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# generic folder to ignore
|
||||||
|
export/
|
||||||
|
|
||||||
|
# Any testing file
|
||||||
|
*test
|
||||||
|
|
||||||
|
# Ignore public and private keys
|
||||||
|
p2prc.publicKey
|
||||||
|
p2prc.privateKey
|
||||||
|
|
||||||
|
# Ignore pem files
|
||||||
|
*.pem
|
||||||
|
|||||||
32
.goreleaser.yml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# This is an example .goreleaser.yml file with some sensible defaults.
|
||||||
|
# Make sure to check the documentation at https://goreleaser.com
|
||||||
|
before:
|
||||||
|
hooks:
|
||||||
|
# You may remove this if you don't use go modules.
|
||||||
|
- go mod tidy
|
||||||
|
# you may remove this if you don't need go generate
|
||||||
|
- go generate ./...
|
||||||
|
builds:
|
||||||
|
- env:
|
||||||
|
- CGO_ENABLED=0
|
||||||
|
goos:
|
||||||
|
- linux
|
||||||
|
- windows
|
||||||
|
- darwin
|
||||||
|
archives:
|
||||||
|
- replacements:
|
||||||
|
darwin: Darwin
|
||||||
|
linux: Linux
|
||||||
|
windows: Windows
|
||||||
|
386: i386
|
||||||
|
amd64: x86_64
|
||||||
|
checksum:
|
||||||
|
name_template: 'checksums.txt'
|
||||||
|
snapshot:
|
||||||
|
name_template: "{{ incpatch .Version }}-next"
|
||||||
|
changelog:
|
||||||
|
sort: asc
|
||||||
|
filters:
|
||||||
|
exclude:
|
||||||
|
- '^docs:'
|
||||||
|
- '^test:'
|
||||||
169
Bindings/Client.go
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/abstractions"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The Client package where data-types
|
||||||
|
// are manually converted to the
|
||||||
|
// to a string so that it can
|
||||||
|
// be export
|
||||||
|
|
||||||
|
// --------------------------------- Container Control ----------------------------------------
|
||||||
|
|
||||||
|
//export StartContainer
|
||||||
|
func StartContainer(IP string) (output *C.char) {
|
||||||
|
container, err := abstractions.StartContainer(IP)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
return ConvertStructToJSONString(container)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export RemoveContainer
|
||||||
|
func RemoveContainer(IP string, ID string) (output *C.char) {
|
||||||
|
err := abstractions.RemoveContainer(IP, ID)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
return C.CString("Success")
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------- Plugin Control ----------------------------------------
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
|
////export ViewPlugin
|
||||||
|
//func ViewPlugin() (output *C.char) {
|
||||||
|
// plugins, err := plugin.DetectPlugins()
|
||||||
|
// if err != nil {
|
||||||
|
// return C.CString(err.Error())
|
||||||
|
// }
|
||||||
|
// return ConvertStructToJSONString(plugins)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
////export PullPlugin
|
||||||
|
//func PullPlugin(pluginUrl string) (output *C.char) {
|
||||||
|
// err := plugin.DownloadPlugin(pluginUrl)
|
||||||
|
// if err != nil {
|
||||||
|
// return C.CString(err.Error())
|
||||||
|
// }
|
||||||
|
// return C.CString("Success")
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
////export DeletePlugin
|
||||||
|
//func DeletePlugin(pluginName string) (output *C.char) {
|
||||||
|
// err := plugin.DeletePlugin(pluginName)
|
||||||
|
// if err != nil {
|
||||||
|
// return C.CString(err.Error())
|
||||||
|
// }
|
||||||
|
// return C.CString("Success")
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
////export ExecutePlugin
|
||||||
|
//func ExecutePlugin(pluginname string, ContainerID string) (output *C.char) {
|
||||||
|
// err := plugin.RunPluginContainer(pluginname, ContainerID)
|
||||||
|
// if err != nil {
|
||||||
|
// return C.CString(err.Error())
|
||||||
|
// }
|
||||||
|
// return C.CString("Success")
|
||||||
|
//}
|
||||||
|
|
||||||
|
// --------------------------------- Get Specs ----------------------------------------
|
||||||
|
|
||||||
|
//export GetSpecs
|
||||||
|
func GetSpecs(IP string) (output *C.char) {
|
||||||
|
specs, err := abstractions.GetSpecs(IP)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
return ConvertStructToJSONString(specs)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export Init
|
||||||
|
func Init(customConfig string) (output *C.char) {
|
||||||
|
init, err := abstractions.Init(customConfig)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
return ConvertStructToJSONString(init)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------- P2P Controls -----------------------------------
|
||||||
|
|
||||||
|
//export ViewIPTable
|
||||||
|
func ViewIPTable() (output *C.char) {
|
||||||
|
table, err := abstractions.ViewIPTable()
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
return ConvertStructToJSONString(table)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export UpdateIPTable
|
||||||
|
func UpdateIPTable() (output *C.char) {
|
||||||
|
err := abstractions.UpdateIPTable()
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
return C.CString("Success")
|
||||||
|
}
|
||||||
|
|
||||||
|
//export EscapeFirewall
|
||||||
|
func EscapeFirewall(HostOutsideNATIP string, HostOutsideNATPort string, internalPort string) (output *C.char) {
|
||||||
|
// Get free port from P2PRC server node
|
||||||
|
serverPort, err := frp.GetFRPServerPort("http://" + HostOutsideNATIP + ":" + HostOutsideNATPort)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
|
||||||
|
ExposedPort, err := frp.StartFRPClientForServer(HostOutsideNATIP+":"+HostOutsideNATPort, serverPort, internalPort, "")
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return C.CString(ExposedPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export MapPort
|
||||||
|
func MapPort(Port string, DomainName string) *C.char {
|
||||||
|
entireAddress, _, err := abstractions.MapPort(Port, DomainName)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
return C.CString(entireAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------- Controlling Server ----------------------------------------
|
||||||
|
|
||||||
|
//export Server
|
||||||
|
func Server() (output *C.char) {
|
||||||
|
_, err := abstractions.Start()
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConvertStructToJSONString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------- Helper Functions ----------------------------------------
|
||||||
|
|
||||||
|
func ConvertStructToJSONString(Struct interface{}) *C.char {
|
||||||
|
jsonBytes, err := json.Marshal(Struct)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the JSON bytes to a string
|
||||||
|
return C.CString(string(jsonBytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {}
|
||||||
BIN
Bindings/python/.DS_Store
vendored
Normal file
11
Bindings/python/p2prc.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import ctypes
|
||||||
|
|
||||||
|
p2prc = ctypes.CDLL("SharedOBjects/p2prc.so")
|
||||||
|
|
||||||
|
p2prc.Init("")
|
||||||
|
|
||||||
|
def StartServer():
|
||||||
|
# Starting P2PRC as a server mode
|
||||||
|
p2prc.Server()
|
||||||
|
for _ in iter(int, 1):
|
||||||
|
pass
|
||||||
9
CITATION.cff
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
cff-version: 1.0.0
|
||||||
|
message: "If you use this software, please cite it as below."
|
||||||
|
authors:
|
||||||
|
- family-names: Selvacoumar
|
||||||
|
given-names: Akilan
|
||||||
|
title: P2PRC
|
||||||
|
license: "GPL-2.0"
|
||||||
|
version: 2.0.0
|
||||||
|
date-released: 2023-06-08
|
||||||
BIN
Docs/.DS_Store
vendored
Normal file
20
Docs/Abstractions.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Abstractions
|
||||||
|
|
||||||
|
| [◀ Previous](Installation.md) | [Next ▶](Implementation.md) |
|
||||||
|
|:-----------:|---------|
|
||||||
|
|
||||||
|
The Abstractions package consists of black-boxed functions for P2PRC.
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
- ```Init(<Project name>)```: Initializes P2PRC with all the needed configurations.
|
||||||
|
- ```Start()```: Starts p2prc as a server and makes it possible to extend by adding other routes and functionality to P2PRC.
|
||||||
|
- ```MapPort(<port no>)```: On the local machine the port you want to export to world.
|
||||||
|
- ```StartContainer(<ip address>)```: The machine on the p2p network where you want to spin up a docker container.
|
||||||
|
- ```RemoveContainer(<ip address>,<container id>)```: Terminate container based on the IP address and container name.
|
||||||
|
- ```GetSpecs(<ip address>)```: Get specs of a machine on the network based on the IP address.
|
||||||
|
- ```ViewIPTable()```: View the IP table which about nodes in the network.
|
||||||
|
- ```UpdateIPTable()```: Force update IP table to learn about new nodes faster.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Next Chapter: [Implementation](Implementation.md)
|
||||||
139
Docs/Bindings.md
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
# Language Bindings
|
||||||
|
[Language bindings](https://en.wikipedia.org/wiki/Language_binding) refers to wrappers to bridge 2 programming languages. This is used in P2PRC to extend calling P2PRC functions in other programming languages. Currently this is done by generating ```.so``` and ```.h``` from the Go compiler.
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
## How to build shared object files
|
||||||
|
#### The easier way
|
||||||
|
```bash
|
||||||
|
# Run
|
||||||
|
make sharedObjects
|
||||||
|
```
|
||||||
|
#### Or the direct way
|
||||||
|
```bash
|
||||||
|
# Run
|
||||||
|
cd Bindings && go build -buildmode=c-shared -o p2prc.so
|
||||||
|
```
|
||||||
|
#### If successfully built:
|
||||||
|
```bash
|
||||||
|
# Enter into the Bindings directory
|
||||||
|
cd Bindings
|
||||||
|
# List files
|
||||||
|
ls
|
||||||
|
# Find files
|
||||||
|
p2prc.h p2prc.so
|
||||||
|
```
|
||||||
|
<br>
|
||||||
|
|
||||||
|
## Workings under the hood
|
||||||
|
Below are a sample set of commands to
|
||||||
|
open the bindings implementation.
|
||||||
|
```
|
||||||
|
# run
|
||||||
|
cd Bindings/
|
||||||
|
# list files
|
||||||
|
ls
|
||||||
|
# search for file
|
||||||
|
Client.go
|
||||||
|
```
|
||||||
|
### In Client go
|
||||||
|
There a few things to notice which are different from
|
||||||
|
your standard Go programs:
|
||||||
|
|
||||||
|
#### 1. We import "C" which means [Cgo](https://pkg.go.dev/cmd/cgo) is required.
|
||||||
|
```go
|
||||||
|
import "C"
|
||||||
|
```
|
||||||
|
#### 2. All functions which are required to be called from other programming languages have comment such as.
|
||||||
|
```go
|
||||||
|
//export <function name>
|
||||||
|
|
||||||
|
// ------------ Example ----------------
|
||||||
|
// The function below allows to externally
|
||||||
|
// to call the P2PRC function to start containers
|
||||||
|
// in a specific node in the know list of nodes
|
||||||
|
// in the p2p network.
|
||||||
|
// Note: the comment "//export StartContainer".
|
||||||
|
|
||||||
|
//export StartContainer
|
||||||
|
func StartContainer(IP string) (output *C.char) {
|
||||||
|
container, err := client.StartContainer(IP, 0, false, "", "")
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
return ConvertStructToJSONString(container)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
#### 3. While looking through the file (If 2 files are compared it is pretty trivial to notice a common structure).
|
||||||
|
```go
|
||||||
|
// --------- Example ------------
|
||||||
|
|
||||||
|
//export StartContainer
|
||||||
|
func StartContainer(IP string) (output *C.char) {
|
||||||
|
container, err := client.StartContainer(IP, 0, false, "", "")
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
return ConvertStructToJSONString(container)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export ViewPlugin
|
||||||
|
func ViewPlugin() (output *C.char) {
|
||||||
|
plugins, err := plugin.DetectPlugins()
|
||||||
|
if err != nil {
|
||||||
|
return C.CString(err.Error())
|
||||||
|
}
|
||||||
|
return ConvertStructToJSONString(plugins)
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
#### It is easy to notice that:
|
||||||
|
- ```ConvertStructToJSONString(<go object>)```: This is a helper function that convert
|
||||||
|
a go object to JSON string initially and converts it to ```CString```.
|
||||||
|
- ```(output *C.char)```: This is the return type for most of the functions.
|
||||||
|
|
||||||
|
#### A Pseudo code to refer to the common function implementation shape could be represented as:
|
||||||
|
```
|
||||||
|
func <Function name> (output *C.char) {
|
||||||
|
<response>,<error> := <P2PRC function name>(<parameters if needed>)
|
||||||
|
if <error> != nil {
|
||||||
|
return C.CString(<error>.Error())
|
||||||
|
}
|
||||||
|
return ConvertStructToJSONString(<response>)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
## Current languages supported
|
||||||
|
- Python
|
||||||
|
|
||||||
|
### Build sample python program
|
||||||
|
The easier way
|
||||||
|
```bash
|
||||||
|
# Run
|
||||||
|
make python
|
||||||
|
# Expected ouput
|
||||||
|
Output is in the Directory Bindings/python/export/
|
||||||
|
# Run
|
||||||
|
cd Bindings/python/export/
|
||||||
|
# list files
|
||||||
|
ls
|
||||||
|
# Expected output
|
||||||
|
SharedObjects/ p2prc.py
|
||||||
|
```
|
||||||
|
Above shows a generated folder which consists of a folder
|
||||||
|
called "SharedObjects/" which consists of ```p2prc.so```
|
||||||
|
and ```p2prc.h``` files. ```p2prc.py``` refers to a
|
||||||
|
sample python script calling P2PRC go functions.
|
||||||
|
To start an any project to extend P2PRC with python,
|
||||||
|
This generated folder can copied and created as a new
|
||||||
|
git repo for P2PRC extensions scripted or used a reference
|
||||||
|
point as proof of concept that P2PRC can be called from
|
||||||
|
other programming languages.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ commands as possible. The cli was built using the library called urfave cli v2 .
|
|||||||
major files created named as flags.go and actions.go.
|
major files created named as flags.go and actions.go.
|
||||||
### Flags.go
|
### Flags.go
|
||||||
The flags .go file is responsible to create the appropriate flags for the cli. There are 2 types of flags
|
The flags .go file is responsible to create the appropriate flags for the cli. There are 2 types of flags
|
||||||
called boolean and string as described in Fig 5.3.1. Each of the flags outputs are assigned to a
|
called boolean and string. Each of the flags outputs are assigned to a
|
||||||
variable to be handled. The flags can also detect environment variables set. This feature is useful
|
variable to be handled. The flags can also detect environment variables set. This feature is useful
|
||||||
because if the user wants to call certain flags in a repeated sequence it only has to be initialized
|
because if the user wants to call certain flags in a repeated sequence it only has to be initialized
|
||||||
once.
|
once.
|
||||||
|
|||||||
@@ -1,25 +1,13 @@
|
|||||||
# Client Module
|
# Client Module
|
||||||
This module is incharge of communicating with the server and receiving the appropriate information back from the server.
|
This module is incharge of communicating with the server and receiving the appropriate information back from the server.
|
||||||
Note: To [read more about the functions](https://pkg.go.dev/git.sr.ht/~akilan1999/p2p-rendering-computation@v0.0.0-20210404191839-6a046babcb02/client)
|
|
||||||
|
|
||||||
## Functions of the Client Module
|
## Functions of the Client Module
|
||||||
- [Interact with the Server Api](#functions-of-the-client-module)
|
<!-- - [Interact with the Server Api](#functions-of-the-client-module) -->
|
||||||
- [Decision maker on how the ip table is created or updated](#decision-maker-on-how-the-ip-table-is-created-or-updated)
|
- [Decision maker on how the ip table is created or updated](#decision-maker-on-how-the-ip-table-is-created-or-updated)
|
||||||
|
|
||||||
|
|
||||||
## Interact with the Server Api
|
|
||||||
This sections talks about the functionality implemented till now.
|
|
||||||
- The client can start docker containers using the function StartContainer.
|
|
||||||
This functions calls the route:
|
|
||||||
```
|
|
||||||
http://<server IP address>:<server port>/startcontainer
|
|
||||||
```
|
|
||||||
TODO: Outputs and how it's printed
|
|
||||||
|
|
||||||
## Decision maker on how the IP table is created or updated
|
## Decision maker on how the IP table is created or updated
|
||||||
- Does a local speedtest to verify and see if the server IP's in the IP table
|
- Does a local speedtest to verify and see if the server IP's in the IP table
|
||||||
are pingable.
|
are pingable.
|
||||||
- Downloads the Servers IP table.
|
|
||||||
- Tries to ping the servers IP Table addresses.
|
- Tries to ping the servers IP Table addresses.
|
||||||
- If it's pingable then it's added as a new entry in the IP table.
|
- If it's pingable then it's added as a new entry in the IP table.
|
||||||
- The following steps occurs in the clients IP table.
|
- The following steps occurs in the clients IP table.
|
||||||
|
|||||||
@@ -1,10 +1,21 @@
|
|||||||
# Client Module Implementation
|
# Client Module Implementation
|
||||||
|
|
||||||
This section focuses in depth on how the client module works. To understand the architecture of
|
The Client Module interacts with the P2P module and Server Module. It is responsible for interacting with the server module and appropriately updating the IP table on the client side. It connects to the server using the server's REST Apis. It is also the primary decision maker on how the IP table is updated is on the client side. This is because each user can have requirements like how many number of hops they would want to do to update their IP table. Hops is the number of times the client is going to download the IP table from different servers ,once it gets the IP tables from the previous servers.
|
||||||
the client module refer to section 4.2. The client module is incharge of communicating with
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
## Topics
|
||||||
|
1. [Updating the IP table](#updating-the-IP-table)
|
||||||
|
2. [Reading server specifications](#reading-server-specifications)
|
||||||
|
3. [Client creating and removing container](#Client-creating-and-removing-container)
|
||||||
|
4. [Tracking Containers](#Tracking-Containers)
|
||||||
|
5. [Grouping Containers](#Grouping-Containers)
|
||||||
|
|
||||||
|
This section focuses in depth on how the client module works. The client module is incharge of communicating with
|
||||||
different servers based on the IP addresses provided to the user. The IP addresses are derived
|
different servers based on the IP addresses provided to the user. The IP addresses are derived
|
||||||
from peer to peer modules. Section 5.6 talks more in depth regarding the peer to peer module.
|
from peer to peer modules. The objective here is how the client module interacts with peer to peer module
|
||||||
The objective here is how the client module interacts with peer to peer module and server module.
|
and server module.
|
||||||
|
|
||||||
### Updating the IP table
|
### Updating the IP table
|
||||||
The client module calls the peer to peer module to get the local IP table initially, Based on the
|
The client module calls the peer to peer module to get the local IP table initially, Based on the
|
||||||
@@ -32,3 +43,46 @@ At the moment the username and password are hard coded from the server side for
|
|||||||
VNC.
|
VNC.
|
||||||
To remove a container the client module only requires the server IP address and the container ID.
|
To remove a container the client module only requires the server IP address and the container ID.
|
||||||
The client prints the response from the server Rest api.
|
The client prints the response from the server Rest api.
|
||||||
|
|
||||||
|
### Tracking Containers
|
||||||
|
Clients create docker images in multiple machines. This means if the client (i.e user) has many
|
||||||
|
containers created there needs to be a way to track them. To track containers there is a file
|
||||||
|
called ```trackcontainers.json``` which tracks all the containers running. The snippet below
|
||||||
|
show a sample structure of file ```trackcontainer.json```.
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"TrackContainer": [
|
||||||
|
{
|
||||||
|
"ID": "<ID>",
|
||||||
|
"Container": {<docker.DockerVM struct>},
|
||||||
|
"IpAddress": "<IP Address>"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
The default path to the container tracker is ```client/trackcontainers/trackcontainers.json```.
|
||||||
|
|
||||||
|
### Grouping Containers
|
||||||
|
When starting a set container possibility to be able to group them.
|
||||||
|
The benefit this would be that when executing plugins the group ID would be enough to execute
|
||||||
|
plugin in a set of containers. This provides the possibility to execute repetitive tasks in containers in
|
||||||
|
a single cli command. To store groups there is a file called ```grouptrackcontainer.json``` which tracks all
|
||||||
|
the groups currently present set by the client. The snippet below
|
||||||
|
show a sample structure of file ```grouptrackcontainer.json```.
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"Groups": [
|
||||||
|
{
|
||||||
|
"ID": "grp<Random UUID>",
|
||||||
|
"TrackContainer": [{client.TrackContainers struct}]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
The default path to the container tracker is ```client/trackcontainers/grouptrackcontainer.json```.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> The group id will be auto-generated and will have its own prefix in the start which will mostly be ```grp<UUID>```.
|
||||||
|
> When a container is removed using the command. ```p2prc --rm <IP Address> --id <Container id>```. It will be automatically deleted from the groups it exists in.
|
||||||
|
|||||||
@@ -13,9 +13,19 @@ JSON format.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"dockerfile": "/<path>/p2p-rendering-computation/server/docker/containers/docker-ubuntu-sshd/",
|
"MachineName": "pc-74-120.customer.ask4.lan",
|
||||||
"iptable": "/<path>/p2p-rendering-computation/p2p/ip_table.json",
|
"IPTable": "/Users/akilan/Documents/p2p-rendering-computation/p2p/iptable/ip_table.json",
|
||||||
"speedtestfile": "/<path>/p2p-rendering-computation/p2p/50.bin"
|
"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
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
2
Docs/DomainNameMappingsImplementation.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Domain name mappings
|
||||||
|
This
|
||||||
@@ -1,18 +1,23 @@
|
|||||||
# Implementation
|
# Implementation
|
||||||
|
| [◀ Previous](Introduction.md) | [Back to TOC](README.md) |
|
||||||
|
|:-----------:|---------|
|
||||||
|
|
||||||
This chapter describes how the project was built. It talks in depth of the implementation
|
This chapter describes how the project was built. It talks in depth of the implementation
|
||||||
performed to give a better understanding of the project.
|
performed to give a better understanding of the project.
|
||||||
|
|
||||||
## Programming langauge used
|
## Programming langauge used
|
||||||
The programming language used for this project was Golang. The reason Go lang was chosen was
|
The programming language used for this project was [Golang](https://go.dev/). The reason Go lang was chosen was
|
||||||
because it is a compiled language.
|
because it is a compiled language.<br>
|
||||||
The entire codebase is just a single binary file. When
|
The entire codebase is just a single binary file. When
|
||||||
distributing to other linux distributing the only requirement would be the binary file to run the
|
distributing to other linux distributing the only requirement would be the binary file to run the
|
||||||
code. It is easy to write independant modules and be monolithic at the sametime using Go. Using
|
code. It is easy to write independant modules and be monolithic at the sametime using Go.<br>
|
||||||
Go.mod makes it very easy to handle external libraries and modularise code. The go.mod name for
|
Using Go.mod makes it very easy to handle external libraries and modularise code. The go.mod name for
|
||||||
the project is git.sr.ht/~akilan1999/p2p-rendering-computation.
|
the project is [git.sr.ht/~akilan1999/p2p-rendering-computation](https://git.sr.ht/~akilan1999/p2p-rendering-computation).
|
||||||
|
|
||||||
## [Cli Module](CliImplementation.md)
|
- ## [Cli Module](CliImplementation.md)
|
||||||
## [Config Module](ConfigImplementation.md)
|
- ## [Config Module](ConfigImplementation.md)
|
||||||
## [Server Module](ServerImplementation.md)
|
- ## [Server Module](ServerImplementation.md)
|
||||||
## [Client Module](ClientImplementation.md)
|
- ## [Client Module](ClientImplementation.md)
|
||||||
## [P2P Module](P2PImplementation.md)
|
- ## [P2P Module](P2PImplementation.md)
|
||||||
|
- ## [Plugin Module](PluginImplementation.md)
|
||||||
|
- ## [Generate Module](GenerateImplementation.md)
|
||||||
@@ -1,7 +1,15 @@
|
|||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
|
| [◀ Previous](Introduction.md) | [Next ▶](Abstractions.md) |
|
||||||
|
|:-----------:|---------|
|
||||||
|
|
||||||
Over here we will cover the basic steps to get the server and client side running.
|
Over here we will cover the basic steps to get the server and client side running.
|
||||||
|
|
||||||
|
## Latest release install
|
||||||
|
https://github.com/Akilan1999/p2p-rendering-computation/releases
|
||||||
|
|
||||||
|
## Install from Github master branch
|
||||||
|
|
||||||
### Install Go lang
|
### Install Go lang
|
||||||
The entire the implementation of this project is done using Go lang.
|
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.
|
Thus, we need go lang to compile to code to a binary file.
|
||||||
@@ -16,7 +24,8 @@ interact with the containers.
|
|||||||
|
|
||||||
[Instructions to install docker GPU](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker)
|
[Instructions to install docker GPU](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker)
|
||||||
````
|
````
|
||||||
Do ensure that the docker command does not need sudo to run
|
// Do ensure that the docker command does not need sudo to run
|
||||||
|
sudo chmod 666 /var/run/docker.sock
|
||||||
````
|
````
|
||||||
|
|
||||||
### Build Project and install project
|
### Build Project and install project
|
||||||
@@ -26,6 +35,26 @@ into a single binary
|
|||||||
make install
|
make install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### For Windows
|
||||||
|
To set up P2PRC on Windows, simply run this batch file.
|
||||||
|
**Make sure you are not in admin mode when running this.**
|
||||||
|
```
|
||||||
|
.\install.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add appropriate paths to `.bashrc`
|
||||||
|
```
|
||||||
|
export P2PRC=/<PATH>/p2p-rendering-computation
|
||||||
|
export PATH=/<PATH>/p2p-rendering-computation:${PATH}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set up configuration file
|
||||||
|
```
|
||||||
|
make configfile
|
||||||
|
```
|
||||||
|
Open the config file ```config.json``` and add the IPv6 address
|
||||||
|
if you have one.
|
||||||
|
|
||||||
### Test if binary works
|
### Test if binary works
|
||||||
```
|
```
|
||||||
p2prc --help
|
p2prc --help
|
||||||
@@ -36,31 +65,180 @@ NAME:
|
|||||||
p2p-rendering-computation - p2p cli application to create and access VMs in other servers
|
p2p-rendering-computation - p2p cli application to create and access VMs in other servers
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
p2p-rendering-computation [global options] command [command options] [arguments...]
|
p2prc [global options] command [command options] [arguments...]
|
||||||
|
|
||||||
VERSION:
|
VERSION:
|
||||||
1.0.0
|
<version no>
|
||||||
|
|
||||||
COMMANDS:
|
COMMANDS:
|
||||||
help, h Shows a list of commands or help for one command
|
help, h Shows a list of commands or help for one command
|
||||||
|
|
||||||
GLOBAL OPTIONS:
|
GLOBAL OPTIONS:
|
||||||
--Mode value Specifies mode of running (default: "client") [$P2P_MODE]
|
--Server, -s Starts server (default: false) [$SERVER]
|
||||||
--UpdateServerList Update List of Server available based on servers iptables (default: false) [$UPDATE_SERVER_LIST]
|
--UpdateServerList, --us Update List of Server available based on servers iptables (default: false) [$UPDATE_SERVER_LIST]
|
||||||
--ListServers List servers which can render tasks (default: false) [$LIST_SERVERS]
|
--ListServers, --ls List servers which can render tasks (default: false) [$LIST_SERVERS]
|
||||||
--CreateVM value Creates Docker container on the selected server [$CREATE_VM]
|
--AddServer value, --as value Adds server IP address to iptables [$ADD_SERVER]
|
||||||
--RemoveVM value Stop and Remove Docker container [$REMOVE_VM]
|
--ViewImages value, --vi value View images available on the server IP address [$VIEW_IMAGES]
|
||||||
--ID value Docker Container ID [$ID]
|
--CreateVM value, --touch value Creates Docker container on the selected server [$CREATE_VM]
|
||||||
--Ports value Number of ports to open for the Docker Container [$NUM_PORTS]
|
--ContainerName value, --cn value Specifying the container run on the server side [$CONTAINER_NAME]
|
||||||
--GPU Create Docker Containers to access GPU (default: false) [$USE_GPU]
|
--RemoveVM value, --rm value Stop and Remove Docker container (IP:port) accompanied by container ID via --ID or --id [$REMOVE_VM]
|
||||||
--Specs value Specs of the server node [$SPECS]
|
--ID value, --id value Docker Container ID [$ID]
|
||||||
--SetDefaultConfig Sets a default configuration file (default: false) [$SET_DEFAULT_CONFIG]
|
--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]
|
||||||
|
--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]
|
||||||
--help, -h show help (default: false)
|
--help, -h show help (default: false)
|
||||||
--version, -v print the version (default: false)
|
--version, -v print the version (default: false)
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
#### Note: The steps on how to use the commands will be added later.
|
<br>
|
||||||
|
|
||||||
|
# Using basic commands
|
||||||
|
|
||||||
|
### Start as a server
|
||||||
|
Do ensure you have Docker installed for this
|
||||||
|
```
|
||||||
|
p2prc -s
|
||||||
|
```
|
||||||
|
|
||||||
|
### View server Specification
|
||||||
|
```
|
||||||
|
p2prc --specs=<ip address>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run container
|
||||||
|
use the ```--gpu``` if you know the other machine has a gpu.
|
||||||
|
```
|
||||||
|
p2prc --touch=<server ip address> -p <number of ports> --gpu
|
||||||
|
```
|
||||||
|
|
||||||
|
### Remove container
|
||||||
|
The docker id is present in the output where you create a container
|
||||||
|
```
|
||||||
|
p2prc --rm=<server ip address> --id=<docker container id>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adding servers to ip table
|
||||||
|
```
|
||||||
|
p2prc --as=<server ip address you want to add>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Update ip table
|
||||||
|
```
|
||||||
|
p2prc --us
|
||||||
|
```
|
||||||
|
|
||||||
|
### List Servers
|
||||||
|
```
|
||||||
|
p2prc --ls
|
||||||
|
```
|
||||||
|
|
||||||
|
### View Network interfaces
|
||||||
|
```
|
||||||
|
p2prc --ni
|
||||||
|
```
|
||||||
|
|
||||||
|
### Viewing Containers created Client side
|
||||||
|
```
|
||||||
|
p2prc --tc
|
||||||
|
```
|
||||||
|
[read more on tracking containers](ClientImplementation.md#tracking-containers)
|
||||||
|
|
||||||
|
### Running plugin
|
||||||
|
```
|
||||||
|
p2prc --plugin <plugin name> --id <container id or group id>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create group
|
||||||
|
```
|
||||||
|
p2prc --cgroup
|
||||||
|
```
|
||||||
|
### Add container to group
|
||||||
|
```
|
||||||
|
p2prc --group <group id> --id <container id>
|
||||||
|
```
|
||||||
|
### View groups
|
||||||
|
```
|
||||||
|
p2prc --groups
|
||||||
|
```
|
||||||
|
### View specific group
|
||||||
|
```
|
||||||
|
p2prc --group <group id>
|
||||||
|
```
|
||||||
|
### Delete container from group
|
||||||
|
```
|
||||||
|
p2prc --rmcgroup --group <group id> --id <container id>
|
||||||
|
```
|
||||||
|
### Delete entire group
|
||||||
|
```
|
||||||
|
p2prc --rmgroup <group id>
|
||||||
|
```
|
||||||
|
[read more on grouping containers](ClientImplementation.md#Grouping-Containers)
|
||||||
|
### Extending usecase of P2PRC (Requires a go compiler to run)
|
||||||
|
```
|
||||||
|
p2prc --gen <project name> --mod <go module name>
|
||||||
|
```
|
||||||
|
[read more about the generate module](GenerateImplementation.md)
|
||||||
|
|
||||||
|
### Pulling plugin from a remote repo
|
||||||
|
```
|
||||||
|
p2prc --pp <repo link>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deleting plugin from the plugin directory
|
||||||
|
```
|
||||||
|
p2prc --rp <plugin name>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Added custom metadata about the current node
|
||||||
|
```
|
||||||
|
p2prc --amd "custom metadata"
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
# Using Plugins
|
||||||
|
This feature is still Under Development:
|
||||||
|
[Read more on the implementation](PluginImplementation.md)
|
||||||
|
|
||||||
|
#### Dependencies
|
||||||
|
- Ansible:
|
||||||
|
- Debian/ubuntu: ```sudo apt install ansible```
|
||||||
|
- Others: [Installation link](https://ansible-tips-and-tricks.readthedocs.io/en/latest/ansible/install/)
|
||||||
|
|
||||||
|
#### Run Test Cases
|
||||||
|
- Generate Test Case Ansible file
|
||||||
|
- ```make testcases```
|
||||||
|
- Enter inside plugin directory and run tests.<br>
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> That docker needs to installed and needs to run without
|
||||||
|
> sudo. Refer the section [Install Docker](#install-docker).
|
||||||
|
> - ```cd plugin```
|
||||||
|
> - ```go test .```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Next Chapter: [Abstractions](Abstractions.md)
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
# Chapter 1: Introduction
|
# Chapter 1: Introduction
|
||||||
|
|
||||||
|
| [◀ Back to TOC](README.md) | [Next ▶](Installation.md) |
|
||||||
|
|:-----------:|---------|
|
||||||
|
|
||||||
## Abstract
|
## Abstract
|
||||||
This project focuses on creating a framework on running heavy tasks that a regular computer
|
This project focuses on creating a framework on running heavy tasks that a regular computer
|
||||||
cannot run easily such as graphically demanding video games, rendering 3D animations , protein
|
cannot run easily such as graphically demanding video games, rendering 3D animations , protein
|
||||||
@@ -21,7 +24,7 @@ run these heavy tasks can be really useful. Ethically speaking this is leading t
|
|||||||
computing power similar to what is happening in the web server area. By using peer to peer
|
computing power similar to what is happening in the web server area. By using peer to peer
|
||||||
principles it is possible to remove the monopolisation factor and increase the bandwidth between
|
principles it is possible to remove the monopolisation factor and increase the bandwidth between
|
||||||
the client and server.
|
the client and server.
|
||||||
|
<!--
|
||||||
## Aim
|
## Aim
|
||||||
This project aims to create a peer to peer (p2p) network, where a user can use the p2p network to
|
This project aims to create a peer to peer (p2p) network, where a user can use the p2p network to
|
||||||
act as a client (i.e sending tasks) or the server (i.e executing the tasks). A prototype application will
|
act as a client (i.e sending tasks) or the server (i.e executing the tasks). A prototype application will
|
||||||
@@ -33,4 +36,8 @@ or virtual environments across selected nodes.
|
|||||||
rendering tools and tools to batch any sort of tasks.
|
rendering tools and tools to batch any sort of tasks.
|
||||||
- Creating p2p network
|
- Creating p2p network
|
||||||
- Server to create a containerised environment
|
- Server to create a containerised environment
|
||||||
- The client node to run tasks on Server containerised node
|
- The client node to run tasks on Server containerised node -->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Next Chapter: [Installation](Installation.md)
|
||||||
37
Docs/NAT-Traveral.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# NAT Traversal
|
||||||
|
P2PRC currently supports TURN for NAT traversal.
|
||||||
|
|
||||||
|
## TURN
|
||||||
|
The current TURN implementation used is FRP. The TURN server is also required when
|
||||||
|
a P2PRC node is acting as a Server. The TURN server is determined based on the Node
|
||||||
|
with the least amount of latency based on the Nodes available on the IPTable.
|
||||||
|
Once a TURN server is determined there are 2 actions performed. The first one is
|
||||||
|
```/FRPPort``` to the TURN server to receive a port which is used to generate the external
|
||||||
|
port from the TURN server. The flow below describes the workflow.
|
||||||
|
|
||||||
|
### Client mode
|
||||||
|
- Call ```/FRPPort```
|
||||||
|
```
|
||||||
|
http://<turn server ip>:<server port no>/FRPport
|
||||||
|
```
|
||||||
|
- Call the TURN server in the following manner. The following is a sample code snippet below.
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
serverPort, err := frp.GetFRPServerPort("http://" + <lowestLatencyIpAddress.Ipv4> + ":" + lowestLatencyIpAddress.ServerPort)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Create 1 second delay to allow FRP server to start
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
// Starts FRP as a client with
|
||||||
|
proxyPort, err := frp.StartFRPClientForServer(<lowestLatencyIpAddress.Ipv4>, serverPort, <the port you want to expose externally>)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
@@ -19,11 +19,9 @@ In this repository the P2P module has been designed from sratch at the point of
|
|||||||
|
|
||||||
|
|
||||||
## Responsibility
|
## Responsibility
|
||||||
- To perform speed test to determine best node to connect
|
|
||||||
- To ensure the IP table has nodes which are pingable
|
- To ensure the IP table has nodes which are pingable
|
||||||
- Using techniques such as [UPNP](https://en.wikipedia.org/wiki/Universal_Plug_and_Play). Still under development
|
- Taking to nodes behind NAT. [More about the implementation](NAT-Traversal)...
|
||||||
- Port Forwarding (To be introducted in a future release)
|
|
||||||
|
|
||||||
|
|
||||||
## Note:
|
> [!NOTE]
|
||||||
If you are running in server mode it is recommended to use [DMZ](https://routerguide.net/when-and-how-to-setup-dmz-host-for-home-use/) to bypass the [NAT](https://en.wikipedia.org/wiki/Network_address_translation).
|
> If you are running in server mode it is recommended to use [DMZ](https://routerguide.net/when-and-how-to-setup-dmz-host-for-home-use/) to bypass the [NAT](https://en.wikipedia.org/wiki/Network_address_translation).
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
# P2P Module Implementation
|
# P2P Module Implementation
|
||||||
|
|
||||||
|
The P2P module (i.e Peer to Peer Module) is responsible for storing the IP table and interacting
|
||||||
|
with the IP table. In the following implementation of the P2P module ,the IP table stores
|
||||||
|
information about servers available in the network. The other functionality the P2P module takes
|
||||||
|
care of is doing the appropriate speed tests to the servers in the IP table. This is for informing the
|
||||||
|
users about nodes which are close by and nodes which have quicker uploads and downloads
|
||||||
|
speeds. The module is responsible to ensure that there are no duplicate server IPs in the IP table
|
||||||
|
and to remove all server IPs which are not pingable.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
The peer to peer implementation was built from scratch. This is because other peer to peer
|
The peer to peer implementation was built from scratch. This is because other peer to peer
|
||||||
libraries were on the implementation of the Distributed hash table. At the current moment all
|
libraries were on the implementation of the Distributed hash table. At the current moment all
|
||||||
those heavy features are not needed because the objective is to search and list all possible servers
|
those heavy features are not needed because the objective is to search and list all possible servers
|
||||||
available. The limitation being that to be a part of the network the user has to know at least 1
|
available. The limitation being that to be a part of the network the user has to know at least 1
|
||||||
server and has to have DMZ enabled from the router if the user wants to act as a server out of the
|
server. The advantage of building from scratch makes the module super light and
|
||||||
users local network. The advantage of building from scratch makes the module super light and
|
|
||||||
possibility for custom functions and structs. The sub topics below will mention the
|
possibility for custom functions and structs. The sub topics below will mention the
|
||||||
implementations of each functionality in depth.
|
implementations of each functionality in depth.
|
||||||
|
|
||||||
@@ -23,26 +33,53 @@ path of the IP table json file is received from the configuration module.
|
|||||||
"latency": "<latency>",
|
"latency": "<latency>",
|
||||||
"download": "<download>",
|
"download": "<download>",
|
||||||
"upload": "<upload>"
|
"upload": "<upload>"
|
||||||
|
"port no": "<server port no>",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Speed Test
|
|
||||||
The speed test functions populate the fields which are latency, download, upload speed. Before the
|
|
||||||
speed test begins for each server IP address. The p2p module ensures that each server IP address
|
|
||||||
is pingable. If the server IP address is not pingable then it removes that IP address from the struct.
|
|
||||||
|
|
||||||
### Latency
|
### Latency
|
||||||
The latency is measured in milliseconds. The route /server_info is called from the
|
The latency is measured in milliseconds. The route /server_info is called from the
|
||||||
server and time it takes to provide a json response is recorded.
|
server and time it takes to provide a json response is recorded.
|
||||||
|
|
||||||
### Download speed
|
## NAT Traversal
|
||||||
The download speed is measured as (<file size>/<time taken to
|
P2PRC currently supports TURN for NAT traversal.
|
||||||
download>)*8. This gives the result in megabits per second. The file downloaded is a 50 mb
|
|
||||||
auto generated file.
|
|
||||||
|
|
||||||
|
## TURN
|
||||||
|
The current TURN implementation used is FRP. The TURN server is also required when
|
||||||
|
a P2PRC node is acting as a Server. The TURN server is determined based on the Node
|
||||||
|
with the least amount of latency based on the Nodes available on the IPTable.
|
||||||
|
Once a TURN server is determined there are 2 actions performed. The first one is
|
||||||
|
```/FRPPort``` to the TURN server to receive a port which is used to generate the external
|
||||||
|
port from the TURN server. The flow below describes the workflow.
|
||||||
|
|
||||||
|
### Client mode
|
||||||
|
- Call ```/FRPPort```
|
||||||
|
```
|
||||||
|
http://<turn server ip>:<server port no>/FRPport
|
||||||
|
```
|
||||||
|
- Call the TURN server in the following manner. The following is a sample code snippet below.
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
serverPort, err := frp.GetFRPServerPort("http://" + <lowestLatencyIpAddress.Ipv4> + ":" + lowestLatencyIpAddress.ServerPort)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Create 1 second delay to allow FRP server to start
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
// Starts FRP as a client with
|
||||||
|
proxyPort, err := frp.StartFRPClientForServer(<lowestLatencyIpAddress.Ipv4>, serverPort, <the port you want to expose externally>)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Upload speed
|
|
||||||
The upload speed is measured as (<file size>/<time taken to upload>)*8. This
|
|
||||||
gives the results in megabits per second. The file uploaded is a 50 mb auto generated file.
|
|
||||||
The route /upload is called from the server side to upload the file.
|
|
||||||
|
|||||||
156
Docs/PluginImplementation.md
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
# Plugin Module Implementation
|
||||||
|
## Topics
|
||||||
|
1. [Introduciton](#introduction)
|
||||||
|
2. [Site.yml](#site-File-Template)
|
||||||
|
3. [Host](#hosts-file)
|
||||||
|
4. [Description](#description-file)
|
||||||
|
5. [Automatic port allocations](#automatic-port-allocations)
|
||||||
|
6. [Sample plugins implemented](#sample-plugins-implemented)
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
The plugin module is designed to ensure clients can execute instructions in a declarative manner across different
|
||||||
|
containers created. This means the user (i.e client) needs to write the instruction only once, and these instructions
|
||||||
|
can be executed across different nodes in a repetitive manner.
|
||||||
|
|
||||||
|
In the scenario of this project Ansibles will be used as the way the users can create these instructions.
|
||||||
|
|
||||||
|
- [Setup instruction](Installation.md#Using-Plugins)
|
||||||
|
|
||||||
|
The plugin module introduces a new path to the config file known as pluginpath. This path by defaults points to
|
||||||
|
```${P2PRC}/plugin/deploy```. Any file/folder inside ```plugin/deploy``` is part of the .gitginore. Plugins are
|
||||||
|
detected by folder names inside the ```plugin/deploy```.
|
||||||
|
```
|
||||||
|
plugin
|
||||||
|
|___ Deploy
|
||||||
|
|___<plugin name>
|
||||||
|
|___ site.yml
|
||||||
|
|___ hosts
|
||||||
|
|___ ports.json
|
||||||
|
|___ description.txt
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
n: n number of plugins possible
|
||||||
|
```
|
||||||
|
|
||||||
|
## Site File Template
|
||||||
|
The site file is also known as the Ansible playbook and is incharge of executing
|
||||||
|
instructions in a declarative manner. The below example specifies how to make one.
|
||||||
|
```
|
||||||
|
- hosts: all
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: <task name>
|
||||||
|
<ansible task>
|
||||||
|
debug:
|
||||||
|
msg: <debug message>
|
||||||
|
```
|
||||||
|
Read more about ansible tasks: https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html#about-playbooks
|
||||||
|
|
||||||
|
## Hosts file
|
||||||
|
hosts file is also known as the inventory file. This file consists of all the information required to connect to other
|
||||||
|
nodes to execute Ansible instructions. In this project this file needs to be set in a certain configuration because the
|
||||||
|
go code or binary will populate this file automatically with the appropriate information required to connect to local or
|
||||||
|
remote containers.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Add as exactly specified below:
|
||||||
|
> ```
|
||||||
|
>all:
|
||||||
|
> vars:
|
||||||
|
> ansible_python_interpreter: /usr/bin/python3 // Path to your python 3 interpreter
|
||||||
|
>main:
|
||||||
|
> hosts:
|
||||||
|
> host1:
|
||||||
|
> // Note: These values will be automatically overwritten
|
||||||
|
> // by the Go functions
|
||||||
|
> ansible_host: 0.0.0.0
|
||||||
|
> ansible_port: 39269
|
||||||
|
> ansible_user: master
|
||||||
|
> ansible_ssh_pass: password
|
||||||
|
> ansible_sudo_pass: password
|
||||||
|
>```
|
||||||
|
|
||||||
|
## Ports.json
|
||||||
|
The ```ports.json``` file is intended to mention the number of ports required
|
||||||
|
by the plugin.
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"NumOfPorts": <number of ports>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Description file
|
||||||
|
This is a simple text file used to describe what the module does.
|
||||||
|
When the client is looking at various commands via the ClI.
|
||||||
|
The description is displayed along-side the plugin name.
|
||||||
|
|
||||||
|
Ex: When the flag ```--ViewPlugins``` or ```--vp``` is called
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"PluginsDetected": [
|
||||||
|
{
|
||||||
|
"FolderName": "<name of the plugin>",
|
||||||
|
"PluginDescription": "<description of the plugin>"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Automatic port allocations
|
||||||
|
P2PRC would be in-charge to set to the ports to various TCP ports
|
||||||
|
opened. Due to this implementation the plugin being executed is
|
||||||
|
copied to the tmp directory with a unique UUID.
|
||||||
|
```
|
||||||
|
Command: ls /tmp
|
||||||
|
output: Semantic <UUID>_<Plugin Name>
|
||||||
|
2e6d76c4-0ed1-4b55-9385-79a58d4f0492_p2prc-vscode-browser
|
||||||
|
7b631e08-62ee-4c1c-a2a4-c05857b9aa7d_p2prc-vscode-browser
|
||||||
|
```
|
||||||
|
Once the copy of the plugin is added to the /tmp directory
|
||||||
|
the site.yml file inside the appropriate yaml is modified
|
||||||
|
with the appropriate ports assigned to the container.
|
||||||
|
|
||||||
|
### Ex:
|
||||||
|
1. Create container called c1 with an automatic generated TCP port
|
||||||
|
3313 (external) - 3313 (internal)
|
||||||
|
2. Assumption of plugin p1 exists. p1 has one server which needs to
|
||||||
|
be mapped to a free open TCP port in container c1. Below shows
|
||||||
|
an implementation of a sample site.yml file.
|
||||||
|
```
|
||||||
|
---
|
||||||
|
- hosts: all
|
||||||
|
tasks:
|
||||||
|
- name: start vscode code server
|
||||||
|
shell: sh server.sh 0.0.0.0:{{index . 0}}
|
||||||
|
```
|
||||||
|
Notice there is the following {{index . 0}}. {{index . 0}} does not belong to
|
||||||
|
Ansible but rather is a way to mention where to add the external free port
|
||||||
|
of the container. We use the golang [template library](https://pkg.go.dev/text/template)
|
||||||
|
to parse and populate the site.yml with the appropriate open ports. An array of ints
|
||||||
|
which consists of open free ports are sent to the site.yml. 0 in {{index . 0}} refers
|
||||||
|
to the index in the int array passed on.
|
||||||
|
|
||||||
|
After the port is automatically it's ready to run !
|
||||||
|
```
|
||||||
|
---
|
||||||
|
- hosts: all
|
||||||
|
tasks:
|
||||||
|
- name: start vscode code server
|
||||||
|
shell: sh server.sh 0.0.0.0:3313
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sample plugins implemented:
|
||||||
|
- [VSCode Plugin](https://github.com/Akilan1999/p2prc-vscode-browser)
|
||||||
|
|
||||||
|
## Pull Plugins
|
||||||
|
The following allows us to pull plugins from a remote git repository and store them
|
||||||
|
in the default plugins directory. The implementation uses a Go git library to pull the
|
||||||
|
git repo and automatically save it as a folder in the plugin path.
|
||||||
|
|
||||||
|
## Delete Plugins
|
||||||
|
We delete the plugin folder based on the plugin name provided as an argument on the cli command.
|
||||||
|
Once the folder is deleted, the plugin manager automatically knows that the plugin does not exist anymore.
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
# Problems in implementation
|
|
||||||
|
|
||||||
### Number of Devices in the network:
|
|
||||||
The current implementation has the major flaw which is that
|
|
||||||
the server has to be in port 8088 to detected in the public
|
|
||||||
network. As we know most personal networks have a single IP
|
|
||||||
address. This means we cannot have duplicate ports. A fix can
|
|
||||||
be to mention the open port on the IP table file.
|
|
||||||
(Ex: Possible feild to be added)
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"ip_address": [
|
|
||||||
{
|
|
||||||
"ipv4": "localhost",
|
|
||||||
"latency": 14981051,
|
|
||||||
"download": 8142.122540206258,
|
|
||||||
"upload": 3578.766512629995,
|
|
||||||
"port": 8088
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Broadcast of container specs
|
|
||||||
At the moment the container specs are not broadcasted rather
|
|
||||||
just the machines specs and this module has yet to be tested
|
|
||||||
rigorously.
|
|
||||||
|
|
||||||
### Intergration with GPU
|
|
||||||
Certain machines have GPUs present in them which provide a
|
|
||||||
huge advantage for those who want to do rendering and certain
|
|
||||||
sort of computation. The Aim is to only allow it to be compatible
|
|
||||||
with Nvidia. But an better idea would be to provide compatability
|
|
||||||
with multiple GPU providers.
|
|
||||||
|
|
||||||
@@ -2,15 +2,19 @@
|
|||||||
# Table of contents
|
# Table of contents
|
||||||
1. [Introduction](Introduction.md)
|
1. [Introduction](Introduction.md)
|
||||||
2. [Installation](Installation.md)
|
2. [Installation](Installation.md)
|
||||||
3. [Design Architecture](DesignArchtectureIntro.md)
|
3. [Abstractions](Abstractions.md)
|
||||||
|
<!-- 3. [Design Architecture](DesignArchtectureIntro.md)
|
||||||
1. [Client Module](ClientArchitecture.md)
|
1. [Client Module](ClientArchitecture.md)
|
||||||
2. [P2P Module](P2PArchitecture.md)
|
2. [P2P Module](P2PArchitecture.md)
|
||||||
3. [Server Module](ServerArchitecture.md)
|
3. [Server Module](ServerArchitecture.md) -->
|
||||||
4. [Implementation](Implementation.md)
|
4. [Implementation](Implementation.md)
|
||||||
1. [Client Module](ClientImplementation.md)
|
1. [Client Module](ClientImplementation.md)
|
||||||
2. [P2P Module](P2PImplementation.md)
|
2. [P2P Module](P2PImplementation.md)
|
||||||
3. [Server Module](ServerImplementation.md)
|
3. [Server Module](ServerImplementation.md)
|
||||||
4. [Config Module](ConfigImplementation.md)
|
4. [Config Module](ConfigImplementation.md)
|
||||||
5. [Cli Module](CliImplementation.md)
|
5. [Cli Module](CliImplementation.md)
|
||||||
5. [Problems](Problems.md)
|
6. [Plugin Module](PluginImplementation.md)
|
||||||
|
7. [Language bindings](Bindings.md)
|
||||||
|
8. [Domain name mappings](Bindings.md)
|
||||||
|
<!-- 5. [Problems](https://github.com/Akilan1999/p2p-rendering-computation/issues) -->
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,14 @@ This section focuses on an in-depth understanding of the server module implement
|
|||||||
understand the architecture of the server module refer. The server module can be split
|
understand the architecture of the server module refer. The server module can be split
|
||||||
into various sections. Each section will provide information on how a certain feature works.
|
into various sections. Each section will provide information on how a certain feature works.
|
||||||
|
|
||||||
|
The server module takes care of setting and removing the virtualization environment (i.e
|
||||||
|
containers) for accessing and doing the appropriate computation. It also interacts with the peer to
|
||||||
|
peer module to update the IP table on the server side. The server module
|
||||||
|
accesses information regarding CPU and GPU specifications of the machine running the server
|
||||||
|
module. To do Speed tests the server has routes which allows it to upload and download a 50mb.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Web framework
|
## Web framework
|
||||||
The web framework used for the server module is called Gin. The reason Gin was chosen is due to
|
The web framework used for the server module is called Gin. The reason Gin was chosen is due to
|
||||||
its wide use and strong documentation available on the official github repository. The default
|
its wide use and strong documentation available on the official github repository. The default
|
||||||
@@ -159,6 +167,33 @@ it does not utilize server resources when it is not being used, or the task that
|
|||||||
To run this function all that is needed is the docker container ID. If the function is successful it returns
|
To run this function all that is needed is the docker container ID. If the function is successful it returns
|
||||||
a string that says success.
|
a string that says success.
|
||||||
|
|
||||||
|
### Ports json file
|
||||||
|
This file will help map internal ports inside a container to external ports inside a container. A common example
|
||||||
|
would be the SSH port which is port 22 inside the docker container and is mapped to random TCP port outside container
|
||||||
|
so that any external machines can directly connect into the container. The below representation mentions of where
|
||||||
|
the ports.json file is located and also the format of that file.
|
||||||
|
```
|
||||||
|
|_ <Container name>
|
||||||
|
|_ Dockerfile
|
||||||
|
|_ description.txt
|
||||||
|
|_ ports.json // The ports file
|
||||||
|
```
|
||||||
|
Format of the ports.json file
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"Port": [
|
||||||
|
{
|
||||||
|
"PortName": "<Port name>",
|
||||||
|
"InternalPort": <internal port>,
|
||||||
|
"Type": "<tcp/udp>",
|
||||||
|
"ExternalPort": <external port>,
|
||||||
|
"IsUsed": "<boolean value (i.e true or false)>",
|
||||||
|
"Description": "<description about the port>"
|
||||||
|
}, ... n
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
BIN
Docs/images/p2prclogo.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
24
Makefile
@@ -1,20 +1,20 @@
|
|||||||
SHELL := /bin/bash
|
SHELL := /bin/bash
|
||||||
|
|
||||||
install:
|
install:
|
||||||
go build -o p2prc
|
sh install.sh p2prc
|
||||||
echo '# Paths for p2p rendering and computation' >> ~/.bashrc
|
|
||||||
echo 'export P2PRC=${PWD}' >> ~/.bashrc
|
|
||||||
echo 'export path=${PWD}:$${PATH}' >> ~/.bashrc
|
|
||||||
source ~/.bashrc
|
|
||||||
./p2prc --SetDefaultConfig
|
|
||||||
|
|
||||||
|
testcases:
|
||||||
build:
|
sh plugin/generate_test_case.sh
|
||||||
go build -o p2prc
|
|
||||||
|
|
||||||
config:
|
|
||||||
./p2p-rendering-computation --SetDefaultConfig
|
|
||||||
|
|
||||||
run:
|
run:
|
||||||
go run main.go
|
go run main.go
|
||||||
|
|
||||||
|
sharedObjects:
|
||||||
|
sh build-bindings.sh
|
||||||
|
|
||||||
|
python:
|
||||||
|
sh build-python-package.sh
|
||||||
|
|
||||||
|
clean:
|
||||||
|
go clean -modcache
|
||||||
|
rm -fr .go-build vendor result*
|
||||||
|
|||||||
159
README.md
@@ -1,13 +1,164 @@
|
|||||||
# P2P rendering and computation
|
> [!NOTE]
|
||||||
|
> Fixing documentation to latest changes. If you have any questions setting up P2PRC either [create an issue](https://github.com/Akilan1999/p2p-rendering-computation/issues/new/choose) or send me an email (me AT akilan dot io).
|
||||||
|
> Currently HEAD is always intended to stay on a working state. It is recommended to always use HEAD in your go.mod file.
|
||||||
|
|
||||||
[](https://www.youtube.com/watch?v=LRv3NR2lu7I "Simple P2P Cli application for creating containers")
|
<h1 align="center">
|
||||||
|
<br>
|
||||||
|
<a href=""><img src="https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/master/Docs/images/p2prclogo.png" alt="p2prc" width="400"></a>
|
||||||
|
<br>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<!-- seperator -->
|
||||||
|
|
||||||
|
<div style="display:flex;flex-wrap:wrap;">
|
||||||
|
<a href="http://perso.crans.org/besson/LICENSE.html"><img alt="GPLv2 license" src="https://img.shields.io/badge/License-GPLv2-blue.svg" style="padding:5px;margin:5px;" /></a>
|
||||||
|
<a href="https://GitHub.com/Akilan1999/p2p-rendering-computation/graphs/commit-activity"><img alt="Maintenance" src="https://img.shields.io/badge/Maintained%3F-yes-green.svg" style="padding:5px;margin:5px;" /></a>
|
||||||
|
<a href="http://golang.org"><img alt="made-with-Go" src="https://img.shields.io/badge/Made%20with-Go-1f425f.svg" style="padding:5px;margin:5px;" /></a>
|
||||||
|
<a href="https://pkg.go.dev/git.sr.ht/~akilan1999/p2p-rendering-computation"><img alt="GoDoc reference example" src="https://img.shields.io/badge/godoc-reference-blue.svg" style="padding:5px;margin:5px;" /></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
The main aim of this project was to create a custom peer to peer network. The user acting as the
|
The main aim of this project was to create a custom peer to peer network. The user acting as the
|
||||||
client has total flexibility on how to batch the tasks and the user acting as the server has complete
|
client has total flexibility on how to batch the tasks and the user acting as the server has complete
|
||||||
flexibility on tracking the container's usages and killing the containers at any point of time.
|
flexibility on tracking the container's usages and killing the containers at any point of time.
|
||||||
|
|
||||||
1. [Installation](Docs/Installation.md)
|
## Latest tutorial
|
||||||
2. [Documentation](Docs/README.md)
|
[](https://www.youtube.com/watch?v=OMwCpedu5cs")
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
## Table of contents in the current README
|
||||||
|
1. [Introduction](#Introduction)
|
||||||
|
2. [Installation](#extend-your-application-with-p2prc)
|
||||||
|
3. [Design Architecture](#Design-Architecture)
|
||||||
|
4. [Implementation](#Implementation)
|
||||||
|
5. [Find out more](#Find-out-more)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
# Table of contents in the Docs folder
|
||||||
|
1. [Introduction](Docs/Introduction.md)
|
||||||
|
2. [Installation](Docs/Installation.md)
|
||||||
|
3. [Abstractions](Docs/Abstractions.md)
|
||||||
|
<!-- 3. [Design Architecture](DesignArchtectureIntro.md)
|
||||||
|
1. [Client Module](ClientArchitecture.md)
|
||||||
|
2. [P2P Module](P2PArchitecture.md)
|
||||||
|
3. [Server Module](ServerArchitecture.md) -->
|
||||||
|
4. [Implementation](Docs/Implementation.md)
|
||||||
|
1. [Client Module](Docs/ClientImplementation.md)
|
||||||
|
2. [P2P Module](Docs/P2PImplementation.md)
|
||||||
|
3. [Server Module](Docs/ServerImplementation.md)
|
||||||
|
4. [Config Module](Docs/ConfigImplementation.md)
|
||||||
|
5. [Cli Module](Docs/CliImplementation.md)
|
||||||
|
6. [Plugin Module](Docs/PluginImplementation.md)
|
||||||
|
7. [Language Bindings](Docs/Bindings.md)
|
||||||
|
<!-- 5. [Problems](https://github.com/Akilan1999/p2p-rendering-computation/issues) -->
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
This project aims to create a peer to peer (p2p) network, where a user can use the p2p network to act as a client (i.e sending tasks) or the server (i.e executing the tasks). A prototype application will be developed, which comes bundled with a p2p module and possible to execute docker containers or virtual environments across selected nodes.
|
||||||
|
|
||||||
|
### Objectives
|
||||||
|
- Background review on peer to peer network, virtual environments, decentralized rendering tools and tools to batch any sort of tasks.
|
||||||
|
- Creating p2p network
|
||||||
|
- Server to create a containerised environment
|
||||||
|
- The client node to run tasks on Server containerised node
|
||||||
|
|
||||||
|
[Read more on the introduction](Docs/Introduction.md)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
## Extend your application with P2PRC
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/abstractions"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
_, err := abstractions.Init(nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// start p2prc
|
||||||
|
_, err = abstractions.Start()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run server till termination
|
||||||
|
for {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Export once this is added export P2PRC as environment paths
|
||||||
|
```
|
||||||
|
export P2PRC=<PROJECT PATH>
|
||||||
|
export PATH=<PROJECT PATH>:${PATH}
|
||||||
|
```
|
||||||
|
[Read more](Docs/Abstractions.md) ...
|
||||||
|
|
||||||
|
## Installation from source
|
||||||
|
1. Ensure the Go compiler is installed
|
||||||
|
```
|
||||||
|
go version
|
||||||
|
```
|
||||||
|
3. Ensure docker is installed (Should run without sudo)
|
||||||
|
```
|
||||||
|
docker ps
|
||||||
|
```
|
||||||
|
3. Clone this repository
|
||||||
|
```
|
||||||
|
git clone https://github.com/Akilan1999/p2p-rendering-computation
|
||||||
|
```
|
||||||
|
4. Install and build the project
|
||||||
|
```
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
- If you look closely you will get outputs such as:
|
||||||
|
```
|
||||||
|
// Add them to your .bashrc file
|
||||||
|
export P2PRC=/<path>/p2p-rendering-computation
|
||||||
|
export PATH=/<path>/p2p-rendering-computation:${PATH}
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Test if it works
|
||||||
|
```
|
||||||
|
p2prc -h
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```
|
||||||
|
./p2prc -h
|
||||||
|
```
|
||||||
|
[Read more on the installation and usage](Docs/Installation.md)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
## Design Architecture
|
||||||
|
The design architecture was inspired and based on the linux kernel design. The project is segmented into various modules. Each module is responsible for certain tasks in the project. The modules are highly dependent on each other hence the entire codebase can be considered as a huge monolithic chuck which acts as its own library
|
||||||
|
|
||||||
|
[Read more on the Design Architecture](Docs/DesignArchtectureIntro.md)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
The programming language used for this project was Golang. The reason Go lang was chosen was because it is a compiled language. The entire codebase is just a single binary file. When distributing to other linux distributing the only requirement would be the binary file to run the code. It is easy to write independant modules and be monolithic at the sametime using Go. Using Go.mod makes it very easy to handle external libraries and modularise code. The go.mod name for the project is git.sr.ht/~akilan1999/p2p-rendering-computation.
|
||||||
|
|
||||||
|
[Read more on the Implementation](Docs/Implementation.md)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
## Find out more
|
||||||
|
As we are working on the open source project p2prc (i.e p2p network designed for computation).If you are interested in participating as a contributor
|
||||||
|
or just providing feedback on new features to build or even just curious about new features added to the project. We have decided to create a discord group.
|
||||||
|
[](https://discord.gg/b4nRGTjYqy)
|
||||||
|
|
||||||
|
[](https://github.com/Gaurav-Gosain)
|
||||||
|
|||||||
9
_config.yml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
remote_theme: abhinavs/moonwalk
|
||||||
|
|
||||||
|
favicon: "favicon-32x32.png" # relative path to site's favicon
|
||||||
|
|
||||||
|
theme_config:
|
||||||
|
appearance: "dark" # can be "light", "dark" or "auto"
|
||||||
|
appearance_toggle: true # if appearance can be switched by user
|
||||||
|
show_navbar: false
|
||||||
|
show_footer: false
|
||||||
88
abstractions/base.go
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
package abstractions
|
||||||
|
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/client"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
|
||||||
|
Config "github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/config/generate"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/server"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Init Initialises p2prc
|
||||||
|
func Init(customConfig interface{}) (config *Config.Config, err error) {
|
||||||
|
|
||||||
|
// Get config file path
|
||||||
|
// Checks P2PRC path initially
|
||||||
|
// - Get PATH if environment varaible
|
||||||
|
path, err := Config.GetPathP2PRC("P2PRC")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// check if the config file exists
|
||||||
|
if _, err = os.Stat(path + "config.json"); err != nil {
|
||||||
|
// Initialize with base p2prc config files
|
||||||
|
// set the config file with default paths
|
||||||
|
config, err = generate.SetDefaults("P2PRC", false, customConfig, false)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If the configs are available then use them over generating new ones.
|
||||||
|
config, err = Config.ConfigInit(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start p2prc in a server mode
|
||||||
|
func Start() (*gin.Engine, error) {
|
||||||
|
engine, err := server.Server()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return engine, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MapPort Creates a reverse proxy connection and maps the appropriate port
|
||||||
|
func MapPort(port string, domainName string) (entireAddres string, mapPort string, err error) {
|
||||||
|
entireAddres, mapPort, err = server.MapPort(port, domainName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartContainer Starts docker container on the remote machine
|
||||||
|
func StartContainer(IP string) (container *docker.DockerVM, err error) {
|
||||||
|
container, err = client.StartContainer(IP, 0, false, "", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveContainer Removes docker container based on the IP address and ID
|
||||||
|
// provided
|
||||||
|
func RemoveContainer(IP string, ID string) error {
|
||||||
|
return client.RemoveContianer(IP, ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSpecs Get spec information about the remote server
|
||||||
|
func GetSpecs(IP string) (specs *server.SysInfo, err error) {
|
||||||
|
specs, err = client.GetSpecs(IP)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ViewIPTable View information of nodes in the network
|
||||||
|
func ViewIPTable() (table *p2p.IpAddresses, err error) {
|
||||||
|
table, err = p2p.ReadIpTable()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateIPTable Force updates IP tables based on new
|
||||||
|
// new nodes discovered in the network
|
||||||
|
func UpdateIPTable() (err error) {
|
||||||
|
return clientIPTable.UpdateIpTableListClient()
|
||||||
|
}
|
||||||
BIN
artwork/.DS_Store
vendored
Normal file
14
artwork/README.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
# p2prc_logo
|
||||||
|
|
||||||
|
## Pure HTML Version of the p2prc Logo :)
|
||||||
|

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

|
||||||
46
artwork/embed.svg
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<svg width="800" height="800" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<foreignObject width="800" height="800">
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--size: 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg {
|
||||||
|
width: calc(var(--size)*100px);
|
||||||
|
height: calc(var(--size)*100px);
|
||||||
|
background: linear-gradient(90deg,
|
||||||
|
rgb(254, 188, 80) 30%,
|
||||||
|
rgb(235, 162, 118) 50%,
|
||||||
|
rgb(255, 97, 69) 70%);
|
||||||
|
-webkit-mask-size: calc(var(--size)*100px) calc(var(--size)*100px);
|
||||||
|
-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0iZTdReFVvNjhGTlMxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIg0KICAgIHZpZXdCb3g9IjAgMCA2MDAgNjAwIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+DQogICAgPGc+DQogICAgICAgIDxsaW5lIHgxPSItMzIuNSIgeTE9Ii0xMy41IiB4Mj0iMzIuNSIgeTI9IjEzLjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5Mi41IDI1MS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTE3LjI1IiB5MT0iMjMuNzUiIHgyPSIxNy4yNSIgeTI9Ii0yMy43NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA3Ljc1IDI4OC43NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iLTE3LjUiIHgyPSIyNC41IiB5Mj0iMTcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQ5LjUgMjgyLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjQuNSIgeTE9IjI1LjUiIHgyPSIyNC41IiB5Mj0iLTI1LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0OS41IDIzOS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTMzLjI1IiB5MT0iLTE2LjI1IiB4Mj0iMzMuMjUiIHkyPSIxNi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLjc1IDE5Ny4zMTAyNDkpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMTMiIHkxPSIyNyIgeDI9IjEzIiB5Mj0iLTI3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODYuMTIwNDk4IDE4NykiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzNmNTc4NyINCiAgICAgICAgICAgIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yMy43NSIgeTE9Ii0xOC44NzUiIHgyPSIyMy43NSIgeTI9IjE4Ljg3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzIyLjg3MDQ5OSAxNzguODc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTAuNSIgeTE9Ii00MC4zNzUiIHgyPSIwLjUiIHkyPSI0MC4zNzUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OCAyMzguMTI1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iMzcuMjUiIHkxPSIzMi4yNSIgeDI9Ii0zNy4yNSIgeTI9Ii0zMi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzExLjI1IDI0Ni4yNSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9IjM2Ljc1IiB5MT0iLTExLjI1IiB4Mj0iLTM2Ljc1IiB5Mj0iMTEuMjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMxMC43NSAyODguNzUpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjEuMjUiIHkxPSItMTguMjUiIHgyPSIyMS4yNSIgeTI9IjE4LjI1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNjkuNzUgMjk1Ljc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTIxLjUiIHkxPSItMTUuMTI1IiB4Mj0iMjEuNSIgeTI9IjE1LjEyNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzY5LjUgMjEyLjg3NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iMTYuNSIgeDI9IjI0LjUiIHkyPSItMTYuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDE1LjUgMjExLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjMuMjUiIHkxPSItMjQuNzUiIHgyPSIyMy4yNSIgeTI9IjI0Ljc1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MTQuMjUgMjUyLjc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgIDwvZz4NCiAgICA8Zz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMDcuNSAxODEuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMwMCAxNjApIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxMCIgcnk9IjEwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjAgMjM4KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTQiIHJ5PSIxNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjc0IDIxNCkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNDcuNSAxOTcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0MCAxOTUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIyMCIgcnk9IjIwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMjUgMjY1KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTguNSIgcnk9IjE4LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OC41IDI3OC41KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iNy41IiByeT0iNy41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MzcuNSAyNzcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjcuNSIgcnk9IjcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTkwLjUgMzEyLjUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxNCIgcnk9IjE0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNzQgMjk5KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iOSIgcnk9IjkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM5MSAzMTQpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgPC9nPg0KPC9zdmc+");
|
||||||
|
mask-size: calc(var(--size)*100px) calc(var(--size)*100px);
|
||||||
|
mask-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0iZTdReFVvNjhGTlMxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIg0KICAgIHZpZXdCb3g9IjAgMCA2MDAgNjAwIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+DQogICAgPGc+DQogICAgICAgIDxsaW5lIHgxPSItMzIuNSIgeTE9Ii0xMy41IiB4Mj0iMzIuNSIgeTI9IjEzLjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5Mi41IDI1MS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTE3LjI1IiB5MT0iMjMuNzUiIHgyPSIxNy4yNSIgeTI9Ii0yMy43NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA3Ljc1IDI4OC43NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iLTE3LjUiIHgyPSIyNC41IiB5Mj0iMTcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQ5LjUgMjgyLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjQuNSIgeTE9IjI1LjUiIHgyPSIyNC41IiB5Mj0iLTI1LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0OS41IDIzOS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTMzLjI1IiB5MT0iLTE2LjI1IiB4Mj0iMzMuMjUiIHkyPSIxNi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLjc1IDE5Ny4zMTAyNDkpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMTMiIHkxPSIyNyIgeDI9IjEzIiB5Mj0iLTI3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODYuMTIwNDk4IDE4NykiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzNmNTc4NyINCiAgICAgICAgICAgIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yMy43NSIgeTE9Ii0xOC44NzUiIHgyPSIyMy43NSIgeTI9IjE4Ljg3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzIyLjg3MDQ5OSAxNzguODc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTAuNSIgeTE9Ii00MC4zNzUiIHgyPSIwLjUiIHkyPSI0MC4zNzUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OCAyMzguMTI1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iMzcuMjUiIHkxPSIzMi4yNSIgeDI9Ii0zNy4yNSIgeTI9Ii0zMi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzExLjI1IDI0Ni4yNSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9IjM2Ljc1IiB5MT0iLTExLjI1IiB4Mj0iLTM2Ljc1IiB5Mj0iMTEuMjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMxMC43NSAyODguNzUpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjEuMjUiIHkxPSItMTguMjUiIHgyPSIyMS4yNSIgeTI9IjE4LjI1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNjkuNzUgMjk1Ljc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTIxLjUiIHkxPSItMTUuMTI1IiB4Mj0iMjEuNSIgeTI9IjE1LjEyNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzY5LjUgMjEyLjg3NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iMTYuNSIgeDI9IjI0LjUiIHkyPSItMTYuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDE1LjUgMjExLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjMuMjUiIHkxPSItMjQuNzUiIHgyPSIyMy4yNSIgeTI9IjI0Ljc1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MTQuMjUgMjUyLjc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgIDwvZz4NCiAgICA8Zz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMDcuNSAxODEuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMwMCAxNjApIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxMCIgcnk9IjEwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjAgMjM4KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTQiIHJ5PSIxNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjc0IDIxNCkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNDcuNSAxOTcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0MCAxOTUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIyMCIgcnk9IjIwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMjUgMjY1KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTguNSIgcnk9IjE4LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OC41IDI3OC41KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iNy41IiByeT0iNy41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MzcuNSAyNzcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjcuNSIgcnk9IjcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTkwLjUgMzEyLjUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxNCIgcnk9IjE0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNzQgMjk5KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iOSIgcnk9IjkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM5MSAzMTQpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgPC9nPg0KPC9zdmc+");
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.p2prc {
|
||||||
|
position: fixed;
|
||||||
|
top: 63%;
|
||||||
|
font-size: calc((var(--size) * 100px)/8);
|
||||||
|
font-weight: 700;
|
||||||
|
font-family: sans-serif;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="logo">
|
||||||
|
<div class="bg"></div>
|
||||||
|
<div class="p2prc">p2prc</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 11 KiB |
53
artwork/index.html
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>p2prc</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--size: 8;
|
||||||
|
}
|
||||||
|
.bg {
|
||||||
|
width: calc(var(--size)*100px);
|
||||||
|
height: calc(var(--size)*100px);
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
rgb(254,188,80) 30%,
|
||||||
|
rgb(235,162,118) 50%,
|
||||||
|
rgb(255,97,69) 70%
|
||||||
|
);
|
||||||
|
-webkit-mask-size: calc(var(--size)*100px) calc(var(--size)*100px);
|
||||||
|
-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0iZTdReFVvNjhGTlMxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIg0KICAgIHZpZXdCb3g9IjAgMCA2MDAgNjAwIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+DQogICAgPGc+DQogICAgICAgIDxsaW5lIHgxPSItMzIuNSIgeTE9Ii0xMy41IiB4Mj0iMzIuNSIgeTI9IjEzLjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5Mi41IDI1MS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTE3LjI1IiB5MT0iMjMuNzUiIHgyPSIxNy4yNSIgeTI9Ii0yMy43NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA3Ljc1IDI4OC43NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iLTE3LjUiIHgyPSIyNC41IiB5Mj0iMTcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQ5LjUgMjgyLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjQuNSIgeTE9IjI1LjUiIHgyPSIyNC41IiB5Mj0iLTI1LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0OS41IDIzOS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTMzLjI1IiB5MT0iLTE2LjI1IiB4Mj0iMzMuMjUiIHkyPSIxNi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLjc1IDE5Ny4zMTAyNDkpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMTMiIHkxPSIyNyIgeDI9IjEzIiB5Mj0iLTI3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODYuMTIwNDk4IDE4NykiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzNmNTc4NyINCiAgICAgICAgICAgIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yMy43NSIgeTE9Ii0xOC44NzUiIHgyPSIyMy43NSIgeTI9IjE4Ljg3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzIyLjg3MDQ5OSAxNzguODc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTAuNSIgeTE9Ii00MC4zNzUiIHgyPSIwLjUiIHkyPSI0MC4zNzUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OCAyMzguMTI1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iMzcuMjUiIHkxPSIzMi4yNSIgeDI9Ii0zNy4yNSIgeTI9Ii0zMi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzExLjI1IDI0Ni4yNSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9IjM2Ljc1IiB5MT0iLTExLjI1IiB4Mj0iLTM2Ljc1IiB5Mj0iMTEuMjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMxMC43NSAyODguNzUpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjEuMjUiIHkxPSItMTguMjUiIHgyPSIyMS4yNSIgeTI9IjE4LjI1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNjkuNzUgMjk1Ljc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTIxLjUiIHkxPSItMTUuMTI1IiB4Mj0iMjEuNSIgeTI9IjE1LjEyNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzY5LjUgMjEyLjg3NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iMTYuNSIgeDI9IjI0LjUiIHkyPSItMTYuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDE1LjUgMjExLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjMuMjUiIHkxPSItMjQuNzUiIHgyPSIyMy4yNSIgeTI9IjI0Ljc1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MTQuMjUgMjUyLjc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgIDwvZz4NCiAgICA8Zz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMDcuNSAxODEuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMwMCAxNjApIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxMCIgcnk9IjEwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjAgMjM4KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTQiIHJ5PSIxNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjc0IDIxNCkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNDcuNSAxOTcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0MCAxOTUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIyMCIgcnk9IjIwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMjUgMjY1KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTguNSIgcnk9IjE4LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OC41IDI3OC41KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iNy41IiByeT0iNy41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MzcuNSAyNzcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjcuNSIgcnk9IjcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTkwLjUgMzEyLjUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxNCIgcnk9IjE0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNzQgMjk5KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iOSIgcnk9IjkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM5MSAzMTQpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgPC9nPg0KPC9zdmc+");
|
||||||
|
mask-size: calc(var(--size)*100px) calc(var(--size)*100px);
|
||||||
|
mask-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0iZTdReFVvNjhGTlMxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIg0KICAgIHZpZXdCb3g9IjAgMCA2MDAgNjAwIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+DQogICAgPGc+DQogICAgICAgIDxsaW5lIHgxPSItMzIuNSIgeTE9Ii0xMy41IiB4Mj0iMzIuNSIgeTI9IjEzLjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5Mi41IDI1MS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTE3LjI1IiB5MT0iMjMuNzUiIHgyPSIxNy4yNSIgeTI9Ii0yMy43NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA3Ljc1IDI4OC43NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iLTE3LjUiIHgyPSIyNC41IiB5Mj0iMTcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQ5LjUgMjgyLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjQuNSIgeTE9IjI1LjUiIHgyPSIyNC41IiB5Mj0iLTI1LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0OS41IDIzOS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTMzLjI1IiB5MT0iLTE2LjI1IiB4Mj0iMzMuMjUiIHkyPSIxNi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLjc1IDE5Ny4zMTAyNDkpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMTMiIHkxPSIyNyIgeDI9IjEzIiB5Mj0iLTI3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODYuMTIwNDk4IDE4NykiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzNmNTc4NyINCiAgICAgICAgICAgIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yMy43NSIgeTE9Ii0xOC44NzUiIHgyPSIyMy43NSIgeTI9IjE4Ljg3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzIyLjg3MDQ5OSAxNzguODc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTAuNSIgeTE9Ii00MC4zNzUiIHgyPSIwLjUiIHkyPSI0MC4zNzUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OCAyMzguMTI1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iMzcuMjUiIHkxPSIzMi4yNSIgeDI9Ii0zNy4yNSIgeTI9Ii0zMi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzExLjI1IDI0Ni4yNSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9IjM2Ljc1IiB5MT0iLTExLjI1IiB4Mj0iLTM2Ljc1IiB5Mj0iMTEuMjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMxMC43NSAyODguNzUpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjEuMjUiIHkxPSItMTguMjUiIHgyPSIyMS4yNSIgeTI9IjE4LjI1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNjkuNzUgMjk1Ljc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTIxLjUiIHkxPSItMTUuMTI1IiB4Mj0iMjEuNSIgeTI9IjE1LjEyNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzY5LjUgMjEyLjg3NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iMTYuNSIgeDI9IjI0LjUiIHkyPSItMTYuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDE1LjUgMjExLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjMuMjUiIHkxPSItMjQuNzUiIHgyPSIyMy4yNSIgeTI9IjI0Ljc1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MTQuMjUgMjUyLjc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgIDwvZz4NCiAgICA8Zz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMDcuNSAxODEuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMwMCAxNjApIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxMCIgcnk9IjEwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjAgMjM4KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTQiIHJ5PSIxNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjc0IDIxNCkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNDcuNSAxOTcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0MCAxOTUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIyMCIgcnk9IjIwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMjUgMjY1KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTguNSIgcnk9IjE4LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OC41IDI3OC41KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iNy41IiByeT0iNy41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MzcuNSAyNzcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjcuNSIgcnk9IjcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTkwLjUgMzEyLjUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxNCIgcnk9IjE0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNzQgMjk5KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iOSIgcnk9IjkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM5MSAzMTQpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgPC9nPg0KPC9zdmc+");
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
border: 4px solid black;
|
||||||
|
border-radius: 2em;
|
||||||
|
}
|
||||||
|
.p2prc {
|
||||||
|
position: fixed;
|
||||||
|
top: 63%;
|
||||||
|
font-size: calc((var(--size) * 100px)/8);
|
||||||
|
font-weight: 700;
|
||||||
|
font-family: sans-serif;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="logo">
|
||||||
|
<div class="bg"></div>
|
||||||
|
<div class="p2prc">p2prc</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
artwork/p2prc-logos/.DS_Store
vendored
Normal file
BIN
artwork/p2prc-logos/Black-Image.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
11
artwork/p2prc-logos/Black-Vector.svg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<svg width="151" height="150" viewBox="0 0 151 150" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_1_93)">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.6403 7.65789C76.6403 8.32645 76.5018 8.96264 76.252 9.53936L92.9656 22.3203C94.4069 20.7725 96.4626 19.8045 98.7444 19.8045C103.105 19.8045 106.639 23.3391 106.639 27.6992C106.639 28.8372 106.398 29.9189 105.965 30.8963L125.373 41.7419L140.792 28.173C140.62 27.6823 140.526 27.1547 140.526 26.6053C140.526 23.9892 142.647 21.8684 145.263 21.8684C147.879 21.8684 150 23.9892 150 26.6053C150 29.2213 147.879 31.3421 145.263 31.3421C144.06 31.3421 142.961 30.8934 142.126 30.1542L127.101 43.3758L143.687 67.2589C144.18 67.0849 144.71 66.9903 145.263 66.9903C147.879 66.9903 150 69.111 150 71.7271C150 74.3432 147.879 76.4639 145.263 76.4639C142.647 76.4639 140.526 74.3432 140.526 71.7271C140.526 70.5198 140.978 69.418 141.722 68.5815L124.71 44.0845L104.688 32.8957C103.39 34.3793 101.545 35.3725 99.4678 35.5612L98.1139 60.3828C101.679 61.7432 104.211 65.1943 104.211 69.2368C104.211 71.372 103.504 73.3422 102.312 74.9265L114.018 84.3809C114.807 83.7944 115.784 83.4474 116.842 83.4474C119.458 83.4474 121.579 85.5681 121.579 88.1842C121.579 90.8003 119.458 92.9211 116.842 92.9211C114.226 92.9211 112.105 90.8003 112.105 88.1842C112.105 87.4847 112.257 86.8205 112.529 86.2229L100.657 76.6336C99.035 77.9332 96.9767 78.7105 94.7368 78.7105C91.7849 78.7105 89.1482 77.3604 87.4108 75.2439L63.7377 81.6554C63.4383 84.2469 61.2365 86.2589 58.5648 86.2589C55.6887 86.2589 53.3572 83.9273 53.3572 81.0513C53.3572 80.5695 53.4226 80.103 53.5451 79.6601L39.0832 68.7042C37.3508 70.9489 34.6337 72.3947 31.5789 72.3947C30.1375 72.3947 28.7712 72.0728 27.5481 71.4969L18.8395 84.5598C19.871 85.4288 20.5263 86.7299 20.5263 88.1842C20.5263 90.8003 18.4056 92.9211 15.7895 92.9211C13.1734 92.9211 11.0526 90.8003 11.0526 88.1842C11.0526 85.5681 13.1734 83.4474 15.7895 83.4474C16.0935 83.4474 16.3909 83.476 16.6791 83.5308L25.548 70.2274C23.4453 68.4898 22.1053 65.8619 22.1053 62.9211C22.1053 61.6607 22.3514 60.4578 22.7982 59.3579L11.5333 54.5788C10.3959 56.2426 8.48337 57.3346 6.31579 57.3346C2.82767 57.3346 0 54.5069 0 51.0188C0 47.5307 2.82767 44.703 6.31579 44.703C9.80391 44.703 12.6316 47.5307 12.6316 51.0188C12.6316 51.4957 12.5787 51.9604 12.4785 52.4071L23.9665 57.2808C25.6928 54.9548 28.4598 53.4474 31.5789 53.4474C33.8143 53.4474 35.8689 54.2216 37.4891 55.5165L50.7399 42.6673C49.6198 41.3044 48.9474 39.5597 48.9474 37.6579C48.9474 36.3371 49.2717 35.092 49.8451 33.9981L30.7505 24.6728C29.3053 26.5154 27.0584 27.6992 24.5351 27.6992C20.1749 27.6992 16.6403 24.1646 16.6403 19.8045C16.6403 15.4443 20.1749 11.9097 24.5351 11.9097C28.8952 11.9097 32.4298 15.4443 32.4298 19.8045C32.4298 20.7915 32.2487 21.7362 31.9179 22.6071L51.2747 32.0605C52.7022 30.6406 54.6697 29.7632 56.8421 29.7632C57.9909 29.7632 59.0824 30.0085 60.067 30.4497L68.868 11.2945C67.8282 10.4256 67.1667 9.11898 67.1667 7.65789C67.1667 5.04181 69.2874 2.92105 71.9035 2.92105C74.5196 2.92105 76.6403 5.04181 76.6403 7.65789ZM63.4621 79.2763C62.7362 77.2741 60.8176 75.8437 58.5648 75.8437C57.0307 75.8437 55.6515 76.507 54.6984 77.5626L40.2913 66.6481C40.7813 65.5042 41.0526 64.2443 41.0526 62.9211C41.0526 60.7779 40.341 58.801 39.1411 57.2137L52.5045 44.2553C53.7493 45.0754 55.24 45.5526 56.8421 45.5526C59.3127 45.5526 61.5182 44.4178 62.9658 42.6409L86.6296 64.3327C85.7624 65.7633 85.2632 67.4418 85.2632 69.2368C85.2632 70.6299 85.5639 71.9528 86.1039 73.1441L63.4621 79.2763ZM71.9035 12.3947C71.5973 12.3947 71.2979 12.3657 71.0078 12.3102L62.0769 31.7481C63.7085 33.1944 64.7368 35.3061 64.7368 37.6579C64.7368 38.6789 64.543 39.6546 64.1902 40.5503L88.1046 62.4719C89.8135 60.7964 92.1545 59.7632 94.7368 59.7632C95.0869 59.7632 95.4325 59.7821 95.7727 59.8192L97.1034 35.4232C93.5308 34.6679 90.8497 31.4967 90.8497 27.6992C90.8497 26.4737 91.1289 25.3134 91.6272 24.2785L74.7972 11.4084C73.9968 12.0268 72.9931 12.3947 71.9035 12.3947Z" fill="#3A3A3A"/>
|
||||||
|
<path d="M28.2947 139.433C26.2905 139.433 24.5369 138.991 23.0337 138.106C21.5305 137.222 20.3516 135.881 19.4969 134.083C18.6716 132.256 18.259 129.957 18.259 127.186C18.259 124.386 18.6569 122.087 19.4526 120.289C20.2484 118.492 21.3979 117.151 22.9011 116.266C24.4042 115.382 26.2021 114.94 28.2947 114.94C30.5348 114.94 32.539 115.456 34.3074 116.487C36.1053 117.489 37.52 118.904 38.5516 120.732C39.6126 122.559 40.1432 124.711 40.1432 127.186C40.1432 129.692 39.6126 131.858 38.5516 133.685C37.52 135.513 36.1053 136.927 34.3074 137.929C32.539 138.932 30.5348 139.433 28.2947 139.433ZM14.2358 147.656V115.294H20.8232V120.157L20.6905 127.231L21.1326 134.26V147.656H14.2358ZM27.1011 133.774C28.2505 133.774 29.2674 133.508 30.1516 132.978C31.0653 132.447 31.7874 131.696 32.3179 130.723C32.8779 129.721 33.1579 128.542 33.1579 127.186C33.1579 125.801 32.8779 124.622 32.3179 123.649C31.7874 122.677 31.0653 121.925 30.1516 121.395C29.2674 120.864 28.2505 120.599 27.1011 120.599C25.9516 120.599 24.92 120.864 24.0063 121.395C23.0926 121.925 22.3705 122.677 21.84 123.649C21.3095 124.622 21.0442 125.801 21.0442 127.186C21.0442 128.542 21.3095 129.721 21.84 130.723C22.3705 131.696 23.0926 132.447 24.0063 132.978C24.92 133.508 25.9516 133.774 27.1011 133.774ZM41.7199 139.079V134.437L53.6567 123.163C54.5999 122.308 55.2925 121.542 55.7346 120.864C56.1767 120.186 56.4715 119.567 56.6188 119.007C56.7957 118.447 56.8841 117.932 56.8841 117.46C56.8841 116.222 56.4567 115.279 55.602 114.631C54.7767 113.953 53.5536 113.614 51.9325 113.614C50.6357 113.614 49.4273 113.864 48.3073 114.365C47.2167 114.866 46.2883 115.647 45.522 116.708L40.3052 113.348C41.4841 111.58 43.1346 110.18 45.2567 109.148C47.3788 108.117 49.8252 107.601 52.5957 107.601C54.8946 107.601 56.8988 107.984 58.6083 108.751C60.3473 109.487 61.6883 110.534 62.6315 111.889C63.6041 113.245 64.0904 114.866 64.0904 116.753C64.0904 117.755 63.9578 118.757 63.6925 119.759C63.4567 120.732 62.9557 121.763 62.1894 122.854C61.4525 123.944 60.362 125.167 58.9178 126.523L49.0146 135.852L47.6441 133.243H65.1073V139.079H41.7199ZM82.6962 139.433C80.6919 139.433 78.9383 138.991 77.4351 138.106C75.9319 137.222 74.753 135.881 73.8983 134.083C73.073 132.256 72.6604 129.957 72.6604 127.186C72.6604 124.386 73.0583 122.087 73.854 120.289C74.6498 118.492 75.7993 117.151 77.3025 116.266C78.8056 115.382 80.6035 114.94 82.6962 114.94C84.9362 114.94 86.9404 115.456 88.7088 116.487C90.5067 117.489 91.9214 118.904 92.953 120.732C94.014 122.559 94.5446 124.711 94.5446 127.186C94.5446 129.692 94.014 131.858 92.953 133.685C91.9214 135.513 90.5067 136.927 88.7088 137.929C86.9404 138.932 84.9362 139.433 82.6962 139.433ZM68.6372 147.656V115.294H75.2246V120.157L75.0919 127.231L75.534 134.26V147.656H68.6372ZM81.5025 133.774C82.6519 133.774 83.6688 133.508 84.553 132.978C85.4667 132.447 86.1888 131.696 86.7193 130.723C87.2793 129.721 87.5593 128.542 87.5593 127.186C87.5593 125.801 87.2793 124.622 86.7193 123.649C86.1888 122.677 85.4667 121.925 84.553 121.395C83.6688 120.864 82.6519 120.599 81.5025 120.599C80.353 120.599 79.3214 120.864 78.4077 121.395C77.494 121.925 76.7719 122.677 76.2414 123.649C75.7109 124.622 75.4456 125.801 75.4456 127.186C75.4456 128.542 75.7109 129.721 76.2414 130.723C76.7719 131.696 77.494 132.447 78.4077 132.978C79.3214 133.508 80.353 133.774 81.5025 133.774ZM98.2773 139.079V115.294H104.865V122.014L103.936 120.068C104.644 118.388 105.778 117.121 107.34 116.266C108.903 115.382 110.804 114.94 113.044 114.94V121.306C112.749 121.277 112.484 121.262 112.248 121.262C112.012 121.233 111.761 121.218 111.496 121.218C109.61 121.218 108.077 121.763 106.898 122.854C105.749 123.915 105.174 125.58 105.174 127.849V139.079H98.2773ZM127.582 139.433C125.018 139.433 122.734 138.917 120.73 137.885C118.725 136.824 117.149 135.365 115.999 133.508C114.879 131.652 114.319 129.544 114.319 127.186C114.319 124.799 114.879 122.692 115.999 120.864C117.149 119.007 118.725 117.563 120.73 116.532C122.734 115.471 125.018 114.94 127.582 114.94C130.088 114.94 132.269 115.471 134.125 116.532C135.982 117.563 137.353 119.052 138.237 120.997L132.888 123.871C132.269 122.751 131.488 121.925 130.544 121.395C129.631 120.864 128.629 120.599 127.538 120.599C126.359 120.599 125.298 120.864 124.355 121.395C123.412 121.925 122.66 122.677 122.1 123.649C121.57 124.622 121.304 125.801 121.304 127.186C121.304 128.572 121.57 129.751 122.1 130.723C122.66 131.696 123.412 132.447 124.355 132.978C125.298 133.508 126.359 133.774 127.538 133.774C128.629 133.774 129.631 133.523 130.544 133.022C131.488 132.492 132.269 131.652 132.888 130.502L138.237 133.42C137.353 135.336 135.982 136.824 134.125 137.885C132.269 138.917 130.088 139.433 127.582 139.433Z" fill="#3A3A3A"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_1_93">
|
||||||
|
<rect width="150" height="150" fill="white" transform="translate(0.5)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 8.7 KiB |
BIN
artwork/p2prc-logos/Colored-Image.png
Normal file
|
After Width: | Height: | Size: 433 KiB |
BIN
artwork/p2prc-logos/Colored-On-Dark-Image.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
15
artwork/p2prc-logos/Colored-On-Dark-Vector.svg
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<svg width="151" height="150" viewBox="0 0 151 150" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_1_46)">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.6403 7.65789C76.6403 8.32645 76.5018 8.96264 76.252 9.53936L92.9656 22.3203C94.4069 20.7725 96.4626 19.8045 98.7444 19.8045C103.105 19.8045 106.639 23.3391 106.639 27.6992C106.639 28.8372 106.398 29.9189 105.965 30.8963L125.373 41.7419L140.792 28.173C140.62 27.6823 140.526 27.1547 140.526 26.6053C140.526 23.9892 142.647 21.8684 145.263 21.8684C147.879 21.8684 150 23.9892 150 26.6053C150 29.2213 147.879 31.3421 145.263 31.3421C144.06 31.3421 142.961 30.8934 142.126 30.1542L127.101 43.3758L143.687 67.2589C144.18 67.0849 144.71 66.9903 145.263 66.9903C147.879 66.9903 150 69.111 150 71.7271C150 74.3432 147.879 76.4639 145.263 76.4639C142.647 76.4639 140.526 74.3432 140.526 71.7271C140.526 70.5198 140.978 69.418 141.722 68.5815L124.71 44.0845L104.688 32.8957C103.39 34.3793 101.545 35.3725 99.4678 35.5612L98.1139 60.3828C101.679 61.7432 104.211 65.1943 104.211 69.2368C104.211 71.372 103.504 73.3422 102.312 74.9265L114.018 84.3809C114.807 83.7944 115.784 83.4474 116.842 83.4474C119.458 83.4474 121.579 85.5681 121.579 88.1842C121.579 90.8003 119.458 92.9211 116.842 92.9211C114.226 92.9211 112.105 90.8003 112.105 88.1842C112.105 87.4847 112.257 86.8205 112.529 86.2229L100.657 76.6336C99.035 77.9332 96.9767 78.7105 94.7368 78.7105C91.7849 78.7105 89.1482 77.3604 87.4108 75.2439L63.7377 81.6554C63.4383 84.2469 61.2365 86.2589 58.5648 86.2589C55.6887 86.2589 53.3572 83.9273 53.3572 81.0513C53.3572 80.5695 53.4226 80.103 53.5451 79.6601L39.0832 68.7042C37.3508 70.9489 34.6337 72.3947 31.5789 72.3947C30.1375 72.3947 28.7712 72.0728 27.5481 71.4969L18.8395 84.5598C19.871 85.4288 20.5263 86.7299 20.5263 88.1842C20.5263 90.8003 18.4056 92.9211 15.7895 92.9211C13.1734 92.9211 11.0526 90.8003 11.0526 88.1842C11.0526 85.5681 13.1734 83.4474 15.7895 83.4474C16.0935 83.4474 16.3909 83.476 16.6791 83.5308L25.548 70.2274C23.4453 68.4898 22.1053 65.8619 22.1053 62.9211C22.1053 61.6607 22.3514 60.4578 22.7982 59.3579L11.5333 54.5788C10.3959 56.2426 8.48337 57.3346 6.31579 57.3346C2.82767 57.3346 0 54.5069 0 51.0188C0 47.5307 2.82767 44.703 6.31579 44.703C9.80391 44.703 12.6316 47.5307 12.6316 51.0188C12.6316 51.4957 12.5787 51.9604 12.4785 52.4071L23.9665 57.2808C25.6928 54.9548 28.4598 53.4474 31.5789 53.4474C33.8143 53.4474 35.8689 54.2216 37.4891 55.5165L50.7399 42.6673C49.6198 41.3044 48.9474 39.5597 48.9474 37.6579C48.9474 36.3371 49.2717 35.092 49.8451 33.9981L30.7505 24.6728C29.3053 26.5154 27.0584 27.6992 24.5351 27.6992C20.1749 27.6992 16.6403 24.1646 16.6403 19.8045C16.6403 15.4443 20.1749 11.9097 24.5351 11.9097C28.8952 11.9097 32.4298 15.4443 32.4298 19.8045C32.4298 20.7915 32.2487 21.7362 31.9179 22.6071L51.2747 32.0605C52.7022 30.6406 54.6697 29.7632 56.8421 29.7632C57.9909 29.7632 59.0824 30.0085 60.067 30.4497L68.868 11.2945C67.8282 10.4256 67.1667 9.11898 67.1667 7.65789C67.1667 5.04181 69.2874 2.92105 71.9035 2.92105C74.5196 2.92105 76.6403 5.04181 76.6403 7.65789ZM63.4621 79.2763C62.7362 77.2741 60.8176 75.8437 58.5648 75.8437C57.0307 75.8437 55.6515 76.507 54.6984 77.5626L40.2913 66.6481C40.7813 65.5042 41.0526 64.2443 41.0526 62.9211C41.0526 60.7779 40.341 58.801 39.1411 57.2137L52.5045 44.2553C53.7493 45.0754 55.24 45.5526 56.8421 45.5526C59.3127 45.5526 61.5182 44.4178 62.9658 42.6409L86.6296 64.3327C85.7624 65.7633 85.2632 67.4418 85.2632 69.2368C85.2632 70.6299 85.5639 71.9528 86.1039 73.1441L63.4621 79.2763ZM71.9035 12.3947C71.5973 12.3947 71.2979 12.3657 71.0078 12.3102L62.0769 31.7481C63.7085 33.1944 64.7368 35.3061 64.7368 37.6579C64.7368 38.6789 64.543 39.6546 64.1902 40.5503L88.1046 62.4719C89.8135 60.7964 92.1545 59.7632 94.7368 59.7632C95.0869 59.7632 95.4325 59.7821 95.7727 59.8192L97.1034 35.4232C93.5308 34.6679 90.8497 31.4967 90.8497 27.6992C90.8497 26.4737 91.1289 25.3134 91.6272 24.2785L74.7972 11.4084C73.9968 12.0268 72.9931 12.3947 71.9035 12.3947Z" fill="url(#paint0_linear_1_46)"/>
|
||||||
|
<path d="M28.2947 139.433C26.2905 139.433 24.5368 138.991 23.0337 138.106C21.5305 137.222 20.3516 135.881 19.4968 134.083C18.6716 132.256 18.2589 129.957 18.2589 127.186C18.2589 124.386 18.6568 122.087 19.4526 120.289C20.2484 118.492 21.3979 117.151 22.9011 116.266C24.4042 115.382 26.2021 114.94 28.2947 114.94C30.5347 114.94 32.5389 115.456 34.3074 116.487C36.1053 117.489 37.52 118.904 38.5516 120.732C39.6126 122.559 40.1432 124.711 40.1432 127.186C40.1432 129.692 39.6126 131.858 38.5516 133.685C37.52 135.513 36.1053 136.927 34.3074 137.929C32.5389 138.932 30.5347 139.433 28.2947 139.433ZM14.2358 147.656V115.294H20.8232V120.157L20.6905 127.231L21.1326 134.26V147.656H14.2358ZM27.1011 133.774C28.2505 133.774 29.2674 133.508 30.1516 132.978C31.0653 132.447 31.7874 131.696 32.3179 130.723C32.8779 129.721 33.1579 128.542 33.1579 127.186C33.1579 125.801 32.8779 124.622 32.3179 123.649C31.7874 122.677 31.0653 121.925 30.1516 121.395C29.2674 120.864 28.2505 120.599 27.1011 120.599C25.9516 120.599 24.92 120.864 24.0063 121.395C23.0926 121.925 22.3705 122.677 21.84 123.649C21.3095 124.622 21.0442 125.801 21.0442 127.186C21.0442 128.542 21.3095 129.721 21.84 130.723C22.3705 131.696 23.0926 132.447 24.0063 132.978C24.92 133.508 25.9516 133.774 27.1011 133.774ZM41.7199 139.079V134.437L53.6567 123.163C54.5999 122.308 55.2925 121.542 55.7346 120.864C56.1767 120.186 56.4715 119.567 56.6188 119.007C56.7957 118.447 56.8841 117.932 56.8841 117.46C56.8841 116.222 56.4567 115.279 55.602 114.631C54.7767 113.953 53.5536 113.614 51.9325 113.614C50.6357 113.614 49.4273 113.864 48.3073 114.365C47.2167 114.866 46.2883 115.647 45.522 116.708L40.3051 113.348C41.4841 111.58 43.1346 110.18 45.2567 109.148C47.3788 108.117 49.8252 107.601 52.5957 107.601C54.8946 107.601 56.8988 107.984 58.6083 108.751C60.3473 109.487 61.6883 110.534 62.6315 111.889C63.6041 113.245 64.0904 114.866 64.0904 116.753C64.0904 117.755 63.9578 118.757 63.6925 119.759C63.4567 120.732 62.9557 121.763 62.1894 122.854C61.4525 123.944 60.362 125.167 58.9178 126.523L49.0146 135.852L47.6441 133.243H65.1073V139.079H41.7199ZM82.6961 139.433C80.6919 139.433 78.9382 138.991 77.4351 138.106C75.9319 137.222 74.753 135.881 73.8982 134.083C73.073 132.256 72.6603 129.957 72.6603 127.186C72.6603 124.386 73.0582 122.087 73.854 120.289C74.6498 118.492 75.7993 117.151 77.3025 116.266C78.8056 115.382 80.6035 114.94 82.6961 114.94C84.9361 114.94 86.9404 115.456 88.7088 116.487C90.5067 117.489 91.9214 118.904 92.953 120.732C94.014 122.559 94.5446 124.711 94.5446 127.186C94.5446 129.692 94.014 131.858 92.953 133.685C91.9214 135.513 90.5067 136.927 88.7088 137.929C86.9404 138.932 84.9361 139.433 82.6961 139.433ZM68.6372 147.656V115.294H75.2246V120.157L75.0919 127.231L75.534 134.26V147.656H68.6372ZM81.5025 133.774C82.6519 133.774 83.6688 133.508 84.553 132.978C85.4667 132.447 86.1888 131.696 86.7193 130.723C87.2793 129.721 87.5593 128.542 87.5593 127.186C87.5593 125.801 87.2793 124.622 86.7193 123.649C86.1888 122.677 85.4667 121.925 84.553 121.395C83.6688 120.864 82.6519 120.599 81.5025 120.599C80.353 120.599 79.3214 120.864 78.4077 121.395C77.494 121.925 76.7719 122.677 76.2414 123.649C75.7109 124.622 75.4456 125.801 75.4456 127.186C75.4456 128.542 75.7109 129.721 76.2414 130.723C76.7719 131.696 77.494 132.447 78.4077 132.978C79.3214 133.508 80.353 133.774 81.5025 133.774ZM98.2772 139.079V115.294H104.865V122.014L103.936 120.068C104.644 118.388 105.778 117.121 107.34 116.266C108.903 115.382 110.804 114.94 113.044 114.94V121.306C112.749 121.277 112.484 121.262 112.248 121.262C112.012 121.233 111.761 121.218 111.496 121.218C109.61 121.218 108.077 121.763 106.898 122.854C105.749 123.915 105.174 125.58 105.174 127.849V139.079H98.2772ZM127.582 139.433C125.018 139.433 122.734 138.917 120.73 137.885C118.725 136.824 117.149 135.365 115.999 133.508C114.879 131.652 114.319 129.544 114.319 127.186C114.319 124.799 114.879 122.692 115.999 120.864C117.149 119.007 118.725 117.563 120.73 116.532C122.734 115.471 125.018 114.94 127.582 114.94C130.088 114.94 132.269 115.471 134.125 116.532C135.982 117.563 137.353 119.052 138.237 120.997L132.888 123.871C132.269 122.751 131.488 121.925 130.544 121.395C129.631 120.864 128.629 120.599 127.538 120.599C126.359 120.599 125.298 120.864 124.355 121.395C123.412 121.925 122.66 122.677 122.1 123.649C121.57 124.622 121.304 125.801 121.304 127.186C121.304 128.572 121.57 129.751 122.1 130.723C122.66 131.696 123.412 132.447 124.355 132.978C125.298 133.508 126.359 133.774 127.538 133.774C128.629 133.774 129.631 133.523 130.544 133.022C131.488 132.492 132.269 131.652 132.888 130.502L138.237 133.42C137.353 135.336 135.982 136.824 134.125 137.885C132.269 138.917 130.088 139.433 127.582 139.433Z" fill="#F5F5F5"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_1_46" x1="145.974" y1="17.9477" x2="-4.68153e-06" y2="62.4661" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#FF593C"/>
|
||||||
|
<stop offset="1" stop-color="#FFBF57"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip0_1_46">
|
||||||
|
<rect width="150" height="150" fill="white" transform="translate(0.5)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 8.9 KiB |
BIN
artwork/p2prc-logos/Colored-On-Light-Image.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
15
artwork/p2prc-logos/Colored-On-Light-Vector.svg
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<svg width="151" height="150" viewBox="0 0 151 150" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_1_41)">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.6403 7.65789C76.6403 8.32645 76.5018 8.96264 76.252 9.53936L92.9656 22.3203C94.4069 20.7725 96.4626 19.8045 98.7444 19.8045C103.105 19.8045 106.639 23.3391 106.639 27.6992C106.639 28.8372 106.398 29.9189 105.965 30.8963L125.373 41.7419L140.792 28.173C140.62 27.6823 140.526 27.1547 140.526 26.6053C140.526 23.9892 142.647 21.8684 145.263 21.8684C147.879 21.8684 150 23.9892 150 26.6053C150 29.2213 147.879 31.3421 145.263 31.3421C144.06 31.3421 142.961 30.8934 142.126 30.1542L127.101 43.3758L143.687 67.2589C144.18 67.0849 144.71 66.9903 145.263 66.9903C147.879 66.9903 150 69.111 150 71.7271C150 74.3432 147.879 76.4639 145.263 76.4639C142.647 76.4639 140.526 74.3432 140.526 71.7271C140.526 70.5198 140.978 69.418 141.722 68.5815L124.71 44.0845L104.688 32.8957C103.39 34.3793 101.545 35.3725 99.4678 35.5612L98.1139 60.3828C101.679 61.7432 104.211 65.1943 104.211 69.2368C104.211 71.372 103.504 73.3422 102.312 74.9265L114.018 84.3809C114.807 83.7944 115.784 83.4474 116.842 83.4474C119.458 83.4474 121.579 85.5681 121.579 88.1842C121.579 90.8003 119.458 92.9211 116.842 92.9211C114.226 92.9211 112.105 90.8003 112.105 88.1842C112.105 87.4847 112.257 86.8205 112.529 86.2229L100.657 76.6336C99.035 77.9332 96.9767 78.7105 94.7368 78.7105C91.7849 78.7105 89.1482 77.3604 87.4108 75.2439L63.7377 81.6554C63.4383 84.2469 61.2365 86.2589 58.5648 86.2589C55.6887 86.2589 53.3572 83.9273 53.3572 81.0513C53.3572 80.5695 53.4226 80.103 53.5451 79.6601L39.0832 68.7042C37.3508 70.9489 34.6337 72.3947 31.5789 72.3947C30.1375 72.3947 28.7712 72.0728 27.5481 71.4969L18.8395 84.5598C19.871 85.4288 20.5263 86.7299 20.5263 88.1842C20.5263 90.8003 18.4056 92.9211 15.7895 92.9211C13.1734 92.9211 11.0526 90.8003 11.0526 88.1842C11.0526 85.5681 13.1734 83.4474 15.7895 83.4474C16.0935 83.4474 16.3909 83.476 16.6791 83.5308L25.548 70.2274C23.4453 68.4898 22.1053 65.8619 22.1053 62.9211C22.1053 61.6607 22.3514 60.4578 22.7982 59.3579L11.5333 54.5788C10.3959 56.2426 8.48337 57.3346 6.31579 57.3346C2.82767 57.3346 0 54.5069 0 51.0188C0 47.5307 2.82767 44.703 6.31579 44.703C9.80391 44.703 12.6316 47.5307 12.6316 51.0188C12.6316 51.4957 12.5787 51.9604 12.4785 52.4071L23.9665 57.2808C25.6928 54.9548 28.4598 53.4474 31.5789 53.4474C33.8143 53.4474 35.8689 54.2216 37.4891 55.5165L50.7399 42.6673C49.6198 41.3044 48.9474 39.5597 48.9474 37.6579C48.9474 36.3371 49.2717 35.092 49.8451 33.9981L30.7505 24.6728C29.3053 26.5154 27.0584 27.6992 24.5351 27.6992C20.1749 27.6992 16.6403 24.1646 16.6403 19.8045C16.6403 15.4443 20.1749 11.9097 24.5351 11.9097C28.8952 11.9097 32.4298 15.4443 32.4298 19.8045C32.4298 20.7915 32.2487 21.7362 31.9179 22.6071L51.2747 32.0605C52.7022 30.6406 54.6697 29.7632 56.8421 29.7632C57.9909 29.7632 59.0824 30.0085 60.067 30.4497L68.868 11.2945C67.8282 10.4256 67.1667 9.11898 67.1667 7.65789C67.1667 5.04181 69.2874 2.92105 71.9035 2.92105C74.5196 2.92105 76.6403 5.04181 76.6403 7.65789ZM63.4621 79.2763C62.7362 77.2741 60.8176 75.8437 58.5648 75.8437C57.0307 75.8437 55.6515 76.507 54.6984 77.5626L40.2913 66.6481C40.7813 65.5042 41.0526 64.2443 41.0526 62.9211C41.0526 60.7779 40.341 58.801 39.1411 57.2137L52.5045 44.2553C53.7493 45.0754 55.24 45.5526 56.8421 45.5526C59.3127 45.5526 61.5182 44.4178 62.9658 42.6409L86.6296 64.3327C85.7624 65.7633 85.2632 67.4418 85.2632 69.2368C85.2632 70.6299 85.5639 71.9528 86.1039 73.1441L63.4621 79.2763ZM71.9035 12.3947C71.5973 12.3947 71.2979 12.3657 71.0078 12.3102L62.0769 31.7481C63.7085 33.1944 64.7368 35.3061 64.7368 37.6579C64.7368 38.6789 64.543 39.6546 64.1902 40.5503L88.1046 62.4719C89.8135 60.7964 92.1545 59.7632 94.7368 59.7632C95.0869 59.7632 95.4325 59.7821 95.7727 59.8192L97.1034 35.4232C93.5308 34.6679 90.8497 31.4967 90.8497 27.6992C90.8497 26.4737 91.1289 25.3134 91.6272 24.2785L74.7972 11.4084C73.9968 12.0268 72.9931 12.3947 71.9035 12.3947Z" fill="url(#paint0_linear_1_41)"/>
|
||||||
|
<path d="M28.2947 139.433C26.2905 139.433 24.5368 138.991 23.0337 138.106C21.5305 137.222 20.3516 135.881 19.4968 134.083C18.6716 132.256 18.2589 129.957 18.2589 127.186C18.2589 124.386 18.6568 122.087 19.4526 120.289C20.2484 118.492 21.3979 117.151 22.901 116.266C24.4042 115.382 26.2021 114.94 28.2947 114.94C30.5347 114.94 32.5389 115.456 34.3074 116.487C36.1053 117.489 37.52 118.904 38.5516 120.732C39.6126 122.559 40.1432 124.711 40.1432 127.186C40.1432 129.692 39.6126 131.858 38.5516 133.685C37.52 135.513 36.1053 136.927 34.3074 137.929C32.5389 138.932 30.5347 139.433 28.2947 139.433ZM14.2358 147.656V115.294H20.8232V120.157L20.6905 127.231L21.1326 134.26V147.656H14.2358ZM27.101 133.774C28.2505 133.774 29.2674 133.508 30.1516 132.978C31.0653 132.447 31.7874 131.696 32.3179 130.723C32.8779 129.721 33.1579 128.542 33.1579 127.186C33.1579 125.801 32.8779 124.622 32.3179 123.649C31.7874 122.677 31.0653 121.925 30.1516 121.395C29.2674 120.864 28.2505 120.599 27.101 120.599C25.9516 120.599 24.92 120.864 24.0063 121.395C23.0926 121.925 22.3705 122.677 21.84 123.649C21.3095 124.622 21.0442 125.801 21.0442 127.186C21.0442 128.542 21.3095 129.721 21.84 130.723C22.3705 131.696 23.0926 132.447 24.0063 132.978C24.92 133.508 25.9516 133.774 27.101 133.774ZM41.7199 139.079V134.437L53.6567 123.163C54.5999 122.308 55.2925 121.542 55.7346 120.864C56.1767 120.186 56.4715 119.567 56.6188 119.007C56.7957 118.447 56.8841 117.932 56.8841 117.46C56.8841 116.222 56.4567 115.279 55.602 114.631C54.7767 113.953 53.5536 113.614 51.9325 113.614C50.6357 113.614 49.4273 113.864 48.3073 114.365C47.2167 114.866 46.2883 115.647 45.522 116.708L40.3051 113.348C41.4841 111.58 43.1346 110.18 45.2567 109.148C47.3788 108.117 49.8251 107.601 52.5957 107.601C54.8946 107.601 56.8988 107.984 58.6083 108.751C60.3473 109.487 61.6883 110.534 62.6315 111.889C63.6041 113.245 64.0904 114.866 64.0904 116.753C64.0904 117.755 63.9578 118.757 63.6925 119.759C63.4567 120.732 62.9557 121.763 62.1894 122.854C61.4525 123.944 60.362 125.167 58.9178 126.523L49.0146 135.852L47.6441 133.243H65.1073V139.079H41.7199ZM82.6961 139.433C80.6919 139.433 78.9382 138.991 77.4351 138.106C75.9319 137.222 74.753 135.881 73.8982 134.083C73.073 132.256 72.6603 129.957 72.6603 127.186C72.6603 124.386 73.0582 122.087 73.854 120.289C74.6498 118.492 75.7993 117.151 77.3025 116.266C78.8056 115.382 80.6035 114.94 82.6961 114.94C84.9361 114.94 86.9403 115.456 88.7088 116.487C90.5067 117.489 91.9214 118.904 92.953 120.732C94.014 122.559 94.5446 124.711 94.5446 127.186C94.5446 129.692 94.014 131.858 92.953 133.685C91.9214 135.513 90.5067 136.927 88.7088 137.929C86.9403 138.932 84.9361 139.433 82.6961 139.433ZM68.6372 147.656V115.294H75.2246V120.157L75.0919 127.231L75.534 134.26V147.656H68.6372ZM81.5025 133.774C82.6519 133.774 83.6688 133.508 84.553 132.978C85.4667 132.447 86.1888 131.696 86.7193 130.723C87.2793 129.721 87.5593 128.542 87.5593 127.186C87.5593 125.801 87.2793 124.622 86.7193 123.649C86.1888 122.677 85.4667 121.925 84.553 121.395C83.6688 120.864 82.6519 120.599 81.5025 120.599C80.353 120.599 79.3214 120.864 78.4077 121.395C77.494 121.925 76.7719 122.677 76.2414 123.649C75.7109 124.622 75.4456 125.801 75.4456 127.186C75.4456 128.542 75.7109 129.721 76.2414 130.723C76.7719 131.696 77.494 132.447 78.4077 132.978C79.3214 133.508 80.353 133.774 81.5025 133.774ZM98.2772 139.079V115.294H104.865V122.014L103.936 120.068C104.644 118.388 105.778 117.121 107.34 116.266C108.903 115.382 110.804 114.94 113.044 114.94V121.306C112.749 121.277 112.484 121.262 112.248 121.262C112.012 121.233 111.761 121.218 111.496 121.218C109.61 121.218 108.077 121.763 106.898 122.854C105.749 123.915 105.174 125.58 105.174 127.849V139.079H98.2772ZM127.582 139.433C125.018 139.433 122.734 138.917 120.73 137.885C118.725 136.824 117.149 135.365 115.999 133.508C114.879 131.652 114.319 129.544 114.319 127.186C114.319 124.799 114.879 122.692 115.999 120.864C117.149 119.007 118.725 117.563 120.73 116.532C122.734 115.471 125.018 114.94 127.582 114.94C130.088 114.94 132.269 115.471 134.125 116.532C135.982 117.563 137.353 119.052 138.237 120.997L132.888 123.871C132.269 122.751 131.488 121.925 130.544 121.395C129.631 120.864 128.629 120.599 127.538 120.599C126.359 120.599 125.298 120.864 124.355 121.395C123.412 121.925 122.66 122.677 122.1 123.649C121.57 124.622 121.304 125.801 121.304 127.186C121.304 128.572 121.57 129.751 122.1 130.723C122.66 131.696 123.412 132.447 124.355 132.978C125.298 133.508 126.359 133.774 127.538 133.774C128.629 133.774 129.631 133.523 130.544 133.022C131.488 132.492 132.269 131.652 132.888 130.502L138.237 133.42C137.353 135.336 135.982 136.824 134.125 137.885C132.269 138.917 130.088 139.433 127.582 139.433Z" fill="#3A3A3A"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_1_41" x1="145.974" y1="17.9477" x2="-4.68153e-06" y2="62.4661" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#FF593C"/>
|
||||||
|
<stop offset="1" stop-color="#FFBF57"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip0_1_41">
|
||||||
|
<rect width="150" height="150" fill="white" transform="translate(0.5)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 8.9 KiB |
19
artwork/p2prc-logos/Colored-Vector.svg
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<svg width="151" height="150" viewBox="0 0 151 150" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_1_52)">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.6403 7.65789C76.6403 8.32645 76.5018 8.96264 76.252 9.53936L92.9656 22.3203C94.4069 20.7725 96.4626 19.8045 98.7444 19.8045C103.105 19.8045 106.639 23.3391 106.639 27.6992C106.639 28.8372 106.398 29.9189 105.965 30.8963L125.373 41.7419L140.792 28.173C140.62 27.6823 140.526 27.1547 140.526 26.6053C140.526 23.9892 142.647 21.8684 145.263 21.8684C147.879 21.8684 150 23.9892 150 26.6053C150 29.2213 147.879 31.3421 145.263 31.3421C144.06 31.3421 142.961 30.8934 142.126 30.1542L127.101 43.3758L143.687 67.2589C144.18 67.0849 144.71 66.9903 145.263 66.9903C147.879 66.9903 150 69.111 150 71.7271C150 74.3432 147.879 76.4639 145.263 76.4639C142.647 76.4639 140.526 74.3432 140.526 71.7271C140.526 70.5198 140.978 69.418 141.722 68.5815L124.71 44.0845L104.688 32.8957C103.39 34.3793 101.545 35.3725 99.4678 35.5612L98.1139 60.3828C101.679 61.7432 104.211 65.1943 104.211 69.2368C104.211 71.372 103.504 73.3422 102.312 74.9265L114.018 84.3809C114.807 83.7944 115.784 83.4474 116.842 83.4474C119.458 83.4474 121.579 85.5681 121.579 88.1842C121.579 90.8003 119.458 92.9211 116.842 92.9211C114.226 92.9211 112.105 90.8003 112.105 88.1842C112.105 87.4847 112.257 86.8205 112.529 86.2229L100.657 76.6336C99.035 77.9332 96.9767 78.7105 94.7368 78.7105C91.7849 78.7105 89.1482 77.3604 87.4108 75.2439L63.7377 81.6554C63.4383 84.2469 61.2365 86.2589 58.5648 86.2589C55.6887 86.2589 53.3572 83.9273 53.3572 81.0513C53.3572 80.5695 53.4226 80.103 53.5451 79.6601L39.0832 68.7042C37.3508 70.9489 34.6337 72.3947 31.5789 72.3947C30.1375 72.3947 28.7712 72.0728 27.5481 71.4969L18.8395 84.5598C19.871 85.4288 20.5263 86.7299 20.5263 88.1842C20.5263 90.8003 18.4056 92.9211 15.7895 92.9211C13.1734 92.9211 11.0526 90.8003 11.0526 88.1842C11.0526 85.5681 13.1734 83.4474 15.7895 83.4474C16.0935 83.4474 16.3909 83.476 16.6791 83.5308L25.548 70.2274C23.4453 68.4898 22.1053 65.8619 22.1053 62.9211C22.1053 61.6607 22.3514 60.4578 22.7982 59.3579L11.5333 54.5788C10.3959 56.2426 8.48337 57.3346 6.31579 57.3346C2.82767 57.3346 0 54.5069 0 51.0188C0 47.5307 2.82767 44.703 6.31579 44.703C9.80391 44.703 12.6316 47.5307 12.6316 51.0188C12.6316 51.4957 12.5787 51.9604 12.4785 52.4071L23.9665 57.2808C25.6928 54.9548 28.4598 53.4474 31.5789 53.4474C33.8143 53.4474 35.8689 54.2216 37.4891 55.5165L50.7399 42.6673C49.6198 41.3044 48.9474 39.5597 48.9474 37.6579C48.9474 36.3371 49.2717 35.092 49.8451 33.9981L30.7505 24.6728C29.3053 26.5154 27.0584 27.6992 24.5351 27.6992C20.1749 27.6992 16.6403 24.1646 16.6403 19.8045C16.6403 15.4443 20.1749 11.9097 24.5351 11.9097C28.8952 11.9097 32.4298 15.4443 32.4298 19.8045C32.4298 20.7915 32.2487 21.7362 31.9179 22.6071L51.2747 32.0605C52.7022 30.6406 54.6697 29.7632 56.8421 29.7632C57.9909 29.7632 59.0824 30.0085 60.067 30.4497L68.868 11.2945C67.8282 10.4256 67.1667 9.11898 67.1667 7.65789C67.1667 5.04181 69.2874 2.92105 71.9035 2.92105C74.5196 2.92105 76.6403 5.04181 76.6403 7.65789ZM63.4621 79.2763C62.7362 77.2741 60.8176 75.8437 58.5648 75.8437C57.0307 75.8437 55.6515 76.507 54.6984 77.5626L40.2913 66.6481C40.7813 65.5042 41.0526 64.2443 41.0526 62.9211C41.0526 60.7779 40.341 58.801 39.1411 57.2137L52.5045 44.2553C53.7493 45.0754 55.24 45.5526 56.8421 45.5526C59.3127 45.5526 61.5182 44.4178 62.9658 42.6409L86.6296 64.3327C85.7624 65.7633 85.2632 67.4418 85.2632 69.2368C85.2632 70.6299 85.5639 71.9528 86.1039 73.1441L63.4621 79.2763ZM71.9035 12.3947C71.5973 12.3947 71.2979 12.3657 71.0078 12.3102L62.0769 31.7481C63.7085 33.1944 64.7368 35.3061 64.7368 37.6579C64.7368 38.6789 64.543 39.6546 64.1902 40.5503L88.1046 62.4719C89.8135 60.7964 92.1545 59.7632 94.7368 59.7632C95.0869 59.7632 95.4325 59.7821 95.7727 59.8192L97.1034 35.4232C93.5308 34.6679 90.8497 31.4967 90.8497 27.6992C90.8497 26.4737 91.1289 25.3134 91.6272 24.2785L74.7972 11.4084C73.9968 12.0268 72.9931 12.3947 71.9035 12.3947Z" fill="url(#paint0_linear_1_52)"/>
|
||||||
|
<path d="M28.2947 139.433C26.2905 139.433 24.5369 138.991 23.0337 138.106C21.5305 137.222 20.3516 135.881 19.4969 134.083C18.6716 132.256 18.259 129.957 18.259 127.186C18.259 124.386 18.6569 122.087 19.4526 120.289C20.2484 118.492 21.3979 117.151 22.9011 116.266C24.4042 115.382 26.2021 114.94 28.2947 114.94C30.5348 114.94 32.539 115.456 34.3074 116.487C36.1053 117.489 37.52 118.904 38.5516 120.732C39.6126 122.559 40.1432 124.711 40.1432 127.186C40.1432 129.692 39.6126 131.858 38.5516 133.685C37.52 135.513 36.1053 136.927 34.3074 137.929C32.539 138.932 30.5348 139.433 28.2947 139.433ZM14.2358 147.656V115.294H20.8232V120.157L20.6905 127.231L21.1326 134.26V147.656H14.2358ZM27.1011 133.774C28.2505 133.774 29.2674 133.508 30.1516 132.978C31.0653 132.447 31.7874 131.696 32.3179 130.723C32.8779 129.721 33.1579 128.542 33.1579 127.186C33.1579 125.801 32.8779 124.622 32.3179 123.649C31.7874 122.677 31.0653 121.925 30.1516 121.395C29.2674 120.864 28.2505 120.599 27.1011 120.599C25.9516 120.599 24.92 120.864 24.0063 121.395C23.0926 121.925 22.3705 122.677 21.84 123.649C21.3095 124.622 21.0442 125.801 21.0442 127.186C21.0442 128.542 21.3095 129.721 21.84 130.723C22.3705 131.696 23.0926 132.447 24.0063 132.978C24.92 133.508 25.9516 133.774 27.1011 133.774ZM41.7199 139.079V134.437L53.6567 123.163C54.5999 122.308 55.2925 121.542 55.7346 120.864C56.1767 120.186 56.4715 119.567 56.6188 119.007C56.7957 118.447 56.8841 117.932 56.8841 117.46C56.8841 116.222 56.4567 115.279 55.602 114.631C54.7767 113.953 53.5536 113.614 51.9325 113.614C50.6357 113.614 49.4273 113.864 48.3073 114.365C47.2167 114.866 46.2883 115.647 45.522 116.708L40.3052 113.348C41.4841 111.58 43.1346 110.18 45.2567 109.148C47.3788 108.117 49.8252 107.601 52.5957 107.601C54.8946 107.601 56.8988 107.984 58.6083 108.751C60.3473 109.487 61.6883 110.534 62.6315 111.889C63.6041 113.245 64.0904 114.866 64.0904 116.753C64.0904 117.755 63.9578 118.757 63.6925 119.759C63.4567 120.732 62.9557 121.763 62.1894 122.854C61.4525 123.944 60.362 125.167 58.9178 126.523L49.0146 135.852L47.6441 133.243H65.1073V139.079H41.7199ZM82.6962 139.433C80.6919 139.433 78.9383 138.991 77.4351 138.106C75.9319 137.222 74.753 135.881 73.8983 134.083C73.073 132.256 72.6604 129.957 72.6604 127.186C72.6604 124.386 73.0583 122.087 73.854 120.289C74.6498 118.492 75.7993 117.151 77.3025 116.266C78.8056 115.382 80.6035 114.94 82.6962 114.94C84.9362 114.94 86.9404 115.456 88.7088 116.487C90.5067 117.489 91.9214 118.904 92.953 120.732C94.014 122.559 94.5446 124.711 94.5446 127.186C94.5446 129.692 94.014 131.858 92.953 133.685C91.9214 135.513 90.5067 136.927 88.7088 137.929C86.9404 138.932 84.9362 139.433 82.6962 139.433ZM68.6372 147.656V115.294H75.2246V120.157L75.0919 127.231L75.534 134.26V147.656H68.6372ZM81.5025 133.774C82.6519 133.774 83.6688 133.508 84.553 132.978C85.4667 132.447 86.1888 131.696 86.7193 130.723C87.2793 129.721 87.5593 128.542 87.5593 127.186C87.5593 125.801 87.2793 124.622 86.7193 123.649C86.1888 122.677 85.4667 121.925 84.553 121.395C83.6688 120.864 82.6519 120.599 81.5025 120.599C80.353 120.599 79.3214 120.864 78.4077 121.395C77.494 121.925 76.7719 122.677 76.2414 123.649C75.7109 124.622 75.4456 125.801 75.4456 127.186C75.4456 128.542 75.7109 129.721 76.2414 130.723C76.7719 131.696 77.494 132.447 78.4077 132.978C79.3214 133.508 80.353 133.774 81.5025 133.774ZM98.2773 139.079V115.294H104.865V122.014L103.936 120.068C104.644 118.388 105.778 117.121 107.34 116.266C108.903 115.382 110.804 114.94 113.044 114.94V121.306C112.749 121.277 112.484 121.262 112.248 121.262C112.012 121.233 111.761 121.218 111.496 121.218C109.61 121.218 108.077 121.763 106.898 122.854C105.749 123.915 105.174 125.58 105.174 127.849V139.079H98.2773ZM127.582 139.433C125.018 139.433 122.734 138.917 120.73 137.885C118.725 136.824 117.149 135.365 115.999 133.508C114.879 131.652 114.319 129.544 114.319 127.186C114.319 124.799 114.879 122.692 115.999 120.864C117.149 119.007 118.725 117.563 120.73 116.532C122.734 115.471 125.018 114.94 127.582 114.94C130.088 114.94 132.269 115.471 134.125 116.532C135.982 117.563 137.353 119.052 138.237 120.997L132.888 123.871C132.269 122.751 131.488 121.925 130.544 121.395C129.631 120.864 128.629 120.599 127.538 120.599C126.359 120.599 125.298 120.864 124.355 121.395C123.412 121.925 122.66 122.677 122.1 123.649C121.57 124.622 121.304 125.801 121.304 127.186C121.304 128.572 121.57 129.751 122.1 130.723C122.66 131.696 123.412 132.447 124.355 132.978C125.298 133.508 126.359 133.774 127.538 133.774C128.629 133.774 129.631 133.523 130.544 133.022C131.488 132.492 132.269 131.652 132.888 130.502L138.237 133.42C137.353 135.336 135.982 136.824 134.125 137.885C132.269 138.917 130.088 139.433 127.582 139.433Z" fill="url(#paint1_linear_1_52)"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_1_52" x1="145.974" y1="17.9477" x2="-4.68153e-06" y2="62.4661" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#FF593C"/>
|
||||||
|
<stop offset="1" stop-color="#FFBF57"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_1_52" x1="135.617" y1="105.095" x2="21.0253" y2="154.798" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#FF593C"/>
|
||||||
|
<stop offset="1" stop-color="#FFBF57"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip0_1_52">
|
||||||
|
<rect width="150" height="150" fill="white" transform="translate(0.5)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 9.1 KiB |
BIN
artwork/p2prc-logos/White-Image.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
11
artwork/p2prc-logos/White-Vector.svg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<svg width="151" height="150" viewBox="0 0 151 150" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_1_101)">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.6403 7.65789C76.6403 8.32645 76.5018 8.96264 76.252 9.53936L92.9656 22.3203C94.4069 20.7725 96.4626 19.8045 98.7444 19.8045C103.105 19.8045 106.639 23.3391 106.639 27.6992C106.639 28.8372 106.398 29.9189 105.965 30.8963L125.373 41.7419L140.792 28.173C140.62 27.6823 140.526 27.1547 140.526 26.6053C140.526 23.9892 142.647 21.8684 145.263 21.8684C147.879 21.8684 150 23.9892 150 26.6053C150 29.2213 147.879 31.3421 145.263 31.3421C144.06 31.3421 142.961 30.8934 142.126 30.1542L127.101 43.3758L143.687 67.2589C144.18 67.0849 144.71 66.9903 145.263 66.9903C147.879 66.9903 150 69.111 150 71.7271C150 74.3432 147.879 76.4639 145.263 76.4639C142.647 76.4639 140.526 74.3432 140.526 71.7271C140.526 70.5198 140.978 69.418 141.722 68.5815L124.71 44.0845L104.688 32.8957C103.39 34.3793 101.545 35.3725 99.4678 35.5612L98.1139 60.3828C101.679 61.7432 104.211 65.1943 104.211 69.2368C104.211 71.372 103.504 73.3422 102.312 74.9265L114.018 84.3809C114.807 83.7944 115.784 83.4474 116.842 83.4474C119.458 83.4474 121.579 85.5681 121.579 88.1842C121.579 90.8003 119.458 92.9211 116.842 92.9211C114.226 92.9211 112.105 90.8003 112.105 88.1842C112.105 87.4847 112.257 86.8205 112.529 86.2229L100.657 76.6336C99.035 77.9332 96.9767 78.7105 94.7368 78.7105C91.7849 78.7105 89.1482 77.3604 87.4108 75.2439L63.7377 81.6554C63.4383 84.2469 61.2365 86.2589 58.5648 86.2589C55.6887 86.2589 53.3572 83.9273 53.3572 81.0513C53.3572 80.5695 53.4226 80.103 53.5451 79.6601L39.0832 68.7042C37.3508 70.9489 34.6337 72.3947 31.5789 72.3947C30.1375 72.3947 28.7712 72.0728 27.5481 71.4969L18.8395 84.5598C19.871 85.4288 20.5263 86.7299 20.5263 88.1842C20.5263 90.8003 18.4056 92.9211 15.7895 92.9211C13.1734 92.9211 11.0526 90.8003 11.0526 88.1842C11.0526 85.5681 13.1734 83.4474 15.7895 83.4474C16.0935 83.4474 16.3909 83.476 16.6791 83.5308L25.548 70.2274C23.4453 68.4898 22.1053 65.8619 22.1053 62.9211C22.1053 61.6607 22.3514 60.4578 22.7982 59.3579L11.5333 54.5788C10.3959 56.2426 8.48337 57.3346 6.31579 57.3346C2.82767 57.3346 0 54.5069 0 51.0188C0 47.5307 2.82767 44.703 6.31579 44.703C9.80391 44.703 12.6316 47.5307 12.6316 51.0188C12.6316 51.4957 12.5787 51.9604 12.4785 52.4071L23.9665 57.2808C25.6928 54.9548 28.4598 53.4474 31.5789 53.4474C33.8143 53.4474 35.8689 54.2216 37.4891 55.5165L50.7399 42.6673C49.6198 41.3044 48.9474 39.5597 48.9474 37.6579C48.9474 36.3371 49.2717 35.092 49.8451 33.9981L30.7505 24.6728C29.3053 26.5154 27.0584 27.6992 24.5351 27.6992C20.1749 27.6992 16.6403 24.1646 16.6403 19.8045C16.6403 15.4443 20.1749 11.9097 24.5351 11.9097C28.8952 11.9097 32.4298 15.4443 32.4298 19.8045C32.4298 20.7915 32.2487 21.7362 31.9179 22.6071L51.2747 32.0605C52.7022 30.6406 54.6697 29.7632 56.8421 29.7632C57.9909 29.7632 59.0824 30.0085 60.067 30.4497L68.868 11.2945C67.8282 10.4256 67.1667 9.11898 67.1667 7.65789C67.1667 5.04181 69.2874 2.92105 71.9035 2.92105C74.5196 2.92105 76.6403 5.04181 76.6403 7.65789ZM63.4621 79.2763C62.7362 77.2741 60.8176 75.8437 58.5648 75.8437C57.0307 75.8437 55.6515 76.507 54.6984 77.5626L40.2913 66.6481C40.7813 65.5042 41.0526 64.2443 41.0526 62.9211C41.0526 60.7779 40.341 58.801 39.1411 57.2137L52.5045 44.2553C53.7493 45.0754 55.24 45.5526 56.8421 45.5526C59.3127 45.5526 61.5182 44.4178 62.9658 42.6409L86.6296 64.3327C85.7624 65.7633 85.2632 67.4418 85.2632 69.2368C85.2632 70.6299 85.5639 71.9528 86.1039 73.1441L63.4621 79.2763ZM71.9035 12.3947C71.5973 12.3947 71.2979 12.3657 71.0078 12.3102L62.0769 31.7481C63.7085 33.1944 64.7368 35.3061 64.7368 37.6579C64.7368 38.6789 64.543 39.6546 64.1902 40.5503L88.1046 62.4719C89.8135 60.7964 92.1545 59.7632 94.7368 59.7632C95.0869 59.7632 95.4325 59.7821 95.7727 59.8192L97.1034 35.4232C93.5308 34.6679 90.8497 31.4967 90.8497 27.6992C90.8497 26.4737 91.1289 25.3134 91.6272 24.2785L74.7972 11.4084C73.9968 12.0268 72.9931 12.3947 71.9035 12.3947Z" fill="#F5F5F5"/>
|
||||||
|
<path d="M28.2947 139.433C26.2905 139.433 24.5368 138.991 23.0337 138.106C21.5305 137.222 20.3516 135.881 19.4968 134.083C18.6716 132.256 18.2589 129.957 18.2589 127.186C18.2589 124.386 18.6568 122.087 19.4526 120.289C20.2484 118.492 21.3979 117.151 22.901 116.266C24.4042 115.382 26.2021 114.94 28.2947 114.94C30.5347 114.94 32.5389 115.456 34.3074 116.487C36.1052 117.489 37.52 118.904 38.5516 120.732C39.6126 122.559 40.1431 124.711 40.1431 127.186C40.1431 129.692 39.6126 131.858 38.5516 133.685C37.52 135.513 36.1052 136.927 34.3074 137.929C32.5389 138.932 30.5347 139.433 28.2947 139.433ZM14.2358 147.656V115.294H20.8231V120.157L20.6905 127.231L21.1326 134.26V147.656H14.2358ZM27.101 133.774C28.2505 133.774 29.2674 133.508 30.1516 132.978C31.0652 132.447 31.7874 131.696 32.3179 130.723C32.8779 129.721 33.1579 128.542 33.1579 127.186C33.1579 125.801 32.8779 124.622 32.3179 123.649C31.7874 122.677 31.0652 121.925 30.1516 121.395C29.2674 120.864 28.2505 120.599 27.101 120.599C25.9516 120.599 24.92 120.864 24.0063 121.395C23.0926 121.925 22.3705 122.677 21.84 123.649C21.3095 124.622 21.0442 125.801 21.0442 127.186C21.0442 128.542 21.3095 129.721 21.84 130.723C22.3705 131.696 23.0926 132.447 24.0063 132.978C24.92 133.508 25.9516 133.774 27.101 133.774ZM41.7199 139.079V134.437L53.6567 123.163C54.5999 122.308 55.2925 121.542 55.7346 120.864C56.1767 120.186 56.4714 119.567 56.6188 119.007C56.7957 118.447 56.8841 117.932 56.8841 117.46C56.8841 116.222 56.4567 115.279 55.602 114.631C54.7767 113.953 53.5536 113.614 51.9325 113.614C50.6357 113.614 49.4272 113.864 48.3072 114.365C47.2167 114.866 46.2883 115.647 45.522 116.708L40.3051 113.348C41.4841 111.58 43.1346 110.18 45.2567 109.148C47.3788 108.117 49.8251 107.601 52.5957 107.601C54.8946 107.601 56.8988 107.984 58.6083 108.751C60.3472 109.487 61.6883 110.534 62.6314 111.889C63.6041 113.245 64.0904 114.866 64.0904 116.753C64.0904 117.755 63.9578 118.757 63.6925 119.759C63.4567 120.732 62.9557 121.763 62.1893 122.854C61.4525 123.944 60.362 125.167 58.9178 126.523L49.0146 135.852L47.6441 133.243H65.1072V139.079H41.7199ZM82.6961 139.433C80.6919 139.433 78.9382 138.991 77.4351 138.106C75.9319 137.222 74.753 135.881 73.8982 134.083C73.073 132.256 72.6603 129.957 72.6603 127.186C72.6603 124.386 73.0582 122.087 73.854 120.289C74.6498 118.492 75.7993 117.151 77.3024 116.266C78.8056 115.382 80.6035 114.94 82.6961 114.94C84.9361 114.94 86.9403 115.456 88.7088 116.487C90.5066 117.489 91.9214 118.904 92.953 120.732C94.014 122.559 94.5445 124.711 94.5445 127.186C94.5445 129.692 94.014 131.858 92.953 133.685C91.9214 135.513 90.5066 136.927 88.7088 137.929C86.9403 138.932 84.9361 139.433 82.6961 139.433ZM68.6372 147.656V115.294H75.2245V120.157L75.0919 127.231L75.534 134.26V147.656H68.6372ZM81.5024 133.774C82.6519 133.774 83.6688 133.508 84.553 132.978C85.4666 132.447 86.1888 131.696 86.7193 130.723C87.2793 129.721 87.5593 128.542 87.5593 127.186C87.5593 125.801 87.2793 124.622 86.7193 123.649C86.1888 122.677 85.4666 121.925 84.553 121.395C83.6688 120.864 82.6519 120.599 81.5024 120.599C80.353 120.599 79.3214 120.864 78.4077 121.395C77.494 121.925 76.7719 122.677 76.2414 123.649C75.7109 124.622 75.4456 125.801 75.4456 127.186C75.4456 128.542 75.7109 129.721 76.2414 130.723C76.7719 131.696 77.494 132.447 78.4077 132.978C79.3214 133.508 80.353 133.774 81.5024 133.774ZM98.2772 139.079V115.294H104.865V122.014L103.936 120.068C104.644 118.388 105.778 117.121 107.34 116.266C108.902 115.382 110.804 114.94 113.044 114.94V121.306C112.749 121.277 112.484 121.262 112.248 121.262C112.012 121.233 111.761 121.218 111.496 121.218C109.61 121.218 108.077 121.763 106.898 122.854C105.749 123.915 105.174 125.58 105.174 127.849V139.079H98.2772ZM127.582 139.433C125.018 139.433 122.734 138.917 120.73 137.885C118.725 136.824 117.149 135.365 115.999 133.508C114.879 131.652 114.319 129.544 114.319 127.186C114.319 124.799 114.879 122.692 115.999 120.864C117.149 119.007 118.725 117.563 120.73 116.532C122.734 115.471 125.018 114.94 127.582 114.94C130.088 114.94 132.269 115.471 134.125 116.532C135.982 117.563 137.353 119.052 138.237 120.997L132.888 123.871C132.269 122.751 131.488 121.925 130.544 121.395C129.631 120.864 128.629 120.599 127.538 120.599C126.359 120.599 125.298 120.864 124.355 121.395C123.412 121.925 122.66 122.677 122.1 123.649C121.57 124.622 121.304 125.801 121.304 127.186C121.304 128.572 121.57 129.751 122.1 130.723C122.66 131.696 123.412 132.447 124.355 132.978C125.298 133.508 126.359 133.774 127.538 133.774C128.629 133.774 129.631 133.523 130.544 133.022C131.488 132.492 132.269 131.652 132.888 130.502L138.237 133.42C137.353 135.336 135.982 136.824 134.125 137.885C132.269 138.917 130.088 139.433 127.582 139.433Z" fill="#F5F5F5"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_1_101">
|
||||||
|
<rect width="150" height="150" fill="white" transform="translate(0.5)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 8.7 KiB |
1
build-bindings.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
cd Bindings && go build -buildmode=c-shared -o p2prc.so
|
||||||
28
build-python-package.sh
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# Create export directory for python
|
||||||
|
mkdir Bindings/python/export
|
||||||
|
|
||||||
|
# Creating SharedObjects directory for python
|
||||||
|
mkdir Bindings/python/export/SharedObjects
|
||||||
|
|
||||||
|
sh build-bindings.sh
|
||||||
|
|
||||||
|
cp Bindings/p2prc.h Bindings/python/export/SharedObjects/
|
||||||
|
cp Bindings/p2prc.so Bindings/python/export/SharedObjects/
|
||||||
|
|
||||||
|
cp Bindings/python/p2prc.py Bindings/python/export/
|
||||||
|
|
||||||
|
echo "Output is in the Directory Bindings/python/export/"
|
||||||
|
|
||||||
|
# Architectures for Linux
|
||||||
|
#archs=(amd64 arm64)
|
||||||
|
#
|
||||||
|
#for arch in ${archs[@]}
|
||||||
|
#do
|
||||||
|
# mkdir Bindings/python/export/SharedObjects/linux-${arch}
|
||||||
|
# cd Bindings/
|
||||||
|
# env GOOS=linux GOARCH=${arch} go build -buildmode=c-shared -o python/export/SharedObjects/linux-${arch}/p2prc.so
|
||||||
|
# echo "GOOS=linux GOARCH=${arch} go build -buildmode=c-shared -o python/export/SharedObjects/linux-${arch}/p2prc.so"
|
||||||
|
# cd ..
|
||||||
|
#done
|
||||||
310
client/GroupTrackContainer.go
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Groups Data Structure type
|
||||||
|
type Groups struct {
|
||||||
|
GroupList []*Group `json:"Groups"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group Information about a single group
|
||||||
|
type Group struct {
|
||||||
|
ID string `json:"ID"`
|
||||||
|
TrackContainerList []*TrackContainer `json:"TrackContainer"`
|
||||||
|
// Sneaky as required only when removing the element
|
||||||
|
// Set when GetGroup function is called
|
||||||
|
index int
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateGroup Creates a new group to add a set of track containers
|
||||||
|
func CreateGroup() (*Group, error) {
|
||||||
|
// Creating variable of type new group
|
||||||
|
var NewGroup Group
|
||||||
|
// Generate new UUID for group ID
|
||||||
|
id := uuid.New()
|
||||||
|
// Add new group id and prepend with the string "grp"
|
||||||
|
// The reason this is done is to differentiate between a
|
||||||
|
// group ID and docker container ID
|
||||||
|
NewGroup.ID = "grp" + id.String()
|
||||||
|
// Adding the new group to the
|
||||||
|
// GroupTrackContainer File
|
||||||
|
err := NewGroup.AddGroupToFile()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &NewGroup, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveGroup Removes group based on the group ID provided
|
||||||
|
func RemoveGroup(GroupID string) error {
|
||||||
|
// Read group information from the
|
||||||
|
//grouptrackcontainer json file
|
||||||
|
groups, err := ReadGroup()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Gets Group struct based on group ID
|
||||||
|
// provided
|
||||||
|
group, err := GetGroup(GroupID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Remove Group struct from the groups variable
|
||||||
|
groups.GroupList = append(groups.GroupList[:group.index], groups.GroupList[group.index+1:]...)
|
||||||
|
|
||||||
|
// Write new groups to the grouptrackcontainer json file
|
||||||
|
err = groups.WriteGroup()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddContainerToGroup Adds container information to the Group based on the Group ID
|
||||||
|
func AddContainerToGroup(ContainerID string, GroupID string) (*Group, error) {
|
||||||
|
// Gets container information based on container ID provided
|
||||||
|
containerInfo, err := GetContainerInformation(ContainerID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Gets group information based on the group ID provided
|
||||||
|
group, err := GetGroup(GroupID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Adds container information the group
|
||||||
|
group.AddContainer(containerInfo)
|
||||||
|
|
||||||
|
// Get Groups information from reading the grouptrackcontainer.json file
|
||||||
|
groups, err := ReadGroup()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Updating specific element in the group list with the added container
|
||||||
|
groups.GroupList[group.index] = group
|
||||||
|
// Write groups information on the grouptrackcontainer.json file
|
||||||
|
err = groups.WriteGroup()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return group, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveContainerGroup Remove Container from the group ID specified
|
||||||
|
func RemoveContainerGroup(ContainerID string, GroupID string) (*Group, error) {
|
||||||
|
// Get container information based on container ID provided
|
||||||
|
containerInfo, err := GetContainerInformation(ContainerID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Gets group information based on the group ID provided
|
||||||
|
group, err := GetGroup(GroupID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Remove container from the appropriate group
|
||||||
|
err = group.RemoveContainerGroup(containerInfo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Get Groups information from reading the grouptrackcontainer.json file
|
||||||
|
groups, err := ReadGroup()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Updating specific element in the group list with the remove container
|
||||||
|
groups.GroupList[group.index] = group
|
||||||
|
// Write groups information on the grouptrackcontainer.json file
|
||||||
|
err = groups.WriteGroup()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return group, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// the tracked container list
|
||||||
|
func RemoveContainerGroups(ContainerID string) error {
|
||||||
|
// Get container information based on container ID provided
|
||||||
|
containerInfo, err := GetContainerInformation(ContainerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Get Groups information from reading the grouptrackcontainer.json file
|
||||||
|
groups, err := ReadGroup()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Removes container information from all groups it is found in
|
||||||
|
err = groups.RemoveContainerGroups(containerInfo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Write groups information on the grouptrackcontainer.json file
|
||||||
|
err = groups.WriteGroup()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGroup Gets group information based on
|
||||||
|
// group id provided
|
||||||
|
func GetGroup(GroupID string) (*Group, error) {
|
||||||
|
// Read group information from the
|
||||||
|
//grouptrackcontainer json file
|
||||||
|
groups, err := ReadGroup()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Iterate through the set of groups and
|
||||||
|
// if the group ID matches then return it
|
||||||
|
for i, group := range groups.GroupList {
|
||||||
|
if group.ID == GroupID {
|
||||||
|
group.index = i
|
||||||
|
return group, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("Group not found. ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddGroupToFile Adds Group struct to the GroupTrackContainer File
|
||||||
|
func (grp *Group) AddGroupToFile() error {
|
||||||
|
// Gets all group information from the
|
||||||
|
// GroupTrackContainer JSON file
|
||||||
|
groups, err := ReadGroup()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Appending the newly created group
|
||||||
|
groups.GroupList = append(groups.GroupList, grp)
|
||||||
|
// Writing Group information to the GroupTrackContainer
|
||||||
|
// JSON file
|
||||||
|
err = groups.WriteGroup()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadGroup Function reads grouptrackcontainers.json and converts
|
||||||
|
// result to Groups
|
||||||
|
func ReadGroup() (*Groups, error) {
|
||||||
|
// Get Path from config
|
||||||
|
config, err := config.ConfigInit(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
jsonFile, err := os.Open(config.GroupTrackContainersPath)
|
||||||
|
// if we os.Open returns an error then handle it
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// defer the closing of our jsonFile so that we can parse it later on
|
||||||
|
defer jsonFile.Close()
|
||||||
|
// read our opened xmlFile as a byte array.
|
||||||
|
byteValue, _ := ioutil.ReadAll(jsonFile)
|
||||||
|
// we initialize our Users array
|
||||||
|
var groups Groups
|
||||||
|
// we unmarshal our byteArray which contains our
|
||||||
|
// jsonFile's content into 'users' which we defined above
|
||||||
|
json.Unmarshal(byteValue, &groups)
|
||||||
|
return &groups, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteGroup Function to write type Groups to the grouptrackcontainers.json file
|
||||||
|
func (grp *Groups) WriteGroup() error {
|
||||||
|
file, err := json.MarshalIndent(grp, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Get Path from config
|
||||||
|
config, err := config.ConfigInit(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Writes to the appropriate file
|
||||||
|
err = ioutil.WriteFile(config.GroupTrackContainersPath, file, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddContainer Adds a container to the Tracked container list of the group
|
||||||
|
func (grp *Group) AddContainer(Container *TrackContainer) error {
|
||||||
|
grp.TrackContainerList = append(grp.TrackContainerList, Container)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveContainerGroup Removes container information from the group
|
||||||
|
func (grp *Group) RemoveContainerGroup(Container *TrackContainer) error {
|
||||||
|
// Iterating through all container in the Group of Tracked Container
|
||||||
|
for i, container := range grp.TrackContainerList {
|
||||||
|
// If the container ID matches then remove the container from the group
|
||||||
|
if container.Id == Container.Id {
|
||||||
|
grp.TrackContainerList = append(grp.TrackContainerList[:i], grp.TrackContainerList[i+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveContainerGroups removes container found in all groups
|
||||||
|
func (grp *Groups) RemoveContainerGroups(Container *TrackContainer) error {
|
||||||
|
// Iterating through all groups
|
||||||
|
for i, group := range grp.GroupList {
|
||||||
|
// Removes the container in the following group
|
||||||
|
// if it exists
|
||||||
|
err := group.RemoveContainerGroup(Container)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Set group information to list groups
|
||||||
|
grp.GroupList[i] = group
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyContainerGroups Modifies container information is all groups
|
||||||
|
// available
|
||||||
|
func (TC *TrackContainer) ModifyContainerGroups() error {
|
||||||
|
group, err := ReadGroup()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Iterate though all groups and modify the container
|
||||||
|
// information in groups where the modified container
|
||||||
|
// ID matches
|
||||||
|
for i, _ := range group.GroupList {
|
||||||
|
// Checking in each group if the modified container ID exists
|
||||||
|
for j, _ := range group.GroupList[i].TrackContainerList {
|
||||||
|
// If there is match then change them
|
||||||
|
if group.GroupList[i].TrackContainerList[j].Id == TC.Id {
|
||||||
|
group.GroupList[i].TrackContainerList[j] = TC
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write modified result to the Groups track container JSON file
|
||||||
|
err = group.WriteGroup()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
267
client/GroupTrackContainer_test.go
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Testing out if a new group is getting created
|
||||||
|
func TestCreateGroup(t *testing.T) {
|
||||||
|
group, err := CreateGroup()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
PrettyPrint(group)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing if the group gets removed when a
|
||||||
|
// group ID is provided
|
||||||
|
func TestRemoveGroup(t *testing.T) {
|
||||||
|
// Creates a new group
|
||||||
|
group, err := CreateGroup()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
// Removes the new group
|
||||||
|
// it created
|
||||||
|
err = RemoveGroup(group.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing if container information is added
|
||||||
|
// to the created group
|
||||||
|
func TestAddContainerToGroup(t *testing.T) {
|
||||||
|
// Creates a new group
|
||||||
|
group, err := CreateGroup()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creating and adding the container to the
|
||||||
|
// tracked list
|
||||||
|
container1, err := docker.BuildRunContainer(0, "false", "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing the AddTrackContainer Function and adding the first container created
|
||||||
|
err = AddTrackContainer(container1, "0.0.0.0")
|
||||||
|
if err != nil {
|
||||||
|
// Killing docker container created
|
||||||
|
err = docker.StopAndRemoveContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds container information to the group
|
||||||
|
Group, err := AddContainerToGroup(container1.ID, group.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
PrettyPrint(Group)
|
||||||
|
|
||||||
|
// Killing docker container created
|
||||||
|
err = docker.StopAndRemoveContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removing container 1 from the tracked list
|
||||||
|
err = RemoveTrackedContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes the new group
|
||||||
|
// it created
|
||||||
|
err = RemoveGroup(group.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing if the container information is removed from the group
|
||||||
|
func TestGroup_RemoveContainerGroup(t *testing.T) {
|
||||||
|
// Creates a new group
|
||||||
|
group, err := CreateGroup()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creating and adding the container to the
|
||||||
|
// tracked list
|
||||||
|
container1, err := docker.BuildRunContainer(0, "false", "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing the AddTrackContainer Function and adding the first container created
|
||||||
|
err = AddTrackContainer(container1, "0.0.0.0")
|
||||||
|
if err != nil {
|
||||||
|
// Killing docker container created
|
||||||
|
err = docker.StopAndRemoveContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds container information to the group
|
||||||
|
Group, err := AddContainerToGroup(container1.ID, group.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fmt.Println("Container added")
|
||||||
|
PrettyPrint(Group)
|
||||||
|
|
||||||
|
// Removing docker container from the group
|
||||||
|
Group, err = RemoveContainerGroup(container1.ID, group.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fmt.Println("Container removed")
|
||||||
|
PrettyPrint(Group)
|
||||||
|
|
||||||
|
// Killing docker container created
|
||||||
|
err = docker.StopAndRemoveContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removing container 1 from the tracked list
|
||||||
|
err = RemoveTrackedContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes the new group
|
||||||
|
// it created
|
||||||
|
err = RemoveGroup(group.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing that container are removed from all
|
||||||
|
// created groups
|
||||||
|
// Scenario:
|
||||||
|
// - Create 2 groups
|
||||||
|
// - Add Container information to each group
|
||||||
|
// - Remove Container information from each group
|
||||||
|
func TestGroups_RemoveContainerGroups(t *testing.T) {
|
||||||
|
// Creates a new group
|
||||||
|
group, err := CreateGroup()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
// Created another group assigned to variable group 1
|
||||||
|
group1, err := CreateGroup()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creating and adding the container to the
|
||||||
|
// tracked list
|
||||||
|
container1, err := docker.BuildRunContainer(0, "false", "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing the AddTrackContainer Function and adding the first container created
|
||||||
|
err = AddTrackContainer(container1, "0.0.0.0")
|
||||||
|
if err != nil {
|
||||||
|
// Killing docker container created
|
||||||
|
err = docker.StopAndRemoveContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds container information to the group
|
||||||
|
Group, err := AddContainerToGroup(container1.ID, group.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fmt.Println("Container added")
|
||||||
|
PrettyPrint(Group)
|
||||||
|
|
||||||
|
// Adds container information to the group
|
||||||
|
Group1, err := AddContainerToGroup(container1.ID, group1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fmt.Println("Container added")
|
||||||
|
PrettyPrint(Group1)
|
||||||
|
|
||||||
|
// Removing docker container from the group
|
||||||
|
err = RemoveContainerGroups(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Killing docker container created
|
||||||
|
err = docker.StopAndRemoveContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removing container 1 from the tracked list
|
||||||
|
err = RemoveTrackedContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes the new group
|
||||||
|
// it created
|
||||||
|
err = RemoveGroup(group.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes the new group
|
||||||
|
// it created
|
||||||
|
err = RemoveGroup(group1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,246 +0,0 @@
|
|||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
|
||||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"mime/multipart"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
type IP struct {
|
|
||||||
Query string
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateIpTable Does the following to update it's IP table
|
|
||||||
func UpdateIpTable(IpAddress string) error {
|
|
||||||
|
|
||||||
config, err := config.ConfigInit()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
client := http.Client{}
|
|
||||||
|
|
||||||
resp, err := UploadMultipartFile(client,"http://"+IpAddress+":8088/IpTable","json",config.IPTable)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
//resp, err := SendPostRequest("http://"+IpAddress+":8088/IpTable",
|
|
||||||
// config.IPTable,
|
|
||||||
// "json")
|
|
||||||
//
|
|
||||||
//if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
|
|
||||||
var ipStruct p2p.IpAddresses
|
|
||||||
json.Unmarshal(resp, &ipStruct)
|
|
||||||
|
|
||||||
// Updates IP table based on information provided
|
|
||||||
// by the server
|
|
||||||
if len(ipStruct.IpAddress) > 0 {
|
|
||||||
err = ipStruct.SpeedTestUpdatedIPTable()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// UpdateIpTableListClient updates IP tables (Default 3 hops) based on server information available
|
|
||||||
//on the ip tables
|
|
||||||
func UpdateIpTableListClient() error {
|
|
||||||
// Ensure that the IP Table has Node pingable
|
|
||||||
err := p2p.LocalSpeedTestIpTable()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// IP addresses to not append to struct due to
|
|
||||||
// duplication
|
|
||||||
|
|
||||||
Addresses, err := p2p.ReadIpTable()
|
|
||||||
var DoNotRead p2p.IpAddresses
|
|
||||||
|
|
||||||
// Run loop 3 times
|
|
||||||
for i := 0; i < 3; i++ {
|
|
||||||
// Gets information from IP table
|
|
||||||
Addresses, err = p2p.ReadIpTable()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Appending current machine public IP address as should not be there in IP Table
|
|
||||||
var PublicIP p2p.IpAddress
|
|
||||||
ip, err := CurrentPublicIP()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
PublicIP.Ipv4 = ip
|
|
||||||
DoNotRead.IpAddress = append(DoNotRead.IpAddress, PublicIP)
|
|
||||||
|
|
||||||
// Updates IP table based on server IP table
|
|
||||||
for j := range Addresses.IpAddress {
|
|
||||||
|
|
||||||
Exists := false
|
|
||||||
|
|
||||||
if PublicIP.Ipv4 == Addresses.IpAddress[j].Ipv4 {
|
|
||||||
Exists = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if IP addresses is there in the struct DoNotRead
|
|
||||||
for k := range DoNotRead.IpAddress {
|
|
||||||
if DoNotRead.IpAddress[k].Ipv4 == Addresses.IpAddress[j].Ipv4 {
|
|
||||||
Exists = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the struct exists then continues
|
|
||||||
if Exists {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err = UpdateIpTable(Addresses.IpAddress[j].Ipv4)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
//Appends server1 IP address to variable DoNotRead
|
|
||||||
DoNotRead.IpAddress = append(DoNotRead.IpAddress, Addresses.IpAddress[j])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removing duplicates in the IP table
|
|
||||||
if err := p2p.RemoveDuplicates(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendPostRequest Sends a file as a
|
|
||||||
//POST request.
|
|
||||||
// Reference (https://stackoverflow.com/questions/51234464/upload-a-file-with-post-request-golang)
|
|
||||||
//func SendPostRequest (url string, filename string, filetype string) ([]byte,error) {
|
|
||||||
// file, err := os.Open(filename)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil,err
|
|
||||||
// }
|
|
||||||
// defer file.Close()
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// body := &bytes.Buffer{}
|
|
||||||
// writer := multipart.NewWriter(body)
|
|
||||||
// part, err := writer.CreateFormFile(filetype, filepath.Base(file.Name()))
|
|
||||||
//
|
|
||||||
// if err != nil {
|
|
||||||
// return nil,err
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// io.Copy(part, file)
|
|
||||||
// writer.Close()
|
|
||||||
// request, err := http.NewRequest("POST", url, body)
|
|
||||||
//
|
|
||||||
// if err != nil {
|
|
||||||
// return nil,err
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// request.Header.Add("Content-Type", writer.FormDataContentType())
|
|
||||||
// client := &http.Client{}
|
|
||||||
//
|
|
||||||
// response, err := client.Do(request)
|
|
||||||
//
|
|
||||||
// if err != nil {
|
|
||||||
// return nil,err
|
|
||||||
// }
|
|
||||||
// defer response.Body.Close()
|
|
||||||
//
|
|
||||||
// content, err := ioutil.ReadAll(response.Body)
|
|
||||||
//
|
|
||||||
// if err != nil {
|
|
||||||
// return nil,err
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return content, nil
|
|
||||||
//}
|
|
||||||
|
|
||||||
func UploadMultipartFile(client http.Client, uri, key, path string) ([]byte, error) {
|
|
||||||
body, writer := io.Pipe()
|
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, uri, body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
mwriter := multipart.NewWriter(writer)
|
|
||||||
req.Header.Add("Content-Type", mwriter.FormDataContentType())
|
|
||||||
|
|
||||||
errchan := make(chan error)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer close(errchan)
|
|
||||||
defer writer.Close()
|
|
||||||
defer mwriter.Close()
|
|
||||||
|
|
||||||
w, err := mwriter.CreateFormFile(key, path)
|
|
||||||
if err != nil {
|
|
||||||
errchan <- err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
in, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
errchan <- err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer in.Close()
|
|
||||||
|
|
||||||
if written, err := io.Copy(w, in); err != nil {
|
|
||||||
errchan <- fmt.Errorf("error copying %s (%d bytes written): %v", path, written, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := mwriter.Close(); err != nil {
|
|
||||||
errchan <- err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
content, err := ioutil.ReadAll(resp.Body)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return content, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// CurrentPublicIP Get Current Public IP address
|
|
||||||
func CurrentPublicIP() (string,error) {
|
|
||||||
req, err := http.Get("http://ip-api.com/json/")
|
|
||||||
if err != nil {
|
|
||||||
return "",err
|
|
||||||
}
|
|
||||||
defer req.Body.Close()
|
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(req.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "",err
|
|
||||||
}
|
|
||||||
|
|
||||||
var ip IP
|
|
||||||
json.Unmarshal(body, &ip)
|
|
||||||
|
|
||||||
return ip.Query, nil
|
|
||||||
}
|
|
||||||
39
client/MAPPort.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ResponseMAPPort struct {
|
||||||
|
IPAddress string
|
||||||
|
}
|
||||||
|
|
||||||
|
func MAPPort(port string, domainName string) (*ResponseMAPPort, error) {
|
||||||
|
Config, err := config.ConfigInit(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//if version == "version 6" {
|
||||||
|
URL := "http://0.0.0.0:" + Config.ServerPort + "/MAPPort?port=" + port + "&domain_name=" + domainName
|
||||||
|
//} else {
|
||||||
|
// URL = "http://" + IP + ":" + serverPort + "/server_info"
|
||||||
|
//}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
var response ResponseMAPPort
|
||||||
|
response.IPAddress = string(byteValue)
|
||||||
|
|
||||||
|
return &response, nil
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ package client
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server"
|
"github.com/Akilan1999/p2p-rendering-computation/server"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
@@ -11,17 +11,30 @@ import (
|
|||||||
// GetSpecs Gets Specs from the server such CPU, GPU usage
|
// GetSpecs Gets Specs from the server such CPU, GPU usage
|
||||||
// and other basic information which helps set a
|
// and other basic information which helps set a
|
||||||
// cluster of computer
|
// cluster of computer
|
||||||
func GetSpecs(IP string)(*server.SysInfo,error) {
|
func GetSpecs(IP string) (*server.SysInfo, error) {
|
||||||
URL := "http://" + IP + ":" + serverPort + "/server_info"
|
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 + "/server_info"
|
||||||
|
//} else {
|
||||||
|
// URL = "http://" + IP + ":" + serverPort + "/server_info"
|
||||||
|
//}
|
||||||
resp, err := http.Get(URL)
|
resp, err := http.Get(URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil,err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert response to byte value
|
// Convert response to byte value
|
||||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
byteValue, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil,err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create variable for result response type
|
// Create variable for result response type
|
||||||
@@ -30,7 +43,7 @@ func GetSpecs(IP string)(*server.SysInfo,error) {
|
|||||||
// Adds byte value to docker.DockerVM struct
|
// Adds byte value to docker.DockerVM struct
|
||||||
json.Unmarshal(byteValue, &serverSpecsResult)
|
json.Unmarshal(byteValue, &serverSpecsResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil,err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &serverSpecsResult, nil
|
return &serverSpecsResult, nil
|
||||||
|
|||||||
220
client/TrackContainers.go
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TrackContainers This struct stores arrays of current containers running
|
||||||
|
type TrackContainers struct {
|
||||||
|
TrackContainerList []TrackContainer `json:"TrackContainer"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrackContainer Stores information of current containers
|
||||||
|
type TrackContainer struct {
|
||||||
|
Id string `json:"ID"`
|
||||||
|
Container *docker.DockerVM `json:"Container"`
|
||||||
|
IpAddress string `json:"IpAddress"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
if d == nil {
|
||||||
|
return errors.New("d is nil")
|
||||||
|
}
|
||||||
|
//Get config information to derive paths for track containers json file
|
||||||
|
config, err := config.ConfigInit(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getting information about the file trackcontainers.json file
|
||||||
|
stat, err := os.Stat(config.TrackContainersPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Initialize variable for TrackContainers
|
||||||
|
var trackContainers TrackContainers
|
||||||
|
// If the trackcontainers.json file is not empty then
|
||||||
|
// Read from that file
|
||||||
|
if stat.Size() != 0 {
|
||||||
|
// Reads tracked container file
|
||||||
|
trackContainersFile, err := ReadTrackContainers(config.TrackContainersPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
trackContainers = *trackContainersFile
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize new variable with type struct TrackContainers and
|
||||||
|
// add container struct and ip address
|
||||||
|
var trackContainer TrackContainer
|
||||||
|
trackContainer.Id = d.ID
|
||||||
|
trackContainer.Container = d
|
||||||
|
trackContainer.IpAddress = ipAddress
|
||||||
|
|
||||||
|
// Adds new container as passed in the parameter to the struct
|
||||||
|
if &trackContainer == nil {
|
||||||
|
return errors.New("trackContainer variable is nil")
|
||||||
|
}
|
||||||
|
trackContainers.TrackContainerList = append(trackContainers.TrackContainerList, trackContainer)
|
||||||
|
|
||||||
|
// write modified information to the tracked json file
|
||||||
|
data, err := json.MarshalIndent(trackContainers, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveTrackedContainer This function removos tracked container from the trackcontainer JSON file
|
||||||
|
func RemoveTrackedContainer(id string) error {
|
||||||
|
//Get config information to derive paths for track containers json file
|
||||||
|
config, err := config.ConfigInit(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Getting tracked container struct
|
||||||
|
trackedContainers, err := ReadTrackContainers(config.TrackContainersPath)
|
||||||
|
// Storing index of element to remove
|
||||||
|
var removeElement int
|
||||||
|
removeElement = -1
|
||||||
|
for i := range trackedContainers.TrackContainerList {
|
||||||
|
if trackedContainers.TrackContainerList[i].Id == id {
|
||||||
|
removeElement = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Checks if the element to be removed has been detected
|
||||||
|
if removeElement == -1 {
|
||||||
|
return errors.New("Container ID not found in the tracked list")
|
||||||
|
}
|
||||||
|
// Remove the detected element from the struct
|
||||||
|
trackedContainers.TrackContainerList = append(trackedContainers.TrackContainerList[:removeElement], trackedContainers.TrackContainerList[removeElement+1:]...)
|
||||||
|
|
||||||
|
// write modified information to the tracked json file
|
||||||
|
data, err := json.MarshalIndent(trackedContainers, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ViewTrackedContainers View Containers currently tracked
|
||||||
|
func ViewTrackedContainers() (error, *TrackContainers) {
|
||||||
|
config, err := config.ConfigInit(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
trackedContianers, err := ReadTrackContainers(config.TrackContainersPath)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, trackedContianers
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadTrackContainers Reads containers which are currently tracked
|
||||||
|
func ReadTrackContainers(filename string) (*TrackContainers, error) {
|
||||||
|
buf, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &TrackContainers{}
|
||||||
|
err = json.Unmarshal(buf, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("in file %q: %v", filename, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//func ModifyTrackContainers()
|
||||||
|
|
||||||
|
// GetContainerInformation gets information about container based on
|
||||||
|
// container ID provided
|
||||||
|
func GetContainerInformation(ID string) (*TrackContainer, error) {
|
||||||
|
// Getting the current containers
|
||||||
|
err, CurrentContainers := ViewTrackedContainers()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Iterating through all tracked containers to get the container information
|
||||||
|
// of the ID passed through the function parameter
|
||||||
|
for _, container := range CurrentContainers.TrackContainerList {
|
||||||
|
if container.Container.ID == ID {
|
||||||
|
return &container, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, errors.New("Container not found. ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyContainerInformation Modifies information inside the container
|
||||||
|
func (TC *TrackContainer) ModifyContainerInformation() error {
|
||||||
|
// Gets all the information of tracker containers
|
||||||
|
err, t := ViewTrackedContainers()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Find the element where the containers match and
|
||||||
|
// change them
|
||||||
|
for i, container := range t.TrackContainerList {
|
||||||
|
if TC.Id == container.Id {
|
||||||
|
t.TrackContainerList[i] = *TC
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Write the modified information to the file
|
||||||
|
// write modified information to the tracked json file
|
||||||
|
err = t.WriteContainers()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteContainers Write information back to the config file
|
||||||
|
func (TC *TrackContainers) WriteContainers() error {
|
||||||
|
// Initialize config file
|
||||||
|
config, err := config.ConfigInit(nil, nil)
|
||||||
|
// write modified information to the tracked json file
|
||||||
|
data, err := json.MarshalIndent(TC, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
120
client/TrackContianers_test.go
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tests a scenario where the container are getting tracked
|
||||||
|
func TestAddTrackContainer(t *testing.T) {
|
||||||
|
// Create docker container and get SSH port
|
||||||
|
container1, err := docker.BuildRunContainer(0, "false", "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
// Testing the AddTrackContainer Function
|
||||||
|
err = AddTrackContainer(container1, "0.0.0.0")
|
||||||
|
if err != nil {
|
||||||
|
// Killing docker container created
|
||||||
|
err = docker.StopAndRemoveContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
// Killing docker container created
|
||||||
|
err = docker.StopAndRemoveContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing the remove container function
|
||||||
|
// NOTE: This test can also be considered as a whole flow on the process of
|
||||||
|
// tracked containers
|
||||||
|
func TestRemoveTrackedContainer(t *testing.T) {
|
||||||
|
container1, err := docker.BuildRunContainer(0, "false", "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
container2, err := docker.BuildRunContainer(0, "false", "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing the AddTrackContainer Function and adding the first container created
|
||||||
|
err = AddTrackContainer(container1, "0.0.0.0")
|
||||||
|
if err != nil {
|
||||||
|
// Killing docker container created
|
||||||
|
err = docker.StopAndRemoveContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
// Killing docker container created
|
||||||
|
err = docker.StopAndRemoveContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing the AddTrackContainer Function and the adding the second container created
|
||||||
|
err = AddTrackContainer(container2, "0.0.0.0")
|
||||||
|
if err != nil {
|
||||||
|
// Killing docker container created
|
||||||
|
err = docker.StopAndRemoveContainer(container2.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
// Killing docker container created
|
||||||
|
err = docker.StopAndRemoveContainer(container2.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removing container 1 from the tracked list
|
||||||
|
err = RemoveTrackedContainer(container1.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removing container 2 from the tracked list
|
||||||
|
err = RemoveTrackedContainer(container2.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test function that checks if the ID belongs to
|
||||||
|
// a group or container running
|
||||||
|
func TestCheckID(t *testing.T) {
|
||||||
|
id := "grp123"
|
||||||
|
checkID, err := CheckID(id)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
if checkID == "group" {
|
||||||
|
fmt.Println("pass")
|
||||||
|
} else {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
40
client/clientIPTable/AddCustomInformationToIPTable.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package clientIPTable
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddCustomInformationToIPTable(text string) error {
|
||||||
|
// Get config information
|
||||||
|
Config, err := config.ConfigInit(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get IPTable information
|
||||||
|
table, err := p2p.ReadIpTable()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
found := false
|
||||||
|
|
||||||
|
for i, _ := range table.IpAddress {
|
||||||
|
if table.IpAddress[i].Name == Config.MachineName {
|
||||||
|
table.IpAddress[i].CustomInformation = text
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found {
|
||||||
|
table.WriteIpTable()
|
||||||
|
// update IPTable after modified entry
|
||||||
|
go UpdateIpTableListClient()
|
||||||
|
} else {
|
||||||
|
return errors.New("start server with p2prc -s as the server is currently not running")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
264
client/clientIPTable/Iptable.go
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
package clientIPTable
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"mime/multipart"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var mu sync.Mutex
|
||||||
|
|
||||||
|
// UpdateIpTable Does the following to update it's IP table
|
||||||
|
func UpdateIpTable(IpAddress string, serverPort string, wg *sync.WaitGroup) error {
|
||||||
|
|
||||||
|
config, err := config.ConfigInit(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := http.Client{}
|
||||||
|
|
||||||
|
var resp []byte
|
||||||
|
|
||||||
|
version := p2p.Ip4or6(IpAddress)
|
||||||
|
if version == "version 6" {
|
||||||
|
resp, err = UploadMultipartFile(client, "http://["+IpAddress+"]:"+serverPort+"/IpTable", "json", config.IPTable)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resp, err = UploadMultipartFile(client, "http://"+IpAddress+":"+serverPort+"/IpTable", "json", config.IPTable)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//resp, err := SendPostRequest("http://"+IpAddress+":8088/IpTable",
|
||||||
|
// config.IPTable,
|
||||||
|
// "json")
|
||||||
|
//
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
|
||||||
|
var ipStruct p2p.IpAddresses
|
||||||
|
json.Unmarshal(resp, &ipStruct)
|
||||||
|
|
||||||
|
// Updates IP table based on information provided
|
||||||
|
// by the server
|
||||||
|
if len(ipStruct.IpAddress) > 0 {
|
||||||
|
err = ipStruct.SpeedTestUpdatedIPTable()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not required to update IP table as speed test updates the IP Table
|
||||||
|
//err = ipStruct.WriteIpTable()
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
|
||||||
|
wg.Done()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateIpTableListClient updates IP tables (Default 3 hops) based on server information available
|
||||||
|
// on the ip tables
|
||||||
|
func UpdateIpTableListClient() error {
|
||||||
|
// Get config information
|
||||||
|
Config, err := config.ConfigInit(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that the IP Table has Node pingable
|
||||||
|
err = p2p.LocalSpeedTestIpTable()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IP addresses to not append to struct due to
|
||||||
|
// duplication
|
||||||
|
|
||||||
|
Addresses, err := p2p.ReadIpTable()
|
||||||
|
var DoNotRead p2p.IpAddresses
|
||||||
|
|
||||||
|
currentIPV4, err := p2p.CurrentPublicIP()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var w sync.WaitGroup
|
||||||
|
|
||||||
|
// Run loop 2 times
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
// Gets information from IP table
|
||||||
|
Addresses, err = p2p.ReadIpTable()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//DoNotRead.IpAddress = append(DoNotRead.IpAddress, PublicIP)
|
||||||
|
|
||||||
|
// Updates IP table based on server IP table
|
||||||
|
for j := range Addresses.IpAddress {
|
||||||
|
|
||||||
|
Exists := false
|
||||||
|
// If the address is local then add to the local list
|
||||||
|
if currentIPV4 == Addresses.IpAddress[j].Ipv4 && Addresses.IpAddress[j].ServerPort == Config.ServerPort {
|
||||||
|
Exists = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if IP addresses is there in the struct DoNotRead
|
||||||
|
for k := range DoNotRead.IpAddress {
|
||||||
|
if (DoNotRead.IpAddress[k].Ipv4 == Addresses.IpAddress[j].Ipv4 && DoNotRead.IpAddress[k].ServerPort == Addresses.IpAddress[j].ServerPort) || (DoNotRead.IpAddress[k].Ipv6 != "" && Addresses.IpAddress[j].Ipv6 == DoNotRead.IpAddress[k].Ipv6) {
|
||||||
|
Exists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the struct exists then continues
|
||||||
|
if Exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Add(1)
|
||||||
|
if Addresses.IpAddress[j].Ipv6 != "" {
|
||||||
|
go UpdateIpTable(Addresses.IpAddress[j].Ipv6, Addresses.IpAddress[j].ServerPort, &w)
|
||||||
|
} else if Addresses.IpAddress[j].Ipv4 != currentIPV4 {
|
||||||
|
go UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort, &w)
|
||||||
|
}
|
||||||
|
w.Wait()
|
||||||
|
|
||||||
|
//Appends server1 IP address to variable DoNotRead
|
||||||
|
DoNotRead.IpAddress = append(DoNotRead.IpAddress, Addresses.IpAddress[j])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveOfflineNodes() error {
|
||||||
|
// Ensure that the IP Table has Node pingable
|
||||||
|
err := p2p.LocalSpeedTestIpTable()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendPostRequest Sends a file as a
|
||||||
|
//POST request.
|
||||||
|
// Reference (https://stackoverflow.com/questions/51234464/upload-a-file-with-post-request-golang)
|
||||||
|
//func SendPostRequest (url string, filename string, filetype string) ([]byte,error) {
|
||||||
|
// file, err := os.Open(filename)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil,err
|
||||||
|
// }
|
||||||
|
// defer file.Close()
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// body := &bytes.Buffer{}
|
||||||
|
// writer := multipart.NewWriter(body)
|
||||||
|
// part, err := writer.CreateFormFile(filetype, filepath.Base(file.Name()))
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// return nil,err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// io.Copy(part, file)
|
||||||
|
// writer.Close()
|
||||||
|
// request, err := http.NewRequest("POST", url, body)
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// return nil,err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// request.Header.Add("Content-Type", writer.FormDataContentType())
|
||||||
|
// client := &http.Client{}
|
||||||
|
//
|
||||||
|
// response, err := client.Do(request)
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// return nil,err
|
||||||
|
// }
|
||||||
|
// defer response.Body.Close()
|
||||||
|
//
|
||||||
|
// content, err := ioutil.ReadAll(response.Body)
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// return nil,err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return content, nil
|
||||||
|
//}
|
||||||
|
|
||||||
|
func UploadMultipartFile(client http.Client, uri, key, path string) ([]byte, error) {
|
||||||
|
body, writer := io.Pipe()
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, uri, body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mwriter := multipart.NewWriter(writer)
|
||||||
|
req.Header.Add("Content-Type", mwriter.FormDataContentType())
|
||||||
|
|
||||||
|
errchan := make(chan error)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer close(errchan)
|
||||||
|
defer writer.Close()
|
||||||
|
defer mwriter.Close()
|
||||||
|
|
||||||
|
w, err := mwriter.CreateFormFile(key, path)
|
||||||
|
if err != nil {
|
||||||
|
errchan <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
in, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
errchan <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer in.Close()
|
||||||
|
|
||||||
|
if written, err := io.Copy(w, in); err != nil {
|
||||||
|
errchan <- fmt.Errorf("error copying %s (%d bytes written): %v", path, written, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mwriter.Close(); err != nil {
|
||||||
|
errchan <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := ioutil.ReadAll(resp.Body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return content, nil
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package client
|
package clientIPTable
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func TestUpdateIpTableListClient(t *testing.T) {
|
func TestUpdateIpTableListClient(t *testing.T) {
|
||||||
err := UpdateIpTableListClient()
|
err := UpdateIpTableListClient()
|
||||||
@@ -1,36 +1,65 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
b64 "encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker"
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
var (
|
||||||
serverPort = "8088"
|
serverPort = "8088"
|
||||||
|
client = http.Client{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
var client = http.Client{}
|
|
||||||
|
|
||||||
// StartContainer Start container using REST api Implementation
|
// StartContainer Start container using REST api Implementation
|
||||||
// From the selected server IP address
|
// From the selected server IP address
|
||||||
// TODO: Test cases for this function
|
// TODO: Test cases for this function
|
||||||
func StartContainer(IP string, NumPorts int, GPU bool) (*docker.DockerVM ,error) {
|
// 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
|
// Passes URL with number of TCP ports to allocated and to give GPU access to the docker container
|
||||||
URL := "http://" + IP + ":" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU)
|
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 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get public key
|
||||||
|
PublicKey, err := Config.GetPublicKey()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used in URL to pass public key -> b64.StdEncoding.EncodeToString([]byte(PublicKey))
|
||||||
|
URL = `http://` + IP + `/startcontainer?ports=` + fmt.Sprint(NumPorts) + `&GPU=` + strconv.FormatBool(GPU) + `&ContainerName=` + ContainerName + `&BaseImage=` + baseImage + `&PublicKey=` + b64.StdEncoding.EncodeToString([]byte(PublicKey))
|
||||||
|
|
||||||
|
// Encode URL due to public key passed.
|
||||||
resp, err := http.Get(URL)
|
resp, err := http.Get(URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil,err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert response to byte value
|
// Convert response to byte value
|
||||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
byteValue, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil,err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create variable for result response type
|
// Create variable for result response type
|
||||||
@@ -39,15 +68,34 @@ func StartContainer(IP string, NumPorts int, GPU bool) (*docker.DockerVM ,error)
|
|||||||
// Adds byte value to docker.DockerVM struct
|
// Adds byte value to docker.DockerVM struct
|
||||||
json.Unmarshal(byteValue, &dockerResult)
|
json.Unmarshal(byteValue, &dockerResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil,err
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds the container to the tracked list
|
||||||
|
err = AddTrackContainer(&dockerResult, IP)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &dockerResult, nil
|
return &dockerResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveContianer Stops and removes container from the server
|
// RemoveContianer Stops and removes container from the server
|
||||||
func RemoveContianer(IP string,ID string) error {
|
func RemoveContianer(IP string, ID string) error {
|
||||||
URL := "http://" + IP + ":" + serverPort + "/RemoveContainer?id=" + ID
|
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)
|
resp, err := http.Get(URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -59,26 +107,100 @@ func RemoveContianer(IP string,ID string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if success is returned in the body
|
||||||
if string(byteValue[:]) == "success" {
|
if string(byteValue[:]) == "success" {
|
||||||
fmt.Println("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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintStartContainer Prints results Generated container
|
// ViewContainers This function displays all containers available on server side
|
||||||
func PrintStartContainer(d *docker.DockerVM){
|
func ViewContainers(IP string) (*docker.DockerContainers, error) {
|
||||||
fmt.Println("ID : " + fmt.Sprint(d.ID))
|
// Passes URL with route /ShowImages
|
||||||
fmt.Println("SSH port: " + fmt.Sprint(d.SSHPort))
|
var URL string
|
||||||
fmt.Println("SSH username: " + fmt.Sprint(d.SSHUsername))
|
//version := p2p.Ip4or6(IP)
|
||||||
fmt.Println("SSH password: " + fmt.Sprint(d.SSHPassword))
|
//
|
||||||
fmt.Println("VNC port: " + fmt.Sprint(d.VNCPort))
|
////Get port number of the server
|
||||||
fmt.Println("VNC password: " + fmt.Sprint(d.VNCPassword))
|
//serverPort, err := GetServerPort(IP)
|
||||||
fmt.Println("Ports Open (All TCP ports):")
|
//if err != nil {
|
||||||
for i := range d.Ports {
|
// return nil, err
|
||||||
fmt.Println(d.Ports[i])
|
//}
|
||||||
|
|
||||||
|
//if version == "version 6" {
|
||||||
|
// URL = "http://[" + IP + "]:" + serverPort + "/ShowImages"
|
||||||
|
//} else {
|
||||||
|
URL = "http://" + IP + "/ShowImages"
|
||||||
|
//}
|
||||||
|
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
|
||||||
|
//func PrintStartContainer(d *docker.DockerVM){
|
||||||
|
// fmt.Println("ID : " + fmt.Sprint(d.ID))
|
||||||
|
// fmt.Println("SSH port: " + fmt.Sprint(d.SSHPort))
|
||||||
|
// fmt.Println("SSH username: " + fmt.Sprint(d.SSHUsername))
|
||||||
|
// fmt.Println("SSH password: " + fmt.Sprint(d.SSHPassword))
|
||||||
|
// fmt.Println("VNC port: " + fmt.Sprint(d.VNCPort))
|
||||||
|
// fmt.Println("VNC password: " + fmt.Sprint(d.VNCPassword))
|
||||||
|
// fmt.Println("Ports Open (All TCP ports):")
|
||||||
|
// for i := range d.Ports {
|
||||||
|
// fmt.Println(d.Ports[i])
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
// TODO implementation using RPC calls
|
// TODO implementation using RPC calls
|
||||||
//func StartContainer(Ip string) (*docker.DockerVM,error){
|
//func StartContainer(Ip string) (*docker.DockerVM,error){
|
||||||
|
|||||||
1
client/grouptrackcontainers.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
1
client/trackcontainers.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
244
cmd/action.go
@@ -2,41 +2,109 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/client"
|
"github.com/Akilan1999/p2p-rendering-computation/client"
|
||||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
"github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
|
||||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p"
|
"github.com/Akilan1999/p2p-rendering-computation/config/generate"
|
||||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server"
|
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/plugin"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/server"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var CliAction = func(ctx *cli.Context) error {
|
var CliAction = func(ctx *cli.Context) error {
|
||||||
if Mode == "server" {
|
if Server {
|
||||||
// TODO: with RPC calls
|
_, err := server.Server()
|
||||||
server.Server()
|
if err != nil {
|
||||||
|
fmt.Print(err)
|
||||||
|
}
|
||||||
//server.Rpc()
|
//server.Rpc()
|
||||||
|
for {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Listing servers and also updates IP tables (Default 3 hops)
|
//Listing servers and also updates IP tables (Default 3 hops)
|
||||||
if UpdateServerList {
|
if UpdateServerList {
|
||||||
err := client.UpdateIpTableListClient()
|
err := clientIPTable.UpdateIpTableListClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Print(err)
|
fmt.Print(err)
|
||||||
}
|
}
|
||||||
|
// Reads from ip table and passes it
|
||||||
|
// on to struct print function
|
||||||
|
//Servers, err := p2p.ReadIpTable()
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
//client.PrettyPrint(Servers)
|
||||||
p2p.PrintIpTable()
|
p2p.PrintIpTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Displays the IP table
|
||||||
if ServerList {
|
if ServerList {
|
||||||
|
// Reads from ip table and passes it
|
||||||
|
// on to struct print function
|
||||||
|
//Servers, err := p2p.ReadIpTable()
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
p2p.PrintIpTable()
|
p2p.PrintIpTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add provided IP to the IP table
|
||||||
|
if AddServer != "" {
|
||||||
|
res, err := p2p.ReadIpTable()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create variable of type IpAddress and set IP address
|
||||||
|
// to it
|
||||||
|
var IpAddr p2p.IpAddress
|
||||||
|
|
||||||
|
//Checking if the address is a ipv4
|
||||||
|
// or ipv6 address
|
||||||
|
ip4Orip6 := p2p.Ip4or6(AddServer)
|
||||||
|
if ip4Orip6 == "version 6" {
|
||||||
|
IpAddr.Ipv6 = AddServer
|
||||||
|
} else {
|
||||||
|
IpAddr.Ipv4 = AddServer
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a server port is provided then set it
|
||||||
|
if Ports != "" {
|
||||||
|
IpAddr.ServerPort = Ports
|
||||||
|
} else {
|
||||||
|
IpAddr.ServerPort = "8088"
|
||||||
|
}
|
||||||
|
// Append IP address to variable result which
|
||||||
|
// is a list
|
||||||
|
res.IpAddress = append(res.IpAddress, IpAddr)
|
||||||
|
// Adds the new server IP to the iptable
|
||||||
|
res.WriteIpTable()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Displays all images available on the server side
|
||||||
|
if ViewImages != "" {
|
||||||
|
imageRes, err := client.ViewContainers(ViewImages)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(err)
|
||||||
|
}
|
||||||
|
client.PrettyPrint(imageRes)
|
||||||
|
}
|
||||||
|
|
||||||
// Function called to stop and remove server from Docker
|
// Function called to stop and remove server from Docker
|
||||||
if RemoveVM != "" && ID != "" {
|
if RemoveVM != "" {
|
||||||
err := client.RemoveContianer(RemoveVM,ID)
|
if ID == "" {
|
||||||
|
fmt.Println("provide container ID via --ID or --id")
|
||||||
|
} else {
|
||||||
|
err := client.RemoveContianer(RemoveVM, ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Print(err)
|
fmt.Print(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Call function to create Docker container
|
//Call function to create Docker container
|
||||||
if CreateVM != "" {
|
if CreateVM != "" {
|
||||||
@@ -48,7 +116,8 @@ var CliAction = func(ctx *cli.Context) error {
|
|||||||
fmt.Sscanf(Ports, "%d", &PortsInt)
|
fmt.Sscanf(Ports, "%d", &PortsInt)
|
||||||
}
|
}
|
||||||
|
|
||||||
imageRes, err := client.StartContainer(CreateVM,PortsInt,GPU)
|
// Calls function to do Api call to start the container on the server side
|
||||||
|
imageRes, err := client.StartContainer(CreateVM, PortsInt, GPU, ContainerName, BaseImage)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Print(err)
|
fmt.Print(err)
|
||||||
@@ -69,12 +138,161 @@ var CliAction = func(ctx *cli.Context) error {
|
|||||||
|
|
||||||
//Sets default paths to the config file
|
//Sets default paths to the config file
|
||||||
if SetDefaultConfig {
|
if SetDefaultConfig {
|
||||||
err := config.SetDefaults()
|
_, err := generate.SetDefaults("P2PRC", false, nil, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Print(err)
|
fmt.Print(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//If the network interface flag is called
|
||||||
|
// Then all the network interfaces are displayed
|
||||||
|
if NetworkInterface {
|
||||||
|
err := p2p.ViewNetworkInterface()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the view plugin flag is called then display all
|
||||||
|
// plugins available
|
||||||
|
if ViewPlugin {
|
||||||
|
plugins, err := plugin.DetectPlugins()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(err)
|
||||||
|
}
|
||||||
|
client.PrettyPrint(plugins)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the flag Tracked Container is called or the flag
|
||||||
|
// --tc
|
||||||
|
if TrackedContainers {
|
||||||
|
err, trackedContainers := client.ViewTrackedContainers()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(err)
|
||||||
|
}
|
||||||
|
client.PrettyPrint(trackedContainers)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Executing plugin when the plugin flag is called
|
||||||
|
// --plugin
|
||||||
|
if ExecutePlugin != "" {
|
||||||
|
// To execute plugin requires the container ID or group ID provided when being executed
|
||||||
|
if ID != "" {
|
||||||
|
err := plugin.CheckRunPlugin(ExecutePlugin, ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("Success")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("provide container ID via --ID or --id")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executing function to create new group
|
||||||
|
// Creates new group and outputs JSON file
|
||||||
|
if CreateGroup {
|
||||||
|
group, err := client.CreateGroup()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
client.PrettyPrint(group)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actions to be performed when the
|
||||||
|
// group flag is called
|
||||||
|
// --group <Group ID>
|
||||||
|
if Group != "" {
|
||||||
|
// Remove container from group based on group ID provided
|
||||||
|
// --rmcgroup --id <contianer id>
|
||||||
|
if RemoveContainerGroup && ID != "" {
|
||||||
|
group, err := client.RemoveContainerGroup(ID, Group)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
client.PrettyPrint(group)
|
||||||
|
}
|
||||||
|
} else if ID != "" { // Add container to group based on group ID provided
|
||||||
|
// --id <Container ID>
|
||||||
|
group, err := client.AddContainerToGroup(ID, Group)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
client.PrettyPrint(group)
|
||||||
|
}
|
||||||
|
} else { // View all information about current group
|
||||||
|
group, err := client.GetGroup(Group)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
client.PrettyPrint(group)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute function to remove entire group
|
||||||
|
// when remove group flag is called
|
||||||
|
// --rmgroup
|
||||||
|
if RemoveGroup != "" {
|
||||||
|
err := client.RemoveGroup(RemoveGroup)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("Group Removed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute Function to view all groups
|
||||||
|
if Groups {
|
||||||
|
groups, err := client.ReadGroup()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
client.PrettyPrint(groups)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
if PullPlugin != "" {
|
||||||
|
err := plugin.DownloadPlugin(PullPlugin)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("Success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if RemovePlugin != "" {
|
||||||
|
err := plugin.DeletePlugin(RemovePlugin)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("Success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if AddMetaData != "" {
|
||||||
|
err := clientIPTable.AddCustomInformationToIPTable(AddMetaData)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("Success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if MAPPort != "" {
|
||||||
|
address, err := client.MAPPort(MAPPort, DomainName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
client.PrettyPrint(address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
202
cmd/flags.go
@@ -6,9 +6,13 @@ import (
|
|||||||
|
|
||||||
// Variables declared for CLI
|
// Variables declared for CLI
|
||||||
var (
|
var (
|
||||||
|
AddServer string
|
||||||
|
ViewImages string
|
||||||
CreateVM string
|
CreateVM string
|
||||||
|
ContainerName string
|
||||||
|
BaseImage string
|
||||||
Ports string
|
Ports string
|
||||||
Mode string
|
Server bool
|
||||||
RemoveVM string
|
RemoveVM string
|
||||||
ID string
|
ID string
|
||||||
Specs string
|
Specs string
|
||||||
@@ -16,69 +20,249 @@ var (
|
|||||||
UpdateServerList bool
|
UpdateServerList bool
|
||||||
ServerList bool
|
ServerList bool
|
||||||
SetDefaultConfig bool
|
SetDefaultConfig bool
|
||||||
|
NetworkInterface bool
|
||||||
|
ViewPlugin bool
|
||||||
|
TrackedContainers bool
|
||||||
|
ExecutePlugin string
|
||||||
|
CreateGroup bool
|
||||||
|
Group string
|
||||||
|
Groups bool
|
||||||
|
RemoveContainerGroup bool
|
||||||
|
RemoveGroup string
|
||||||
|
MAPPort string
|
||||||
|
DomainName string
|
||||||
|
//FRPProxy bool
|
||||||
|
// Generate only allowed in dev release
|
||||||
|
// -- REMOVE ON REGULAR RELEASE --
|
||||||
|
Generate string
|
||||||
|
Modulename string
|
||||||
|
//--------------------------------
|
||||||
|
PullPlugin string
|
||||||
|
RemovePlugin string
|
||||||
|
AddMetaData string
|
||||||
)
|
)
|
||||||
|
|
||||||
var AppConfigFlags = []cli.Flag{
|
var AppConfigFlags = []cli.Flag{
|
||||||
// Deprecated to be implemented using GRPC
|
// Deprecated to be implemented using GRPC
|
||||||
&cli.StringFlag{
|
&cli.BoolFlag{
|
||||||
Name: "Mode",
|
Name: "Server",
|
||||||
Value: "client",
|
Aliases: []string{"s"},
|
||||||
Usage: "Specifies mode of running",
|
Usage: "Starts server",
|
||||||
EnvVars: []string{"P2P_MODE"},
|
EnvVars: []string{"SERVER"},
|
||||||
Destination: &Mode,
|
Destination: &Server,
|
||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "UpdateServerList",
|
Name: "UpdateServerList",
|
||||||
|
Aliases: []string{"us"},
|
||||||
Usage: "Update List of Server available based on servers iptables",
|
Usage: "Update List of Server available based on servers iptables",
|
||||||
EnvVars: []string{"UPDATE_SERVER_LIST"},
|
EnvVars: []string{"UPDATE_SERVER_LIST"},
|
||||||
Destination: &UpdateServerList,
|
Destination: &UpdateServerList,
|
||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "ListServers",
|
Name: "ListServers",
|
||||||
|
Aliases: []string{"ls"},
|
||||||
Usage: "List servers which can render tasks",
|
Usage: "List servers which can render tasks",
|
||||||
EnvVars: []string{"LIST_SERVERS"},
|
EnvVars: []string{"LIST_SERVERS"},
|
||||||
Destination: &ServerList,
|
Destination: &ServerList,
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "AddServer",
|
||||||
|
Aliases: []string{"as"},
|
||||||
|
Usage: "Adds server IP address to iptables",
|
||||||
|
EnvVars: []string{"ADD_SERVER"},
|
||||||
|
Destination: &AddServer,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "ViewImages",
|
||||||
|
Aliases: []string{"vi"},
|
||||||
|
Usage: "View images available on the server IP address",
|
||||||
|
EnvVars: []string{"VIEW_IMAGES"},
|
||||||
|
Destination: &ViewImages,
|
||||||
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "CreateVM",
|
Name: "CreateVM",
|
||||||
|
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{
|
||||||
|
Name: "ContainerName",
|
||||||
|
Aliases: []string{"cn"},
|
||||||
|
Usage: "Specifying the container run on the server side",
|
||||||
|
EnvVars: []string{"CONTAINER_NAME"},
|
||||||
|
Destination: &ContainerName,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "BaseImage",
|
||||||
|
Aliases: []string{"bi"},
|
||||||
|
Usage: "Specifying the docker base image to template the dockerfile",
|
||||||
|
EnvVars: []string{"CONTAINER_NAME"},
|
||||||
|
Destination: &BaseImage,
|
||||||
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "RemoveVM",
|
Name: "RemoveVM",
|
||||||
Usage: "Stop and Remove Docker container",
|
Aliases: []string{"rm"},
|
||||||
|
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"},
|
||||||
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"},
|
||||||
Usage: "Number of ports to open for the Docker Container",
|
Usage: "Number of ports to open for the Docker Container",
|
||||||
EnvVars: []string{"NUM_PORTS"},
|
EnvVars: []string{"NUM_PORTS"},
|
||||||
Destination: &Ports,
|
Destination: &Ports,
|
||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "GPU",
|
Name: "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: "Specs",
|
Name: "Specification",
|
||||||
|
Aliases: []string{"specs"},
|
||||||
Usage: "Specs of the server node",
|
Usage: "Specs of the server node",
|
||||||
EnvVars: []string{"SPECS"},
|
EnvVars: []string{"SPECS"},
|
||||||
Destination: &Specs,
|
Destination: &Specs,
|
||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "SetDefaultConfig",
|
Name: "SetDefaultConfig",
|
||||||
|
Aliases: []string{"dc"},
|
||||||
Usage: "Sets a default configuration file",
|
Usage: "Sets a default configuration file",
|
||||||
EnvVars: []string{"SET_DEFAULT_CONFIG"},
|
EnvVars: []string{"SET_DEFAULT_CONFIG"},
|
||||||
Destination: &SetDefaultConfig,
|
Destination: &SetDefaultConfig,
|
||||||
},
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "NetworkInterfaces",
|
||||||
|
Aliases: []string{"ni"},
|
||||||
|
Usage: "Shows the network interface in your computer",
|
||||||
|
EnvVars: []string{"NETWORK_INTERFACE"},
|
||||||
|
Destination: &NetworkInterface,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "ViewPlugins",
|
||||||
|
Aliases: []string{"vp"},
|
||||||
|
Usage: "Shows plugins available to be executed",
|
||||||
|
EnvVars: []string{"VIEW_PLUGIN"},
|
||||||
|
Destination: &ViewPlugin,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "TrackedContainers",
|
||||||
|
Aliases: []string{"tc"},
|
||||||
|
Usage: "View (currently running) containers which have " +
|
||||||
|
"been created from the client side ",
|
||||||
|
EnvVars: []string{"TRACKED_CONTAINERS"},
|
||||||
|
Destination: &TrackedContainers,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "ExecutePlugin",
|
||||||
|
Aliases: []string{"plugin"},
|
||||||
|
Usage: "Plugin which needs to be executed",
|
||||||
|
EnvVars: []string{"EXECUTE_PLUGIN"},
|
||||||
|
Destination: &ExecutePlugin,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "CreateGroup",
|
||||||
|
Aliases: []string{"cgroup"},
|
||||||
|
Usage: "Creates a new group",
|
||||||
|
EnvVars: []string{"CREATE_GROUP"},
|
||||||
|
Destination: &CreateGroup,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "Group",
|
||||||
|
Aliases: []string{"group"},
|
||||||
|
Usage: "group flag with argument group ID",
|
||||||
|
EnvVars: []string{"GROUP"},
|
||||||
|
Destination: &Group,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "Groups",
|
||||||
|
Aliases: []string{"groups"},
|
||||||
|
Usage: "View all groups",
|
||||||
|
EnvVars: []string{"GROUPS"},
|
||||||
|
Destination: &Groups,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "RemoveContainerGroup",
|
||||||
|
Aliases: []string{"rmcgroup"},
|
||||||
|
Usage: "Remove specific container in the group",
|
||||||
|
EnvVars: []string{"REMOVE_CONTAINER_GROUP"},
|
||||||
|
Destination: &RemoveContainerGroup,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "RemoveGroup",
|
||||||
|
Aliases: []string{"rmgroup"},
|
||||||
|
Usage: "Removes the entire group",
|
||||||
|
EnvVars: []string{"REMOVE_GROUP"},
|
||||||
|
Destination: &RemoveGroup,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "MAPPort",
|
||||||
|
Aliases: []string{"mp"},
|
||||||
|
Usage: "Maps port for a specific port provided as the parameter",
|
||||||
|
EnvVars: []string{"MAPPORT"},
|
||||||
|
Destination: &MAPPort,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "DomainName",
|
||||||
|
Aliases: []string{"dn"},
|
||||||
|
Usage: "While mapping ports allows to set a domain name to create a mapping in the proxy server",
|
||||||
|
EnvVars: []string{"DOMAINNAME"},
|
||||||
|
Destination: &DomainName,
|
||||||
|
},
|
||||||
|
// Generate only allowed in dev release
|
||||||
|
// -- REMOVE ON REGULAR RELEASE --
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "Generate",
|
||||||
|
Aliases: []string{"gen"},
|
||||||
|
Usage: "Generates a new copy of P2PRC which can be modified based on your needs",
|
||||||
|
EnvVars: []string{"GENERATE"},
|
||||||
|
Destination: &Generate,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "ModuleName",
|
||||||
|
Aliases: []string{"mod"},
|
||||||
|
Usage: "New go project module name",
|
||||||
|
EnvVars: []string{"MODULENAME"},
|
||||||
|
Destination: &Modulename,
|
||||||
|
},
|
||||||
|
//&cli.BoolFlag{
|
||||||
|
// Name: "FRPServerProxy",
|
||||||
|
// Aliases: []string{"proxy"},
|
||||||
|
// Usage: "Starts proxy for server",
|
||||||
|
// EnvVars: []string{"FRPSERVERPROXY"},
|
||||||
|
// Destination: &FRPProxy,
|
||||||
|
//},
|
||||||
|
//--------------------------------
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "PullPlugin",
|
||||||
|
Aliases: []string{"pp"},
|
||||||
|
Usage: "Pulls plugin from git repos",
|
||||||
|
EnvVars: []string{"PULLPLUGIN"},
|
||||||
|
Destination: &PullPlugin,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "RemovePlugin",
|
||||||
|
Aliases: []string{"rp"},
|
||||||
|
Usage: "Removes plugin",
|
||||||
|
EnvVars: []string{"REMOVEPLUGIN"},
|
||||||
|
Destination: &RemovePlugin,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "AddMetaData",
|
||||||
|
Aliases: []string{"amd"},
|
||||||
|
Usage: "Adds metadata about the current node in the p2p network which is then propagated through the network",
|
||||||
|
EnvVars: []string{"ADDMETADATA"},
|
||||||
|
Destination: &AddMetaData,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
234
config/config.go
@@ -1,105 +1,185 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/viper"
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
defaultPath string
|
//defaultPath string
|
||||||
defaults = map[string]interface{}{
|
defaults = map[string]interface{}{}
|
||||||
"IPTable": "/etc/p2p-rendering/ip_table.json",
|
|
||||||
"DockerFile": "/home/akilan/Documents/p2prendering/p2p-redering-computation/server/docker/containers/docker-ubuntu-sshd/",
|
|
||||||
"SpeedTestFile":"/etc/p2p-rendering/50.bin",
|
|
||||||
}
|
|
||||||
configName = "config"
|
configName = "config"
|
||||||
configType = "json"
|
configType = "json"
|
||||||
configFile = "config.json"
|
configFile = "config.json"
|
||||||
configPaths []string
|
configPaths []string
|
||||||
|
defaultEnvName = "P2PRC"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
MachineName string
|
||||||
IPTable string
|
IPTable string
|
||||||
DockerFile string
|
DockerContainers string
|
||||||
|
DefaultDockerFile string
|
||||||
|
DockerRunLogs string
|
||||||
SpeedTestFile string
|
SpeedTestFile string
|
||||||
|
IPV6Address string
|
||||||
|
PluginPath string
|
||||||
|
TrackContainersPath string
|
||||||
|
ServerPort string
|
||||||
|
ProxyPort string
|
||||||
|
GroupTrackContainersPath string
|
||||||
|
FRPServerPort string
|
||||||
|
BehindNAT string
|
||||||
|
IPTableKey string
|
||||||
|
PublicKeyFile string
|
||||||
|
PrivateKeyFile string
|
||||||
|
PemFile string
|
||||||
|
KeyFile string
|
||||||
|
BareMetal bool
|
||||||
|
UnsafeMode bool
|
||||||
|
CustomConfig interface{}
|
||||||
|
//NetworkInterface string
|
||||||
|
//NetworkInterfaceIPV6Index int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exists reports whether the named file or directory exists.
|
// GetCurrentPath Getting P2PRC Directory from environment variable
|
||||||
func fileExists(name string) bool {
|
func GetCurrentPath() (string, error) {
|
||||||
if _, err := os.Stat(name); err != nil {
|
curDir := os.Getenv("PWD")
|
||||||
if os.IsNotExist(err) {
|
return curDir + "/", nil
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDefaults This function to be called only during a
|
// GetPathP2PRC Getting P2PRC Directory from environment variable
|
||||||
// make install
|
func GetPathP2PRC(Envname string) (string, error) {
|
||||||
func SetDefaults() error {
|
if Envname != "" {
|
||||||
//Getting Current Directory from environment variable
|
err := SetEnvName(Envname)
|
||||||
curDir := os.Getenv("P2PRC")
|
|
||||||
|
|
||||||
//Setting current directory to default path
|
|
||||||
defaultPath = curDir + "/"
|
|
||||||
|
|
||||||
//Setting default paths for the config file
|
|
||||||
defaults["IPTable"] = defaultPath + "p2p/ip_table.json"
|
|
||||||
defaults["DockerFile"] = defaultPath + "server/docker/containers/docker-ubuntu-sshd/"
|
|
||||||
defaults["SpeedTestFile"] = defaultPath + "p2p/50.bin"
|
|
||||||
|
|
||||||
//Paths to search for config file
|
|
||||||
configPaths = append(configPaths, defaultPath)
|
|
||||||
|
|
||||||
if fileExists(defaultPath + "config.json") {
|
|
||||||
err := os.Remove(defaultPath + "config.json")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
curDir := os.Getenv(defaultEnvName)
|
||||||
|
if curDir == "" {
|
||||||
|
// if the OS env path is not found then you use
|
||||||
|
// the current directory path.
|
||||||
|
currentPath, _ := GetCurrentPath()
|
||||||
|
return currentPath, nil
|
||||||
|
}
|
||||||
|
return curDir + "/", nil
|
||||||
|
}
|
||||||
|
|
||||||
//Calling configuration file
|
// SetEnvName Sets the environment name
|
||||||
_, err := ConfigInit()
|
// This is to ensure that the Path of your project is detected from
|
||||||
if err != nil {
|
// your environment variable
|
||||||
return err
|
// This is useful when extending the use case of P2PRC
|
||||||
}
|
func SetEnvName(EnvName string) error {
|
||||||
|
defaultEnvName = EnvName
|
||||||
|
// Handling error to be implemented only if needed
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConfigInit()(*Config,error) {
|
func GetEnvName() string {
|
||||||
|
return defaultEnvName
|
||||||
curDir := os.Getenv("P2PRC")
|
}
|
||||||
//Setting current directory to default path
|
|
||||||
defaultPath = curDir + "/"
|
// ConfigInit Pass environment name as an optional parameter
|
||||||
//Paths to search for config file
|
func ConfigInit(defaultsParameter map[string]interface{}, CustomConfig interface{}, envNameOptional ...string) (*Config, error) {
|
||||||
configPaths = append(configPaths, defaultPath)
|
if len(envNameOptional) > 0 {
|
||||||
|
defaultEnvName = envNameOptional[0]
|
||||||
//Add all possible configurations paths
|
}
|
||||||
for _,v := range configPaths {
|
//
|
||||||
viper.AddConfigPath(v)
|
////Setting current directory to default path
|
||||||
}
|
//defaultPath, err := GetPathP2PRC(defaultEnvName)
|
||||||
|
//if err != nil {
|
||||||
//Read config file
|
// return nil, err
|
||||||
if err := viper.ReadInConfig(); err != nil {
|
//}
|
||||||
// If the error thrown is config file not found
|
////Paths to search for config file
|
||||||
//Sets default configuration to viper
|
//configPaths = append(configPaths, defaultPath)
|
||||||
for k,v := range defaults {
|
//
|
||||||
viper.SetDefault(k,v)
|
////Add all possible configurations paths
|
||||||
}
|
//for _, v := range configPaths {
|
||||||
viper.SetConfigName(configName)
|
// viper.AddConfigPath(v)
|
||||||
viper.SetConfigFile(configFile)
|
//}
|
||||||
viper.SetConfigType(configType)
|
//
|
||||||
|
////Read config file
|
||||||
if err = viper.WriteConfig(); err != nil {
|
//if err := viper.ReadInConfig(); err != nil {
|
||||||
return nil,err
|
// // If the error thrown is config file not found
|
||||||
}
|
// //Sets default configuration to viper
|
||||||
}
|
// for k, v := range defaults {
|
||||||
|
// viper.SetDefault(k, v)
|
||||||
// Adds configuration to the struct
|
// }
|
||||||
var config Config
|
// viper.SetConfigName(configName)
|
||||||
if err := viper.Unmarshal(&config); err != nil {
|
// viper.SetConfigFile(configFile)
|
||||||
return nil,err
|
// viper.SetConfigType(configType)
|
||||||
}
|
//
|
||||||
|
// if err = viper.WriteConfig(); err != nil {
|
||||||
return &config,nil
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// Adds configuration to the struct
|
||||||
|
//var config Config
|
||||||
|
//if err := viper.Unmarshal(&config); err != nil {
|
||||||
|
// return nil, err
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//return &config, nil
|
||||||
|
|
||||||
|
defaultPath, err := GetPathP2PRC(defaultEnvName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open our jsonFile
|
||||||
|
jsonFile, err := os.Open(defaultPath + configFile)
|
||||||
|
// if we os.Open returns an error then handle it
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// defer the closing of our jsonFile so that we can parse it later on
|
||||||
|
defer jsonFile.Close()
|
||||||
|
|
||||||
|
byteValue, _ := ioutil.ReadAll(jsonFile)
|
||||||
|
|
||||||
|
var config Config
|
||||||
|
json.Unmarshal(byteValue, &config)
|
||||||
|
|
||||||
|
if CustomConfig != nil {
|
||||||
|
// Convert Custom Config to byte
|
||||||
|
customConfigByte, err := json.Marshal(config.CustomConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Again map the byte to the CustomConfig interface
|
||||||
|
json.Unmarshal(customConfigByte, &CustomConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) WriteConfig() error {
|
||||||
|
//Getting Current Directory from environment variable
|
||||||
|
//curDir := os.Getenv("REMOTEGAMING")
|
||||||
|
|
||||||
|
defaultPath, err := GetPathP2PRC(defaultEnvName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
file, _ := json.MarshalIndent(c, "", " ")
|
||||||
|
|
||||||
|
_ = ioutil.WriteFile(defaultPath+"config.json", file, 0644)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPublicKey Gets public key of the current machine
|
||||||
|
// based on the path provided on the
|
||||||
|
// config file
|
||||||
|
func (c *Config) GetPublicKey() (string, error) {
|
||||||
|
publicKey, err := ioutil.ReadFile(c.PublicKeyFile) // just pass the file name
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(publicKey), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestConfigInit(t *testing.T) {
|
|
||||||
_,err := ConfigInit()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetDefaults(t *testing.T) {
|
|
||||||
err := SetDefaults()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
64
config/generate/config_test.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// func TestConfigInit(t *testing.T) {
|
||||||
|
// _, err := config.ConfigInit(nil)
|
||||||
|
// if err != nil {
|
||||||
|
// t.Error(err)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func TestSetDefaults(t *testing.T) {
|
||||||
|
// _, err := SetDefaults("", false)
|
||||||
|
// if err != nil {
|
||||||
|
// t.Error(err)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
func TestGetCurrentPath(t *testing.T) {
|
||||||
|
path, err := GetCurrentPath()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
fmt.Println(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetPathP2PRC(t *testing.T) {
|
||||||
|
path, err := config.GetPathP2PRC("")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
fmt.Println(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetEnvName(t *testing.T) {
|
||||||
|
// Create an Env variable TEST with the value "lol"
|
||||||
|
err := os.Setenv("TEST", "lol")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
// Sets the environment variable as the default to read
|
||||||
|
// for P2PRC
|
||||||
|
err = config.SetEnvName("TEST")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the output for the default read is "lol"
|
||||||
|
path, err := config.GetPathP2PRC("")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
fmt.Println(path)
|
||||||
|
}
|
||||||
178
config/generate/generate.go
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
package generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
defaults = map[string]interface{}{}
|
||||||
|
configPaths []string
|
||||||
|
defaultEnvName = "P2PRC"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetPathP2PRC Getting P2PRC Directory from environment variable
|
||||||
|
func GetPathP2PRC() (string, error) {
|
||||||
|
curDir := os.Getenv(defaultEnvName)
|
||||||
|
return curDir + "/", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetEnvName Sets the environment name
|
||||||
|
// This is to ensure that the Path of your project is detected from
|
||||||
|
// your environment variable
|
||||||
|
// This is useful when extending the use case of P2PRC
|
||||||
|
func SetEnvName(EnvName string) error {
|
||||||
|
if EnvName != "" {
|
||||||
|
defaultEnvName = EnvName
|
||||||
|
}
|
||||||
|
// Handling error to be implemented only if needed
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDefaults This function to be called only during a
|
||||||
|
// make install
|
||||||
|
func SetDefaults(envName string, forceDefault bool, CustomConfig interface{}, NoBoilerPlate bool, ConfigUpdate ...*config.Config) (*config.Config, error) {
|
||||||
|
//Setting current directory to default path
|
||||||
|
defaultPath, err := config.GetCurrentPath()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set Env name
|
||||||
|
err = config.SetEnvName(envName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
////Creates ip_table.json in the json directory
|
||||||
|
//err = Copy("p2p/ip_table.json", "p2p/iptable/ip_table.json")
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
////Creates a copy of trackcontainers.json in the appropriate directory
|
||||||
|
//err = Copy("client/trackcontainers.json", "client/trackcontainers/trackcontainers.json")
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
////Creates a copy of trackcontainers.json in the appropriate directory
|
||||||
|
//err = Copy("client/grouptrackcontainers.json", "client/trackcontainers/grouptrackcontainers.json")
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
|
||||||
|
var Defaults config.Config
|
||||||
|
|
||||||
|
if len(ConfigUpdate) == 0 {
|
||||||
|
//Setting default paths for the config file
|
||||||
|
Defaults.IPTable = defaultPath + "p2p/iptable/ip_table.json"
|
||||||
|
Defaults.DefaultDockerFile = defaultPath + "server/docker/containers/docker-ubuntu-sshd/"
|
||||||
|
Defaults.DockerContainers = defaultPath + "server/docker/containers/"
|
||||||
|
Defaults.SpeedTestFile = defaultPath + "p2p/50.bin"
|
||||||
|
Defaults.IPV6Address = ""
|
||||||
|
Defaults.PluginPath = defaultPath + "plugin/deploy"
|
||||||
|
Defaults.TrackContainersPath = defaultPath + "client/trackcontainers/trackcontainers.json"
|
||||||
|
Defaults.GroupTrackContainersPath = defaultPath + "client/trackcontainers/grouptrackcontainers.json"
|
||||||
|
Defaults.ServerPort = "8088"
|
||||||
|
Defaults.ProxyPort = ""
|
||||||
|
Defaults.FRPServerPort = "True"
|
||||||
|
Defaults.CustomConfig = CustomConfig
|
||||||
|
Defaults.BehindNAT = "True"
|
||||||
|
Defaults.DockerRunLogs = "/tmp/"
|
||||||
|
// Generate a random key to be added to IPTable
|
||||||
|
Defaults.IPTableKey = String(12)
|
||||||
|
// Random name generator
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate Public and private keys and set path
|
||||||
|
Defaults.PublicKeyFile = defaultPath + "p2prc.publicKey"
|
||||||
|
Defaults.PrivateKeyFile = defaultPath + "p2prc.privateKey"
|
||||||
|
Defaults.BareMetal = false
|
||||||
|
Defaults.UnsafeMode = false
|
||||||
|
|
||||||
|
// Generate certificate files for SSL
|
||||||
|
err = GenerateCertificate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
Defaults.PemFile = defaultPath + "cert.pem"
|
||||||
|
Defaults.KeyFile = defaultPath + "key.pem"
|
||||||
|
|
||||||
|
PrivateKeyExists, err := FileExists(Defaults.PrivateKeyFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !PrivateKeyExists {
|
||||||
|
// Generate SSH keys
|
||||||
|
err = MakeSSHKeyPair(Defaults.PublicKeyFile, Defaults.PrivateKeyFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Defaults.MachineName = hostname + "-" + String(7)
|
||||||
|
} else {
|
||||||
|
Defaults = *ConfigUpdate[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
//defaults["NetworkInterface"] = "wlp0s20f3"
|
||||||
|
//defaults["NetworkInterfaceIPV6Index"] = "2"
|
||||||
|
|
||||||
|
//Paths to search for config file
|
||||||
|
configPaths = append(configPaths, defaultPath)
|
||||||
|
|
||||||
|
if fileExists(defaultPath+"config.json") && forceDefault {
|
||||||
|
err := os.Remove(defaultPath + "config.json")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write defaults to the config file
|
||||||
|
err = Defaults.WriteConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Calling configuration file
|
||||||
|
Config, err := config.ConfigInit(defaults, nil, envName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !NoBoilerPlate {
|
||||||
|
err = GenerateFiles()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generating a random string
|
||||||
|
const charset = "abcdefghijklmnopqrstuvwxyz" +
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
|
||||||
|
var seededRand *rand.Rand = rand.New(
|
||||||
|
rand.NewSource(time.Now().UnixNano()))
|
||||||
|
|
||||||
|
func StringWithCharset(length int, charset string) string {
|
||||||
|
b := make([]byte, length)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = charset[seededRand.Intn(len(charset))]
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func String(length int) string {
|
||||||
|
return StringWithCharset(length, charset)
|
||||||
|
}
|
||||||
177
config/generate/generateCertificate.go
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.x
|
||||||
|
|
||||||
|
// Generate a self-signed X.509 certificate for a TLS server. Outputs to
|
||||||
|
// 'cert.pem' and 'key.pem' and will overwrite existing files.
|
||||||
|
|
||||||
|
package generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"encoding/pem"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||||
|
"log"
|
||||||
|
"math/big"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
host = ""
|
||||||
|
validFrom = ""
|
||||||
|
validFor = 365 * 24 * time.Hour
|
||||||
|
isCA = false
|
||||||
|
rsaBits = 2048
|
||||||
|
ecdsaCurve = ""
|
||||||
|
ed25519Key = false
|
||||||
|
)
|
||||||
|
|
||||||
|
func publicKey(priv any) any {
|
||||||
|
switch k := priv.(type) {
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
return &k.PublicKey
|
||||||
|
case *ecdsa.PrivateKey:
|
||||||
|
return &k.PublicKey
|
||||||
|
case ed25519.PrivateKey:
|
||||||
|
return k.Public().(ed25519.PublicKey)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateCertificate() error {
|
||||||
|
var priv any
|
||||||
|
var err error
|
||||||
|
|
||||||
|
//flag.Parse()
|
||||||
|
|
||||||
|
host, err = p2p.CurrentPublicIP()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(host) == 0 {
|
||||||
|
log.Fatalf("Missing required --host parameter")
|
||||||
|
}
|
||||||
|
switch ecdsaCurve {
|
||||||
|
case "":
|
||||||
|
if ed25519Key {
|
||||||
|
_, priv, err = ed25519.GenerateKey(rand.Reader)
|
||||||
|
} else {
|
||||||
|
priv, err = rsa.GenerateKey(rand.Reader, rsaBits)
|
||||||
|
}
|
||||||
|
case "P224":
|
||||||
|
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
||||||
|
case "P256":
|
||||||
|
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
|
case "P384":
|
||||||
|
priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||||
|
case "P521":
|
||||||
|
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||||
|
default:
|
||||||
|
log.Fatalf("Unrecognized elliptic curve: %q", ecdsaCurve)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to generate private key: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ECDSA, ED25519 and RSA subject keys should have the DigitalSignature
|
||||||
|
// KeyUsage bits set in the x509.Certificate template
|
||||||
|
keyUsage := x509.KeyUsageDigitalSignature
|
||||||
|
// Only RSA subject keys should have the KeyEncipherment KeyUsage bits set. In
|
||||||
|
// the context of TLS this KeyUsage is particular to RSA key exchange and
|
||||||
|
// authentication.
|
||||||
|
if _, isRSA := priv.(*rsa.PrivateKey); isRSA {
|
||||||
|
keyUsage |= x509.KeyUsageKeyEncipherment
|
||||||
|
}
|
||||||
|
|
||||||
|
var notBefore time.Time
|
||||||
|
if len(validFrom) == 0 {
|
||||||
|
notBefore = time.Now()
|
||||||
|
} else {
|
||||||
|
notBefore, err = time.Parse("Jan 2 15:04:05 2006", validFrom)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to parse creation date: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notAfter := notBefore.Add(validFor)
|
||||||
|
|
||||||
|
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||||
|
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to generate serial number: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
template := x509.Certificate{
|
||||||
|
SerialNumber: serialNumber,
|
||||||
|
Subject: pkix.Name{
|
||||||
|
Organization: []string{"Acme Co"},
|
||||||
|
},
|
||||||
|
NotBefore: notBefore,
|
||||||
|
NotAfter: notAfter,
|
||||||
|
|
||||||
|
KeyUsage: keyUsage,
|
||||||
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
hosts := strings.Split(host, ",")
|
||||||
|
for _, h := range hosts {
|
||||||
|
if ip := net.ParseIP(h); ip != nil {
|
||||||
|
template.IPAddresses = append(template.IPAddresses, ip)
|
||||||
|
} else {
|
||||||
|
template.DNSNames = append(template.DNSNames, h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isCA {
|
||||||
|
template.IsCA = true
|
||||||
|
template.KeyUsage |= x509.KeyUsageCertSign
|
||||||
|
}
|
||||||
|
|
||||||
|
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to create certificate: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
certOut, err := os.Create("cert.pem")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to open cert.pem for writing: %v", err)
|
||||||
|
}
|
||||||
|
if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
|
||||||
|
log.Fatalf("Failed to write data to cert.pem: %v", err)
|
||||||
|
}
|
||||||
|
if err := certOut.Close(); err != nil {
|
||||||
|
log.Fatalf("Error closing cert.pem: %v", err)
|
||||||
|
}
|
||||||
|
log.Print("wrote cert.pem\n")
|
||||||
|
|
||||||
|
keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to open key.pem for writing: %v", err)
|
||||||
|
}
|
||||||
|
privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to marshal private key: %v", err)
|
||||||
|
}
|
||||||
|
if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
|
||||||
|
log.Fatalf("Failed to write data to key.pem: %v", err)
|
||||||
|
}
|
||||||
|
if err := keyOut.Close(); err != nil {
|
||||||
|
log.Fatalf("Error closing key.pem: %v", err)
|
||||||
|
}
|
||||||
|
log.Print("wrote key.pem\n")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
291
config/generate/generateFiles.go
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
package generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||||
|
"github.com/go-git/go-git/v5"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GenerateFiles Generates all the files needed to setup P2PRC
|
||||||
|
func GenerateFiles(rootNodes ...p2p.IpAddress) (err error) {
|
||||||
|
err = GenerateIPTableFile(rootNodes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = GenerateDockerFiles()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = GeneratePluginDirectory()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = GenerateClientTrackContainers()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateIPTableFile Generates the IPTable file with the appropirate root node
|
||||||
|
func GenerateIPTableFile(rootNodes []p2p.IpAddress) (err error) {
|
||||||
|
var rootnodes p2p.IpAddresses
|
||||||
|
var rootnode p2p.IpAddress
|
||||||
|
|
||||||
|
err = CreateIPTableFolderStructure()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If root node addresses are not provided as optional parameters
|
||||||
|
if len(rootNodes) <= 0 {
|
||||||
|
rootnode.Name = "Node1"
|
||||||
|
rootnode.ServerPort = "8078"
|
||||||
|
rootnode.NAT = "False"
|
||||||
|
rootnode.Ipv4 = "217.76.63.222"
|
||||||
|
rootnode.ProxyServer = "True"
|
||||||
|
|
||||||
|
rootnodes.IpAddress = append(rootnodes.IpAddress, rootnode)
|
||||||
|
} else {
|
||||||
|
// if root nodes are provided then override them as the optional parameter
|
||||||
|
for i := range rootNodes {
|
||||||
|
rootnodes.IpAddress = append(rootnodes.IpAddress, rootNodes[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = rootnodes.WriteIpTable()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateIPTableFolderStructure Create folder structure for IPTable
|
||||||
|
func CreateIPTableFolderStructure() (err error) {
|
||||||
|
path, err := config.GetCurrentPath()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = os.Stat(path + "p2p"); os.IsNotExist(err) {
|
||||||
|
if err = os.Mkdir(path+"p2p", os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err = os.Stat(path + "p2p/iptable"); os.IsNotExist(err) {
|
||||||
|
if err = os.Mkdir(path+"p2p/iptable", os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err = os.Stat(path + "p2p/iptable/ip_table.json"); os.IsNotExist(err) {
|
||||||
|
_, err = os.Create(path + "p2p/iptable/ip_table.json")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateDockerFiles Generate default docker files
|
||||||
|
func GenerateDockerFiles() (err error) {
|
||||||
|
path, err := config.GetCurrentPath()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = os.Stat(path + "server"); os.IsNotExist(err) {
|
||||||
|
if err = os.Mkdir(path+"server", os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = os.Stat(path + "server/docker"); os.IsNotExist(err) {
|
||||||
|
if err = os.Mkdir(path+"server/docker", os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err = os.Stat(path + "server/docker/containers"); os.IsNotExist(err) {
|
||||||
|
if err = os.Mkdir(path+"server/docker/containers", os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err = os.Stat(path + "server/docker/containers"); os.IsNotExist(err) {
|
||||||
|
if err = os.Mkdir(path+"server/docker/containers", os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err = os.Stat(path + "server/docker/containers/docker-ubuntu-sshd"); os.IsNotExist(err) {
|
||||||
|
if err = os.Mkdir(path+"server/docker/containers/docker-ubuntu-sshd", os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone base docker image
|
||||||
|
_, err = git.PlainClone(path+"server/docker/containers/docker-ubuntu-sshd", false, &git.CloneOptions{
|
||||||
|
URL: "https://github.com/Akilan1999/docker-ubuntu-sshd",
|
||||||
|
Progress: os.Stdout,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GeneratePluginDirectory Generates plugin directory structure
|
||||||
|
func GeneratePluginDirectory() (err error) {
|
||||||
|
path, err := config.GetCurrentPath()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = os.Stat(path + "plugin"); os.IsNotExist(err) {
|
||||||
|
if err = os.Mkdir(path+"plugin", os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = os.Stat(path + "plugin/deploy"); os.IsNotExist(err) {
|
||||||
|
if err = os.Mkdir(path+"plugin/deploy", os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateClientTrackContainers() (err error) {
|
||||||
|
path, err := config.GetCurrentPath()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = os.Stat(path + "client"); os.IsNotExist(err) {
|
||||||
|
if err = os.Mkdir(path+"client", os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = os.Mkdir(path+"client/trackcontainers", os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = os.Stat(path + "client/trackcontainers/trackcontainers.json"); os.IsNotExist(err) {
|
||||||
|
_, err = os.Create(path + "client/trackcontainers/trackcontainers.json")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = os.Create(path + "client/trackcontainers/grouptrackcontainers.json")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeSSHKeyPair make a pair of public and private keys for SSH access.
|
||||||
|
// Public key is encoded in the format for inclusion in an OpenSSH authorized_keys file.
|
||||||
|
// Private Key generated is PEM encoded
|
||||||
|
// source: https://gist.github.com/goliatone/e9c13e5f046e34cef6e150d06f20a34c
|
||||||
|
func MakeSSHKeyPair(pubKeyPath, privateKeyPath string) error {
|
||||||
|
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// generate and write private key as PEM
|
||||||
|
privateKeyFile, err := os.Create(privateKeyPath)
|
||||||
|
defer privateKeyFile.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set permission to private key to SSH into docker machine
|
||||||
|
err = os.Chmod(privateKeyPath, 600)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}
|
||||||
|
if err := pem.Encode(privateKeyFile, privateKeyPEM); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// generate and write public key
|
||||||
|
pub, err := ssh.NewPublicKey(&privateKey.PublicKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return ioutil.WriteFile(pubKeyPath, ssh.MarshalAuthorizedKey(pub), 0655)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileExists exists returns whether the given file or directory exists
|
||||||
|
// source: https://stackoverflow.com/questions/10510691/how-to-check-whether-a-file-or-directory-exists
|
||||||
|
func FileExists(path string) (bool, error) {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
if err == nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthorizedKey struct represents the structure of an authorized key
|
||||||
|
type AuthorizedKey struct {
|
||||||
|
Username string
|
||||||
|
Key string
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddPublicKeyBareMetal Adds the parameter public key to the auth list
|
||||||
|
// Generated by ChatGPT
|
||||||
|
// Prompts:
|
||||||
|
// - Generate a go program to read authorised key and map it to a struct and write it back to the same location.
|
||||||
|
// - Can you follow the original format
|
||||||
|
// (TURNED OUT TO BE PRETTY SHITTY GENERATED CODE)
|
||||||
|
//func AddPublicKeyBareMetal(PublicKey string) error {
|
||||||
|
// // Specify the path to the authorized_keys file
|
||||||
|
// dirname, err := os.UserHomeDir()
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// authorizedKeysPath := dirname + "/.ssh/" + "authorized_keys"
|
||||||
|
//
|
||||||
|
// // Read the contents of the authorized_keys file
|
||||||
|
// file, err := os.Open(authorizedKeysPath)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// defer file.Close()
|
||||||
|
//
|
||||||
|
// // Create a slice to store AuthorizedKey structs
|
||||||
|
// var authorizedKeys []AuthorizedKey
|
||||||
|
//
|
||||||
|
// // Read each line of the file and parse the data
|
||||||
|
// scanner := bufio.NewScanner(file)
|
||||||
|
// for scanner.Scan() {
|
||||||
|
// line := scanner.Text()
|
||||||
|
// parts := strings.Fields(line)
|
||||||
|
// if len(parts) >= 2 {
|
||||||
|
// authorizedKey := AuthorizedKey{
|
||||||
|
// Username: parts[0],
|
||||||
|
// Key: parts[1],
|
||||||
|
// }
|
||||||
|
// authorizedKeys = append(authorizedKeys, authorizedKey)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if err := scanner.Err(); err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Modify the slice of structs if needed
|
||||||
|
// // authorizedKeys[0].Username = "newUsername"
|
||||||
|
// // authorizedKeys[0].Key = "newKey"
|
||||||
|
// authorizedKeys = append(authorizedKeys, AuthorizedKey{Username: "", Key: PublicKey})
|
||||||
|
//
|
||||||
|
// // Write the modified data back to the authorized_keys file
|
||||||
|
// newFile, err := os.Create(authorizedKeysPath)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// defer newFile.Close()
|
||||||
|
//
|
||||||
|
// return nil
|
||||||
|
//}
|
||||||
40
config/generate/gernerate_test.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CustomConfig struct {
|
||||||
|
Test string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test case to generate defaults with custom data-structure
|
||||||
|
func TestSetDefaults(t *testing.T) {
|
||||||
|
setDefaults, err := SetDefaults("", true, &CustomConfig{Test: "lol"}, true)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(setDefaults)
|
||||||
|
|
||||||
|
var c CustomConfig
|
||||||
|
|
||||||
|
_, err = config.ConfigInit(nil, &c)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(c)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test case to generate public and private keys
|
||||||
|
func TestGeneratePublicAndPrivateKeys(t *testing.T) {
|
||||||
|
MakeSSHKeyPair("test.pub", "test.prv")
|
||||||
|
}
|
||||||
39
config/generate/helperFunctions.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Exists reports whether the named file or directory exists.
|
||||||
|
func fileExists(name string) bool {
|
||||||
|
if _, err := os.Stat(name); err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the src file to dst. Any existing file will be overwritten and will not
|
||||||
|
// copy file attributes.
|
||||||
|
// Source: https://stackoverflow.com/questions/21060945/simple-way-to-copy-a-file
|
||||||
|
func Copy(src, dst string) error {
|
||||||
|
in, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer in.Close()
|
||||||
|
|
||||||
|
out, err := os.Create(dst)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(out, in)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return out.Close()
|
||||||
|
}
|
||||||
22
default.nix
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{ nixpkgs ? import <nixpkgs> { } }:
|
||||||
|
|
||||||
|
let
|
||||||
|
pkgs = [
|
||||||
|
nixpkgs.go
|
||||||
|
nixpkgs.tmux
|
||||||
|
nixpkgs.docker
|
||||||
|
nixpkgs.vim
|
||||||
|
];
|
||||||
|
|
||||||
|
in
|
||||||
|
nixpkgs.stdenv.mkDerivation {
|
||||||
|
name = "env";
|
||||||
|
buildInputs = pkgs;
|
||||||
|
pure-eval = true;
|
||||||
|
shellHook =
|
||||||
|
''
|
||||||
|
make
|
||||||
|
export P2PRC=$PWD
|
||||||
|
export PATH=$PWD:$PATH
|
||||||
|
'';
|
||||||
|
}
|
||||||
201
deploy/LICENSE
@@ -1,201 +0,0 @@
|
|||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
148
deploy/README.md
@@ -1,148 +0,0 @@
|
|||||||
# Ansible p2p-rendering-computation
|
|
||||||
### Modified from:
|
|
||||||
|
|
||||||
This repository contains an Ansible playbook and instructions to create and manage a single (or many) bare metal deep learning machines. For a description of why Ansible was chosen and what other alternatives were considered, please see [ToolSelection.md](ToolSelection.md)
|
|
||||||
|
|
||||||
## Quick Reference
|
|
||||||
|
|
||||||
If you've already [installed Ansible](#Installation), you can execute the entire playbook by running:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ ansible-playbook packages.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also execute only the pieces you need by passing tags on the command line:
|
|
||||||
|
|
||||||
- Install only apt/pip [pre-requisites](roles/packages) to execute the other roles:
|
|
||||||
```bash
|
|
||||||
$ ansible-playbook packages.yml --tags "packages"
|
|
||||||
```
|
|
||||||
- Install [Docker CE](roles/docker):
|
|
||||||
```bash
|
|
||||||
$ ansible-playbook packages.yml --tags "docker"
|
|
||||||
```
|
|
||||||
- Install the [Nvidia CUDA GPU drivers](roles/cuda):
|
|
||||||
```bash
|
|
||||||
$ ansible-playbook packages.yml --tags "cuda"
|
|
||||||
```
|
|
||||||
- Install the [Nvidia Docker Runtime](roles/nvidia):
|
|
||||||
```bash
|
|
||||||
$ ansible-playbook packages.yml --tags "nvidia"
|
|
||||||
```
|
|
||||||
|
|
||||||
## What's Included
|
|
||||||
|
|
||||||
After running the ansible script your machines will be loaded with the following:
|
|
||||||
|
|
||||||
1. Docker
|
|
||||||
2. Nvidia CUDA GPU Drivers
|
|
||||||
3. Nvidia Docker Runtime
|
|
||||||
4. TensorFlow GPU Python3 Docker Container
|
|
||||||
5. JupyterLab
|
|
||||||
|
|
||||||
## Using This Repository to Configure Your Environment
|
|
||||||
|
|
||||||
1. [Installation](#Installation)
|
|
||||||
2. [Configuration](#Configuration)
|
|
||||||
3. [Running](#Running)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
Ansible runs on your local machine and sends commands to the remote (machine learning) machines. You'll need ansible installed locally (not on the machine learning boxes).
|
|
||||||
For macOS users, the easiest way to install Ansible is via [Homebrew](https://brew.sh/):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ brew install ansible
|
|
||||||
```
|
|
||||||
|
|
||||||
If that's not your cup of tea, install Ansible by following the directions for your machine [here](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-the-control-machine).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Configuration
|
|
||||||
|
|
||||||
Gather the following:
|
|
||||||
|
|
||||||
- SSH key or user credentials for the remote account
|
|
||||||
|
|
||||||
**Note:** Ansible does not expose a channel to allow communication between the user and the ssh process to accept a password manually to decrypt an ssh key when using the ssh connection plugin (which is the default). The use of `ssh-agent` is highly recommended.
|
|
||||||
|
|
||||||
- List of servers you wish to manage:
|
|
||||||
- hostnames/IP addresses
|
|
||||||
- SSH port
|
|
||||||
- usernames
|
|
||||||
|
|
||||||
Copy [hosts.example] to `/etc/ansible/hosts` (if it does not already exist). Populate the `hosts` file (no extension) with the information about the servers you gathered above.
|
|
||||||
|
|
||||||
Confirm that you have populated your Ansible hosts file correctly:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ ansible-inventory --list
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Running
|
|
||||||
|
|
||||||
Once you're satisfied that you correctly populated your `hosts` file, update the `- hosts:` line of [tensorflow.yml] to reflect the hosts or groups you want to configure.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
- Apply against a single host defined as `ml2` in `/etc/ansible/hosts`:
|
|
||||||
```yaml
|
|
||||||
- hosts: ml2
|
|
||||||
```
|
|
||||||
- Apply against a group of hosts defined as `production` in `/etc/ansible/hosts`:
|
|
||||||
```yaml
|
|
||||||
- hosts: production
|
|
||||||
```
|
|
||||||
- Apply against all hosts defined in `/etc/ansible/hosts`:
|
|
||||||
```yaml
|
|
||||||
- hosts: all
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, when you're ready, run the playbook:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ ansible-playbook packages.yml --ask-become-pass
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note:** You must have `sudo` access to run the playbook!
|
|
||||||
|
|
||||||
Review the output:
|
|
||||||
|
|
||||||
- `[ok]` means no change (this task was already completed)
|
|
||||||
- `[changed]` means the task successfully ran and the change was applied
|
|
||||||
- `[unreachable]` means the host could not be reached
|
|
||||||
- `[failed]` means the task ran but failed to complete
|
|
||||||
|
|
||||||
`[ok]` and `[changed]` are successful outcomes. Any `[unreachable]` and `[failed]` outputs should be investigated and resolved.
|
|
||||||
|
|
||||||
**Note:** This Ansible playbook is idempotent; once a configuration has been successfully applied, if you apply it again, all actions will report `[ok]`.
|
|
||||||
|
|
||||||
## Executing Tensorflow Jobs in Your New Environment
|
|
||||||
|
|
||||||
1. Point your browser to http://<hostname>:8888 and login with the password you provided.
|
|
||||||
2. The `jupyter.volumes.source` folder will be mounted as the `notebooks` folder.
|
|
||||||
3. Edit and execute your Jupyter notebooks as normal!
|
|
||||||
|
|
||||||
### Command Line Access
|
|
||||||
|
|
||||||
If you need to drop into a GPU-powered TensorFlow environment, SSH into the remote machine and execute the following:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ docker run --runtime=nvidia -it --rm tensorflow/tensorflow:latest-gpu-py3 bash
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note:** You must be a member of the `docker` group or have `sudo` access on the _remote machine_ to execute docker commands.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Additional Files
|
|
||||||
|
|
||||||
- [ansible.cfg](ansible.cfg) enables SSH credential forwarding. This is a necessary step during data synchronization, as Ansible delegates those credentials to the master/writer host to push the data folder out to each of the mirrors.
|
|
||||||
- [Dockerfile](Dockerfile) is used to build the Arricor TensorFlow image. See [Docker.md](Docker.md) for additional details.
|
|
||||||
- [hosts.example](hosts.example) is an example of the Ansible inventory hosts file saved in `/etc/ansible/hosts`
|
|
||||||
- [secrets.example.yml](secrets.example.yml) is an example of the expected structure of the `secrets.yml` file
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
# Configuration Management Tool Selection
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
Ansible is proposed as the configuration management tool for this project due to the following characteristics:
|
|
||||||
|
|
||||||
- no agent installation on the managed nodes
|
|
||||||
- push-based configuration changes do not require a separate machine to be provisioned
|
|
||||||
- commands can be pushed from any developer/operator workstation
|
|
||||||
- all updates are performed over SSH
|
|
||||||
|
|
||||||
## Tools Considered
|
|
||||||
|
|
||||||
Where a tool offers an open source and an enterprise version (e.g., Puppet, Terraform), only the open source version was considered. Web or other graphical user interfaces (GUIs) were not considered, as the goal of this phase is to produce infrastructure as code which can be run (and re-run) from the command line interface (CLI).
|
|
||||||
|
|
||||||
- [Ansible](#Ansible)
|
|
||||||
- [Chef](#Chef)
|
|
||||||
- [Puppet](#Puppet)
|
|
||||||
- [Salt](#Salt)
|
|
||||||
- [Terraform](#Terraform)
|
|
||||||
|
|
||||||
### Ansible
|
|
||||||
|
|
||||||
[Ansible's simple interface and usability fit right into the sys admin mindset, and in a shop with lots of Linux and Unix systems, Ansible is quick and easy to run right out of the gate](https://www.infoworld.com/article/2609482/data-center/data-center-review-puppet-vs-chef-vs-ansible-vs-Salt.html?page=4).
|
|
||||||
|
|
||||||
#### Ansible Pros
|
|
||||||
|
|
||||||
- Requires no agent installation on the managed nodes.
|
|
||||||
- Push-based.
|
|
||||||
- Does not require a separate machine to be provisioned. Commands can be pushed from any developer/operator workstation.
|
|
||||||
- All updates are performed over SSH.
|
|
||||||
|
|
||||||
#### Ansible Cons
|
|
||||||
|
|
||||||
- Push-based synchronization means that the configuration is only refreshed on demand.
|
|
||||||
|
|
||||||
### Chef
|
|
||||||
|
|
||||||
[Chef has a stable and well-designed layout, and while it's not quite up to the level of Puppet in terms of raw features, it's a very capable solution. Chef may pose the most difficult learning curve to administrators who lack significant programming experience, but it could be the most natural fit for development-minded admins and development shops](https://www.infoworld.com/article/2609482/data-center/data-center-review-puppet-vs-chef-vs-ansible-vs-Salt.html?page=4).
|
|
||||||
|
|
||||||
#### Chef Pros
|
|
||||||
|
|
||||||
- AWS OpsWorks is based on Chef; any future migration to AWS could benefit from the existing configuration files.
|
|
||||||
|
|
||||||
#### Chef Cons
|
|
||||||
|
|
||||||
- **(Fatal)** Requires a master server and a workstation that will need to be maintained separately from the already provisioned deep learning machines.
|
|
||||||
- **(Fatal)** Requires an agent (client) to be installed on each machine.
|
|
||||||
- Requires an on-premises Chef server and [Push Jobs](https://docs.chef.io/push_jobs.html) plugin to push configurations manually. Otherwise, managed machines must check in with the master on a schedule.
|
|
||||||
|
|
||||||
### Puppet
|
|
||||||
|
|
||||||
[Puppet is the most mature and probably the most approachable of the four from a usability standpoint, though a solid knowledge of Ruby is highly recommended. Puppet is not as streamlined as Ansible or Salt, and its configuration can get Byzantine at times. Puppet is the safest bet for heterogeneous environments, but you may find Ansible or Salt to be a better fit in a larger or more homogenous infrastructure](https://www.infoworld.com/article/2609482/data-center/data-center-review-puppet-vs-chef-vs-ansible-vs-salt.html?page=4).
|
|
||||||
|
|
||||||
#### Puppet Pros
|
|
||||||
|
|
||||||
- Configuration can be kept up to date via a schedule or manual configuration pushes.
|
|
||||||
|
|
||||||
#### Puppet Cons
|
|
||||||
|
|
||||||
- **(Fatal)** Requires a "puppet master" (server) that will need to be maintained separately from the already provisioned machines.
|
|
||||||
- **(Fatal)** Requires an agent (client) to be installed on each machine.
|
|
||||||
|
|
||||||
### Salt
|
|
||||||
|
|
||||||
[Salt is the sleekest and most robust of the four, and like Ansible it will resonate with sys admins. Highly scalable and quite capable, Salt is hamstrung only by the Web UI](https://www.infoworld.com/article/2609482/data-center/data-center-review-puppet-vs-chef-vs-ansible-vs-salt.html?page=4).
|
|
||||||
|
|
||||||
#### Salt Pros
|
|
||||||
|
|
||||||
- Push-based.
|
|
||||||
- Can function via regular SSH or via client agents called "minions".
|
|
||||||
|
|
||||||
#### Salt Cons
|
|
||||||
|
|
||||||
- When running agentless, push-based synchronization means that the configuration is only refreshed on demand.
|
|
||||||
|
|
||||||
### Terraform
|
|
||||||
|
|
||||||
The initial hope was that [Terraform](https://terraform.io) could be used for configuration management for this project. However, after reviewing the [available Terraform provider plugins](https://terraform.io/docs/providers) and other available material, it was agreed on 23 January 2019 that Terraform was not suitable for this stage of the project.
|
|
||||||
|
|
||||||
In the future, if Arricor migrates its instances to a cloud service provider (CSP) such as AWS, Azure, or Google Cloud Platform, this configuration may be reusable as a first step via the [terraform-provisioner-ansible](https://github.com/jonmorehouse/terraform-provisioner-ansible) plugin. This plugin allows the user to create CSP instances, then execute the given Ansible playbook against those instances.
|
|
||||||
|
|
||||||
#### Terraform Pros
|
|
||||||
|
|
||||||
- Cloud native with support for multiple service providers.
|
|
||||||
|
|
||||||
#### Terraform Cons
|
|
||||||
|
|
||||||
- **(Fatal)** No support for provisioning bare metal instances.
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
Ansible allows for management of a server from scratch, with only the requirement to have a valid username and password. Additionally, its agentless approach avoids having to configure and maintain an admin server, further simplifying operations at the scale Arricor requires.
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
[defaults]
|
|
||||||
host_key_checking = False
|
|
||||||
|
|
||||||
[ssh_connection]
|
|
||||||
ssh_args = -o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
---
|
|
||||||
all:
|
|
||||||
vars:
|
|
||||||
ansible_python_interpreter: /usr/bin/python3
|
|
||||||
test:
|
|
||||||
hosts:
|
|
||||||
test1:
|
|
||||||
ansible_host: 127.0.0.1 # Replace with your remote IP
|
|
||||||
ansible_port: 2222 # Replace with your remote SSH port
|
|
||||||
ansible_user: vagrant # Replace wtih your username
|
|
||||||
|
|
||||||
production:
|
|
||||||
hosts:
|
|
||||||
writer:
|
|
||||||
ansible_host: 192.168.1.100 # Replace with your remote IP
|
|
||||||
ansible_port: 2202 # Replace with your remote SSH port
|
|
||||||
ansible_user: ansible # Replace wtih your username
|
|
||||||
mirror1:
|
|
||||||
ansible_host: 192.168.1.101 # Replace with your remote IP
|
|
||||||
ansible_port: 2202 # Replace with your remote SSH port
|
|
||||||
ansible_user: ansible # Replace wtih your username
|
|
||||||
mirror2:
|
|
||||||
ansible_host: 192.168.1.102 # Replace with your remote IP
|
|
||||||
ansible_port: 2202 # Replace with your remote SSH port
|
|
||||||
ansible_user: ansible # Replace wtih your username
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
################################################################################
|
|
||||||
# This file consists of three main sections:
|
|
||||||
# 1. vars - variables used throughout the playbook are defined here. If you want to change packages or version, this is the place to do it.
|
|
||||||
# 2. tasks - these are the steps that will be executed by the playbook. This is a straightforward, sequential playbook.
|
|
||||||
# 3. handlers - these steps run only in response to specific events. If the event does not occur, the handler does not run.
|
|
||||||
################################################################################
|
|
||||||
---
|
|
||||||
- hosts: test # Alternatively, 'canary', 'blue'|'green', 'all' according to your deployment strategy and your /etc/ansible/hosts file
|
|
||||||
become: yes # All commands must run as root
|
|
||||||
strategy: free # Allows all hosts to run to the end of the playbook as fast as they can
|
|
||||||
|
|
||||||
vars_files:
|
|
||||||
- secrets.yml
|
|
||||||
|
|
||||||
roles:
|
|
||||||
- role: packages # General Dependencies
|
|
||||||
tags: [packages]
|
|
||||||
|
|
||||||
# - role: rsync # Rsync Setup
|
|
||||||
# tags: [rsync]
|
|
||||||
# vars:
|
|
||||||
# sync: "{{ secrets.sync }}"
|
|
||||||
|
|
||||||
- role: docker # General Docker setup
|
|
||||||
tags: [docker]
|
|
||||||
vars:
|
|
||||||
users: "{{ secrets.users }}"
|
|
||||||
|
|
||||||
- role: cuda # CUDA Driver Setup
|
|
||||||
tags: [cuda]
|
|
||||||
|
|
||||||
- role: nvidia # NVIDIA-Docker Runtime Setup
|
|
||||||
tags: [nvidia]
|
|
||||||
|
|
||||||
- role: jupyter # Launch Jupyter Container in Docker
|
|
||||||
tags: [jupyter]
|
|
||||||
vars:
|
|
||||||
volumes: "{{ secrets.volumes }}"
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
# The `cuda` Role
|
|
||||||
|
|
||||||
The `cuda` role installs the Nvidia CUDA GPU repository and drivers.
|
|
||||||
|
|
||||||
This role may be executed independently by running:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ ansible-playbook packages.yml --tags "cuda"
|
|
||||||
```
|
|
||||||
|
|
||||||
On execution, this role installs the following directly to the remote machine's operating system:
|
|
||||||
|
|
||||||
### Apt Repositories (Debian/Ubuntu)
|
|
||||||
|
|
||||||
- Nvidia CUDA
|
|
||||||
|
|
||||||
### Apt GPG Signing Keys (Debian/Ubuntu)
|
|
||||||
|
|
||||||
- cudatools <cudatools@nvidia.com>
|
|
||||||
|
|
||||||
### Operating System Packages (Debian/Ubuntu)
|
|
||||||
|
|
||||||
- cuda v10.x
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
# CUDA Driver Setup
|
|
||||||
- name: reboot the machine
|
|
||||||
reboot:
|
|
||||||
listen: "reboot the machine"
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
---
|
|
||||||
# Cuda Driver Package Installation
|
|
||||||
- name: copy the CUDA repo onto the machine
|
|
||||||
copy:
|
|
||||||
src: "{{ cuda.apt.repo }}"
|
|
||||||
dest: "{{ general.working_dir }}/{{ cuda.apt.repo }}"
|
|
||||||
|
|
||||||
- name: get the CUDA signing key
|
|
||||||
apt_key:
|
|
||||||
state: present
|
|
||||||
url: "{{ cuda.apt.signing_key_url }}"
|
|
||||||
|
|
||||||
- name: add the CUDA repo
|
|
||||||
apt:
|
|
||||||
deb: "{{ general.working_dir }}/{{ cuda.apt.repo }}"
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: install the CUDA drivers
|
|
||||||
apt:
|
|
||||||
name: "{{ cuda.apt.package }}"
|
|
||||||
update_cache: yes
|
|
||||||
notify: "reboot the machine"
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
- import_tasks: debian.yml
|
|
||||||
when: ansible_facts['os_family']|lower == 'debian' # debian, ubuntu
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
---
|
|
||||||
cuda:
|
|
||||||
apt:
|
|
||||||
package: cuda=10.* # known good with 10.0.130-1
|
|
||||||
repo: cuda-repo-ubuntu1804_10.0.130-1_amd64.deb # Network install
|
|
||||||
signing_key_url: https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
|
|
||||||
|
|
||||||
general:
|
|
||||||
working_dir: /tmp
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# The `docker` Role
|
|
||||||
|
|
||||||
The `docker` role installs the Docker CE repository and runtime packages.
|
|
||||||
|
|
||||||
This role may be executed independently by running:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ ansible-playbook packages.yml --tags "docker"
|
|
||||||
```
|
|
||||||
|
|
||||||
On execution, this role installs the following directly to the remote machine's operating system:
|
|
||||||
|
|
||||||
### Apt Repositories (Debian/Ubuntu)
|
|
||||||
|
|
||||||
- Docker CE
|
|
||||||
|
|
||||||
### Apt GPG Signing Keys (Debian/Ubuntu)
|
|
||||||
|
|
||||||
- Docker Release (CE deb) <docker@docker.com>
|
|
||||||
|
|
||||||
### Operating System Packages (Debian/Ubuntu)
|
|
||||||
|
|
||||||
- docker-ce v5:18.x
|
|
||||||
|
|
||||||
### System Services
|
|
||||||
|
|
||||||
- `docker` (enabled and started)
|
|
||||||
|
|
||||||
### User Groups
|
|
||||||
|
|
||||||
- docker
|
|
||||||
|
|
||||||
All users listed under `secrets.users` in `secrets.yml` will be added to the `docker` group.
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
# Docker Package Installation
|
|
||||||
- name: add Docker's official GPG key
|
|
||||||
apt_key:
|
|
||||||
state: present
|
|
||||||
url: "{{ docker.apt.signing_key_url }}"
|
|
||||||
|
|
||||||
- name: add Docker apt repository
|
|
||||||
apt_repository:
|
|
||||||
repo: "{{ docker.apt.repo }}"
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: install Docker CE
|
|
||||||
apt:
|
|
||||||
name: "{{ docker.apt.package }}"
|
|
||||||
state: present
|
|
||||||
update_cache: yes
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
---
|
|
||||||
# General Docker Setup
|
|
||||||
- import_tasks: debian.yml
|
|
||||||
when: ansible_facts['os_family']|lower == 'debian' # debian, ubuntu
|
|
||||||
|
|
||||||
- name: ensure the docker service starts at boot
|
|
||||||
systemd:
|
|
||||||
name: "{{ docker.service_name }}"
|
|
||||||
enabled: yes
|
|
||||||
state: started
|
|
||||||
|
|
||||||
- name: create Docker group to avoid running as root
|
|
||||||
group:
|
|
||||||
name: "{{ docker.group_name }}"
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: add users to Docker group
|
|
||||||
user:
|
|
||||||
append: yes
|
|
||||||
groups:
|
|
||||||
- "{{ docker.group_name }}"
|
|
||||||
name: "{{ item }}"
|
|
||||||
loop: "{{ users }}"
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
docker:
|
|
||||||
apt:
|
|
||||||
package: docker-ce=5:18.* # known good with 5:18.09.1~3-0~ubuntu-bionic
|
|
||||||
repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable
|
|
||||||
signing_key_url: https://download.docker.com/linux/ubuntu/gpg
|
|
||||||
group_name: docker
|
|
||||||
service_name: docker
|
|
||||||