Compare commits
86 Commits
v1.1.0
...
v2.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
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
|
||||
3
.gitignore
vendored
@@ -21,3 +21,6 @@ generate/Test
|
||||
#ignore windows exe files
|
||||
*.exe
|
||||
dist/
|
||||
|
||||
# ignore docker image files
|
||||
server/docker/containers/
|
||||
|
||||
6
Docs/Abstractions.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Abstractions
|
||||
The Abstractions package consists of black-boxed functions for P2PRC.
|
||||
|
||||
## Functions
|
||||
- ```Init(<Project name>)```: Initializes P2PRC with all the needed configurations.
|
||||
- ```Start()```: Starts p2prc as a server and makes it possible to extend by adding other routes and functionality to P2PRC.
|
||||
37
Docs/NAT-Traveral.md
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Table of contents
|
||||
1. [Introduction](Introduction.md)
|
||||
2. [Installation](Installation.md)
|
||||
3. [Abstractions](Abstractions.md)
|
||||
3. [Design Architecture](DesignArchtectureIntro.md)
|
||||
1. [Client Module](ClientArchitecture.md)
|
||||
2. [P2P Module](P2PArchitecture.md)
|
||||
@@ -13,6 +14,5 @@
|
||||
4. [Config Module](ConfigImplementation.md)
|
||||
5. [Cli Module](CliImplementation.md)
|
||||
6. [Plugin Module](PluginImplementation.md)
|
||||
7. [Generate Module](GenerateImplementation.md)
|
||||
5. [Problems](https://github.com/Akilan1999/p2p-rendering-computation/issues)
|
||||
|
||||
|
||||
45
README.md
@@ -1,3 +1,4 @@
|
||||
|
||||
<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>
|
||||
@@ -6,11 +7,12 @@
|
||||
|
||||
<!-- seperator -->
|
||||
|
||||
|
||||
[](http://perso.crans.org/besson/LICENSE.html)
|
||||
[](https://GitHub.com/Akilan1999/p2p-rendering-computation/graphs/commit-activity)
|
||||
[](http://golang.org)
|
||||
[](https://pkg.go.dev/git.sr.ht/~akilan1999/p2p-rendering-computation)
|
||||
<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
|
||||
client has total flexibility on how to batch the tasks and the user acting as the server has complete
|
||||
@@ -43,6 +45,28 @@ This project aims to create a peer to peer (p2p) network, where a user can use t
|
||||
|
||||
<br>
|
||||
|
||||
## Extend your application with P2PRC
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/Akilan1999/p2p-rendering-computation/abstractions"
|
||||
|
||||
func main() {
|
||||
// Initialize with base p2prc config files
|
||||
err := abstractions.Init("TEST")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// start p2prc
|
||||
_, err = abstractions.Start()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
```
|
||||
[Read more](Docs/Abstractions.md) ...
|
||||
|
||||
## Installation from source
|
||||
1. Ensure the Go compiler is installed
|
||||
```
|
||||
@@ -61,11 +85,11 @@ This project aims to create a peer to peer (p2p) network, where a user can use t
|
||||
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}
|
||||
|
||||
```
|
||||
// Add them to your .bashrc file
|
||||
export P2PRC=/<path>/p2p-rendering-computation
|
||||
export PATH=/<path>/p2p-rendering-computation:${PATH}
|
||||
```
|
||||
|
||||
5. Test if it works
|
||||
```
|
||||
@@ -98,4 +122,5 @@ As we are working on the open source project p2prc (i.e p2p network designed fo
|
||||
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
|
||||
27
abstractions/init.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package abstractions
|
||||
|
||||
import (
|
||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/config/generate"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/server"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Init Initialises p2prc
|
||||
func Init(name string, customConfig interface{}) (config *config.Config, err error) {
|
||||
// set the config file with default paths
|
||||
config, err = generate.SetDefaults(name, false, customConfig, false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Start p2prc in a server mode
|
||||
func Start() (*gin.Engine, error) {
|
||||
engine, err := server.Server()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return engine, nil
|
||||
}
|
||||
16
artwork/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
# 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,311 +1,310 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"github.com/google/uuid"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"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"`
|
||||
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
|
||||
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
|
||||
}
|
||||
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
|
||||
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
|
||||
}
|
||||
// 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:]...)
|
||||
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
|
||||
}
|
||||
// Write new groups to the grouptrackcontainer json file
|
||||
err = groups.WriteGroup()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
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)
|
||||
// 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
|
||||
}
|
||||
// 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
|
||||
}
|
||||
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
|
||||
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
|
||||
}
|
||||
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
|
||||
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
|
||||
}
|
||||
// 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
|
||||
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
|
||||
}
|
||||
}
|
||||
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. ")
|
||||
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
|
||||
// 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 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
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadGroup Function reads grouptrackcontainers.json and converts
|
||||
// result to Groups
|
||||
func ReadGroup() (*Groups,error) {
|
||||
// Get Path from config
|
||||
config, err := config.ConfigInit()
|
||||
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
|
||||
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()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
// Write modified result to the Groups track container JSON file
|
||||
err = group.WriteGroup()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -46,14 +46,14 @@ func TestAddContainerToGroup(t *testing.T) {
|
||||
|
||||
// Creating and adding the container to the
|
||||
// tracked list
|
||||
container1 ,err := docker.BuildRunContainer(0,"false","")
|
||||
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")
|
||||
err = AddTrackContainer(container1, "0.0.0.0")
|
||||
if err != nil {
|
||||
// Killing docker container created
|
||||
err = docker.StopAndRemoveContainer(container1.ID)
|
||||
@@ -66,7 +66,7 @@ func TestAddContainerToGroup(t *testing.T) {
|
||||
}
|
||||
|
||||
// Adds container information to the group
|
||||
Group, err := AddContainerToGroup(container1.ID,group.ID)
|
||||
Group, err := AddContainerToGroup(container1.ID, group.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
@@ -109,14 +109,14 @@ func TestGroup_RemoveContainerGroup(t *testing.T) {
|
||||
|
||||
// Creating and adding the container to the
|
||||
// tracked list
|
||||
container1 ,err := docker.BuildRunContainer(0,"false","")
|
||||
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")
|
||||
err = AddTrackContainer(container1, "0.0.0.0")
|
||||
if err != nil {
|
||||
// Killing docker container created
|
||||
err = docker.StopAndRemoveContainer(container1.ID)
|
||||
@@ -129,7 +129,7 @@ func TestGroup_RemoveContainerGroup(t *testing.T) {
|
||||
}
|
||||
|
||||
// Adds container information to the group
|
||||
Group, err := AddContainerToGroup(container1.ID,group.ID)
|
||||
Group, err := AddContainerToGroup(container1.ID, group.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
@@ -138,7 +138,7 @@ func TestGroup_RemoveContainerGroup(t *testing.T) {
|
||||
PrettyPrint(Group)
|
||||
|
||||
// Removing docker container from the group
|
||||
Group, err = RemoveContainerGroup(container1.ID,group.ID)
|
||||
Group, err = RemoveContainerGroup(container1.ID, group.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
@@ -182,7 +182,7 @@ func TestGroups_RemoveContainerGroups(t *testing.T) {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Created another group assigned to variable group 1
|
||||
// Created another group assigned to variable group 1
|
||||
group1, err := CreateGroup()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@@ -191,14 +191,14 @@ func TestGroups_RemoveContainerGroups(t *testing.T) {
|
||||
|
||||
// Creating and adding the container to the
|
||||
// tracked list
|
||||
container1 ,err := docker.BuildRunContainer(0,"false","")
|
||||
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")
|
||||
err = AddTrackContainer(container1, "0.0.0.0")
|
||||
if err != nil {
|
||||
// Killing docker container created
|
||||
err = docker.StopAndRemoveContainer(container1.ID)
|
||||
@@ -211,7 +211,7 @@ func TestGroups_RemoveContainerGroups(t *testing.T) {
|
||||
}
|
||||
|
||||
// Adds container information to the group
|
||||
Group, err := AddContainerToGroup(container1.ID,group.ID)
|
||||
Group, err := AddContainerToGroup(container1.ID, group.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
@@ -220,7 +220,7 @@ func TestGroups_RemoveContainerGroups(t *testing.T) {
|
||||
PrettyPrint(Group)
|
||||
|
||||
// Adds container information to the group
|
||||
Group1, err := AddContainerToGroup(container1.ID,group1.ID)
|
||||
Group1, err := AddContainerToGroup(container1.ID, group1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
|
||||
@@ -1,237 +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"
|
||||
)
|
||||
|
||||
// UpdateIpTable Does the following to update it's IP table
|
||||
func UpdateIpTable(IpAddress string, serverPort string) error {
|
||||
|
||||
config, err := config.ConfigInit()
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
//}
|
||||
//
|
||||
//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 || (PublicIP.Ipv6 != "" && Addresses.IpAddress[j].Ipv6 == PublicIP.Ipv6){
|
||||
// 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].Ipv6 != "" && Addresses.IpAddress[j].Ipv6 == DoNotRead.IpAddress[k].Ipv6) {
|
||||
// Exists = true
|
||||
// break
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// If the struct exists then continues
|
||||
//if Exists {
|
||||
// continue
|
||||
//}
|
||||
|
||||
if Addresses.IpAddress[j].Ipv6 != "" {
|
||||
err = UpdateIpTable(Addresses.IpAddress[j].Ipv6, Addresses.IpAddress[j].ServerPort)
|
||||
} else {
|
||||
err = UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Appends server1 IP address to variable DoNotRead
|
||||
//DoNotRead.IpAddress = append(DoNotRead.IpAddress, Addresses.IpAddress[j])
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@ package client
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/server"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
@@ -12,30 +11,30 @@ import (
|
||||
// GetSpecs Gets Specs from the server such CPU, GPU usage
|
||||
// and other basic information which helps set a
|
||||
// cluster of computer
|
||||
func GetSpecs(IP string)(*server.SysInfo,error) {
|
||||
func GetSpecs(IP string) (*server.SysInfo, error) {
|
||||
var URL string
|
||||
version := p2p.Ip4or6(IP)
|
||||
//version := p2p.Ip4or6(IP)
|
||||
|
||||
//Get port number of the server
|
||||
serverPort, err := GetServerPort(IP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//serverPort, err := GetServerPort(IP)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
if version == "version 6" {
|
||||
URL = "http://[" + IP + "]:" + serverPort + "/server_info"
|
||||
} else {
|
||||
URL = "http://" + IP + ":" + serverPort + "/server_info"
|
||||
}
|
||||
//if version == "version 6" {
|
||||
URL = "http://" + IP + "/server_info"
|
||||
//} else {
|
||||
// URL = "http://" + IP + ":" + serverPort + "/server_info"
|
||||
//}
|
||||
resp, err := http.Get(URL)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert response to byte value
|
||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create variable for result response type
|
||||
@@ -44,7 +43,7 @@ func GetSpecs(IP string)(*server.SysInfo,error) {
|
||||
// Adds byte value to docker.DockerVM struct
|
||||
json.Unmarshal(byteValue, &serverSpecsResult)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &serverSpecsResult, nil
|
||||
@@ -61,4 +60,4 @@ func PrettyPrint(data interface{}) {
|
||||
return
|
||||
}
|
||||
fmt.Printf("%s \n", p)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,149 +1,149 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"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"`
|
||||
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"`
|
||||
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()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
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
|
||||
}
|
||||
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
|
||||
// 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)
|
||||
// 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
|
||||
}
|
||||
// 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
|
||||
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()
|
||||
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:]...)
|
||||
//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
|
||||
}
|
||||
// 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
|
||||
return nil
|
||||
}
|
||||
|
||||
// ViewTrackedContainers View Containers currently tracked
|
||||
func ViewTrackedContainers() (error,*TrackContainers) {
|
||||
config,err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return err,nil
|
||||
}
|
||||
trackedContianers, err := ReadTrackContainers(config.TrackContainersPath)
|
||||
if err != nil {
|
||||
return err,nil
|
||||
}
|
||||
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
|
||||
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
|
||||
}
|
||||
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)
|
||||
}
|
||||
c := &TrackContainers{}
|
||||
err = json.Unmarshal(buf, c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("in file %q: %v", filename, err)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
return c, nil
|
||||
}
|
||||
|
||||
//func ModifyTrackContainers()
|
||||
@@ -151,70 +151,70 @@ func ReadTrackContainers(filename string) (*TrackContainers, error) {
|
||||
// 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. ")
|
||||
// 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
|
||||
}
|
||||
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
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteContainers Write information back to the config file
|
||||
func (TC *TrackContainers)WriteContainers() error {
|
||||
// Initialize config file
|
||||
config,err := config.ConfigInit()
|
||||
// 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
|
||||
}
|
||||
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
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckID Checks if the ID belongs to a group or a single container
|
||||
func CheckID(ID string) (string,error) {
|
||||
func CheckID(ID string) (string, error) {
|
||||
// For group checks if the 1st characters is "grp"
|
||||
if ID[0:3] == "grp" {
|
||||
return "group", nil
|
||||
} else {
|
||||
return "container", nil
|
||||
}
|
||||
return "",nil
|
||||
}
|
||||
if ID[0:3] == "grp" {
|
||||
return "group", nil
|
||||
} else {
|
||||
return "container", nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
@@ -2,20 +2,20 @@ package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker"
|
||||
"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","")
|
||||
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")
|
||||
err = AddTrackContainer(container1, "0.0.0.0")
|
||||
if err != nil {
|
||||
// Killing docker container created
|
||||
err = docker.StopAndRemoveContainer(container1.ID)
|
||||
@@ -26,7 +26,7 @@ func TestAddTrackContainer(t *testing.T) {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Killing docker container created
|
||||
// Killing docker container created
|
||||
err = docker.StopAndRemoveContainer(container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@@ -38,20 +38,20 @@ func TestAddTrackContainer(t *testing.T) {
|
||||
// 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","")
|
||||
container1, err := docker.BuildRunContainer(0, "false", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
container2 ,err := docker.BuildRunContainer(0,"false","")
|
||||
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")
|
||||
err = AddTrackContainer(container1, "0.0.0.0")
|
||||
if err != nil {
|
||||
// Killing docker container created
|
||||
err = docker.StopAndRemoveContainer(container1.ID)
|
||||
@@ -70,7 +70,7 @@ func TestRemoveTrackedContainer(t *testing.T) {
|
||||
}
|
||||
|
||||
// Testing the AddTrackContainer Function and the adding the second container created
|
||||
err = AddTrackContainer(container2,"0.0.0.0")
|
||||
err = AddTrackContainer(container2, "0.0.0.0")
|
||||
if err != nil {
|
||||
// Killing docker container created
|
||||
err = docker.StopAndRemoveContainer(container2.ID)
|
||||
@@ -106,7 +106,7 @@ func TestRemoveTrackedContainer(t *testing.T) {
|
||||
// Test function that checks if the ID belongs to
|
||||
// a group or container running
|
||||
func TestCheckID(t *testing.T) {
|
||||
id := "grp123"
|
||||
id := "grp123"
|
||||
checkID, err := CheckID(id)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
|
||||
254
client/clientIPTable/Iptable.go
Normal file
@@ -0,0 +1,254 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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,4 +1,4 @@
|
||||
package client
|
||||
package clientIPTable
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -11,4 +11,3 @@ func TestUpdateIpTableListClient(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package client
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@@ -12,39 +12,39 @@ import (
|
||||
|
||||
var (
|
||||
serverPort = "8088"
|
||||
client = http.Client{}
|
||||
client = http.Client{}
|
||||
)
|
||||
|
||||
// StartContainer Start container using REST api Implementation
|
||||
// From the selected server IP address
|
||||
// TODO: Test cases for this function
|
||||
//Calls URL ex: http://0.0.0.0:8088/startcontainer?ports=0&GPU=false&ContainerName=docker-ubuntu-sshd
|
||||
func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string) (*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) (*docker.DockerVM, error) {
|
||||
// Passes URL with number of TCP ports to allocated and to give GPU access to the docker container
|
||||
var URL string
|
||||
version := p2p.Ip4or6(IP)
|
||||
//version := p2p.Ip4or6(IP)
|
||||
//
|
||||
////Get port number of the server
|
||||
//serverPort, err := GetServerPort(IP)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
//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 {
|
||||
URL = "http://" + IP + ":" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
||||
}
|
||||
//if version == "version 6" {
|
||||
// URL = "http://[" + IP + "]:" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
||||
//} else {
|
||||
URL = "http://" + IP + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
||||
//}
|
||||
|
||||
resp, err := http.Get(URL)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert response to byte value
|
||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create variable for result response type
|
||||
@@ -53,7 +53,7 @@ func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string) (*d
|
||||
// Adds byte value to docker.DockerVM struct
|
||||
json.Unmarshal(byteValue, &dockerResult)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Adds the container to the tracked list
|
||||
@@ -66,21 +66,21 @@ func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string) (*d
|
||||
}
|
||||
|
||||
// RemoveContianer Stops and removes container from the server
|
||||
func RemoveContianer(IP string,ID string) error {
|
||||
func RemoveContianer(IP string, ID string) error {
|
||||
var URL string
|
||||
version := p2p.Ip4or6(IP)
|
||||
//version := p2p.Ip4or6(IP)
|
||||
//
|
||||
////Get port number of the server
|
||||
//serverPort, err := GetServerPort(IP)
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
//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 + ":" + serverPort + "/RemoveContainer?id=" + ID
|
||||
}
|
||||
//if version == "version 6" {
|
||||
// URL = "http://[" + IP + "]:" + serverPort + "/RemoveContainer?id=" + ID
|
||||
//} else {
|
||||
URL = "http://" + IP + "/RemoveContainer?id=" + ID
|
||||
//}
|
||||
resp, err := http.Get(URL)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -102,7 +102,7 @@ func RemoveContianer(IP string,ID string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Remove container created from the tracked list
|
||||
// Remove container created from the tracked list
|
||||
err = RemoveTrackedContainer(ID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -112,31 +112,31 @@ func RemoveContianer(IP string,ID string) error {
|
||||
}
|
||||
|
||||
// ViewContainers This function displays all containers available on server side
|
||||
func ViewContainers(IP string)(*docker.DockerContainers, error){
|
||||
func ViewContainers(IP string) (*docker.DockerContainers, error) {
|
||||
// Passes URL with route /ShowImages
|
||||
var URL string
|
||||
version := p2p.Ip4or6(IP)
|
||||
//version := p2p.Ip4or6(IP)
|
||||
//
|
||||
////Get port number of the server
|
||||
//serverPort, err := GetServerPort(IP)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
//Get port number of the server
|
||||
serverPort, err := GetServerPort(IP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if version == "version 6" {
|
||||
URL = "http://[" + IP + "]:" + serverPort + "/ShowImages"
|
||||
} else {
|
||||
URL = "http://" + IP + ":" + serverPort + "/ShowImages"
|
||||
}
|
||||
//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
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert response to byte value
|
||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create variable for result response type
|
||||
@@ -145,18 +145,18 @@ func ViewContainers(IP string)(*docker.DockerContainers, error){
|
||||
// Adds byte value to docker.DockerContainers struct
|
||||
json.Unmarshal(byteValue, &Result)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Result, nil
|
||||
}
|
||||
|
||||
// GetServerPort Helper function to do find out server port information
|
||||
func GetServerPort(IpAddress string) (string,error) {
|
||||
func GetServerPort(IpAddress string) (string, error) {
|
||||
// Getting information from the clients ip table
|
||||
ipTable, err := p2p.ReadIpTable()
|
||||
if err != nil {
|
||||
return "",err
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Iterate thorough ip table struct and find
|
||||
@@ -170,7 +170,7 @@ func GetServerPort(IpAddress string) (string,error) {
|
||||
}
|
||||
|
||||
// We return default port
|
||||
return "8088",nil
|
||||
return "8088", nil
|
||||
}
|
||||
|
||||
// PrintStartContainer Prints results Generated container
|
||||
@@ -187,7 +187,6 @@ func GetServerPort(IpAddress string) (string,error) {
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
// TODO implementation using RPC calls
|
||||
//func StartContainer(Ip string) (*docker.DockerVM,error){
|
||||
// client, err := rpc.DialHTTP("tcp",Ip + ":" + serverPort)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
493
cmd/action.go
@@ -1,294 +1,277 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/client"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/generate"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/plugin"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server"
|
||||
"github.com/urfave/cli/v2"
|
||||
"fmt"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/client"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/config/generate"
|
||||
"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"
|
||||
)
|
||||
|
||||
var CliAction = func(ctx *cli.Context) error {
|
||||
if Server {
|
||||
// TODO: with RPC calls
|
||||
server.Server()
|
||||
//server.Rpc()
|
||||
}
|
||||
if Server {
|
||||
_, err := server.Server()
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
//server.Rpc()
|
||||
for {
|
||||
|
||||
//Listing servers and also updates IP tables (Default 3 hops)
|
||||
if UpdateServerList {
|
||||
err := client.UpdateIpTableListClient()
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
// Reads from ip table and passes it
|
||||
// on to struct print function
|
||||
//Servers, err := p2p.ReadIpTable()
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//client.PrettyPrint(Servers)
|
||||
p2p.PrintIpTable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Displays the IP table
|
||||
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()
|
||||
}
|
||||
//Listing servers and also updates IP tables (Default 3 hops)
|
||||
if UpdateServerList {
|
||||
err := clientIPTable.UpdateIpTableListClient()
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
// Reads from ip table and passes it
|
||||
// on to struct print function
|
||||
//Servers, err := p2p.ReadIpTable()
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//client.PrettyPrint(Servers)
|
||||
p2p.PrintIpTable()
|
||||
}
|
||||
|
||||
// Add provided IP to the IP table
|
||||
if AddServer != "" {
|
||||
res, err := p2p.ReadIpTable()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
// Displays the IP table
|
||||
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()
|
||||
}
|
||||
|
||||
//Create variable of type IpAddress and set IP address
|
||||
// to it
|
||||
var IpAddr p2p.IpAddress
|
||||
// Add provided IP to the IP table
|
||||
if AddServer != "" {
|
||||
res, err := p2p.ReadIpTable()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
//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
|
||||
}
|
||||
//Create variable of type IpAddress and set IP address
|
||||
// to it
|
||||
var IpAddr p2p.IpAddress
|
||||
|
||||
// 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()
|
||||
//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)
|
||||
// Displays all images available on the server side
|
||||
if ViewImages != "" {
|
||||
imageRes, err := client.ViewContainers(ViewImages)
|
||||
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
client.PrettyPrint(imageRes)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
client.PrettyPrint(imageRes)
|
||||
}
|
||||
|
||||
// Function called to stop and remove server from Docker
|
||||
if RemoveVM != "" && ID != "" {
|
||||
err := client.RemoveContianer(RemoveVM,ID)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
}
|
||||
// Function called to stop and remove server from Docker
|
||||
if RemoveVM != "" {
|
||||
if ID == "" {
|
||||
fmt.Println("provide container ID via --ID or --id")
|
||||
} else {
|
||||
err := client.RemoveContianer(RemoveVM, ID)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Call function to create Docker container
|
||||
if CreateVM != "" {
|
||||
//Call function to create Docker container
|
||||
if CreateVM != "" {
|
||||
|
||||
var PortsInt int
|
||||
var PortsInt int
|
||||
|
||||
if Ports != "" {
|
||||
// Convert Get Request value to int
|
||||
fmt.Sscanf(Ports, "%d", &PortsInt)
|
||||
}
|
||||
if Ports != "" {
|
||||
// Convert Get Request value to int
|
||||
fmt.Sscanf(Ports, "%d", &PortsInt)
|
||||
}
|
||||
|
||||
// Calls function to do Api call to start the container on the server side
|
||||
imageRes, err := client.StartContainer(CreateVM,PortsInt,GPU,ContainerName)
|
||||
// Calls function to do Api call to start the container on the server side
|
||||
imageRes, err := client.StartContainer(CreateVM, PortsInt, GPU, ContainerName)
|
||||
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
client.PrettyPrint(imageRes)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
client.PrettyPrint(imageRes)
|
||||
}
|
||||
|
||||
//Call if specs flag is called
|
||||
if Specs != "" {
|
||||
specs, err := client.GetSpecs(Specs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//Call if specs flag is called
|
||||
if Specs != "" {
|
||||
specs, err := client.GetSpecs(Specs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Pretty print
|
||||
client.PrettyPrint(specs)
|
||||
}
|
||||
// Pretty print
|
||||
client.PrettyPrint(specs)
|
||||
}
|
||||
|
||||
//Sets default paths to the config file
|
||||
if SetDefaultConfig {
|
||||
err := config.SetDefaults()
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
}
|
||||
//Sets default paths to the config file
|
||||
if SetDefaultConfig {
|
||||
_, err := generate.SetDefaults("P2PRC", false, nil, false)
|
||||
if err != nil {
|
||||
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 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 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)
|
||||
}
|
||||
// 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")
|
||||
}
|
||||
//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)
|
||||
}
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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 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)
|
||||
}
|
||||
}
|
||||
// -- REMOVE ON REGULAR RELEASE --
|
||||
// when flag --gen is called an extension
|
||||
// of the project is created to repurpose
|
||||
// the project for custom purpose
|
||||
if Generate != "" {
|
||||
var err error
|
||||
// If the module name is provided
|
||||
if Modulename != "" {
|
||||
err = generate.GenerateNewProject(Generate,Modulename)
|
||||
} else {
|
||||
err = generate.GenerateNewProject(Generate,Generate)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println("Created new folder: " + Generate)
|
||||
fmt.Println("1. Enter inside " + Generate + " directory")
|
||||
fmt.Println("2. git remote add " + Generate + " <PATH to the github repo>")
|
||||
fmt.Println("3. git push " + Generate + " <PATH to the github repo>")
|
||||
fmt.Println("4. go mod tidy")
|
||||
fmt.Println("5. sh install.sh " + Generate)
|
||||
fmt.Println("6. ./" + Generate + " -h (This is to test if the binary is working)")
|
||||
}
|
||||
}
|
||||
//--------------------------------
|
||||
// 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 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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
168
cmd/flags.go
@@ -6,223 +6,231 @@ import (
|
||||
|
||||
// Variables declared for CLI
|
||||
var (
|
||||
AddServer string
|
||||
ViewImages string
|
||||
CreateVM string
|
||||
ContainerName string
|
||||
Ports string
|
||||
Server bool
|
||||
RemoveVM string
|
||||
ID string
|
||||
Specs string
|
||||
GPU bool
|
||||
UpdateServerList bool
|
||||
ServerList bool
|
||||
SetDefaultConfig bool
|
||||
NetworkInterface bool
|
||||
ViewPlugin bool
|
||||
TrackedContainers bool
|
||||
ExecutePlugin string
|
||||
CreateGroup bool
|
||||
Group string
|
||||
AddServer string
|
||||
ViewImages string
|
||||
CreateVM string
|
||||
ContainerName string
|
||||
Ports string
|
||||
Server bool
|
||||
RemoveVM string
|
||||
ID string
|
||||
Specs string
|
||||
GPU bool
|
||||
UpdateServerList bool
|
||||
ServerList bool
|
||||
SetDefaultConfig bool
|
||||
NetworkInterface bool
|
||||
ViewPlugin bool
|
||||
TrackedContainers bool
|
||||
ExecutePlugin string
|
||||
CreateGroup bool
|
||||
Group string
|
||||
Groups bool
|
||||
RemoveContainerGroup bool
|
||||
RemoveGroup string
|
||||
RemoveGroup string
|
||||
//FRPProxy bool
|
||||
// Generate only allowed in dev release
|
||||
// -- REMOVE ON REGULAR RELEASE --
|
||||
Generate string
|
||||
Modulename string
|
||||
Generate string
|
||||
Modulename string
|
||||
//--------------------------------
|
||||
PullPlugin string
|
||||
RemovePlugin string
|
||||
PullPlugin string
|
||||
RemovePlugin string
|
||||
)
|
||||
|
||||
var AppConfigFlags = []cli.Flag{
|
||||
// Deprecated to be implemented using GRPC
|
||||
&cli.BoolFlag{
|
||||
Name: "Server",
|
||||
Aliases: []string{"s"},
|
||||
Aliases: []string{"s"},
|
||||
Usage: "Starts server",
|
||||
EnvVars: []string{"SERVER"},
|
||||
EnvVars: []string{"SERVER"},
|
||||
Destination: &Server,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "UpdateServerList",
|
||||
Aliases: []string{"us"},
|
||||
Aliases: []string{"us"},
|
||||
Usage: "Update List of Server available based on servers iptables",
|
||||
EnvVars: []string{"UPDATE_SERVER_LIST"},
|
||||
EnvVars: []string{"UPDATE_SERVER_LIST"},
|
||||
Destination: &UpdateServerList,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "ListServers",
|
||||
Aliases: []string{"ls"},
|
||||
Aliases: []string{"ls"},
|
||||
Usage: "List servers which can render tasks",
|
||||
EnvVars: []string{"LIST_SERVERS"},
|
||||
EnvVars: []string{"LIST_SERVERS"},
|
||||
Destination: &ServerList,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "AddServer",
|
||||
Aliases: []string{"as"},
|
||||
Aliases: []string{"as"},
|
||||
Usage: "Adds server IP address to iptables",
|
||||
EnvVars: []string{"ADD_SERVER"},
|
||||
EnvVars: []string{"ADD_SERVER"},
|
||||
Destination: &AddServer,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "ViewImages",
|
||||
Aliases: []string{"vi"},
|
||||
Aliases: []string{"vi"},
|
||||
Usage: "View images available on the server IP address",
|
||||
EnvVars: []string{"VIEW_IMAGES"},
|
||||
EnvVars: []string{"VIEW_IMAGES"},
|
||||
Destination: &ViewImages,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "CreateVM",
|
||||
Aliases: []string{"touch"},
|
||||
Aliases: []string{"touch"},
|
||||
Usage: "Creates Docker container on the selected server",
|
||||
EnvVars: []string{"CREATE_VM"},
|
||||
EnvVars: []string{"CREATE_VM"},
|
||||
Destination: &CreateVM,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "ContainerName",
|
||||
Aliases: []string{"cn"},
|
||||
Aliases: []string{"cn"},
|
||||
Usage: "Specifying the container run on the server side",
|
||||
EnvVars: []string{"CONTAINER_NAME"},
|
||||
EnvVars: []string{"CONTAINER_NAME"},
|
||||
Destination: &ContainerName,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "RemoveVM",
|
||||
Aliases: []string{"rm"},
|
||||
Usage: "Stop and Remove Docker container",
|
||||
EnvVars: []string{"REMOVE_VM"},
|
||||
Aliases: []string{"rm"},
|
||||
Usage: "Stop and Remove Docker container (IP:port) accompanied by container ID via --ID or --id",
|
||||
EnvVars: []string{"REMOVE_VM"},
|
||||
Destination: &RemoveVM,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "ID",
|
||||
Aliases: []string{"id"},
|
||||
Aliases: []string{"id"},
|
||||
Usage: "Docker Container ID",
|
||||
EnvVars: []string{"ID"},
|
||||
EnvVars: []string{"ID"},
|
||||
Destination: &ID,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "Ports",
|
||||
Aliases: []string{"p"},
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Number of ports to open for the Docker Container",
|
||||
EnvVars: []string{"NUM_PORTS"},
|
||||
EnvVars: []string{"NUM_PORTS"},
|
||||
Destination: &Ports,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "GPU",
|
||||
Aliases: []string{"gpu"},
|
||||
Aliases: []string{"gpu"},
|
||||
Usage: "Create Docker Containers to access GPU",
|
||||
EnvVars: []string{"USE_GPU"},
|
||||
EnvVars: []string{"USE_GPU"},
|
||||
Destination: &GPU,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "Specification",
|
||||
Aliases: []string{"specs"},
|
||||
Aliases: []string{"specs"},
|
||||
Usage: "Specs of the server node",
|
||||
EnvVars: []string{"SPECS"},
|
||||
EnvVars: []string{"SPECS"},
|
||||
Destination: &Specs,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "SetDefaultConfig",
|
||||
Aliases: []string{"dc"},
|
||||
Aliases: []string{"dc"},
|
||||
Usage: "Sets a default configuration file",
|
||||
EnvVars: []string{"SET_DEFAULT_CONFIG"},
|
||||
EnvVars: []string{"SET_DEFAULT_CONFIG"},
|
||||
Destination: &SetDefaultConfig,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "NetworkInterfaces",
|
||||
Aliases: []string{"ni"},
|
||||
Aliases: []string{"ni"},
|
||||
Usage: "Shows the network interface in your computer",
|
||||
EnvVars: []string{"NETWORK_INTERFACE"},
|
||||
EnvVars: []string{"NETWORK_INTERFACE"},
|
||||
Destination: &NetworkInterface,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "ViewPlugins",
|
||||
Aliases: []string{"vp"},
|
||||
Aliases: []string{"vp"},
|
||||
Usage: "Shows plugins available to be executed",
|
||||
EnvVars: []string{"VIEW_PLUGIN"},
|
||||
EnvVars: []string{"VIEW_PLUGIN"},
|
||||
Destination: &ViewPlugin,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "TrackedContainers",
|
||||
Name: "TrackedContainers",
|
||||
Aliases: []string{"tc"},
|
||||
Usage: "View containers which have " +
|
||||
"been created from the client side ",
|
||||
EnvVars: []string{"TRACKED_CONTAINERS"},
|
||||
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"},
|
||||
Aliases: []string{"plugin"},
|
||||
Usage: "Plugin which needs to be executed",
|
||||
EnvVars: []string{"EXECUTE_PLUGIN"},
|
||||
EnvVars: []string{"EXECUTE_PLUGIN"},
|
||||
Destination: &ExecutePlugin,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "CreateGroup",
|
||||
Aliases: []string{"cgroup"},
|
||||
Aliases: []string{"cgroup"},
|
||||
Usage: "Creates a new group",
|
||||
EnvVars: []string{"CREATE_GROUP"},
|
||||
EnvVars: []string{"CREATE_GROUP"},
|
||||
Destination: &CreateGroup,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "Group",
|
||||
Aliases: []string{"group"},
|
||||
Aliases: []string{"group"},
|
||||
Usage: "group flag with argument group ID",
|
||||
EnvVars: []string{"GROUP"},
|
||||
EnvVars: []string{"GROUP"},
|
||||
Destination: &Group,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "Groups",
|
||||
Aliases: []string{"groups"},
|
||||
Aliases: []string{"groups"},
|
||||
Usage: "View all groups",
|
||||
EnvVars: []string{"GROUPS"},
|
||||
EnvVars: []string{"GROUPS"},
|
||||
Destination: &Groups,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "RemoveContainerGroup",
|
||||
Aliases: []string{"rmcgroup"},
|
||||
Aliases: []string{"rmcgroup"},
|
||||
Usage: "Remove specific container in the group",
|
||||
EnvVars: []string{"REMOVE_CONTAINER_GROUP"},
|
||||
EnvVars: []string{"REMOVE_CONTAINER_GROUP"},
|
||||
Destination: &RemoveContainerGroup,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "RemoveGroup",
|
||||
Aliases: []string{"rmgroup"},
|
||||
Aliases: []string{"rmgroup"},
|
||||
Usage: "Removes the entire group",
|
||||
EnvVars: []string{"REMOVE_GROUP"},
|
||||
EnvVars: []string{"REMOVE_GROUP"},
|
||||
Destination: &RemoveGroup,
|
||||
},
|
||||
// Generate only allowed in dev release
|
||||
// -- REMOVE ON REGULAR RELEASE --
|
||||
&cli.StringFlag{
|
||||
Name: "Generate",
|
||||
Aliases: []string{"gen"},
|
||||
Aliases: []string{"gen"},
|
||||
Usage: "Generates a new copy of P2PRC which can be modified based on your needs",
|
||||
EnvVars: []string{"GENERATE"},
|
||||
EnvVars: []string{"GENERATE"},
|
||||
Destination: &Generate,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "ModuleName",
|
||||
Aliases: []string{"mod"},
|
||||
Aliases: []string{"mod"},
|
||||
Usage: "New go project module name",
|
||||
EnvVars: []string{"MODULENAME"},
|
||||
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"},
|
||||
Aliases: []string{"pp"},
|
||||
Usage: "Pulls plugin from git repos",
|
||||
EnvVars: []string{"PULLPLUGIN"},
|
||||
EnvVars: []string{"PULLPLUGIN"},
|
||||
Destination: &PullPlugin,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "RemovePlugin",
|
||||
Aliases: []string{"rp"},
|
||||
Aliases: []string{"rp"},
|
||||
Usage: "Removes plugin",
|
||||
EnvVars: []string{"REMOVEPLUGIN"},
|
||||
EnvVars: []string{"REMOVEPLUGIN"},
|
||||
Destination: &RemovePlugin,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
268
config/config.go
@@ -1,72 +1,52 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/spf13/viper"
|
||||
"io"
|
||||
"os"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultPath string
|
||||
defaults = map[string]interface{}{}
|
||||
configName = "config"
|
||||
configType = "json"
|
||||
configFile = "config.json"
|
||||
configPaths []string
|
||||
defaultEnvName = "P2PRC"
|
||||
//defaultPath string
|
||||
defaults = map[string]interface{}{}
|
||||
configName = "config"
|
||||
configType = "json"
|
||||
configFile = "config.json"
|
||||
configPaths []string
|
||||
defaultEnvName = "P2PRC"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
IPTable string
|
||||
DockerContainers string
|
||||
DefaultDockerFile string
|
||||
SpeedTestFile string
|
||||
IPV6Address string
|
||||
PluginPath string
|
||||
TrackContainersPath string
|
||||
ServerPort string
|
||||
GroupTrackContainersPath string
|
||||
//NetworkInterface string
|
||||
//NetworkInterfaceIPV6Index int
|
||||
}
|
||||
|
||||
// Exists reports whether the named file or directory exists.
|
||||
func fileExists(name string) bool {
|
||||
if _, err := os.Stat(name); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Copy the src file to dst. Any existing file will be overwritten and will not
|
||||
// copy file attributes.
|
||||
// Source: https://stackoverflow.com/questions/21060945/simple-way-to-copy-a-file
|
||||
func Copy(src, dst string) error {
|
||||
in, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer in.Close()
|
||||
|
||||
out, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
_, err = io.Copy(out, in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return out.Close()
|
||||
MachineName string
|
||||
IPTable string
|
||||
DockerContainers string
|
||||
DefaultDockerFile string
|
||||
SpeedTestFile string
|
||||
IPV6Address string
|
||||
PluginPath string
|
||||
TrackContainersPath string
|
||||
ServerPort string
|
||||
GroupTrackContainersPath string
|
||||
FRPServerPort string
|
||||
BehindNAT string
|
||||
CustomConfig interface{}
|
||||
//NetworkInterface string
|
||||
//NetworkInterfaceIPV6Index int
|
||||
}
|
||||
|
||||
// GetPathP2PRC Getting P2PRC Directory from environment variable
|
||||
func GetPathP2PRC()(string,error) {
|
||||
curDir := os.Getenv(defaultEnvName)
|
||||
return curDir + "/", nil
|
||||
func GetPathP2PRC(Envname string) (string, error) {
|
||||
if Envname != "" {
|
||||
err := SetEnvName(Envname)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
curDir := os.Getenv(defaultEnvName)
|
||||
if curDir == "" {
|
||||
return curDir, nil
|
||||
}
|
||||
return curDir + "/", nil
|
||||
}
|
||||
|
||||
// SetEnvName Sets the environment name
|
||||
@@ -74,113 +54,103 @@ func GetPathP2PRC()(string,error) {
|
||||
// your environment variable
|
||||
// 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
|
||||
defaultEnvName = EnvName
|
||||
// Handling error to be implemented only if needed
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCurrentPath Getting P2PRC Directory from environment variable
|
||||
func GetCurrentPath()(string,error) {
|
||||
curDir := os.Getenv("PWD")
|
||||
return curDir + "/", nil
|
||||
func GetEnvName() string {
|
||||
return defaultEnvName
|
||||
}
|
||||
|
||||
// ConfigInit Pass environment name as an optional parameter
|
||||
func ConfigInit(defaultsParameter map[string]interface{}, CustomConfig interface{}, envNameOptional ...string) (*Config, error) {
|
||||
if len(envNameOptional) > 0 {
|
||||
defaultEnvName = envNameOptional[0]
|
||||
}
|
||||
//
|
||||
////Setting current directory to default path
|
||||
//defaultPath, err := GetPathP2PRC(defaultEnvName)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
////Paths to search for config file
|
||||
//configPaths = append(configPaths, defaultPath)
|
||||
//
|
||||
////Add all possible configurations paths
|
||||
//for _, v := range configPaths {
|
||||
// viper.AddConfigPath(v)
|
||||
//}
|
||||
//
|
||||
////Read config file
|
||||
//if err := viper.ReadInConfig(); err != nil {
|
||||
// // If the error thrown is config file not found
|
||||
// //Sets default configuration to viper
|
||||
// for k, v := range defaults {
|
||||
// viper.SetDefault(k, v)
|
||||
// }
|
||||
// viper.SetConfigName(configName)
|
||||
// viper.SetConfigFile(configFile)
|
||||
// viper.SetConfigType(configType)
|
||||
//
|
||||
// if err = viper.WriteConfig(); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// Adds configuration to the struct
|
||||
//var config Config
|
||||
//if err := viper.Unmarshal(&config); err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
//
|
||||
//return &config, nil
|
||||
|
||||
// SetDefaults This function to be called only during a
|
||||
// make install
|
||||
func SetDefaults() error {
|
||||
//Setting current directory to default path
|
||||
defaultPath, err := GetPathP2PRC()
|
||||
if err != nil{
|
||||
return err
|
||||
}
|
||||
defaultPath, err := GetPathP2PRC(defaultEnvName)
|
||||
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
|
||||
}
|
||||
// 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
|
||||
}
|
||||
|
||||
//Creates a copy of trackcontainers.json in the appropriate directory
|
||||
err = Copy("client/trackcontainers.json","client/trackcontainers/trackcontainers.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// defer the closing of our jsonFile so that we can parse it later on
|
||||
defer jsonFile.Close()
|
||||
|
||||
//Creates a copy of trackcontainers.json in the appropriate directory
|
||||
err = Copy("client/grouptrackcontainers.json","client/trackcontainers/grouptrackcontainers.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
byteValue, _ := ioutil.ReadAll(jsonFile)
|
||||
|
||||
var config Config
|
||||
json.Unmarshal(byteValue, &config)
|
||||
|
||||
//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["NetworkInterface"] = "wlp0s20f3"
|
||||
//defaults["NetworkInterfaceIPV6Index"] = "2"
|
||||
if CustomConfig != nil {
|
||||
// Convert Custom Config to byte
|
||||
customConfigByte, err := json.Marshal(config.CustomConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//Paths to search for config file
|
||||
configPaths = append(configPaths, defaultPath)
|
||||
// Again map the byte to the CustomConfig interface
|
||||
json.Unmarshal(customConfigByte, &CustomConfig)
|
||||
}
|
||||
|
||||
if fileExists(defaultPath + "config.json") {
|
||||
err := os.Remove(defaultPath + "config.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
//Calling configuration file
|
||||
_, err = ConfigInit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
func ConfigInit()(*Config,error) {
|
||||
func (c *Config) WriteConfig() error {
|
||||
//Getting Current Directory from environment variable
|
||||
//curDir := os.Getenv("REMOTEGAMING")
|
||||
|
||||
//Setting current directory to default path
|
||||
defaultPath, err := GetPathP2PRC()
|
||||
if err != nil{
|
||||
return nil, err
|
||||
}
|
||||
//Paths to search for config file
|
||||
configPaths = append(configPaths, defaultPath)
|
||||
defaultPath, err := GetPathP2PRC(defaultEnvName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Add all possible configurations paths
|
||||
for _,v := range configPaths {
|
||||
viper.AddConfigPath(v)
|
||||
}
|
||||
file, _ := json.MarshalIndent(c, "", " ")
|
||||
|
||||
//Read config file
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
// If the error thrown is config file not found
|
||||
//Sets default configuration to viper
|
||||
for k,v := range defaults {
|
||||
viper.SetDefault(k,v)
|
||||
}
|
||||
viper.SetConfigName(configName)
|
||||
viper.SetConfigFile(configFile)
|
||||
viper.SetConfigType(configType)
|
||||
|
||||
if err = viper.WriteConfig(); err != nil {
|
||||
return nil,err
|
||||
}
|
||||
}
|
||||
|
||||
// Adds configuration to the struct
|
||||
var config Config
|
||||
if err := viper.Unmarshal(&config); err != nil {
|
||||
return nil,err
|
||||
}
|
||||
|
||||
return &config,nil
|
||||
_ = ioutil.WriteFile(defaultPath+"config.json", file, 0644)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConfigInit(t *testing.T) {
|
||||
_,err := ConfigInit()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaults(t *testing.T) {
|
||||
err := SetDefaults()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCurrentPath(t *testing.T) {
|
||||
path, err := GetCurrentPath()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
fmt.Println(path)
|
||||
}
|
||||
|
||||
func TestGetPathP2PRC(t *testing.T) {
|
||||
path, err := GetPathP2PRC()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
fmt.Println(path)
|
||||
}
|
||||
|
||||
func TestSetEnvName(t *testing.T) {
|
||||
// Create an Env variable TEST with the value "lol"
|
||||
err := os.Setenv("TEST", "lol")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
// Sets the environment variable as the default to read
|
||||
// for P2PRC
|
||||
err = SetEnvName("TEST")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// Checks if the output for the default read is "lol"
|
||||
path, err := GetPathP2PRC()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
fmt.Println(path)
|
||||
}
|
||||
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)
|
||||
}
|
||||
131
config/generate/generate.go
Normal file
@@ -0,0 +1,131 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
defaults = map[string]interface{}{}
|
||||
configPaths []string
|
||||
defaultEnvName = "P2PRC"
|
||||
)
|
||||
|
||||
// GetPathP2PRC Getting P2PRC Directory from environment variable
|
||||
func GetPathP2PRC() (string, error) {
|
||||
curDir := os.Getenv(defaultEnvName)
|
||||
return curDir + "/", nil
|
||||
}
|
||||
|
||||
// SetEnvName Sets the environment name
|
||||
// This is to ensure that the Path of your project is detected from
|
||||
// your environment variable
|
||||
// This is useful when extending the use case of P2PRC
|
||||
func SetEnvName(EnvName string) error {
|
||||
if EnvName != "" {
|
||||
defaultEnvName = EnvName
|
||||
}
|
||||
// Handling error to be implemented only if needed
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCurrentPath Getting P2PRC Directory from environment variable
|
||||
func GetCurrentPath() (string, error) {
|
||||
curDir := os.Getenv("PWD")
|
||||
return curDir + "/", nil
|
||||
}
|
||||
|
||||
// SetDefaults This function to be called only during a
|
||||
// make install
|
||||
func SetDefaults(envName string, forceDefault bool, CustomConfig interface{}, NoBoilerPlate bool, ConfigUpdate ...*config.Config) (*config.Config, error) {
|
||||
//Setting current directory to default path
|
||||
defaultPath, err := GetCurrentPath()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set Env name
|
||||
err = config.SetEnvName(envName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
////Creates ip_table.json in the json directory
|
||||
//err = Copy("p2p/ip_table.json", "p2p/iptable/ip_table.json")
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
////Creates a copy of trackcontainers.json in the appropriate directory
|
||||
//err = Copy("client/trackcontainers.json", "client/trackcontainers/trackcontainers.json")
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
////Creates a copy of trackcontainers.json in the appropriate directory
|
||||
//err = Copy("client/grouptrackcontainers.json", "client/trackcontainers/grouptrackcontainers.json")
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
var Defaults config.Config
|
||||
|
||||
if len(ConfigUpdate) == 0 {
|
||||
//Setting default paths for the config file
|
||||
Defaults.IPTable = defaultPath + "p2p/iptable/ip_table.json"
|
||||
Defaults.DefaultDockerFile = defaultPath + "server/docker/containers/docker-ubuntu-sshd/"
|
||||
Defaults.DockerContainers = defaultPath + "server/docker/containers/"
|
||||
Defaults.SpeedTestFile = defaultPath + "p2p/50.bin"
|
||||
Defaults.IPV6Address = ""
|
||||
Defaults.PluginPath = defaultPath + "plugin/deploy"
|
||||
Defaults.TrackContainersPath = defaultPath + "client/trackcontainers/trackcontainers.json"
|
||||
Defaults.GroupTrackContainersPath = defaultPath + "client/trackcontainers/grouptrackcontainers.json"
|
||||
Defaults.ServerPort = "8088"
|
||||
Defaults.FRPServerPort = "True"
|
||||
Defaults.CustomConfig = CustomConfig
|
||||
Defaults.BehindNAT = "True"
|
||||
// Random name generator
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Defaults.MachineName = hostname
|
||||
} else {
|
||||
Defaults = *ConfigUpdate[0]
|
||||
}
|
||||
|
||||
//defaults["NetworkInterface"] = "wlp0s20f3"
|
||||
//defaults["NetworkInterfaceIPV6Index"] = "2"
|
||||
|
||||
//Paths to search for config file
|
||||
configPaths = append(configPaths, defaultPath)
|
||||
|
||||
if fileExists(defaultPath+"config.json") && forceDefault {
|
||||
err := os.Remove(defaultPath + "config.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// write defaults to the config file
|
||||
err = Defaults.WriteConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//Calling configuration file
|
||||
Config, err := config.ConfigInit(defaults, nil, envName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !NoBoilerPlate {
|
||||
err = GenerateFiles()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return Config, nil
|
||||
}
|
||||
163
config/generate/generateFiles.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"os"
|
||||
)
|
||||
|
||||
// GenerateFiles Generates all the files needed to setup P2PRC
|
||||
func GenerateFiles(rootNodes ...p2p.IpAddress) (err error) {
|
||||
err = GenerateIPTableFile(rootNodes)
|
||||
err = GenerateDockerFiles()
|
||||
err = GeneratePluginDirectory()
|
||||
err = GenerateClientTrackContainers()
|
||||
return
|
||||
}
|
||||
|
||||
// GenerateIPTableFile Generates the IPTable file with the appropirate root node
|
||||
func GenerateIPTableFile(rootNodes []p2p.IpAddress) (err error) {
|
||||
var rootnodes p2p.IpAddresses
|
||||
var rootnode p2p.IpAddress
|
||||
|
||||
err = CreateIPTableFolderStructure()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If root node addresses are not provided as optional parameters
|
||||
if len(rootNodes) <= 0 {
|
||||
rootnode.Name = "Node1"
|
||||
rootnode.ServerPort = "8088"
|
||||
rootnode.NAT = "False"
|
||||
rootnode.Ipv4 = "64.227.168.102"
|
||||
|
||||
rootnodes.IpAddress = append(rootnodes.IpAddress, rootnode)
|
||||
} else {
|
||||
// if root nodes are provided then override them as the optional parameter
|
||||
for i := range rootNodes {
|
||||
rootnodes.IpAddress = append(rootnodes.IpAddress, rootNodes[i])
|
||||
}
|
||||
}
|
||||
|
||||
err = rootnodes.WriteIpTable()
|
||||
return
|
||||
}
|
||||
|
||||
// CreateIPTableFolderStructure Create folder structure for IPTable
|
||||
func CreateIPTableFolderStructure() (err error) {
|
||||
path, err := GetCurrentPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = os.Stat(path + "p2p"); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(path+"p2p", os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err = os.Stat(path + "p2p/iptable"); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(path+"p2p/iptable", os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err = os.Stat(path + "p2p/iptable/ip_table.json"); os.IsNotExist(err) {
|
||||
_, err = os.Create(path + "p2p/iptable/ip_table.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GenerateDockerFiles Generate default docker files
|
||||
func GenerateDockerFiles() (err error) {
|
||||
path, err := GetCurrentPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = os.Stat(path + "server"); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(path+"server", os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = os.Stat(path + "server/docker"); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(path+"server/docker", os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err = os.Stat(path + "server/docker/containers"); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(path+"server/docker/containers", os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err = os.Stat(path + "server/docker/containers"); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(path+"server/docker/containers", os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err = os.Stat(path + "server/docker/containers/docker-ubuntu-sshd"); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(path+"server/docker/containers/docker-ubuntu-sshd", os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Clone base docker image
|
||||
_, err = git.PlainClone(path+"server/docker/containers/docker-ubuntu-sshd", false, &git.CloneOptions{
|
||||
URL: "https://github.com/Akilan1999/docker-ubuntu-sshd",
|
||||
Progress: os.Stdout,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GeneratePluginDirectory Generates plugin directory structure
|
||||
func GeneratePluginDirectory() (err error) {
|
||||
path, err := GetCurrentPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = os.Stat(path + "plugin"); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(path+"plugin", os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = os.Stat(path + "plugin/deploy"); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(path+"plugin/deploy", os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GenerateClientTrackContainers() (err error) {
|
||||
path, err := GetCurrentPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = os.Stat(path + "client"); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(path+"client", os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = os.Stat(path + "client/trackcontainers.json"); os.IsNotExist(err) {
|
||||
_, err = os.Create(path + "client/trackcontainers.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err = os.Stat(path + "client/grouptrackcontainers.json"); os.IsNotExist(err) {
|
||||
_, err = os.Create(path + "client/grouptrackcontainers.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
35
config/generate/gernerate_test.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type CustomConfig struct {
|
||||
Test string
|
||||
}
|
||||
|
||||
// Test case to generate defaults with custom data-structure
|
||||
func TestSetDefaults(t *testing.T) {
|
||||
setDefaults, err := SetDefaults("", true, &CustomConfig{Test: "lol"}, true)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(setDefaults)
|
||||
|
||||
var c CustomConfig
|
||||
|
||||
_, err = config.ConfigInit(nil, &c)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(c)
|
||||
|
||||
}
|
||||
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()
|
||||
}
|
||||
@@ -1,386 +0,0 @@
|
||||
// Package generate The purpose of this package is to ensure that we can extend the use-case of P2PRC.
|
||||
// We will create a project directory with the template to extend the use-case of P2PRC
|
||||
package generate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"github.com/otiai10/copy"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
modfile "golang.org/x/mod/modfile"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// NewProject Struct information required when creating a new project
|
||||
type NewProject struct {
|
||||
Name string
|
||||
Module string
|
||||
NewDir string
|
||||
P2PRCPath string
|
||||
CurrentModule string
|
||||
Option *copy.Options
|
||||
Token *token.FileSet
|
||||
AST *ast.File
|
||||
FileNameAST string
|
||||
}
|
||||
|
||||
// GenerateNewProject creates a new copy of the P2PRC
|
||||
// project for custom modification
|
||||
func GenerateNewProject(name string, module string) error {
|
||||
// Create new variable of type NewProject
|
||||
var newProject NewProject
|
||||
//Setting module name to the new project
|
||||
newProject.Module = module
|
||||
// Get path of the current directory
|
||||
curDir, err := config.GetCurrentPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Folder name of the new generated project
|
||||
newProject.NewDir = curDir + name + "/"
|
||||
// Create a new folder based on name entered
|
||||
err = CreateFolder(name, curDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// get path of P2PRC
|
||||
P2PRCPATH, err := config.GetPathP2PRC()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Assign P2PRC path to the newly generated project
|
||||
newProject.P2PRCPath = P2PRCPATH
|
||||
// Steps:
|
||||
// - copy all files from P2PRC
|
||||
// - remove go.mod and go.sum and create new ones
|
||||
|
||||
// Files we require to skip
|
||||
|
||||
var Options copy.Options
|
||||
|
||||
// IF YOU ARE RELEASING AN EXTENSION OF P2PRC
|
||||
// MODIFY HERE (AN EXTENSION FROM YOUR EXTENSION :P)
|
||||
// Skip or have the appropriate files and directories not needed
|
||||
//----------------------------------------------------------------
|
||||
// Action performed:
|
||||
// - Ensuring main.go file exists
|
||||
// - Ensuring generate.go file exists
|
||||
// - Ensuring modifyGenerate.go file exists
|
||||
// - Ensuring generate_test.go file exists
|
||||
// - Ensuring server/server.go file exists
|
||||
// - Ensuring server/gopsutil.go file exists
|
||||
// - Ensuring server/gpu.go file exists
|
||||
// - Ensuring cmd/action.go file exists
|
||||
// - Ensuring cmd/flags.go file exists
|
||||
// - Skipping all .go files apart from the ones listed above
|
||||
// - Skipping go.mod file
|
||||
// - Skipping go.sum file
|
||||
// - Skipping .idea/ directory
|
||||
// - Skipping Makefile file
|
||||
// - Skipping <Project Name>/ directory
|
||||
//----------------------------------------------------------------
|
||||
Options.Skip = func(src string) (bool, error) {
|
||||
switch {
|
||||
case strings.HasSuffix(src, "main.go"):
|
||||
return false, nil
|
||||
case strings.HasSuffix(src, "generate.go"):
|
||||
return false, nil
|
||||
case strings.HasSuffix(src, "modifyGenerate.go"):
|
||||
return false, nil
|
||||
case strings.HasSuffix(src, "generate_test.go"):
|
||||
return false, nil
|
||||
case strings.HasSuffix(src, "server/server.go"):
|
||||
return false, nil
|
||||
case strings.HasSuffix(src, "server/gopsutil.go"):
|
||||
return false, nil
|
||||
case strings.HasSuffix(src, "server/gpu.go"):
|
||||
return false, nil
|
||||
case strings.HasSuffix(src, "cmd/action.go"):
|
||||
return false, nil
|
||||
case strings.HasSuffix(src, "cmd/flags.go"):
|
||||
return false, nil
|
||||
case strings.HasSuffix(src, "config/config.go"):
|
||||
return false, nil
|
||||
case strings.HasSuffix(src, "config/config_test.go"):
|
||||
return false, nil
|
||||
case strings.HasSuffix(src, ".go"):
|
||||
return true, nil
|
||||
case strings.HasSuffix(src, "go.mod"):
|
||||
return true, nil
|
||||
case strings.HasSuffix(src, "go.sum"):
|
||||
return true, nil
|
||||
case strings.HasSuffix(src, ".idea"):
|
||||
return true, nil
|
||||
case strings.HasSuffix(src, "Makefile"):
|
||||
return true, nil
|
||||
case strings.HasSuffix(src, name):
|
||||
return true, nil
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Storing type option in the struct new project
|
||||
newProject.Option = &Options
|
||||
|
||||
// Copies all files from P2PRC to the new project created
|
||||
err = copy.Copy(newProject.P2PRCPath, newProject.NewDir, *newProject.Option)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Creating a new go.mod file in the appropriate directory
|
||||
err = newProject.CreateGoMod()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get current project mod name
|
||||
err = newProject.GetCurrentGoModule()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Change the appropriate imports
|
||||
err = newProject.ChangeImportFiles()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add changes inside the new project
|
||||
err = newProject.GitAdd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// commit changes inside the new project
|
||||
err = newProject.GitCommit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Creates go.sum file
|
||||
//err = newProject.CreateGoModTidy()
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateFolder Creates a new folder based on the name and path provided
|
||||
func CreateFolder(name string, path string) error {
|
||||
//Create a folder/directory at a full qualified path
|
||||
err := os.Mkdir(path+name, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateGoMod Creates a new go module for the new project created
|
||||
func (a *NewProject) CreateGoMod() error {
|
||||
// Create new go.mod in the appropriate directory
|
||||
cmd := exec.Command("go", "mod", "init", a.Module)
|
||||
cmd.Dir = a.NewDir
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *NewProject) CreateGoModTidy() error {
|
||||
// Installs all the appropriate dependencies and creates go.sum
|
||||
cmd := exec.Command("go", "mod", "tidy")
|
||||
cmd.Dir = a.NewDir
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ChangeImportFiles Changes Appropriate imports in the appropriate file
|
||||
func (a *NewProject) ChangeImportFiles() error {
|
||||
// IF YOU ARE RELEASING AN EXTENSION OF P2PRC
|
||||
// MODIFY HERE (AN EXTENSION FROM YOUR EXTENSION :P)
|
||||
//----------------------------------------------------------------
|
||||
// Action performed:
|
||||
// Files we would need to modify the imports in
|
||||
// - generate/generate.go -> config module
|
||||
// - generate/generate_test.go -> config module
|
||||
// - cmd/action.go -> config module, server module, generate module
|
||||
// - cmd/flags.go -> config module, server module, generate module
|
||||
// - server/server.go -> config module
|
||||
// - main.go -> cmd module
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// 1.0 - generate/generate.go -> config module
|
||||
a.FileNameAST = a.NewDir + "generate/generate.go"
|
||||
// Get AST information of the file
|
||||
err := a.GetASTGoFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Change the appropriate Go file
|
||||
err = a.ChangeImports(a.CurrentModule+"/config", a.Module+"/config")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Writes the change to the appropriate file
|
||||
err = a.WriteGoAst()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// 1.1 - generate/generate_test.go -> config module
|
||||
a.FileNameAST = a.NewDir + "generate/generate_test.go"
|
||||
// Get AST information of the file
|
||||
err = a.GetASTGoFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Change the appropriate Go file
|
||||
err = a.ChangeImports(a.CurrentModule+"/config", a.Module+"/config")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Writes the change to the appropriate file
|
||||
err = a.WriteGoAst()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//-----------------------------------------------------------------
|
||||
// 2.0 - cmd/action.go -> config module, server module, generate module
|
||||
a.FileNameAST = a.NewDir + "cmd/action.go"
|
||||
// Get AST information of the file
|
||||
err = a.GetASTGoFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Change the appropriate Go file
|
||||
err = a.ChangeImports(a.CurrentModule+"/config", a.Module+"/config")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = a.ChangeImports(a.CurrentModule+"/server", a.Module+"/server")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = a.ChangeImports(a.CurrentModule+"/generate", a.Module+"/generate")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Writes the change to the appropriate file
|
||||
err = a.WriteGoAst()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// 2.1 - cmd/flags.go -> config module, server module, generate module
|
||||
a.FileNameAST = a.NewDir + "cmd/flags.go"
|
||||
// Get AST information of the file
|
||||
err = a.GetASTGoFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Change the appropriate Go file
|
||||
err = a.ChangeImports(a.CurrentModule+"/config", a.Module+"/config")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = a.ChangeImports(a.CurrentModule+"/server", a.Module+"/server")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = a.ChangeImports(a.CurrentModule+"/generate", a.Module+"/generate")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Writes the change to the appropriate file
|
||||
err = a.WriteGoAst()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
//-----------------------------------------------------------------
|
||||
// 3.0 - server/server.go -> config module
|
||||
a.FileNameAST = a.NewDir + "server/server.go"
|
||||
// Get AST information of the file
|
||||
err = a.GetASTGoFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Change the appropriate Go file
|
||||
err = a.ChangeImports(a.CurrentModule+"/config", a.Module+"/config")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Writes the change to the appropriate file
|
||||
err = a.WriteGoAst()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
//-----------------------------------------------------------------
|
||||
// 4.0 - server/server.go -> config module
|
||||
a.FileNameAST = a.NewDir + "main.go"
|
||||
// Get AST information of the file
|
||||
err = a.GetASTGoFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Change the appropriate Go file
|
||||
err = a.ChangeImports(a.CurrentModule+"/cmd", a.Module+"/cmd")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Writes the change to the appropriate file
|
||||
err = a.WriteGoAst()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCurrentGoModule Gets the current go module name
|
||||
func (a *NewProject) GetCurrentGoModule() error {
|
||||
goModBytes, err := ioutil.ReadFile(a.P2PRCPath + "go.mod")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
modName := modfile.ModulePath(goModBytes)
|
||||
fmt.Fprintf(os.Stdout, "modName=%+v\n", modName)
|
||||
|
||||
// Set current module to struct of file NewProject
|
||||
a.CurrentModule = modName
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *NewProject) GitAdd() error {
|
||||
// Installs all the appropriate dependencies and creates go.sum
|
||||
cmd := exec.Command("git", "add", ".")
|
||||
cmd.Dir = a.NewDir
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *NewProject) GitCommit() error {
|
||||
// Installs all the appropriate dependencies and creates go.sum
|
||||
cmd := exec.Command("git", "commit", "-m=removed appropriate go files")
|
||||
cmd.Dir = a.NewDir
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Tests the create folder function creates a folder
|
||||
// This test will create a folder in the temporary
|
||||
// directory
|
||||
func TestCreateFolder(t *testing.T) {
|
||||
err := CreateFolder("test", "/tmp/")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Testing if a new project is created successfully
|
||||
func TestGenerateNewProject(t *testing.T) {
|
||||
// Checking if a new project is created successfully
|
||||
err := GenerateNewProject("p2prctest","p2prctest")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Testing AST function to ensure imports are
|
||||
// working as intended
|
||||
func TestChangingImportAST(t *testing.T) {
|
||||
// Create a new variable of type NewProject
|
||||
var np NewProject
|
||||
// Get current directory
|
||||
path, err := config.GetCurrentPath()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
// Create testcase scenario
|
||||
err = config.Copy(path + "testcaseAST.go", path + "/Test/testcaseAST.go")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
// Sets new directory to the folder test
|
||||
np.NewDir = path + "Test/"
|
||||
// Sets file name to be opened and modified in the AST
|
||||
np.FileNameAST = path + "Test/" + "testcaseAST.go"
|
||||
// Call the Read AST function
|
||||
err = np.GetASTGoFile()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
// Change an import
|
||||
err = np.ChangeImports("fmt", "lolol")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
// Write those saved changes
|
||||
err = np.WriteGoAst()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Testing the if Go Mod is created
|
||||
func TestNewProject_CreateGoMod(t *testing.T) {
|
||||
// Create a new variable of type NewProject
|
||||
var np NewProject
|
||||
path, err := config.GetCurrentPath()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
// Set new project name as Test
|
||||
np.Name = "Test"
|
||||
// Set new project module as github.com/Test
|
||||
np.Module = "github.com/Test"
|
||||
// Set Path of the new project
|
||||
np.NewDir = path + "Test/"
|
||||
// Creating a go.mod file
|
||||
err = np.CreateGoMod()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Testing if the current go module is returned
|
||||
func TestNewProject_GetCurrentGoModule(t *testing.T) {
|
||||
// Create a new variable of type NewProject
|
||||
var np NewProject
|
||||
path, err := config.GetPathP2PRC()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
// Set Current project path
|
||||
np.P2PRCPath = path
|
||||
// Get module name
|
||||
err = np.GetCurrentGoModule()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Error(err)
|
||||
}
|
||||
fmt.Println(np.CurrentModule)
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"go/parser"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"os"
|
||||
)
|
||||
|
||||
|
||||
// GetASTGoFile Gets AST of the Go file provided
|
||||
func (np *NewProject)GetASTGoFile() error{
|
||||
fset := token.NewFileSet()
|
||||
node, err := parser.ParseFile(fset, np.FileNameAST, nil, parser.ParseComments)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//Write Token information to the struct
|
||||
np.Token = fset
|
||||
// Write AST information the struct
|
||||
np.AST = node
|
||||
return nil
|
||||
}
|
||||
|
||||
// ChangeImports Changes import of the AST
|
||||
func (np *NewProject)ChangeImports(CurrentImport string,ChangedImport string) error {
|
||||
// Iterating through the loop and changing the appropriate import
|
||||
for i, spec := range np.AST.Imports {
|
||||
// If the current import is found then change it
|
||||
if spec.Path.Value == "\"" + CurrentImport + "\"" {
|
||||
np.AST.Imports[i].Path.Value = "\"" + ChangedImport + "\""
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteGoAst Write changed imports back to the AST
|
||||
func (np *NewProject)WriteGoAst() error {
|
||||
// write new AST to file
|
||||
f, err := os.Create(np.FileNameAST)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer f.Close()
|
||||
if err := printer.Fprint(f, np.Token, np.AST); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func TestCaseAST() {
|
||||
fmt.Println("lol")
|
||||
}
|
||||
16
go.mod
@@ -1,35 +1,27 @@
|
||||
module git.sr.ht/~akilan1999/p2p-rendering-computation
|
||||
module github.com/Akilan1999/p2p-rendering-computation
|
||||
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/Microsoft/hcsshim v0.8.15 // indirect
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
|
||||
github.com/apenella/go-ansible v1.1.0
|
||||
github.com/containerd/continuity v0.0.0-20210315143101-93e15499afd5 // indirect
|
||||
github.com/docker/docker v20.10.0-beta1.0.20201113105859-b6bfff2a628f+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/fatedier/frp v0.45.0
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/go-git/go-git/v5 v5.4.2
|
||||
github.com/go-ole/go-ole v1.2.5 // indirect
|
||||
github.com/google/go-cmp v0.5.4 // indirect
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/lithammer/shortuuid v3.0.0+incompatible
|
||||
github.com/moby/sys/mount v0.2.0 // indirect
|
||||
github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/otiai10/copy v1.6.0
|
||||
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
|
||||
github.com/shirou/gopsutil v3.20.12+incompatible
|
||||
github.com/spf13/viper v1.4.0
|
||||
github.com/shirou/gopsutil/v3 v3.22.10
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40 // indirect
|
||||
gitlab.com/NebulousLabs/go-upnp v0.0.0-20181011194642-3a71999ed0d3
|
||||
golang.org/x/mod v0.3.0
|
||||
golang.org/x/text v0.3.5 // indirect
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
google.golang.org/grpc v1.35.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gotest.tools/v3 v3.0.3 // indirect
|
||||
)
|
||||
|
||||
61
index.html
@@ -1,61 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>P2PRC</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img src="Docs/images/p2prclogo.png" alt="P2PRC Logo">
|
||||
<h1>P2PRC</h1>
|
||||
<b>A peer to peer network designed for computation</b>
|
||||
|
||||
<p><dfn>P2PRC</dfn> is peer to peer to network designed for computation reasons.</p>
|
||||
<p>This project was developed during my 4th year dissertation at Heriot-Watt University and We are getting the
|
||||
project to a usable state.</p>
|
||||
<p> It's purpose is for people to use each others computers rather than servers such as <abbr title="Amazon Web Services">AWS</abbr> and <span title="Microsoft Azure">Azure</span>.</p>
|
||||
|
||||
<p><b>Project:</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://github.com/Akilan1999/p2p-rendering-computation" target="_blank">P2PRC on GitHub</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://discord.gg/b4nRGTjYqy" target="_blank">P2PRC Discord Server</a> <span style="color: red;">(join here to chat!)</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p><b>Community Server to download public network</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Only for v1.0.0</b>
|
||||
<br>
|
||||
<!-- <b>IP Address: 172.104.44.195</b>-->
|
||||
<p>Use this server to only download part of the p2p network</p>
|
||||
</li>
|
||||
<li>
|
||||
<b>Master branch</b>
|
||||
<br>
|
||||
<!-- <b>IP Address: 139.162.246.221</b>-->
|
||||
<p>Use this server to only download part of the p2p network</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p><b>Main developer:</b></p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<b><a href="https://akilan.io" target="_blank"><span title="The Not So Boring Developer">Akilan Selvacoumar</span></a></b>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p><b>Other links:</b></p>
|
||||
<ul>
|
||||
<li><a href="https://www.youtube.com/channel/UChy18QB1hBzZ7MniIW_FJvQ" target="_blank">Akilan Selvacoumar on YouTube</a></li>
|
||||
<li><a href="https://akilan.io/projects/p2prc/" target="_blank">Project info from akilan.io</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
9
main.go
@@ -1,10 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/cmd"
|
||||
"github.com/urfave/cli/v2"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/Akilan1999/p2p-rendering-computation/cmd"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// VERSION specifies the version of the platform
|
||||
@@ -12,7 +13,7 @@ var VERSION = "1.5.0"
|
||||
var mode string
|
||||
|
||||
// Varaibles if mode is client
|
||||
var OS, Pull_location ,Run_script string
|
||||
var OS, Pull_location, Run_script string
|
||||
var List_servers, Ip_table bool
|
||||
|
||||
func main() {
|
||||
@@ -27,4 +28,4 @@ func main() {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
178
p2p/frp/client.go
Normal file
@@ -0,0 +1,178 @@
|
||||
package frp
|
||||
|
||||
import (
|
||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||
"github.com/fatedier/frp/client"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
"github.com/phayes/freeport"
|
||||
)
|
||||
|
||||
// Client This struct stores
|
||||
// client information with server
|
||||
// proxy connected
|
||||
type Client struct {
|
||||
Name string
|
||||
Server *Server
|
||||
ClientMappings []ClientMapping
|
||||
}
|
||||
|
||||
// ClientMapping Stores client mapping ports
|
||||
// to proxy server
|
||||
type ClientMapping struct {
|
||||
LocalIP string
|
||||
LocalPort int
|
||||
RemotePort int
|
||||
}
|
||||
|
||||
// StartFRPClientForServer Starts Server using FRP server
|
||||
// returns back a port
|
||||
// remote port is a custom external port a user would want
|
||||
// to open. This under the assumption the user knows the
|
||||
// exact port available in server doing the TURN connection.
|
||||
func StartFRPClientForServer(ipaddress string, port string, localport string, remoteport string) (string, error) {
|
||||
// Setup server information
|
||||
var s Server
|
||||
s.address = ipaddress
|
||||
// convert port to int
|
||||
portInt, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
s.port = portInt
|
||||
|
||||
// Setup client information
|
||||
var c Client
|
||||
c.Name = "ServerPort"
|
||||
c.Server = &s
|
||||
|
||||
// converts localport to int
|
||||
portInt, err = strconv.Atoi(localport)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var OpenPorts []int
|
||||
// if the remote port is
|
||||
// not empty then set the remote port to that.
|
||||
if remoteport != "" {
|
||||
// converts localport to int
|
||||
portIntRemote, err := strconv.Atoi(remoteport)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
OpenPorts = append(OpenPorts, portIntRemote)
|
||||
} else {
|
||||
//random port
|
||||
//randPort := rangeIn(10000, 99999)
|
||||
OpenPorts, err = freeport.GetFreePorts(1)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
c.ClientMappings = []ClientMapping{
|
||||
{
|
||||
LocalIP: "localhost",
|
||||
LocalPort: portInt,
|
||||
RemotePort: OpenPorts[0],
|
||||
},
|
||||
}
|
||||
|
||||
// Start client server
|
||||
go c.StartFRPClient()
|
||||
|
||||
return strconv.Itoa(OpenPorts[0]), nil
|
||||
|
||||
}
|
||||
|
||||
func StartFRPCDockerContainer(ipaddress string, port string, Docker *docker.DockerVM) (*docker.DockerVM, error) {
|
||||
// setting new docker variable
|
||||
|
||||
//var DockerFRP docker.DockerVM
|
||||
|
||||
//DockerFRP = *Docker
|
||||
//DockerFRP.Ports.PortSet = []docker.Port{}
|
||||
// Setup server information
|
||||
var s Server
|
||||
s.address = ipaddress
|
||||
// convert port to int
|
||||
portInt, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.port = portInt
|
||||
|
||||
// Setup client information
|
||||
var c Client
|
||||
c.Name = "ServerPort"
|
||||
c.Server = &s
|
||||
|
||||
// set client mapping
|
||||
//var clientMappings []ClientMapping
|
||||
for i, _ := range Docker.Ports.PortSet {
|
||||
portMap := Docker.Ports.PortSet[i].ExternalPort
|
||||
|
||||
serverPort, err := GetFRPServerPort("http://" + ipaddress + ":" + port)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//delay to allow the FRP server to start
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
proxyPort, err := StartFRPClientForServer(ipaddress, serverPort, strconv.Itoa(portMap), "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
portInt, err = strconv.Atoi(proxyPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Docker.Ports.PortSet[i].ExternalPort = portInt
|
||||
}
|
||||
|
||||
return Docker, nil
|
||||
|
||||
}
|
||||
|
||||
// StartFRPClient Starts FRP client
|
||||
func (c *Client) StartFRPClient() error {
|
||||
|
||||
cfg := config.GetDefaultClientConf()
|
||||
|
||||
var proxyConfs map[string]config.ProxyConf
|
||||
var visitorCfgs map[string]config.VisitorConf
|
||||
|
||||
proxyConfs = make(map[string]config.ProxyConf)
|
||||
|
||||
cfg.ServerAddr = c.Server.address
|
||||
cfg.ServerPort = c.Server.port
|
||||
|
||||
for i, _ := range c.ClientMappings {
|
||||
var tcpcnf config.TCPProxyConf
|
||||
tcpcnf.LocalIP = c.ClientMappings[i].LocalIP
|
||||
tcpcnf.LocalPort = c.ClientMappings[i].LocalPort
|
||||
tcpcnf.RemotePort = c.ClientMappings[i].RemotePort
|
||||
|
||||
proxyConfs[tcpcnf.ProxyName] = &tcpcnf
|
||||
}
|
||||
|
||||
cli, err := client.NewService(cfg, proxyConfs, visitorCfgs, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cli.Run()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// helper function to generate random
|
||||
// number in a certain range
|
||||
func rangeIn(low, hi int) int {
|
||||
return low + rand.Intn(hi-low)
|
||||
}
|
||||
81
p2p/frp/server.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package frp
|
||||
|
||||
import (
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/server"
|
||||
"github.com/phayes/freeport"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
address string
|
||||
port int
|
||||
}
|
||||
|
||||
// StartFRPProxyFromRandom starts
|
||||
// reverse proxy server based on
|
||||
// a random port generated
|
||||
func StartFRPProxyFromRandom() (int, error) {
|
||||
// gets current configuration
|
||||
//config, err := configP2PRC.ConfigInit()
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
var s Server
|
||||
s.address = "0.0.0.0"
|
||||
|
||||
// use random port
|
||||
OpenPorts, err := freeport.GetFreePorts(1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
s.port = OpenPorts[0]
|
||||
|
||||
// start FRP server
|
||||
|
||||
go s.StartFRPServer()
|
||||
|
||||
return OpenPorts[0], nil
|
||||
|
||||
}
|
||||
|
||||
// StartFRPServer The initial plan is only support reverse proxy
|
||||
// for TCP ports
|
||||
// This function starts a server that can act as a reverse
|
||||
// proxy for nodes behind NAT.
|
||||
func (s *Server) StartFRPServer() error {
|
||||
baseConfig := config.GetDefaultServerConf()
|
||||
baseConfig.BindAddr = s.address
|
||||
|
||||
baseConfig.BindPort = s.port
|
||||
service, err := server.NewService(baseConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
service.Run()
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetFRPServerPort Gets the port no from the FRPServer to establish
|
||||
// the FRP connection needed.
|
||||
func GetFRPServerPort(host string) (string, error) {
|
||||
resp, err := http.Get(host + "/FRPPort")
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(body), nil
|
||||
}
|
||||
46
p2p/frp/server_test.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package frp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Testing scenario FRPServer
|
||||
func TestStartFRPServer(t *testing.T) {
|
||||
var s Server
|
||||
s.address = "127.0.0.1"
|
||||
s.port = 8808
|
||||
err := s.StartFRPServer()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
// Testing scenario FRPServer and FRPClient connection
|
||||
func TestStartFRPClient(t *testing.T) {
|
||||
var s Server
|
||||
s.address = "127.0.0.1"
|
||||
s.port = 8808
|
||||
go s.StartFRPServer()
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
// Sample test client
|
||||
var c Client
|
||||
c.Server = &s
|
||||
c.ClientMappings = []ClientMapping{
|
||||
{
|
||||
LocalIP: "127.0.0.1",
|
||||
LocalPort: 22,
|
||||
RemotePort: 3301,
|
||||
},
|
||||
}
|
||||
|
||||
err := c.StartFRPClient()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"ip_address": [
|
||||
{
|
||||
"ipv4": "139.162.246.221",
|
||||
"ipv6": "",
|
||||
"latency": 0,
|
||||
"download": 0,
|
||||
"upload": 0,
|
||||
"serverport": "8088"
|
||||
"Name": "Node1",
|
||||
"IPV4": "64.227.168.102",
|
||||
"IPV6": "",
|
||||
"Latency": 0,
|
||||
"ServerPort": "8088",
|
||||
"NAT": "False",
|
||||
"EscapeImplementation": "None"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
357
p2p/iptable.go
@@ -1,238 +1,267 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Get IP table Data
|
||||
|
||||
type IpAddresses struct {
|
||||
IpAddress []IpAddress `json:"ip_address"`
|
||||
IpAddress []IpAddress `json:"ip_address"`
|
||||
}
|
||||
|
||||
type IpAddress struct {
|
||||
Ipv4 string `json:"ipv4"`
|
||||
Ipv6 string `json:"ipv6"`
|
||||
Latency time.Duration `json:"latency"`
|
||||
Download float64 `json:"download"`
|
||||
Upload float64 `json:"upload"`
|
||||
ServerPort string `json:"serverport"`
|
||||
Name string `json:"Name"`
|
||||
Ipv4 string `json:"IPV4"`
|
||||
Ipv6 string `json:"IPV6"`
|
||||
Latency time.Duration `json:"Latency"`
|
||||
Download float64 `json:"Download"`
|
||||
Upload float64 `json:"Upload"`
|
||||
ServerPort string `json:"ServerPort"`
|
||||
NAT string `json:"NAT"`
|
||||
EscapeImplementation string `json:"EscapeImplementation"`
|
||||
CustomInformation []byte
|
||||
}
|
||||
|
||||
type IP struct {
|
||||
Query string
|
||||
Query string
|
||||
}
|
||||
|
||||
// ReadIpTable Read data from Ip tables from json file
|
||||
func ReadIpTable()(*IpAddresses ,error){
|
||||
func ReadIpTable() (*IpAddresses, error) {
|
||||
// Get Path from config
|
||||
config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
jsonFile, err := os.Open(config.IPTable)
|
||||
// if we os.Open returns an error then handle it
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
config, err := config.ConfigInit(nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jsonFile, err := os.Open(config.IPTable)
|
||||
// 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()
|
||||
|
||||
// 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)
|
||||
|
||||
// read our opened xmlFile as a byte array.
|
||||
byteValue, _ := ioutil.ReadAll(jsonFile)
|
||||
// we initialize our Users array
|
||||
var ipAddresses IpAddresses
|
||||
|
||||
// we initialize our Users array
|
||||
var ipAddresses IpAddresses
|
||||
// we unmarshal our byteArray which contains our
|
||||
// jsonFile's content into 'users' which we defined above
|
||||
json.Unmarshal(byteValue, &ipAddresses)
|
||||
|
||||
// we unmarshal our byteArray which contains our
|
||||
// jsonFile's content into 'users' which we defined above
|
||||
json.Unmarshal(byteValue, &ipAddresses)
|
||||
var PublicIP IpAddress
|
||||
|
||||
var PublicIP IpAddress
|
||||
ipv6, err := GetCurrentIPV6()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ipv6, err := GetCurrentIPV6()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ip, err := CurrentPublicIP()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
PublicIP.Ipv4 = ip
|
||||
PublicIP.Ipv6 = ipv6
|
||||
PublicIP.ServerPort = config.ServerPort
|
||||
PublicIP.Name = config.MachineName
|
||||
PublicIP.NAT = config.BehindNAT
|
||||
PublicIP.EscapeImplementation = "None"
|
||||
|
||||
ip, err := CurrentPublicIP()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
PublicIP.Ipv4 = ip
|
||||
PublicIP.Ipv6 = ipv6
|
||||
PublicIP.ServerPort = config.ServerPort
|
||||
// Updates current machine IP address to the IP table
|
||||
ipAddresses.IpAddress = append(ipAddresses.IpAddress, PublicIP)
|
||||
|
||||
// Updates current machine IP address to the IP table
|
||||
ipAddresses.IpAddress = append(ipAddresses.IpAddress, PublicIP)
|
||||
|
||||
//before writing to iptable ensures the duplicates are removed
|
||||
if err = ipAddresses.RemoveDuplicates(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//before writing to iptable ensures the duplicates are removed
|
||||
if err = ipAddresses.RemoveDuplicates(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ipAddresses, nil
|
||||
}
|
||||
|
||||
// WriteIpTable Write to IP table json file
|
||||
func (i *IpAddresses) WriteIpTable() error {
|
||||
//before writing to iptable ensures the duplicates are removed
|
||||
if err := i.RemoveDuplicates(); err != nil {
|
||||
return err
|
||||
}
|
||||
//before writing to iptable ensures the duplicates are removed
|
||||
if err := i.RemoveDuplicates(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file, err := json.MarshalIndent(i, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file, err := json.MarshalIndent(i, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get Path from config
|
||||
config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Get Path from config
|
||||
config, err := config.ConfigInit(nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(config.IPTable, file, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(config.IPTable, file, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// PrintIpTable Print Ip table data for Cli
|
||||
func PrintIpTable() error {
|
||||
table, err := ReadIpTable()
|
||||
table, err := ReadIpTable()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i < len(table.IpAddress); i++ {
|
||||
fmt.Printf("\nIP Address: %s\nIPV6: %s\nLatency: %s\nServerPort: %s\n-----------" +
|
||||
"-----------------\n",table.IpAddress[i].Ipv4,table.IpAddress[i].Ipv6,
|
||||
table.IpAddress[i].Latency, table.IpAddress[i].ServerPort)
|
||||
}
|
||||
for i := 0; i < len(table.IpAddress); i++ {
|
||||
fmt.Printf("\nMachine Name: %s\nIP Address: %s\nIPV6: %s\nLatency: %s\nServerPort: %s\nbehindNAT: %s\nEscapeImplementation: %s\n-----------"+
|
||||
"-----------------\n", table.IpAddress[i].Name, table.IpAddress[i].Ipv4, table.IpAddress[i].Ipv6,
|
||||
table.IpAddress[i].Latency, table.IpAddress[i].ServerPort, table.IpAddress[i].NAT, table.IpAddress[i].EscapeImplementation)
|
||||
}
|
||||
//PrettyPrint(table)
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveDuplicates This is a temporary fix current functions failing to remove
|
||||
// Duplicate IP addresses from local IP table
|
||||
func (table *IpAddresses)RemoveDuplicates() error {
|
||||
func (table *IpAddresses) RemoveDuplicates() error {
|
||||
|
||||
var NoDuplicates IpAddresses
|
||||
for i, _:= range table.IpAddress {
|
||||
Exists := false
|
||||
for k := range NoDuplicates.IpAddress {
|
||||
if (NoDuplicates.IpAddress[k].Ipv4 != "" && NoDuplicates.IpAddress[k].Ipv4 == table.IpAddress[i].Ipv4) || (NoDuplicates.IpAddress[k].Ipv6 != "" && NoDuplicates.IpAddress[k].Ipv6 == table.IpAddress[i].Ipv6) {
|
||||
Exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if Exists {
|
||||
continue
|
||||
}
|
||||
NoDuplicates.IpAddress = append(NoDuplicates.IpAddress, table.IpAddress[i])
|
||||
}
|
||||
var NoDuplicates IpAddresses
|
||||
for i, _ := range table.IpAddress {
|
||||
Exists := false
|
||||
for k := range NoDuplicates.IpAddress {
|
||||
// Statements checked for
|
||||
// - duplicate IPV4 addresses [<IPV4>:<Port No>]
|
||||
// - duplicate IPV6 addresses [<IPV6>]
|
||||
// - Node is behind NAT and no escape implementation provided
|
||||
if (NoDuplicates.IpAddress[k].Ipv4 != "" && NoDuplicates.IpAddress[k].Ipv4 == table.IpAddress[i].Ipv4 &&
|
||||
NoDuplicates.IpAddress[k].ServerPort == table.IpAddress[i].ServerPort) ||
|
||||
(NoDuplicates.IpAddress[k].Ipv6 != "" && NoDuplicates.IpAddress[k].Ipv6 == table.IpAddress[i].Ipv6) {
|
||||
Exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
table.IpAddress = NoDuplicates.IpAddress
|
||||
if table.IpAddress[i].NAT == "True" && table.IpAddress[i].EscapeImplementation == "None" {
|
||||
Exists = true
|
||||
}
|
||||
|
||||
return nil
|
||||
if Exists {
|
||||
continue
|
||||
}
|
||||
NoDuplicates.IpAddress = append(NoDuplicates.IpAddress, table.IpAddress[i])
|
||||
}
|
||||
|
||||
table.IpAddress = NoDuplicates.IpAddress
|
||||
|
||||
return 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()
|
||||
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
|
||||
}
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var ip IP
|
||||
json.Unmarshal(body, &ip)
|
||||
var ip IP
|
||||
json.Unmarshal(body, &ip)
|
||||
|
||||
return ip.Query, nil
|
||||
return ip.Query, nil
|
||||
}
|
||||
|
||||
// GetCurrentIPV6 gets the current IPV6 address based on the interface
|
||||
// specified in the config file
|
||||
func GetCurrentIPV6()(string,error){
|
||||
Config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return "",err
|
||||
}
|
||||
func GetCurrentIPV6() (string, error) {
|
||||
Config, err := config.ConfigInit(nil, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Fix in future release
|
||||
//byNameInterface, err := net.InterfaceByName(Config.NetworkInterface)
|
||||
//if err != nil {
|
||||
// return "",err
|
||||
//}
|
||||
//addresses, err := byNameInterface.Addrs()
|
||||
//if err != nil {
|
||||
// return "",err
|
||||
//}
|
||||
//if addresses[1].String() == "" {
|
||||
// return "",errors.New("IPV6 address not detected")
|
||||
//}
|
||||
//IP,_,err := net.ParseCIDR(addresses[Config.NetworkInterfaceIPV6Index].String())
|
||||
//if err != nil {
|
||||
// return "",err
|
||||
//}
|
||||
// Fix in future release
|
||||
//byNameInterface, err := net.InterfaceByName(Config.NetworkInterface)
|
||||
//if err != nil {
|
||||
// return "",err
|
||||
//}
|
||||
//addresses, err := byNameInterface.Addrs()
|
||||
//if err != nil {
|
||||
// return "",err
|
||||
//}
|
||||
//if addresses[1].String() == "" {
|
||||
// return "",errors.New("IPV6 address not detected")
|
||||
//}
|
||||
//IP,_,err := net.ParseCIDR(addresses[Config.NetworkInterfaceIPV6Index].String())
|
||||
//if err != nil {
|
||||
// return "",err
|
||||
//}
|
||||
|
||||
return Config.IPV6Address, nil
|
||||
return Config.IPV6Address, nil
|
||||
}
|
||||
|
||||
// ViewNetworkInterface This function is created to view the network interfaces available
|
||||
func ViewNetworkInterface() error {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, i := range ifaces {
|
||||
addrs, err := i.Addrs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for index, a := range addrs {
|
||||
switch v := a.(type) {
|
||||
case *net.IPAddr:
|
||||
fmt.Printf("(%v) %v : %s (%s)\n", index, i.Name, v, v.IP.DefaultMask())
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, i := range ifaces {
|
||||
addrs, err := i.Addrs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for index, a := range addrs {
|
||||
switch v := a.(type) {
|
||||
case *net.IPAddr:
|
||||
fmt.Printf("(%v) %v : %s (%s)\n", index, i.Name, v, v.IP.DefaultMask())
|
||||
|
||||
case *net.IPNet:
|
||||
fmt.Printf("(%v) %v : %s \n", index, i.Name, v)
|
||||
}
|
||||
case *net.IPNet:
|
||||
fmt.Printf("(%v) %v : %s \n", index, i.Name, v)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ip4or6 Helper function to check if the IP address is IPV4 or
|
||||
//IPV6 (https://socketloop.com/tutorials/golang-check-if-ip-address-is-version-4-or-6)
|
||||
// IPV6 (https://socketloop.com/tutorials/golang-check-if-ip-address-is-version-4-or-6)
|
||||
func Ip4or6(s string) string {
|
||||
for i := 0; i < len(s); i++ {
|
||||
switch s[i] {
|
||||
case '.':
|
||||
return "version 4"
|
||||
case ':':
|
||||
return "version 6"
|
||||
}
|
||||
}
|
||||
return "version 6"
|
||||
for i := 0; i < len(s); i++ {
|
||||
switch s[i] {
|
||||
case '.':
|
||||
return "version 4"
|
||||
case ':':
|
||||
return "version 6"
|
||||
}
|
||||
}
|
||||
return "version 6"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//func PrettyPrint(data interface{}) {
|
||||
// var p []byte
|
||||
// // var err := error
|
||||
// p, err := json.MarshalIndent(data, "", "\t")
|
||||
// if err != nil {
|
||||
// fmt.Println(err)
|
||||
// return
|
||||
// }
|
||||
// fmt.Printf("%s \n", p)
|
||||
//}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package p2p
|
||||
|
||||
// SpeedTest Runs a speed test and does updates IP tables accordingly
|
||||
func (ip *IpAddresses)SpeedTest() error{
|
||||
func (ip *IpAddresses) SpeedTest() error {
|
||||
|
||||
//temp variable to store elements IP addresses and other information
|
||||
// of IP addresses that are pingable
|
||||
var ActiveIP IpAddresses
|
||||
|
||||
|
||||
// Index to remove from struct
|
||||
for _, value := range ip.IpAddress {
|
||||
|
||||
@@ -36,7 +36,6 @@ func (ip *IpAddresses)SpeedTest() error{
|
||||
//Set value to the list
|
||||
|
||||
ActiveIP.IpAddress = append(ActiveIP.IpAddress, value)
|
||||
|
||||
}
|
||||
|
||||
ip.IpAddress = ActiveIP.IpAddress
|
||||
@@ -50,7 +49,7 @@ func (ip *IpAddresses)SpeedTest() error{
|
||||
}
|
||||
|
||||
// SpeedTestUpdatedIPTable Called when ip tables from httpclient/server is also passed on
|
||||
func (ip *IpAddresses)SpeedTestUpdatedIPTable() error{
|
||||
func (ip *IpAddresses) SpeedTestUpdatedIPTable() error {
|
||||
targets, err := ReadIpTable()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -59,24 +58,24 @@ func (ip *IpAddresses)SpeedTestUpdatedIPTable() error{
|
||||
// To ensure struct has no duplicates IP addresses
|
||||
//DoNotRead := targets
|
||||
|
||||
// Appends all IP addresses
|
||||
// Appends all IP addresses
|
||||
for i, _ := range targets.IpAddress {
|
||||
|
||||
// To ensure that there are no duplicate IP addresses
|
||||
//Exists := false
|
||||
//for k := range ip.IpAddress {
|
||||
// // Checks if both the IPV4 addresses are the same or the IPV6 address is not
|
||||
// // an empty string and IPV6 address are the same
|
||||
// if ip.IpAddress[k].Ipv4 == targets.IpAddress[i].Ipv4 || (targets.IpAddress[i].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) {
|
||||
// Exists = true
|
||||
// break
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// If the struct exists then continues
|
||||
//if Exists {
|
||||
// continue
|
||||
//}
|
||||
//To ensure that there are no duplicate IP addresses
|
||||
Exists := false
|
||||
for k := range ip.IpAddress {
|
||||
// Checks if both the IPV4 addresses are the same or the IPV6 address is not
|
||||
// an empty string and IPV6 address are the same
|
||||
if (ip.IpAddress[k].Ipv4 == targets.IpAddress[i].Ipv4 && targets.IpAddress[i].NAT == "True") || (targets.IpAddress[i].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) {
|
||||
Exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If the struct exists then continues
|
||||
if Exists {
|
||||
continue
|
||||
}
|
||||
|
||||
ip.IpAddress = append(ip.IpAddress, targets.IpAddress[i])
|
||||
}
|
||||
@@ -105,7 +104,6 @@ func LocalSpeedTestIpTable() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// Helper function to remove element from an array of a struct
|
||||
//func remove(s []IpAddress, i int) []IpAddress {
|
||||
// s[len(s)-1], s[i] = s[i], s[len(s)-1]
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
"bytes"
|
||||
"errors"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
//var dlSizes = [...]int{350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000}
|
||||
//var ulSizes = [...]int{100, 300, 500, 800, 1000, 1500, 2500, 3000, 3500, 4000} //kB
|
||||
// var dlSizes = [...]int{350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000}
|
||||
// var ulSizes = [...]int{100, 300, 500, 800, 1000, 1500, 2500, 3000, 3500, 4000} //kB
|
||||
var httpclient = http.Client{}
|
||||
|
||||
// DownloadTest executes the test to measure download speed
|
||||
@@ -78,102 +79,101 @@ var httpclient = http.Client{}
|
||||
//}
|
||||
|
||||
// Download Speed
|
||||
func (s *IpAddress)DownloadSpeed() error {
|
||||
start := time.Now()
|
||||
resp, err := httpclient.Get("http://" + s.Ipv4 + ":8088/50")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ioutil.ReadAll(resp.Body)
|
||||
t := time.Since(start)
|
||||
//fmt.Println(s.Seconds())
|
||||
// size * time (seconds)
|
||||
s.Download = (50/t.Seconds())*8
|
||||
func (s *IpAddress) DownloadSpeed() error {
|
||||
start := time.Now()
|
||||
resp, err := httpclient.Get("http://" + s.Ipv4 + ":8088/50")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ioutil.ReadAll(resp.Body)
|
||||
t := time.Since(start)
|
||||
//fmt.Println(s.Seconds())
|
||||
// size * time (seconds)
|
||||
s.Download = (50 / t.Seconds()) * 8
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *IpAddress)UploadSpeed() error {
|
||||
start := time.Now()
|
||||
func (s *IpAddress) UploadSpeed() error {
|
||||
start := time.Now()
|
||||
|
||||
// Get upload file path from config file
|
||||
// Get Path from config
|
||||
config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Get upload file path from config file
|
||||
// Get Path from config
|
||||
config, err := config.ConfigInit(nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, w := createMultipartFormData("file",config.SpeedTestFile)
|
||||
b, w := createMultipartFormData("file", config.SpeedTestFile)
|
||||
|
||||
req, err := http.NewRequest("GET", "http://" + s.Ipv4 + ":" + s.ServerPort + "/upload", &b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Don't forget to set the content type, this will contain the boundary.
|
||||
req.Header.Set("Content-Type", w.FormDataContentType())
|
||||
defer req.Body.Close()
|
||||
ioutil.ReadAll(req.Body)
|
||||
t := time.Since(start)
|
||||
//fmt.Println(s.Seconds())
|
||||
// size * time (seconds)
|
||||
s.Upload = (50/t.Seconds())*8
|
||||
return nil
|
||||
req, err := http.NewRequest("GET", "http://"+s.Ipv4+":"+s.ServerPort+"/upload", &b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Don't forget to set the content type, this will contain the boundary.
|
||||
req.Header.Set("Content-Type", w.FormDataContentType())
|
||||
defer req.Body.Close()
|
||||
ioutil.ReadAll(req.Body)
|
||||
t := time.Since(start)
|
||||
//fmt.Println(s.Seconds())
|
||||
// size * time (seconds)
|
||||
s.Upload = (50 / t.Seconds()) * 8
|
||||
return nil
|
||||
}
|
||||
|
||||
//Upload helper function for uploading
|
||||
//(https://stackoverflow.com/questions/20205796/post-data-using-the-content-type-multipart-form-data
|
||||
// Upload helper function for uploading
|
||||
// (https://stackoverflow.com/questions/20205796/post-data-using-the-content-type-multipart-form-data
|
||||
func createMultipartFormData(fieldName, fileName string) (bytes.Buffer, *multipart.Writer) {
|
||||
var b bytes.Buffer
|
||||
var err error
|
||||
w := multipart.NewWriter(&b)
|
||||
var fw io.Writer
|
||||
file := mustOpen(fileName)
|
||||
if fw, err = w.CreateFormFile(fieldName, file.Name()); err != nil {
|
||||
log.Fatalf("Error creating writer: %v", err)
|
||||
}
|
||||
if _, err = io.Copy(fw, file); err != nil {
|
||||
log.Fatalf("Error with io.Copy: %v", err)
|
||||
//t.Errorf("Error with io.Copy: %v", err)
|
||||
}
|
||||
w.Close()
|
||||
return b, w
|
||||
var b bytes.Buffer
|
||||
var err error
|
||||
w := multipart.NewWriter(&b)
|
||||
var fw io.Writer
|
||||
file := mustOpen(fileName)
|
||||
if fw, err = w.CreateFormFile(fieldName, file.Name()); err != nil {
|
||||
log.Fatalf("Error creating writer: %v", err)
|
||||
}
|
||||
if _, err = io.Copy(fw, file); err != nil {
|
||||
log.Fatalf("Error with io.Copy: %v", err)
|
||||
//t.Errorf("Error with io.Copy: %v", err)
|
||||
}
|
||||
w.Close()
|
||||
return b, w
|
||||
}
|
||||
|
||||
func mustOpen(f string) *os.File {
|
||||
r, err := os.Open(f)
|
||||
if err != nil {
|
||||
log.Fatalf("Error with mustOpen: %v",err)
|
||||
}
|
||||
return r
|
||||
r, err := os.Open(f)
|
||||
if err != nil {
|
||||
log.Fatalf("Error with mustOpen: %v", err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// PingTest executes test to measure latency
|
||||
func (s *IpAddress) PingTest() error {
|
||||
//pingURL := strings.Split(s.URL, "/upload")[0] + "/latency.txt"
|
||||
var pingURL string
|
||||
if s.Ipv6 != "" {
|
||||
pingURL = "http://[" + s.Ipv6 + "]:" + s.ServerPort + "/server_info"
|
||||
s.Ipv4 = ""
|
||||
} else {
|
||||
pingURL = "http://" + s.Ipv4 + ":" + s.ServerPort + "/server_info"
|
||||
}
|
||||
//pingURL := strings.Split(s.URL, "/upload")[0] + "/latency.txt"
|
||||
var pingURL string
|
||||
if s.Ipv6 != "" {
|
||||
pingURL = "http://[" + s.Ipv6 + "]:" + s.ServerPort + "/server_info"
|
||||
s.Ipv4 = ""
|
||||
} else {
|
||||
pingURL = "http://" + s.Ipv4 + ":" + s.ServerPort + "/server_info"
|
||||
}
|
||||
|
||||
l := time.Duration(100000000000) // 10sec
|
||||
for i := 0; i < 3; i++ {
|
||||
sTime := time.Now()
|
||||
resp, err := http.Get(pingURL)
|
||||
fTime := time.Now()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if fTime.Sub(sTime) < l {
|
||||
l = fTime.Sub(sTime)
|
||||
}
|
||||
resp.Body.Close()
|
||||
}
|
||||
l := time.Duration(100000000000) // 10sec
|
||||
for i := 0; i < 3; i++ {
|
||||
sTime := time.Now()
|
||||
resp, err := http.Get(pingURL)
|
||||
fTime := time.Now()
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
return errors.New("Node not found")
|
||||
}
|
||||
if fTime.Sub(sTime) < l {
|
||||
l = fTime.Sub(sTime)
|
||||
}
|
||||
resp.Body.Close()
|
||||
}
|
||||
|
||||
s.Latency = time.Duration(int64(l.Nanoseconds() / 2))
|
||||
s.Latency = time.Duration(int64(l.Nanoseconds() / 2))
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
106
p2p/upnp.go
@@ -1,76 +1,74 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"fmt"
|
||||
"gitlab.com/NebulousLabs/go-upnp"
|
||||
)
|
||||
|
||||
// Port forwarding to the router
|
||||
func ForwardPort(port int) error{
|
||||
// connect to router
|
||||
d, err := upnp.Discover()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func ForwardPort(port int) error {
|
||||
// connect to router
|
||||
d, err := upnp.Discover()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// discover external IP
|
||||
ip, err := d.ExternalIP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Your external IP is:", ip)
|
||||
// discover external IP
|
||||
ip, err := d.ExternalIP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Your external IP is:", ip)
|
||||
|
||||
// forward a port
|
||||
err = d.Forward(50498, "upnp test")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// forward a port
|
||||
err = d.Forward(50498, "upnp test")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// record router's location
|
||||
loc := d.Location()
|
||||
// record router's location
|
||||
loc := d.Location()
|
||||
|
||||
// connect to router directly
|
||||
d, err = upnp.Load(loc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// connect to router directly
|
||||
d, err = upnp.Load(loc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// unForwardPort from router
|
||||
func UnForwardPort(port int) error{
|
||||
// connect to router
|
||||
d, err := upnp.Discover()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// UnForwardPort from router
|
||||
func UnForwardPort(port int) error {
|
||||
// connect to router
|
||||
d, err := upnp.Discover()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// discover external IP
|
||||
ip, err := d.ExternalIP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// discover external IP
|
||||
ip, err := d.ExternalIP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Your external IP is:", ip)
|
||||
|
||||
fmt.Println("Your external IP is:", ip)
|
||||
// un-forward a port
|
||||
err = d.Clear(50498)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// record router's location
|
||||
loc := d.Location()
|
||||
|
||||
// un-forward a port
|
||||
err = d.Clear(50498)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// connect to router directly
|
||||
d, err = upnp.Load(loc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// record router's location
|
||||
loc := d.Location()
|
||||
|
||||
// connect to router directly
|
||||
d, err = upnp.Load(loc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
15
p2p/upnp_test.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Tests if the current has UPNP support
|
||||
func TestForwardUPNPPort(t *testing.T) {
|
||||
err := ForwardPort(6586)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
101
plugin/README.md
@@ -1,102 +1 @@
|
||||
# Laplace
|
||||
|
||||
Laplace is an open-source project to enable screen sharing directly via browser.
|
||||
Made possible using WebRTC for low latency peer-to-peer connections, and WebSocket implemented in golang for WebRTC signaling.
|
||||
|
||||
> Demo video: https://youtu.be/E8cUaPrAlzE
|
||||
|
||||
[](https://youtu.be/E8cUaPrAlzE)
|
||||
|
||||
|
||||
## Try Demo
|
||||
|
||||
For demo, you can visit https://laplace.madeby.monster/
|
||||
|
||||

|
||||
|
||||
|
||||
## Motivation
|
||||
|
||||
There are already possible solutions to share your computer screen, e.g. TeamViewer.
|
||||
But most of them require installations of software or plugins.
|
||||
What Laplace provides is a simple solution to this problem.
|
||||
For users wanting to share their screen, all they need to do is to open a website page with their browsers, clicking some buttons, then share some session ID with their peers.
|
||||
No installation or registration required.
|
||||
|
||||
#### Solving the latency problem
|
||||
|
||||
This project also serves as a proof-of-concept (PoC) for screen sharing capability directly in browsers based on WebRTC.
|
||||
Using WebRTC, real-time communication is made possible through peer-to-peer connections.
|
||||
This proves to be very useful in solving one of the biggest problems is screen streaming: **Latency**.
|
||||
The latency represents how long the delay is from the source to transmit to the remote client.
|
||||
If you notice, this latency problem is usually highlighted by game streaming services, since gameplay relies heavily on the interactivity of inputs and outputs.
|
||||
|
||||
|
||||
#### Low server cost
|
||||
This solution also solves the server cost problem, since the expensive operations (encoding and transmission) are done on client browsers.
|
||||
The server is only needed for serving frontends and for WebRTC signaling.
|
||||
|
||||
|
||||
#### Possible Use Cases
|
||||
|
||||
- Game streaming from PC to mobile devices.
|
||||
- Collaborative work where you need to share your screen with remote coworkers.
|
||||
- Mirroring presentation slides and demonstrations.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
Build from source
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/adamyordan/laplace.git
|
||||
$ cd laplace && go build -o laplace main.go
|
||||
$ ./laplace --help
|
||||
```
|
||||
|
||||
OR, pull the pre-built docker image
|
||||
|
||||
```bash
|
||||
$ docker pull adamyordan/laplace
|
||||
$ docker run adamyordan/laplace ./laplace --help
|
||||
```
|
||||
|
||||
|
||||
## Program Execution
|
||||
|
||||
Executing this project basically serves an HTTP server that will host the frontend and the WebSocket implementation.
|
||||
Note that you sometimes need to run HTTPs in order for browser to connect to websocket.
|
||||
|
||||
```bash
|
||||
$ ./laplace --help
|
||||
-addr string
|
||||
Listen address (default "0.0.0.0:443")
|
||||
-certFile string
|
||||
TLS cert file (default "files/server.crt")
|
||||
-keyFile string
|
||||
TLS key file (default "files/server.key")
|
||||
-tls
|
||||
Use TLS (default true)
|
||||
```
|
||||
|
||||
By default, you can run the executable without any argument to listen to TLS port 443.
|
||||
A self-signed certificate files are provided to ease up development.
|
||||
|
||||
```bash
|
||||
$ ./laplace
|
||||
2020/03/25 01:01:10 Listening on TLS: 0.0.0.0:443
|
||||
```
|
||||
|
||||
You can then open https://localhost:443/ to view Laplace page.
|
||||
You may need to add certificate exceptions. In Chrome, you can type `thisisunsafe`.
|
||||
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
[MIT](https://choosealicense.com/licenses/mit/)
|
||||
|
||||
@@ -1,65 +1,64 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// DownloadPlugin This functions downloads package from
|
||||
// a git repo.
|
||||
func DownloadPlugin(pluginurl string) error {
|
||||
// paring plugin url
|
||||
u, err := url.Parse(pluginurl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
path := u.Path
|
||||
// Trim first character of the string
|
||||
path = path[1:]
|
||||
// trim last element of the string
|
||||
path = path[:len(path)-1]
|
||||
// Replaces / with _
|
||||
folder := strings.Replace(path, "/", "_", -1)
|
||||
// Reads plugin path from the config path
|
||||
config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// clones a repo and stores it at the plugin directory
|
||||
_, err = git.PlainClone(config.PluginPath + "/" + folder, false, &git.CloneOptions{
|
||||
URL: pluginurl,
|
||||
Progress: os.Stdout,
|
||||
})
|
||||
// returns error if raised
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// paring plugin url
|
||||
u, err := url.Parse(pluginurl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
path := u.Path
|
||||
// Trim first character of the string
|
||||
path = path[1:]
|
||||
// trim last element of the string
|
||||
path = path[:len(path)-1]
|
||||
// Replaces / with _
|
||||
folder := strings.Replace(path, "/", "_", -1)
|
||||
// Reads plugin path from the config path
|
||||
config, err := config.ConfigInit(nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// clones a repo and stores it at the plugin directory
|
||||
_, err = git.PlainClone(config.PluginPath+"/"+folder, false, &git.CloneOptions{
|
||||
URL: pluginurl,
|
||||
Progress: os.Stdout,
|
||||
})
|
||||
// returns error if raised
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeletePlugin The following function deletes a plugin based on
|
||||
// the plugin name provided.
|
||||
func DeletePlugin(pluginname string) error {
|
||||
config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config, err := config.ConfigInit(nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
plugin, err := SearchPlugin(pluginname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
plugin, err := SearchPlugin(pluginname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete the directory holding the plugin
|
||||
err = os.RemoveAll(config.PluginPath + "/" + plugin.FolderName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
// Delete the directory holding the plugin
|
||||
err = os.RemoveAll(config.PluginPath + "/" + plugin.FolderName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
700
plugin/plugin.go
@@ -1,452 +1,464 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/client"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"github.com/google/uuid"
|
||||
"gopkg.in/yaml.v2"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"text/template"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/client"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||
"github.com/google/uuid"
|
||||
"gopkg.in/yaml.v2"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"text/template"
|
||||
|
||||
"github.com/apenella/go-ansible/pkg/execute"
|
||||
"github.com/apenella/go-ansible/pkg/options"
|
||||
"github.com/apenella/go-ansible/pkg/playbook"
|
||||
"github.com/apenella/go-ansible/pkg/stdoutcallback/results"
|
||||
"github.com/otiai10/copy"
|
||||
"github.com/apenella/go-ansible/pkg/execute"
|
||||
"github.com/apenella/go-ansible/pkg/options"
|
||||
"github.com/apenella/go-ansible/pkg/playbook"
|
||||
"github.com/apenella/go-ansible/pkg/stdoutcallback/results"
|
||||
"github.com/otiai10/copy"
|
||||
)
|
||||
|
||||
// Plugins Array of all plugins detected
|
||||
type Plugins struct {
|
||||
PluginsDetected []*Plugin
|
||||
PluginsDetected []*Plugin
|
||||
}
|
||||
|
||||
// Plugin Information about the plugins available
|
||||
type Plugin struct {
|
||||
FolderName string
|
||||
PluginDescription string
|
||||
path string
|
||||
Execute []*ExecuteIP
|
||||
NumOfPorts int
|
||||
FolderName string
|
||||
PluginDescription string
|
||||
path string
|
||||
Execute []*ExecuteIP
|
||||
NumOfPorts int
|
||||
}
|
||||
|
||||
// ExecuteIP IP Address to execute Ansible instruction
|
||||
type ExecuteIP struct {
|
||||
ContainerID string
|
||||
IPAddress string
|
||||
SSHPortNo string
|
||||
Success bool
|
||||
ContainerID string
|
||||
IPAddress string
|
||||
SSHPortNo string
|
||||
Success bool
|
||||
}
|
||||
|
||||
// Host Struct for ansible host
|
||||
// Generated from https://zhwt.github.io/yaml-to-go/
|
||||
type Host struct {
|
||||
All struct {
|
||||
Vars struct {
|
||||
AnsiblePythonInterpreter string `yaml:"ansible_python_interpreter"`
|
||||
} `yaml:"vars"`
|
||||
} `yaml:"all"`
|
||||
Main struct {
|
||||
Hosts struct {
|
||||
Host1 struct {
|
||||
AnsibleHost string `yaml:"ansible_host"`
|
||||
AnsiblePort int `yaml:"ansible_port"`
|
||||
AnsibleUser string `yaml:"ansible_user"`
|
||||
AnsibleSSHPass string `yaml:"ansible_ssh_pass"`
|
||||
AnsibleSudoPass string `yaml:"ansible_sudo_pass"`
|
||||
} `yaml:"host1"`
|
||||
} `yaml:"hosts"`
|
||||
} `yaml:"main"`
|
||||
All struct {
|
||||
Vars struct {
|
||||
AnsiblePythonInterpreter string `yaml:"ansible_python_interpreter"`
|
||||
} `yaml:"vars"`
|
||||
} `yaml:"all"`
|
||||
Main struct {
|
||||
Hosts struct {
|
||||
Host1 struct {
|
||||
AnsibleHost string `yaml:"ansible_host"`
|
||||
AnsiblePort int `yaml:"ansible_port"`
|
||||
AnsibleUser string `yaml:"ansible_user"`
|
||||
AnsibleSSHPass string `yaml:"ansible_ssh_pass"`
|
||||
AnsibleSudoPass string `yaml:"ansible_sudo_pass"`
|
||||
} `yaml:"host1"`
|
||||
} `yaml:"hosts"`
|
||||
} `yaml:"main"`
|
||||
}
|
||||
|
||||
// DetectPlugins Detects all the plugins available
|
||||
func DetectPlugins()(*Plugins,error){
|
||||
config, err:= config.ConfigInit()
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
folders, err := ioutil.ReadDir(config.PluginPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func DetectPlugins() (*Plugins, error) {
|
||||
config, err := config.ConfigInit(nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
folders, err := ioutil.ReadDir(config.PluginPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var plugins *Plugins = new(Plugins)
|
||||
var plugins *Plugins = new(Plugins)
|
||||
|
||||
for _, f := range folders {
|
||||
if f.IsDir() {
|
||||
//Declare variable plugin of type Plugin
|
||||
var plugin Plugin
|
||||
for _, f := range folders {
|
||||
if f.IsDir() {
|
||||
//Declare variable plugin of type Plugin
|
||||
var plugin Plugin
|
||||
|
||||
// Setting name of folder to plugin
|
||||
plugin.FolderName = f.Name()
|
||||
// Getting Description from file description.txt
|
||||
Description, err := ioutil.ReadFile(config.PluginPath + "/" + plugin.FolderName + "/description.txt")
|
||||
// if we os.Open returns an error then handle it
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Setting name of folder to plugin
|
||||
plugin.FolderName = f.Name()
|
||||
// Getting Description from file description.txt
|
||||
Description, err := ioutil.ReadFile(config.PluginPath + "/" + plugin.FolderName + "/description.txt")
|
||||
// if we os.Open returns an error then handle it
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get Description from description.txt
|
||||
plugin.PluginDescription = string(Description)
|
||||
// Set plugin path
|
||||
plugin.path = config.PluginPath + "/" + plugin.FolderName
|
||||
// Get Description from description.txt
|
||||
plugin.PluginDescription = string(Description)
|
||||
// Set plugin path
|
||||
plugin.path = config.PluginPath + "/" + plugin.FolderName
|
||||
|
||||
plugins.PluginsDetected = append(plugins.PluginsDetected, &plugin)
|
||||
// Get the number of ports the plugin needs
|
||||
err = plugin.NumPorts()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
plugins.PluginsDetected = append(plugins.PluginsDetected, &plugin)
|
||||
// Get the number of ports the plugin needs
|
||||
err = plugin.NumPorts()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return plugins,nil
|
||||
return plugins, nil
|
||||
}
|
||||
|
||||
// SearchPlugin Detects plugin information based on the
|
||||
// name provided on the parameter
|
||||
func SearchPlugin(pluginname string) (*Plugin,error) {
|
||||
plugins, err := DetectPlugins()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func SearchPlugin(pluginname string) (*Plugin, error) {
|
||||
plugins, err := DetectPlugins()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// loop ot find the plugin name that matches
|
||||
for _, plugin := range plugins.PluginsDetected {
|
||||
if pluginname == plugin.FolderName {
|
||||
return plugin, nil
|
||||
}
|
||||
}
|
||||
// loop ot find the plugin name that matches
|
||||
for _, plugin := range plugins.PluginsDetected {
|
||||
if pluginname == plugin.FolderName {
|
||||
return plugin, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("plugin not detected")
|
||||
return nil, errors.New("plugin not detected")
|
||||
}
|
||||
|
||||
// RunPlugin Executes plugins based on the plugin name provided
|
||||
func RunPlugin(pluginName string ,IPAddresses []*ExecuteIP) (*Plugin,error) {
|
||||
plugins, err := DetectPlugins()
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
func RunPlugin(pluginName string, IPAddresses []*ExecuteIP) (*Plugin, error) {
|
||||
plugins, err := DetectPlugins()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Variable to store struct information about the plugin
|
||||
var plugindetected *Plugin
|
||||
for _,plugin := range plugins.PluginsDetected {
|
||||
if plugin.FolderName == pluginName {
|
||||
plugindetected = plugin
|
||||
plugindetected.Execute = IPAddresses
|
||||
// Get Execute plugin path from config file
|
||||
config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
plugindetected.path = config.PluginPath
|
||||
break
|
||||
}
|
||||
}
|
||||
// Variable to store struct information about the plugin
|
||||
var plugindetected *Plugin
|
||||
for _, plugin := range plugins.PluginsDetected {
|
||||
if plugin.FolderName == pluginName {
|
||||
plugindetected = plugin
|
||||
plugindetected.Execute = IPAddresses
|
||||
// Get Execute plugin path from config file
|
||||
config, err := config.ConfigInit(nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
plugindetected.path = config.PluginPath
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if plugindetected == nil {
|
||||
return nil, errors.New("Plugin not detected")
|
||||
}
|
||||
|
||||
|
||||
// Create copy of the plugin the tmp directory
|
||||
// To ensure we execute the plugin from there
|
||||
err = plugindetected.CopyToTmpPlugin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if plugindetected == nil {
|
||||
return nil, errors.New("Plugin not detected")
|
||||
}
|
||||
|
||||
// Executing the plugin
|
||||
err = plugindetected.ExecutePlugin()
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
// Create copy of the plugin the tmp directory
|
||||
// To ensure we execute the plugin from there
|
||||
err = plugindetected.CopyToTmpPlugin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return plugindetected,nil
|
||||
// Executing the plugin
|
||||
err = plugindetected.ExecutePlugin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return plugindetected, nil
|
||||
}
|
||||
|
||||
// ExecutePlugin Function to execute plugins that are called
|
||||
func (p *Plugin) ExecutePlugin() error {
|
||||
|
||||
// Run ip address to execute ansible inside
|
||||
for _,execute := range p.Execute {
|
||||
// Modify ansible hosts before executing
|
||||
err := execute.ModifyHost(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// sets the ports to the plugin folder
|
||||
err = p.AutoSetPorts(execute.ContainerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = execute.RunAnsible(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// If ran successfully then change success flag to true
|
||||
execute.Success = true
|
||||
}
|
||||
return nil
|
||||
// Run ip address to execute ansible inside
|
||||
for _, execute := range p.Execute {
|
||||
// Modify ansible hosts before executing
|
||||
err := execute.ModifyHost(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// sets the ports to the plugin folder
|
||||
err = p.AutoSetPorts(execute.ContainerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = execute.RunAnsible(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// If ran successfully then change success flag to true
|
||||
execute.Success = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunAnsible Executes based on credentials on the struct
|
||||
func (e *ExecuteIP)RunAnsible(p *Plugin) error {
|
||||
ansiblePlaybookConnectionOptions := &options.AnsibleConnectionOptions{
|
||||
User: "master",
|
||||
}
|
||||
func (e *ExecuteIP) RunAnsible(p *Plugin) error {
|
||||
ansiblePlaybookConnectionOptions := &options.AnsibleConnectionOptions{
|
||||
User: "master",
|
||||
}
|
||||
|
||||
ansiblePlaybookOptions := &playbook.AnsiblePlaybookOptions{
|
||||
Inventory: p.path + "/" + p.FolderName + "/hosts",
|
||||
ExtraVars: map[string]interface{}{"host_key_checking":"false"},
|
||||
}
|
||||
ansiblePlaybookOptions := &playbook.AnsiblePlaybookOptions{
|
||||
Inventory: p.path + "/" + p.FolderName + "/hosts",
|
||||
ExtraVars: map[string]interface{}{"ansible_ssh_common_args": "-o StrictHostKeyChecking=no"},
|
||||
}
|
||||
|
||||
ansiblePlaybookPrivilegeEscalationOptions := &options.AnsiblePrivilegeEscalationOptions{
|
||||
Become: true,
|
||||
}
|
||||
ansiblePlaybookPrivilegeEscalationOptions := &options.AnsiblePrivilegeEscalationOptions{
|
||||
Become: true,
|
||||
}
|
||||
|
||||
playbook := &playbook.AnsiblePlaybookCmd{
|
||||
Playbooks: []string{p.path + "/" + p.FolderName + "/site.yml"},
|
||||
ConnectionOptions: ansiblePlaybookConnectionOptions,
|
||||
PrivilegeEscalationOptions: ansiblePlaybookPrivilegeEscalationOptions,
|
||||
Options: ansiblePlaybookOptions,
|
||||
Exec: execute.NewDefaultExecute(
|
||||
execute.WithTransformers(
|
||||
results.Prepend("success"),
|
||||
),
|
||||
),
|
||||
}
|
||||
playbook := &playbook.AnsiblePlaybookCmd{
|
||||
Playbooks: []string{p.path + "/" + p.FolderName + "/site.yml"},
|
||||
ConnectionOptions: ansiblePlaybookConnectionOptions,
|
||||
PrivilegeEscalationOptions: ansiblePlaybookPrivilegeEscalationOptions,
|
||||
Options: ansiblePlaybookOptions,
|
||||
Exec: execute.NewDefaultExecute(
|
||||
execute.WithTransformers(
|
||||
results.Prepend("success"),
|
||||
),
|
||||
),
|
||||
}
|
||||
|
||||
err := playbook.Run(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err := playbook.Run(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// ModifyHost adds IP address , port no to the config file
|
||||
func (e *ExecuteIP)ModifyHost(p *Plugin) error {
|
||||
host,err := ReadHost(p.path + "/" + p.FolderName + "/hosts")
|
||||
func (e *ExecuteIP) ModifyHost(p *Plugin) error {
|
||||
host, err := ReadHost(p.path + "/" + p.FolderName + "/hosts")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
// Setting ansible host
|
||||
host.Main.Hosts.Host1.AnsibleHost = e.IPAddress
|
||||
// Setting SSH port no
|
||||
host.Main.Hosts.Host1.AnsiblePort, err = strconv.Atoi(e.SSHPortNo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Setting SSH user name
|
||||
host.Main.Hosts.Host1.AnsibleUser = "master"
|
||||
// Setting SSH password
|
||||
host.Main.Hosts.Host1.AnsibleSSHPass = "password"
|
||||
// Setting SSH sudo password
|
||||
host.Main.Hosts.Host1.AnsibleSudoPass = "password"
|
||||
host.Main.Hosts.Host1.AnsibleHost = e.IPAddress
|
||||
// Setting SSH port no
|
||||
host.Main.Hosts.Host1.AnsiblePort, err = strconv.Atoi(e.SSHPortNo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Setting SSH user name
|
||||
host.Main.Hosts.Host1.AnsibleUser = "master"
|
||||
// Setting SSH password
|
||||
host.Main.Hosts.Host1.AnsibleSSHPass = "password"
|
||||
// Setting SSH sudo password
|
||||
host.Main.Hosts.Host1.AnsibleSudoPass = "password"
|
||||
|
||||
// write modified information to the hosts yaml file
|
||||
data,err := yaml.Marshal(host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(p.path + "/" + p.FolderName + "/hosts",data,0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
// write modified information to the hosts yaml file
|
||||
data, err := yaml.Marshal(host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(p.path+"/"+p.FolderName+"/hosts", data, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadHost Reads host file and adds
|
||||
func ReadHost(filename string) (*Host, error) {
|
||||
buf, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := &Host{}
|
||||
err = yaml.Unmarshal(buf, c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("in file %q: %v", filename, err)
|
||||
}
|
||||
c := &Host{}
|
||||
err = yaml.Unmarshal(buf, c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("in file %q: %v", filename, err)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// RunPluginContainer Runs ansible plugin based on plugin name and container name which
|
||||
// is derived from the tracked containers file
|
||||
// We pass in the group ID as a parameter because when we modify the ports taken
|
||||
func RunPluginContainer(PluginName string, ContainerID string) error {
|
||||
// Gets container information based on container ID
|
||||
ContainerInformation, err := client.GetContainerInformation(ContainerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Gets container information based on container ID
|
||||
ContainerInformation, err := client.GetContainerInformation(ContainerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Setting Up IP's for which the plugins will be executed
|
||||
var ExecuteIPs []*ExecuteIP
|
||||
var ExecuteIP ExecuteIP
|
||||
// Getting port no of SSH port
|
||||
for _,port := range ContainerInformation.Container.Ports.PortSet {
|
||||
if port.PortName == "SSH" {
|
||||
ExecuteIP.SSHPortNo = fmt.Sprint(port.ExternalPort)
|
||||
break
|
||||
}
|
||||
}
|
||||
// Handle error if SSH port is not provided
|
||||
if ExecuteIP.SSHPortNo == "" {
|
||||
return errors.New("SSH port not found")
|
||||
}
|
||||
// IP address of the container
|
||||
ExecuteIP.IPAddress = ContainerInformation.IpAddress
|
||||
// Set container ID to ExecutorIP
|
||||
ExecuteIP.ContainerID = ContainerInformation.Id
|
||||
// Setting Up IP's for which the plugins will be executed
|
||||
var ExecuteIPs []*ExecuteIP
|
||||
var ExecuteIP ExecuteIP
|
||||
// Getting port no of SSH port
|
||||
for _, port := range ContainerInformation.Container.Ports.PortSet {
|
||||
if port.PortName == "SSH" {
|
||||
ExecuteIP.SSHPortNo = fmt.Sprint(port.ExternalPort)
|
||||
break
|
||||
}
|
||||
}
|
||||
// Handle error if SSH port is not provided
|
||||
if ExecuteIP.SSHPortNo == "" {
|
||||
return errors.New("SSH port not found")
|
||||
}
|
||||
// Split the port no from ip address since current the IP address
|
||||
// field is populated as
|
||||
// <ip address>:<port no>
|
||||
|
||||
host, _, err := net.SplitHostPort(ContainerInformation.IpAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// IP address of the container
|
||||
ExecuteIP.IPAddress = host
|
||||
// Set container ID to ExecutorIP
|
||||
ExecuteIP.ContainerID = ContainerInformation.Id
|
||||
// Append IP to list of executor IP
|
||||
ExecuteIPs = append(ExecuteIPs, &ExecuteIP)
|
||||
// Run plugin to execute plugin
|
||||
_, err = RunPlugin(PluginName,ExecuteIPs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ExecuteIPs = append(ExecuteIPs, &ExecuteIP)
|
||||
// Run plugin to execute plugin
|
||||
_, err = RunPlugin(PluginName, ExecuteIPs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckRunPlugin Checks if the ID belongs to the group or container
|
||||
// calls the plugin function the appropriate amount of times
|
||||
func CheckRunPlugin(PluginName string, ID string) error {
|
||||
// Check if the ID belongs to the group or container ID
|
||||
id, err := client.CheckID(ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// When the ID belongs to a group
|
||||
if id == "group" {
|
||||
// gets the group information
|
||||
group, err := client.GetGroup(ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Iterate through each container information in the group
|
||||
// and run the plugin in each of them
|
||||
for _, container := range group.TrackContainerList {
|
||||
// runs plugin for each container
|
||||
err := RunPluginContainer(PluginName, container.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else { // This means the following ID is a container ID
|
||||
err := RunPluginContainer(PluginName, ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Check if the ID belongs to the group or container ID
|
||||
id, err := client.CheckID(ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// When the ID belongs to a group
|
||||
if id == "group" {
|
||||
// gets the group information
|
||||
group, err := client.GetGroup(ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Iterate through each container information in the group
|
||||
// and run the plugin in each of them
|
||||
for _, container := range group.TrackContainerList {
|
||||
// runs plugin for each container
|
||||
err := RunPluginContainer(PluginName, container.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else { // This means the following ID is a container ID
|
||||
err := RunPluginContainer(PluginName, ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// CopyToTmpPlugin This function would ensure that we create a copy of the
|
||||
// plugin in the tmp directory, and it would be executed
|
||||
// from there. This due to the reason of automating port allocation
|
||||
// when running plugins
|
||||
func (p *Plugin)CopyToTmpPlugin() error {
|
||||
// generate rand to UUID this is debug the ansible file if needed
|
||||
id := uuid.New()
|
||||
// copies the plugin to the tmp directory
|
||||
err := copy.Copy(p.path+"/"+p.FolderName, "/tmp/"+ id.String() + "_" + p.FolderName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func (p *Plugin) CopyToTmpPlugin() error {
|
||||
// generate rand to UUID this is debug the ansible file if needed
|
||||
id := uuid.New()
|
||||
// copies the plugin to the tmp directory
|
||||
err := copy.Copy(p.path+"/"+p.FolderName, "/tmp/"+id.String()+"_"+p.FolderName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the plugin execution to the tmp location
|
||||
p.path = "/tmp"
|
||||
p.FolderName = id.String() + "_" + p.FolderName
|
||||
// Set the plugin execution to the tmp location
|
||||
p.path = "/tmp"
|
||||
p.FolderName = id.String() + "_" + p.FolderName
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AutoSetPorts Automatically maps free ports to site.yml file
|
||||
func (p *Plugin)AutoSetPorts(containerID string) error {
|
||||
container , err := client.GetContainerInformation(containerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// variable that would have a list of ports
|
||||
// to be allocated to the plugin system
|
||||
var ports []int
|
||||
// Counted that increments when a port is taken
|
||||
PortTaken := 0
|
||||
// setting all external ports available in an array
|
||||
for i, port := range container.Container.Ports.PortSet {
|
||||
if port.IsUsed == false {
|
||||
// Ensuring we break outside the loop once the ports
|
||||
// are set.
|
||||
if PortTaken >= p.NumOfPorts {
|
||||
break
|
||||
}
|
||||
// Setting the following port flag to true
|
||||
container.Container.Ports.PortSet[i].IsUsed = true
|
||||
// Incrementing the variable PortTaken
|
||||
PortTaken++
|
||||
ports = append(ports, port.ExternalPort)
|
||||
}
|
||||
}
|
||||
func (p *Plugin) AutoSetPorts(containerID string) error {
|
||||
container, err := client.GetContainerInformation(containerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// variable that would have a list of ports
|
||||
// to be allocated to the plugin system
|
||||
var ports []int
|
||||
// Counted that increments when a port is taken
|
||||
PortTaken := 0
|
||||
// setting all external ports available in an array
|
||||
for i, port := range container.Container.Ports.PortSet {
|
||||
if port.IsUsed == false {
|
||||
// Ensuring we break outside the loop once the ports
|
||||
// are set.
|
||||
if PortTaken >= p.NumOfPorts {
|
||||
break
|
||||
}
|
||||
// Setting the following port flag to true
|
||||
container.Container.Ports.PortSet[i].IsUsed = true
|
||||
// Incrementing the variable PortTaken
|
||||
PortTaken++
|
||||
// Maps to internal since
|
||||
// Inside the machine
|
||||
// internal port -> (maps) same internal port
|
||||
// TURN (i.e FRP) based approach (internal port -> maps to different external port)
|
||||
ports = append(ports, port.InternalPort)
|
||||
}
|
||||
}
|
||||
|
||||
// parses the site.yml file in the tmp directory
|
||||
t, err := template.ParseFiles(p.path + "/" + p.FolderName + "/site.yml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t, err := template.ParseFiles(p.path + "/" + p.FolderName + "/site.yml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// opens the output file
|
||||
f, err := os.Create(p.path + "/" + p.FolderName + "/site.yml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// sends the ports to the site.yml file to populate them
|
||||
err = t.Execute(f,ports)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Once the following is done set port to taken
|
||||
// n tracked container list
|
||||
err = container.ModifyContainerInformation()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Once the following is done set port to taken
|
||||
// I(Groups)
|
||||
err = container.ModifyContainerGroups()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(p.path + "/" + p.FolderName + "/site.yml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// sends the ports to the site.yml file to populate them
|
||||
err = t.Execute(f, ports)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Once the following is done set port to taken
|
||||
// n tracked container list
|
||||
err = container.ModifyContainerInformation()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Once the following is done set port to taken
|
||||
// I(Groups)
|
||||
err = container.ModifyContainerGroups()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// NumPorts Gets the Number the ports the
|
||||
// plugin requires
|
||||
func (p *Plugin)NumPorts() error {
|
||||
jsonFile, err := os.Open(p.path + "/ports.json")
|
||||
// if we os.Open returns an error then handle it
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func (p *Plugin) NumPorts() error {
|
||||
jsonFile, err := os.Open(p.path + "/ports.json")
|
||||
// if we os.Open returns an error then handle it
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// defer the closing of our jsonFile so that we can parse it later on
|
||||
defer jsonFile.Close()
|
||||
// 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)
|
||||
// read our opened xmlFile as a byte array.
|
||||
byteValue, _ := ioutil.ReadAll(jsonFile)
|
||||
|
||||
// we unmarshal our byteArray which contains our
|
||||
// jsonFile's content into 'users' which we defined above
|
||||
json.Unmarshal(byteValue, &p)
|
||||
// we unmarshal our byteArray which contains our
|
||||
// jsonFile's content into 'users' which we defined above
|
||||
json.Unmarshal(byteValue, &p)
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,246 +1,257 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/client"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker"
|
||||
"strconv"
|
||||
"testing"
|
||||
"fmt"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/client"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||
"net"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Test if the dummy plugin added is detected
|
||||
func TestDetectPlugins(t *testing.T) {
|
||||
_, err := DetectPlugins()
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
_, err := DetectPlugins()
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
// Test ensures that the ansible are executed inside local containers
|
||||
func TestRunPlugin(t *testing.T) {
|
||||
var testips []*ExecuteIP
|
||||
var testip1,testip2 ExecuteIP
|
||||
var testips []*ExecuteIP
|
||||
var testip1, testip2 ExecuteIP
|
||||
|
||||
// Create docker container and get SSH port
|
||||
container1 ,err := docker.BuildRunContainer(0,"false","")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Create docker container and get SSH port
|
||||
container1, err := docker.BuildRunContainer(0, "false", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
//Test IP 1 configuration
|
||||
testip1.IPAddress = "0.0.0.0"
|
||||
testip1.SSHPortNo = strconv.Itoa(container1.Ports.PortSet[0].ExternalPort)
|
||||
//Test IP 1 configuration
|
||||
testip1.IPAddress = "0.0.0.0"
|
||||
testip1.SSHPortNo = strconv.Itoa(container1.Ports.PortSet[0].ExternalPort)
|
||||
|
||||
// Create docker container and get SSH port
|
||||
container2 ,err := docker.BuildRunContainer(0,"false","")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
//Test IP 2 configuration
|
||||
testip2.IPAddress = "0.0.0.0"
|
||||
testip2.SSHPortNo = strconv.Itoa(container2.Ports.PortSet[0].ExternalPort)
|
||||
// Create docker container and get SSH port
|
||||
container2, err := docker.BuildRunContainer(0, "false", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
//Test IP 2 configuration
|
||||
testip2.IPAddress = "0.0.0.0"
|
||||
testip2.SSHPortNo = strconv.Itoa(container2.Ports.PortSet[0].ExternalPort)
|
||||
|
||||
testips = append(testips, &testip1)
|
||||
testips = append(testips, &testip2)
|
||||
testips = append(testips, &testip1)
|
||||
testips = append(testips, &testip2)
|
||||
|
||||
_,err = RunPlugin("TestAnsible",testips)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
_, err = RunPlugin("TestAnsible", testips)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Removing container1 after Ansible is executed
|
||||
err = docker.StopAndRemoveContainer(container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Removing container1 after Ansible is executed
|
||||
err = docker.StopAndRemoveContainer(container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
err = docker.StopAndRemoveContainer(container2.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
err = docker.StopAndRemoveContainer(container2.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
// Test to ensure that the ansible host file is modified to
|
||||
// the appropriate IP
|
||||
func TestExecuteIP_ModifyHost(t *testing.T) {
|
||||
var plugin Plugin
|
||||
var testip ExecuteIP
|
||||
var plugin Plugin
|
||||
var testip ExecuteIP
|
||||
|
||||
// Get plugin path from config file
|
||||
Config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
//Set plugin name
|
||||
plugin.FolderName = "TestAnsible"
|
||||
plugin.path = Config.PluginPath
|
||||
// Get plugin path from config file
|
||||
Config, err := config.ConfigInit(nil, nil)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
//Set plugin name
|
||||
plugin.FolderName = "TestAnsible"
|
||||
plugin.path = Config.PluginPath
|
||||
|
||||
//Test IP 1 configuration
|
||||
testip.IPAddress = "0.0.0.0"
|
||||
testip.SSHPortNo = "41289"
|
||||
//Test IP 1 configuration
|
||||
testip.IPAddress = "0.0.0.0"
|
||||
testip.SSHPortNo = "41289"
|
||||
|
||||
err = testip.ModifyHost(&plugin)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
err = testip.ModifyHost(&plugin)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
// Test to ensure the cli function runs as intended and executes
|
||||
// the test ansible script
|
||||
func TestRunPluginContainer(t *testing.T) {
|
||||
// Create docker container and get SSH port
|
||||
container1 ,err := docker.BuildRunContainer(0,"false","")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Create docker container and get SSH port
|
||||
container1, err := docker.BuildRunContainer(0, "false", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Ensuring created container is the added to the tracked list
|
||||
err = client.AddTrackContainer(container1, "0.0.0.0")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Ensuring created container is the added to the tracked list
|
||||
err = client.AddTrackContainer(container1, "0.0.0.0")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Running test Ansible script
|
||||
err = RunPluginContainer("TestAnsible", container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Running test Ansible script
|
||||
err = RunPluginContainer("TestAnsible", container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Removes container information from the tracker IP addresses
|
||||
err = client.RemoveTrackedContainer(container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Removes container information from the tracker IP addresses
|
||||
err = client.RemoveTrackedContainer(container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Removing container1 after Ansible is executed
|
||||
err = docker.StopAndRemoveContainer(container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Removing container1 after Ansible is executed
|
||||
err = docker.StopAndRemoveContainer(container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
// Testing the function can plugin can run with
|
||||
// group ID and container ID
|
||||
func TestCheckRunPlugin(t *testing.T) {
|
||||
// Create docker container and get SSH port
|
||||
container1 ,err := docker.BuildRunContainer(0,"false","")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Create docker container and get SSH port
|
||||
container2 ,err := docker.BuildRunContainer(0,"false","")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Create docker container and get SSH port
|
||||
container1, err := docker.BuildRunContainer(0, "false", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Create docker container and get SSH port
|
||||
container2, err := docker.BuildRunContainer(0, "false", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Ensuring created container1 is the added to the tracked list
|
||||
err = client.AddTrackContainer(container1, "0.0.0.0")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Ensuring created container2 is the added to the tracked list
|
||||
err = client.AddTrackContainer(container2, "0.0.0.0")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Ensuring created container1 is the added to the tracked list
|
||||
err = client.AddTrackContainer(container1, "0.0.0.0")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Ensuring created container2 is the added to the tracked list
|
||||
err = client.AddTrackContainer(container2, "0.0.0.0")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Create group to add created containers
|
||||
group, err := client.CreateGroup()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Create group to add created containers
|
||||
group, err := client.CreateGroup()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Add container 1 to the group
|
||||
_, err = client.AddContainerToGroup(container1.ID, group.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Add container 1 to the group
|
||||
_, err = client.AddContainerToGroup(container1.ID, group.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Add container 2 to the group
|
||||
_, err = client.AddContainerToGroup(container2.ID, group.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Add container 2 to the group
|
||||
_, err = client.AddContainerToGroup(container2.ID, group.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// -------------------------- Main test cases -------------------------------
|
||||
|
||||
// -------------------------- Main test cases -------------------------------
|
||||
// Checking function against container ID
|
||||
err = CheckRunPlugin("TestAnsible", container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Checking function against container ID
|
||||
err = CheckRunPlugin("TestAnsible", container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Checking function against group ID
|
||||
err = CheckRunPlugin("TestAnsible", group.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Checking function against group ID
|
||||
err = CheckRunPlugin("TestAnsible", group.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Remove created group
|
||||
err = client.RemoveGroup(group.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Remove created group
|
||||
err = client.RemoveGroup(group.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Removes container1 information from the tracker IP addresses
|
||||
err = client.RemoveTrackedContainer(container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Removes container1 information from the tracker IP addresses
|
||||
err = client.RemoveTrackedContainer(container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Removing container1 after Ansible is executed
|
||||
err = docker.StopAndRemoveContainer(container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Removing container1 after Ansible is executed
|
||||
err = docker.StopAndRemoveContainer(container1.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Removes container2 information from the tracker IP addresses
|
||||
err = client.RemoveTrackedContainer(container2.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Removes container2 information from the tracker IP addresses
|
||||
err = client.RemoveTrackedContainer(container2.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Removing container2 after Ansible is executed
|
||||
err = docker.StopAndRemoveContainer(container2.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
// Removing container2 after Ansible is executed
|
||||
err = docker.StopAndRemoveContainer(container2.ID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDownloadPlugin(t *testing.T) {
|
||||
err := DownloadPlugin("https://github.com/Akilan1999/laplace/")
|
||||
if err != nil {
|
||||
err := DownloadPlugin("https://github.com/Akilan1999/laplace/")
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Simple test case implemented to the test if
|
||||
// the port no can be extracted from the IP address.
|
||||
func TestParseIP(t *testing.T) {
|
||||
host, port, err := net.SplitHostPort("12.34.23.13:5432")
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
} else {
|
||||
fmt.Printf("Host: %s\nPort: %s\n", host, port)
|
||||
}
|
||||
}
|
||||
|
||||
BIN
server/.DS_Store
vendored
Normal file
BIN
server/50.bin
BIN
server/docker/.DS_Store
vendored
Normal file
@@ -1,7 +0,0 @@
|
||||
Containers
|
||||
===========
|
||||
|
||||
Structure
|
||||
|_ Containers
|
||||
|_ <name> (To ensure the name is the same as the tag name)
|
||||
|_ DockerFile
|
||||
@@ -1,43 +0,0 @@
|
||||
from horovod/horovod-cpu
|
||||
# Switch to root user to install additional software
|
||||
USER 0
|
||||
|
||||
|
||||
# Make sure we don't get notifications we can't answer during building.
|
||||
env DEBIAN_FRONTEND noninteractive
|
||||
|
||||
run apt-get -q -y update; apt-get -q -y upgrade
|
||||
run apt install net-tools
|
||||
|
||||
# Prepare scripts and configs
|
||||
add ./scripts/start /start
|
||||
|
||||
|
||||
# Set root password
|
||||
run echo 'root:password' >> /root/passwdfile
|
||||
|
||||
|
||||
# Create user and it's password
|
||||
run useradd -m -G sudo master && \
|
||||
echo 'master:password' >> /root/passwdfile
|
||||
|
||||
|
||||
# Apply root password
|
||||
run chpasswd -c SHA512 < /root/passwdfile && \
|
||||
rm /root/passwdfile
|
||||
|
||||
|
||||
# Port 22 is used for ssh
|
||||
expose 22
|
||||
|
||||
|
||||
# Assign /data as static volume.
|
||||
volume ["/data"]
|
||||
|
||||
|
||||
# Fix all permissions
|
||||
run chmod +x /start
|
||||
|
||||
|
||||
# Starting sshd
|
||||
cmd ["/start"]
|
||||
@@ -1 +0,0 @@
|
||||
Running official horovod dockerfile cpu version
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
# -----------------------------------------------------------------------------
|
||||
# docker-ubuntu-sshd /start script
|
||||
#
|
||||
# Authors: Art567
|
||||
# Updated: Sep 20th, 2015
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Run OpenSSH server in daemon mode
|
||||
/usr/sbin/sshd -D
|
||||
@@ -1,61 +0,0 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# This is base image of Ubuntu LTS with SSHD service.
|
||||
#
|
||||
# Authors: Art567
|
||||
# Updated: Sep 20th, 2015
|
||||
# Require: Docker (http://www.docker.io/)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Base system is the latest LTS version of Ubuntu.
|
||||
# from consol/ubuntu-xfce-vnc
|
||||
|
||||
# due to dependency issues vnc is still work in progress
|
||||
from ubuntu:20.04
|
||||
|
||||
# Switch to root user to install additional software
|
||||
USER 0
|
||||
|
||||
|
||||
# Make sure we don't get notifications we can't answer during building.
|
||||
env DEBIAN_FRONTEND noninteractive
|
||||
|
||||
|
||||
# Prepare scripts and configs
|
||||
add ./scripts/start /start
|
||||
|
||||
|
||||
# Download and install everything from the repos.
|
||||
run apt-get -q -y update; apt-get -q -y upgrade && \
|
||||
apt-get -q -y install sudo openssh-server && \
|
||||
mkdir /var/run/sshd
|
||||
|
||||
|
||||
# Set root password
|
||||
run echo 'root:password' >> /root/passwdfile
|
||||
|
||||
|
||||
# Create user and it's password
|
||||
run useradd -m -G sudo master && \
|
||||
echo 'master:password' >> /root/passwdfile
|
||||
|
||||
|
||||
# Apply root password
|
||||
run chpasswd -c SHA512 < /root/passwdfile && \
|
||||
rm /root/passwdfile
|
||||
|
||||
|
||||
# Port 22 is used for ssh
|
||||
expose 22
|
||||
|
||||
|
||||
# Assign /data as static volume.
|
||||
volume ["/data"]
|
||||
|
||||
|
||||
# Fix all permissions
|
||||
run chmod +x /start
|
||||
|
||||
|
||||
# Starting sshd
|
||||
cmd ["/start"]
|
||||
@@ -1,72 +0,0 @@
|
||||
Ubuntu LTS with SSH (Docker)
|
||||
=========
|
||||
|
||||
A Docker file to build a [docker.io] base container with Ubuntu LTS and a sshd service
|
||||
[docker.io]: http://docker.io
|
||||
Nice and easy way to get any server up and running using docker
|
||||
|
||||
|
||||
Instructions
|
||||
-----------
|
||||
- Install Docker first.
|
||||
Read [installation instructions] (http://docs.docker.io/en/latest/installation/).
|
||||
|
||||
|
||||
- Clone this repository:
|
||||
|
||||
`$ git clone https://github.com/art567/docker-ubuntu-sshd.git`
|
||||
|
||||
|
||||
- Enter local directory:
|
||||
|
||||
`$ cd docker-ubuntu-sshd`
|
||||
|
||||
- Change passwords in Dockerfile:
|
||||
|
||||
`$ vi Dockerfile`
|
||||
|
||||
- Build the container:
|
||||
|
||||
`$ sudo docker build -t art567/ubuntu .`
|
||||
|
||||
|
||||
- Run the container:
|
||||
|
||||
`$ sudo docker run -d=true --name=ubuntu --restart=always -p=2222:22 -v=/opt/data:/data art567/ubuntu /start`
|
||||
|
||||
|
||||
- Your container will start and bind ssh to 2222 port.
|
||||
|
||||
|
||||
- Find your local IP Address:
|
||||
|
||||
`$ ifconfig`
|
||||
|
||||
|
||||
- Connect to the SSH server:
|
||||
|
||||
`$ ssh root@<ip-address> -p 2222`
|
||||
|
||||
|
||||
- If you don't want to deal with root:
|
||||
|
||||
`$ ssh master@<ip-address> -p 2222`
|
||||
|
||||
|
||||
**VERY IMPORTANT!!!**
|
||||
-----------
|
||||
|
||||
**Don't forget to change passwords in Dockerfile before building image!**
|
||||
|
||||
|
||||
Versions
|
||||
-----------
|
||||
Some branches represents Ubuntu versions.
|
||||
|
||||
Branch `master` is always represented by latest Ubuntu LTS
|
||||
|
||||
For example:
|
||||
- 12.04 - Ubuntu 12.04 LTS
|
||||
- 14.04 - Ubuntu 14.04 LTS
|
||||
- 16.04 - Ubuntu 16.04 LTS
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Simple Ubuntu 20.04 image
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"Port": [
|
||||
{
|
||||
"PortName": "SSH",
|
||||
"InternalPort": 22,
|
||||
"Type": "tcp",
|
||||
"Description": "SSH Port"
|
||||
},
|
||||
{
|
||||
"PortName": "VNC",
|
||||
"InternalPort": 5900,
|
||||
"Type": "tcp",
|
||||
"Description": "VNC port"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/bin/bash
|
||||
# -----------------------------------------------------------------------------
|
||||
# docker-ubuntu-sshd /start script
|
||||
#
|
||||
# Authors: Art567
|
||||
# Updated: Sep 20th, 2015
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Run OpenSSH server in daemon mode
|
||||
/usr/sbin/sshd -D
|
||||
|
||||
# Running x11 server with password
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# This is base image of Ubuntu LTS with SSHD service.
|
||||
#
|
||||
# Authors: Art567
|
||||
# Updated: Sep 20th, 2015
|
||||
# Require: Docker (http://www.docker.io/)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Base system is the latest LTS version of Ubuntu.
|
||||
# from consol/ubuntu-xfce-vnc
|
||||
|
||||
# due to dependency issues vnc is still work in progress
|
||||
from ubuntu:20.04
|
||||
|
||||
# Switch to root user to install additional software
|
||||
USER 0
|
||||
|
||||
|
||||
# Make sure we don't get notifications we can't answer during building.
|
||||
env DEBIAN_FRONTEND noninteractive
|
||||
|
||||
|
||||
# Prepare scripts and configs
|
||||
add ./scripts/start /start
|
||||
|
||||
|
||||
# Download and install everything from the repos.
|
||||
run apt-get -q -y update; apt-get -q -y upgrade && \
|
||||
apt-get -q -y install sudo openssh-server && \
|
||||
mkdir /var/run/sshd
|
||||
|
||||
|
||||
# Set root password
|
||||
run echo 'root:password' >> /root/passwdfile
|
||||
|
||||
|
||||
# Create user and it's password
|
||||
run useradd -m -G sudo master && \
|
||||
echo 'master:password' >> /root/passwdfile
|
||||
|
||||
|
||||
# Apply root password
|
||||
run chpasswd -c SHA512 < /root/passwdfile && \
|
||||
rm /root/passwdfile
|
||||
|
||||
|
||||
# Port 22 is used for ssh
|
||||
expose 22
|
||||
|
||||
|
||||
# Assign /data as static volume.
|
||||
volume ["/data"]
|
||||
|
||||
|
||||
# Fix all permissions
|
||||
run chmod +x /start
|
||||
|
||||
|
||||
# Starting sshd
|
||||
cmd ["/start"]
|
||||
@@ -1,72 +0,0 @@
|
||||
Ubuntu LTS with SSH (Docker)
|
||||
=========
|
||||
|
||||
A Docker file to build a [docker.io] base container with Ubuntu LTS and a sshd service
|
||||
[docker.io]: http://docker.io
|
||||
Nice and easy way to get any server up and running using docker
|
||||
|
||||
|
||||
Instructions
|
||||
-----------
|
||||
- Install Docker first.
|
||||
Read [installation instructions] (http://docs.docker.io/en/latest/installation/).
|
||||
|
||||
|
||||
- Clone this repository:
|
||||
|
||||
`$ git clone https://github.com/art567/docker-ubuntu-sshd.git`
|
||||
|
||||
|
||||
- Enter local directory:
|
||||
|
||||
`$ cd docker-ubuntu-sshd`
|
||||
|
||||
- Change passwords in Dockerfile:
|
||||
|
||||
`$ vi Dockerfile`
|
||||
|
||||
- Build the container:
|
||||
|
||||
`$ sudo docker build -t art567/ubuntu .`
|
||||
|
||||
|
||||
- Run the container:
|
||||
|
||||
`$ sudo docker run -d=true --name=ubuntu --restart=always -p=2222:22 -v=/opt/data:/data art567/ubuntu /start`
|
||||
|
||||
|
||||
- Your container will start and bind ssh to 2222 port.
|
||||
|
||||
|
||||
- Find your local IP Address:
|
||||
|
||||
`$ ifconfig`
|
||||
|
||||
|
||||
- Connect to the SSH server:
|
||||
|
||||
`$ ssh root@<ip-address> -p 2222`
|
||||
|
||||
|
||||
- If you don't want to deal with root:
|
||||
|
||||
`$ ssh master@<ip-address> -p 2222`
|
||||
|
||||
|
||||
**VERY IMPORTANT!!!**
|
||||
-----------
|
||||
|
||||
**Don't forget to change passwords in Dockerfile before building image!**
|
||||
|
||||
|
||||
Versions
|
||||
-----------
|
||||
Some branches represents Ubuntu versions.
|
||||
|
||||
Branch `master` is always represented by latest Ubuntu LTS
|
||||
|
||||
For example:
|
||||
- 12.04 - Ubuntu 12.04 LTS
|
||||
- 14.04 - Ubuntu 14.04 LTS
|
||||
- 16.04 - Ubuntu 16.04 LTS
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Simple Ubuntu 20.04 image
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"Port": [
|
||||
{
|
||||
"PortName": "SSH",
|
||||
"InternalPort": 22,
|
||||
"Type": "tcp",
|
||||
"Description": "SSH Port"
|
||||
},
|
||||
{
|
||||
"PortName": "NoVNC",
|
||||
"InternalPort": 5901,
|
||||
"Type": "tcp",
|
||||
"Description": "NoVNC port"
|
||||
},
|
||||
{
|
||||
"PortName": "NoVNC",
|
||||
"InternalPort": 6081,
|
||||
"Type": "tcp",
|
||||
"Description": "NoVNC port"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
# -----------------------------------------------------------------------------
|
||||
# docker-ubuntu-sshd /start script
|
||||
#
|
||||
# Authors: Art567
|
||||
# Updated: Sep 20th, 2015
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Run OpenSSH server in daemon mode
|
||||
/usr/sbin/sshd -D
|
||||
@@ -1,41 +0,0 @@
|
||||
from horovod/horovod
|
||||
# Switch to root user to install additional software
|
||||
USER 0
|
||||
|
||||
|
||||
# Make sure we don't get notifications we can't answer during building.
|
||||
env DEBIAN_FRONTEND noninteractive
|
||||
|
||||
|
||||
# Prepare scripts and configs
|
||||
add ./scripts/start /start
|
||||
|
||||
|
||||
# Set root password
|
||||
run echo 'root:password' >> /root/passwdfile
|
||||
|
||||
|
||||
# Create user and it's password
|
||||
run useradd -m -G sudo master && \
|
||||
echo 'master:password' >> /root/passwdfile
|
||||
|
||||
|
||||
# Apply root password
|
||||
run chpasswd -c SHA512 < /root/passwdfile && \
|
||||
rm /root/passwdfile
|
||||
|
||||
|
||||
# Port 22 is used for ssh
|
||||
expose 22
|
||||
|
||||
|
||||
# Assign /data as static volume.
|
||||
volume ["/data"]
|
||||
|
||||
|
||||
# Fix all permissions
|
||||
run chmod +x /start
|
||||
|
||||
|
||||
# Starting sshd
|
||||
cmd ["/start"]
|
||||
@@ -1 +0,0 @@
|
||||
Running official horovod dockerfile cpu version
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
# -----------------------------------------------------------------------------
|
||||
# docker-ubuntu-sshd /start script
|
||||
#
|
||||
# Authors: Art567
|
||||
# Updated: Sep 20th, 2015
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Run OpenSSH server in daemon mode
|
||||
/usr/sbin/sshd -D
|
||||
@@ -1,61 +0,0 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# This is base image of Ubuntu LTS with SSHD service.
|
||||
#
|
||||
# Authors: Art567
|
||||
# Updated: Sep 20th, 2015
|
||||
# Require: Docker (http://www.docker.io/)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Base system is the latest LTS version of Ubuntu.
|
||||
# from consol/ubuntu-xfce-vnc
|
||||
|
||||
# due to dependency issues vnc is still work in progress
|
||||
from dorowu/ubuntu-desktop-lxde-vnc
|
||||
|
||||
# Switch to root user to install additional software
|
||||
USER 0
|
||||
|
||||
|
||||
# Make sure we don't get notifications we can't answer during building.
|
||||
env DEBIAN_FRONTEND noninteractive
|
||||
|
||||
|
||||
# Prepare scripts and configs
|
||||
add ./scripts/start /start
|
||||
|
||||
|
||||
# Download and install everything from the repos.
|
||||
run apt-get -q -y update; apt-get -q -y upgrade && \
|
||||
apt-get -q -y install sudo openssh-server && \
|
||||
mkdir /var/run/sshd
|
||||
|
||||
|
||||
# Set root password
|
||||
run echo 'root:password' >> /root/passwdfile
|
||||
|
||||
|
||||
# Create user and it's password
|
||||
run useradd -m -G sudo master && \
|
||||
echo 'master:password' >> /root/passwdfile
|
||||
|
||||
|
||||
# Apply root password
|
||||
run chpasswd -c SHA512 < /root/passwdfile && \
|
||||
rm /root/passwdfile
|
||||
|
||||
|
||||
# Port 22 is used for ssh
|
||||
expose 22
|
||||
|
||||
|
||||
# Assign /data as static volume.
|
||||
volume ["/data"]
|
||||
|
||||
|
||||
# Fix all permissions
|
||||
run chmod +x /start
|
||||
|
||||
|
||||
# Starting sshd
|
||||
cmd ["/start"]
|
||||
@@ -1,72 +0,0 @@
|
||||
Ubuntu LTS with SSH (Docker)
|
||||
=========
|
||||
|
||||
A Docker file to build a [docker.io] base container with Ubuntu LTS and a sshd service
|
||||
[docker.io]: http://docker.io
|
||||
Nice and easy way to get any server up and running using docker
|
||||
|
||||
|
||||
Instructions
|
||||
-----------
|
||||
- Install Docker first.
|
||||
Read [installation instructions] (http://docs.docker.io/en/latest/installation/).
|
||||
|
||||
|
||||
- Clone this repository:
|
||||
|
||||
`$ git clone https://github.com/art567/docker-ubuntu-sshd.git`
|
||||
|
||||
|
||||
- Enter local directory:
|
||||
|
||||
`$ cd docker-ubuntu-sshd`
|
||||
|
||||
- Change passwords in Dockerfile:
|
||||
|
||||
`$ vi Dockerfile`
|
||||
|
||||
- Build the container:
|
||||
|
||||
`$ sudo docker build -t art567/ubuntu .`
|
||||
|
||||
|
||||
- Run the container:
|
||||
|
||||
`$ sudo docker run -d=true --name=ubuntu --restart=always -p=2222:22 -v=/opt/data:/data art567/ubuntu /start`
|
||||
|
||||
|
||||
- Your container will start and bind ssh to 2222 port.
|
||||
|
||||
|
||||
- Find your local IP Address:
|
||||
|
||||
`$ ifconfig`
|
||||
|
||||
|
||||
- Connect to the SSH server:
|
||||
|
||||
`$ ssh root@<ip-address> -p 2222`
|
||||
|
||||
|
||||
- If you don't want to deal with root:
|
||||
|
||||
`$ ssh master@<ip-address> -p 2222`
|
||||
|
||||
|
||||
**VERY IMPORTANT!!!**
|
||||
-----------
|
||||
|
||||
**Don't forget to change passwords in Dockerfile before building image!**
|
||||
|
||||
|
||||
Versions
|
||||
-----------
|
||||
Some branches represents Ubuntu versions.
|
||||
|
||||
Branch `master` is always represented by latest Ubuntu LTS
|
||||
|
||||
For example:
|
||||
- 12.04 - Ubuntu 12.04 LTS
|
||||
- 14.04 - Ubuntu 14.04 LTS
|
||||
- 16.04 - Ubuntu 16.04 LTS
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Simple Ubuntu 20.04 image
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
# -----------------------------------------------------------------------------
|
||||
# docker-ubuntu-sshd /start script
|
||||
#
|
||||
# Authors: Art567
|
||||
# Updated: Sep 20th, 2015
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Run OpenSSH server in daemon mode
|
||||
/usr/sbin/sshd -D
|
||||
@@ -1,406 +1,404 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/lithammer/shortuuid"
|
||||
"github.com/phayes/freeport"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"time"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/lithammer/shortuuid"
|
||||
"github.com/phayes/freeport"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DockerVM struct {
|
||||
SSHUsername string `json:"SSHUsername"`
|
||||
SSHPassword string `json:"SSHPassword"`
|
||||
ID string `json:"ID"`
|
||||
TagName string `json:"TagName"`
|
||||
ImagePath string `json:"ImagePath"`
|
||||
Ports Ports `json:"Ports"`
|
||||
GPU string `json:"GPU"`
|
||||
SSHUsername string `json:"SSHUsername"`
|
||||
SSHPassword string `json:"SSHPassword"`
|
||||
ID string `json:"ID"`
|
||||
TagName string `json:"TagName"`
|
||||
ImagePath string `json:"ImagePath"`
|
||||
Ports Ports `json:"Ports"`
|
||||
GPU string `json:"GPU"`
|
||||
}
|
||||
|
||||
type DockerContainers struct {
|
||||
DockerContainer []DockerContainer `json:"DockerContainer"`
|
||||
DockerContainer []DockerContainer `json:"DockerContainer"`
|
||||
}
|
||||
|
||||
type DockerContainer struct {
|
||||
ContainerName string `json:"DockerContainerName"`
|
||||
ContainerDescription string `json:"ContainerDescription"`
|
||||
ContainerName string `json:"DockerContainerName"`
|
||||
ContainerDescription string `json:"ContainerDescription"`
|
||||
}
|
||||
|
||||
type Ports struct {
|
||||
PortSet []Port `json:"Port"`
|
||||
PortSet []Port `json:"Port"`
|
||||
}
|
||||
type Port struct {
|
||||
PortName string `json:"PortName"`
|
||||
InternalPort int `json:"InternalPort"`
|
||||
Type string `json:"Type"`
|
||||
ExternalPort int `json:"ExternalPort"`
|
||||
IsUsed bool `json:"IsUsed"`
|
||||
Description string `json:"Description"`
|
||||
PortName string `json:"PortName"`
|
||||
InternalPort int `json:"InternalPort"`
|
||||
Type string `json:"Type"`
|
||||
ExternalPort int `json:"ExternalPort"`
|
||||
IsUsed bool `json:"IsUsed"`
|
||||
Description string `json:"Description"`
|
||||
}
|
||||
|
||||
type ErrorLine struct {
|
||||
Error string `json:"error"`
|
||||
ErrorDetail ErrorDetail `json:"errorDetail"`
|
||||
Error string `json:"error"`
|
||||
ErrorDetail ErrorDetail `json:"errorDetail"`
|
||||
}
|
||||
|
||||
type ErrorDetail struct {
|
||||
Message string `json:"message"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
var dockerRegistryUserID = ""
|
||||
|
||||
// BuildRunContainer Function is incharge to invoke building and running contianer and also allocating external
|
||||
// ports
|
||||
func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerVM,error) {
|
||||
//Docker Struct Variable
|
||||
var RespDocker *DockerVM = new(DockerVM)
|
||||
func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerVM, error) {
|
||||
//Docker Struct Variable
|
||||
var RespDocker *DockerVM = new(DockerVM)
|
||||
|
||||
// Sets if GPU is selected or not
|
||||
RespDocker.GPU = GPU
|
||||
// Sets if GPU is selected or not
|
||||
RespDocker.GPU = GPU
|
||||
|
||||
// Sets Free port to Struct
|
||||
//RespDocker.SSHPort = Ports[0]
|
||||
//RespDocker.VNCPort = Ports[1]
|
||||
// Sets appropriate username and password to the
|
||||
// variables in the struct
|
||||
RespDocker.SSHUsername = "master"
|
||||
RespDocker.SSHPassword = "password"
|
||||
//RespDocker.VNCPassword = "vncpassword"
|
||||
// Sets Free port to Struct
|
||||
//RespDocker.SSHPort = Ports[0]
|
||||
//RespDocker.VNCPort = Ports[1]
|
||||
// Sets appropriate username and password to the
|
||||
// variables in the struct
|
||||
RespDocker.SSHUsername = "master"
|
||||
RespDocker.SSHPassword = "password"
|
||||
//RespDocker.VNCPassword = "vncpassword"
|
||||
|
||||
//Default parameters
|
||||
RespDocker.TagName = "p2p-ubuntu"
|
||||
// Get Path from config
|
||||
config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
RespDocker.ImagePath = config.DefaultDockerFile
|
||||
//Default parameters
|
||||
RespDocker.TagName = "p2p-ubuntu"
|
||||
// Get Path from config
|
||||
config, err := config.ConfigInit(nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
RespDocker.ImagePath = config.DefaultDockerFile
|
||||
|
||||
// We are checking if the container name is not nil and not equal to the default one used
|
||||
// which is docker-ubuntu-sshd
|
||||
if ContainerName != "" && ContainerName != "docker-ubuntu-sshd" {
|
||||
Containers, err := ViewAllContainers()
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
// We are checking if the container name is not nil and not equal to the default one used
|
||||
// which is docker-ubuntu-sshd
|
||||
if ContainerName != "" && ContainerName != "docker-ubuntu-sshd" {
|
||||
Containers, err := ViewAllContainers()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, dockerContainer := range Containers.DockerContainer {
|
||||
if dockerContainer.ContainerName == ContainerName {
|
||||
RespDocker.ImagePath = config.DockerContainers + ContainerName + "/"
|
||||
RespDocker.TagName = ContainerName
|
||||
break
|
||||
}
|
||||
}
|
||||
if RespDocker.ImagePath == config.DefaultDockerFile {
|
||||
return nil, errors.New("Container " + ContainerName + " does not exist in the server")
|
||||
}
|
||||
}
|
||||
for _, dockerContainer := range Containers.DockerContainer {
|
||||
if dockerContainer.ContainerName == ContainerName {
|
||||
RespDocker.ImagePath = config.DockerContainers + ContainerName + "/"
|
||||
RespDocker.TagName = ContainerName
|
||||
break
|
||||
}
|
||||
}
|
||||
if RespDocker.ImagePath == config.DefaultDockerFile {
|
||||
return nil, errors.New("Container " + ContainerName + " does not exist in the server")
|
||||
}
|
||||
}
|
||||
|
||||
PortsInformation, err := OpenPortsFile(RespDocker.ImagePath + "/ports.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
PortsInformation, err := OpenPortsFile(RespDocker.ImagePath + "/ports.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Number of perts we want to open + number of ports required inside the
|
||||
// docker container
|
||||
count := NumPorts + len(PortsInformation.PortSet)
|
||||
// Creates number of ports
|
||||
OpenPorts, err := freeport.GetFreePorts(count)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
// Allocate external ports to ports available in the ports.json file
|
||||
for i := range PortsInformation.PortSet {
|
||||
// Setting external ports
|
||||
PortsInformation.PortSet[i].ExternalPort = OpenPorts[i]
|
||||
PortsInformation.PortSet[i].IsUsed = true
|
||||
}
|
||||
//Length of Ports allocated from thr port file
|
||||
portFileLength := len(PortsInformation.PortSet)
|
||||
// Allocate New ports the user wants to generate
|
||||
for i := 0; i < NumPorts; i++ {
|
||||
var TempPort Port
|
||||
TempPort.PortName = "AutoGen Port"
|
||||
TempPort.Type = "tcp"
|
||||
TempPort.InternalPort = OpenPorts[portFileLength + i]
|
||||
TempPort.ExternalPort = OpenPorts[portFileLength + i]
|
||||
TempPort.Description = "Auto generated TCP port"
|
||||
TempPort.IsUsed = false
|
||||
//Append temp port to port information
|
||||
PortsInformation.PortSet = append(PortsInformation.PortSet, TempPort)
|
||||
}
|
||||
// Setting ports to the docker VM struct
|
||||
RespDocker.Ports = *PortsInformation
|
||||
// Number of perts we want to open + number of ports required inside the
|
||||
// docker container
|
||||
count := NumPorts + len(PortsInformation.PortSet)
|
||||
// Creates number of ports
|
||||
OpenPorts, err := freeport.GetFreePorts(count)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Allocate external ports to ports available in the ports.json file
|
||||
for i := range PortsInformation.PortSet {
|
||||
// Setting external ports
|
||||
PortsInformation.PortSet[i].ExternalPort = OpenPorts[i]
|
||||
PortsInformation.PortSet[i].IsUsed = true
|
||||
}
|
||||
//Length of Ports allocated from thr port file
|
||||
portFileLength := len(PortsInformation.PortSet)
|
||||
// Allocate New ports the user wants to generate
|
||||
for i := 0; i < NumPorts; i++ {
|
||||
var TempPort Port
|
||||
TempPort.PortName = "AutoGen Port"
|
||||
TempPort.Type = "tcp"
|
||||
TempPort.InternalPort = OpenPorts[portFileLength+i]
|
||||
TempPort.ExternalPort = OpenPorts[portFileLength+i]
|
||||
TempPort.Description = "Auto generated TCP port"
|
||||
TempPort.IsUsed = false
|
||||
//Append temp port to port information
|
||||
PortsInformation.PortSet = append(PortsInformation.PortSet, TempPort)
|
||||
}
|
||||
// Setting ports to the docker VM struct
|
||||
RespDocker.Ports = *PortsInformation
|
||||
|
||||
// Gets docker information from env variables
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
// Gets docker information from env variables
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Builds docker image
|
||||
err = RespDocker.imageBuild(cli)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
// Builds docker image
|
||||
err = RespDocker.imageBuild(cli)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Runs docker contianer
|
||||
err = RespDocker.runContainer(cli)
|
||||
// Runs docker contianer
|
||||
err = RespDocker.runContainer(cli)
|
||||
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
return RespDocker,nil
|
||||
return RespDocker, nil
|
||||
|
||||
}
|
||||
|
||||
//Builds docker image (TODO: relative path for Dockerfile deploy)
|
||||
func (d *DockerVM)imageBuild(dockerClient *client.Client) error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
|
||||
//defer cancel()
|
||||
// Builds docker image (TODO: relative path for Dockerfile deploy)
|
||||
func (d *DockerVM) imageBuild(dockerClient *client.Client) error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
|
||||
//defer cancel()
|
||||
|
||||
tar, err := archive.TarWithOptions(d.ImagePath, &archive.TarOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tar, err := archive.TarWithOptions(d.ImagePath, &archive.TarOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opts := types.ImageBuildOptions{
|
||||
Dockerfile: "Dockerfile",
|
||||
Tags: []string{d.TagName},
|
||||
Remove: true,
|
||||
}
|
||||
res, err := dockerClient.ImageBuild(ctx, tar, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := types.ImageBuildOptions{
|
||||
Dockerfile: "Dockerfile",
|
||||
Tags: []string{d.TagName},
|
||||
Remove: true,
|
||||
}
|
||||
res, err := dockerClient.ImageBuild(ctx, tar, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer res.Body.Close()
|
||||
defer res.Body.Close()
|
||||
|
||||
err = print(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = print(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Starts container and assigns port numbers
|
||||
// Sample Docker run Command
|
||||
// docker run -d=true --name=Test123 --restart=always --gpus all
|
||||
//-p 3443:6901 -p 3453:22 -p 3434:3434 -p 3245:3245 -v=/opt/data:/data
|
||||
//p2p-ubuntu /start > /dev/null
|
||||
func (d *DockerVM)runContainer(dockerClient *client.Client) error{
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
|
||||
// -p 3443:6901 -p 3453:22 -p 3434:3434 -p 3245:3245 -v=/opt/data:/data
|
||||
// p2p-ubuntu /start > /dev/null
|
||||
func (d *DockerVM) runContainer(dockerClient *client.Client) error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
|
||||
|
||||
|
||||
// The first mode runs using the Docker Api. As the API supports using
|
||||
// CPU and uses a shell script for GPU call because till this point of
|
||||
// implementation docker api does not support the flag "--gpu all"
|
||||
// The first mode runs using the Docker Api. As the API supports using
|
||||
// CPU and uses a shell script for GPU call because till this point of
|
||||
// implementation docker api does not support the flag "--gpu all"
|
||||
if d.GPU != "true" {
|
||||
//Exposed ports for docker config file
|
||||
var ExposedPort nat.PortSet
|
||||
//Exposed ports for docker config file
|
||||
var ExposedPort nat.PortSet
|
||||
|
||||
ExposedPort = nat.PortSet{
|
||||
"22/tcp": struct{}{},
|
||||
//"6901/tcp": struct{}{},
|
||||
}
|
||||
ExposedPort = nat.PortSet{
|
||||
"22/tcp": struct{}{},
|
||||
//"6901/tcp": struct{}{},
|
||||
}
|
||||
|
||||
// Port forwarding for VNC and SSH ports
|
||||
PortForwarding := nat.PortMap{
|
||||
//"22/tcp": []nat.PortBinding{
|
||||
// {
|
||||
// HostIP: "0.0.0.0",
|
||||
// HostPort: fmt.Sprint(d.SSHPort),
|
||||
// },
|
||||
//},
|
||||
//"6901/tcp": []nat.PortBinding{
|
||||
// {
|
||||
// HostIP: "0.0.0.0",
|
||||
// HostPort: fmt.Sprint(d.VNCPort),
|
||||
// },
|
||||
//},
|
||||
}
|
||||
// Port forwarding for VNC and SSH ports
|
||||
PortForwarding := nat.PortMap{
|
||||
//"22/tcp": []nat.PortBinding{
|
||||
// {
|
||||
// HostIP: "0.0.0.0",
|
||||
// HostPort: fmt.Sprint(d.SSHPort),
|
||||
// },
|
||||
//},
|
||||
//"6901/tcp": []nat.PortBinding{
|
||||
// {
|
||||
// HostIP: "0.0.0.0",
|
||||
// HostPort: fmt.Sprint(d.VNCPort),
|
||||
// },
|
||||
//},
|
||||
}
|
||||
|
||||
for i := range d.Ports.PortSet {
|
||||
// Parameters "tcp or udp", external port
|
||||
Port, err := nat.NewPort(d.Ports.PortSet[i].Type,fmt.Sprint(d.Ports.PortSet[i].InternalPort))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range d.Ports.PortSet {
|
||||
// Parameters "tcp or udp", external port
|
||||
Port, err := nat.NewPort(d.Ports.PortSet[i].Type, fmt.Sprint(d.Ports.PortSet[i].InternalPort))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Exposed Ports
|
||||
ExposedPort[Port] = struct{}{}
|
||||
// Exposed Ports
|
||||
ExposedPort[Port] = struct{}{}
|
||||
|
||||
PortForwarding[Port] = []nat.PortBinding{
|
||||
{
|
||||
HostIP: "0.0.0.0",
|
||||
HostPort: fmt.Sprint(d.Ports.PortSet[i].ExternalPort),
|
||||
},
|
||||
}
|
||||
}
|
||||
PortForwarding[Port] = []nat.PortBinding{
|
||||
{
|
||||
HostIP: "0.0.0.0",
|
||||
HostPort: fmt.Sprint(d.Ports.PortSet[i].ExternalPort),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
config := &container.Config{
|
||||
Image: d.TagName,
|
||||
Entrypoint: []string{"/start"},
|
||||
Volumes: map[string]struct{}{"/opt/data:/data": {}},
|
||||
ExposedPorts: ExposedPort,
|
||||
}
|
||||
hostConfig := &container.HostConfig{
|
||||
PortBindings: PortForwarding,
|
||||
}
|
||||
config := &container.Config{
|
||||
Image: d.TagName,
|
||||
Entrypoint: []string{"/start"},
|
||||
Volumes: map[string]struct{}{"/opt/data:/data": {}},
|
||||
ExposedPorts: ExposedPort,
|
||||
}
|
||||
hostConfig := &container.HostConfig{
|
||||
PortBindings: PortForwarding,
|
||||
}
|
||||
|
||||
res, err := dockerClient.ContainerCreate(ctx, config, hostConfig,
|
||||
nil, nil, "")
|
||||
res, err := dockerClient.ContainerCreate(ctx, config, hostConfig,
|
||||
nil, nil, "")
|
||||
|
||||
// Set response ID
|
||||
d.ID = res.ID
|
||||
// Set response ID
|
||||
d.ID = res.ID
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = dockerClient.ContainerStart(ctx, res.ID, types.ContainerStartOptions{})
|
||||
err = dockerClient.ContainerStart(ctx, res.ID, types.ContainerStartOptions{})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Generate Random ID
|
||||
id := shortuuid.New()
|
||||
d.ID = id
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Generate Random ID
|
||||
id := shortuuid.New()
|
||||
d.ID = id
|
||||
|
||||
var cmd bytes.Buffer
|
||||
cmd.WriteString("docker run -d=true --name="+ id +" --restart=always --gpus all ")
|
||||
for i := range d.Ports.PortSet {
|
||||
cmd.WriteString("-p " + fmt.Sprint(d.Ports.PortSet[i].ExternalPort) + ":" + fmt.Sprint(d.Ports.PortSet[i].InternalPort) + " ")
|
||||
}
|
||||
cmd.WriteString("-v=/opt/data:/data "+ d.TagName +" /start > /dev/null")
|
||||
//"-v=/opt/data:/data p2p-ubuntu /start > /dev/null"
|
||||
cmdStr := cmd.String()
|
||||
_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
var cmd bytes.Buffer
|
||||
cmd.WriteString("docker run -d=true --name=" + id + " --restart=always --gpus all ")
|
||||
for i := range d.Ports.PortSet {
|
||||
cmd.WriteString("-p " + fmt.Sprint(d.Ports.PortSet[i].ExternalPort) + ":" + fmt.Sprint(d.Ports.PortSet[i].InternalPort) + " ")
|
||||
}
|
||||
cmd.WriteString("-v=/opt/data:/data " + d.TagName + " /start > /dev/null")
|
||||
//"-v=/opt/data:/data p2p-ubuntu /start > /dev/null"
|
||||
cmdStr := cmd.String()
|
||||
_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// StopAndRemoveContainer
|
||||
// StopAndRemoveContainer
|
||||
// Stop and remove a container
|
||||
// Reference (https://gist.github.com/frikky/e2efcea6c733ea8d8d015b7fe8a91bf6)
|
||||
func StopAndRemoveContainer(containername string) error {
|
||||
ctx := context.Background()
|
||||
ctx := context.Background()
|
||||
|
||||
// Gets docker information from env variables
|
||||
client, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Gets docker information from env variables
|
||||
client, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = client.ContainerStop(ctx, containername, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = client.ContainerStop(ctx, containername, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
removeOptions := types.ContainerRemoveOptions{
|
||||
RemoveVolumes: true,
|
||||
Force: true,
|
||||
}
|
||||
removeOptions := types.ContainerRemoveOptions{
|
||||
RemoveVolumes: true,
|
||||
Force: true,
|
||||
}
|
||||
|
||||
if err = client.ContainerRemove(ctx, containername, removeOptions); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = client.ContainerRemove(ctx, containername, removeOptions); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// ViewAllContainers returns all containers runnable and which can be built
|
||||
func ViewAllContainers() (*DockerContainers, error){
|
||||
// Traverse the deploy path as per given in the config file
|
||||
config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
func ViewAllContainers() (*DockerContainers, error) {
|
||||
// Traverse the deploy path as per given in the config file
|
||||
config, err := config.ConfigInit(nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
folders, err := ioutil.ReadDir(config.DockerContainers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
folders, err := ioutil.ReadDir(config.DockerContainers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//Declare variable DockerContainers of type struct
|
||||
var Containers *DockerContainers = new(DockerContainers)
|
||||
//Declare variable DockerContainers of type struct
|
||||
var Containers *DockerContainers = new(DockerContainers)
|
||||
|
||||
for _, f := range folders {
|
||||
if f.IsDir() {
|
||||
//Declare variable DockerContainer of type struct
|
||||
for _, f := range folders {
|
||||
if f.IsDir() {
|
||||
//Declare variable DockerContainer of type struct
|
||||
var Container DockerContainer
|
||||
|
||||
// Setting container name to deploy name
|
||||
Container.ContainerName = f.Name()
|
||||
// Getting Description from file description.txt
|
||||
Description, err := ioutil.ReadFile(config.DockerContainers + "/" + Container.ContainerName + "/description.txt")
|
||||
// if we os.Open returns an error then handle it
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Description, err := ioutil.ReadFile(config.DockerContainers + "/" + Container.ContainerName + "/description.txt")
|
||||
// if we os.Open returns an error then handle it
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get Description from description.txt
|
||||
Container.ContainerDescription = string(Description)
|
||||
// Get Description from description.txt
|
||||
Container.ContainerDescription = string(Description)
|
||||
|
||||
Containers.DockerContainer = append(Containers.DockerContainer, Container)
|
||||
}
|
||||
}
|
||||
Containers.DockerContainer = append(Containers.DockerContainer, Container)
|
||||
}
|
||||
}
|
||||
|
||||
return Containers,nil
|
||||
return Containers, nil
|
||||
}
|
||||
|
||||
func print(rd io.Reader) error {
|
||||
var lastLine string
|
||||
var lastLine string
|
||||
|
||||
scanner := bufio.NewScanner(rd)
|
||||
for scanner.Scan() {
|
||||
lastLine = scanner.Text()
|
||||
}
|
||||
scanner := bufio.NewScanner(rd)
|
||||
for scanner.Scan() {
|
||||
lastLine = scanner.Text()
|
||||
}
|
||||
|
||||
errLine := &ErrorLine{}
|
||||
json.Unmarshal([]byte(lastLine), errLine)
|
||||
if errLine.Error != "" {
|
||||
return errors.New(errLine.Error)
|
||||
}
|
||||
errLine := &ErrorLine{}
|
||||
json.Unmarshal([]byte(lastLine), errLine)
|
||||
if errLine.Error != "" {
|
||||
return errors.New(errLine.Error)
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func OpenPortsFile(filename string) (*Ports, error) {
|
||||
buf, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := &Ports{}
|
||||
err = json.Unmarshal(buf, c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("in file %q: %v", filename, err)
|
||||
}
|
||||
c := &Ports{}
|
||||
err = json.Unmarshal(buf, c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("in file %q: %v", filename, err)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
"github.com/shirou/gopsutil/disk"
|
||||
"github.com/shirou/gopsutil/host"
|
||||
"github.com/shirou/gopsutil/mem"
|
||||
"github.com/shirou/gopsutil/v3/cpu"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"github.com/shirou/gopsutil/v3/host"
|
||||
"github.com/shirou/gopsutil/v3/mem"
|
||||
)
|
||||
|
||||
// SysInfo saves the basic system information
|
||||
type SysInfo struct {
|
||||
Hostname string `bson:hostname`
|
||||
Platform string `bson:platform`
|
||||
CPU string `bson:cpu`
|
||||
RAM uint64 `bson:ram`
|
||||
Disk uint64 `bson:disk`
|
||||
GPU *Query `xml: GpuInfo`
|
||||
Hostname string `bson:hostname`
|
||||
Platform string `bson:platform`
|
||||
CPU string `bson:cpu`
|
||||
RAM uint64 `bson:ram`
|
||||
Disk uint64 `bson:disk`
|
||||
GPU *Query `xml: GpuInfo`
|
||||
}
|
||||
|
||||
func ServerInfo() interface{}{
|
||||
hostStat, _ := host.Info()
|
||||
cpuStat, _ := cpu.Info()
|
||||
func ServerInfo() *SysInfo {
|
||||
hostStat, _ := host.Info()
|
||||
cpuStat, _ := cpu.Info()
|
||||
vmStat, _ := mem.VirtualMemory()
|
||||
|
||||
info := new(SysInfo)
|
||||
|
||||
|
||||
filesystem := "/"
|
||||
|
||||
|
||||
// If the server is running windows
|
||||
if info.Hostname == "windows"{
|
||||
if info.Hostname == "windows" {
|
||||
filesystem = "\\"
|
||||
}
|
||||
|
||||
diskStat, _ := disk.Usage(filesystem) // If you're in Unix change this "\\" for "/"
|
||||
diskStat, _ := disk.Usage(filesystem) // If you're in Unix change this "\\" for "/"
|
||||
|
||||
info.Hostname = hostStat.Hostname
|
||||
info.Platform = hostStat.Platform
|
||||
info.CPU = cpuStat[0].ModelName
|
||||
info.RAM = vmStat.Total / 1024 / 1024
|
||||
info.Disk = diskStat.Total / 1024 / 1024
|
||||
info.Hostname = hostStat.Hostname
|
||||
info.Platform = hostStat.Platform
|
||||
info.CPU = cpuStat[0].ModelName
|
||||
info.RAM = vmStat.Total / 1024 / 1024
|
||||
info.Disk = diskStat.Total / 1024 / 1024
|
||||
|
||||
gpu, err := GPUInfo()
|
||||
|
||||
@@ -45,7 +45,6 @@ func ServerInfo() interface{}{
|
||||
info.GPU = gpu
|
||||
}
|
||||
|
||||
return info
|
||||
return info
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||
"net"
|
||||
"net/rpc"
|
||||
)
|
||||
@@ -18,8 +18,8 @@ type Docker struct {
|
||||
}
|
||||
|
||||
// Starts container using RPC calls
|
||||
func (l *Listener) StartContainer( reply *Docker) error {
|
||||
vm, err := docker.BuildRunContainer(3,"false","")
|
||||
func (l *Listener) StartContainer(reply *Docker) error {
|
||||
vm, err := docker.BuildRunContainer(3, "false", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -28,8 +28,6 @@ func (l *Listener) StartContainer( reply *Docker) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
func Rpc() {
|
||||
rpcServer, err := net.ResolveTCPAddr("tcp", "0.0.0.0:"+port)
|
||||
if err != nil {
|
||||
@@ -43,4 +41,3 @@ func Rpc() {
|
||||
rpc.Register(listener)
|
||||
rpc.Accept(inbound)
|
||||
}
|
||||
|
||||
|
||||
305
server/server.go
@@ -1,147 +1,226 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/config"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/p2p"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
|
||||
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Server() error{
|
||||
r := gin.Default()
|
||||
func Server() (*gin.Engine, error) {
|
||||
r := gin.Default()
|
||||
|
||||
// Gets default information of the server
|
||||
r.GET("/server_info", func(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, ServerInfo())
|
||||
})
|
||||
//Get Server port based on the config file
|
||||
config, err := config.ConfigInit(nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Speed test with 50 mbps
|
||||
r.GET("/50", func(c *gin.Context){
|
||||
// Get Path from config
|
||||
config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
c.String(http.StatusOK, fmt.Sprint(err))
|
||||
}
|
||||
c.File(config.SpeedTestFile)
|
||||
})
|
||||
// update IPTable with new port and ip address and update ip table
|
||||
var ProxyIpAddr p2p.IpAddress
|
||||
var lowestLatencyIpAddress p2p.IpAddress
|
||||
|
||||
// Route build to do a speed test
|
||||
r.GET("/upload", func(c *gin.Context) {
|
||||
file, _ := c.FormFile("file")
|
||||
// Gets default information of the server
|
||||
r.GET("/server_info", func(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, ServerInfo())
|
||||
})
|
||||
|
||||
// Upload the file to specific dst.
|
||||
// c.SaveUploadedFile(file, dst)
|
||||
// Speed test with 50 mbps
|
||||
r.GET("/50", func(c *gin.Context) {
|
||||
// Get Path from config
|
||||
c.File(config.SpeedTestFile)
|
||||
})
|
||||
|
||||
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
|
||||
})
|
||||
// Route build to do a speed test
|
||||
r.GET("/upload", func(c *gin.Context) {
|
||||
file, _ := c.FormFile("file")
|
||||
|
||||
//Gets Ip Table from server node
|
||||
r.POST("/IpTable", func(c *gin.Context) {
|
||||
// Getting IPV4 address of client
|
||||
var ClientHost p2p.IpAddress
|
||||
// Upload the file to specific dst.
|
||||
// c.SaveUploadedFile(file, dst)
|
||||
|
||||
if p2p.Ip4or6(c.ClientIP()) == "version 6" {
|
||||
ClientHost.Ipv6 = c.ClientIP()
|
||||
} else {
|
||||
ClientHost.Ipv4 = c.ClientIP()
|
||||
}
|
||||
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
|
||||
})
|
||||
|
||||
// Variable to store IP table information
|
||||
var IPTable p2p.IpAddresses
|
||||
//Gets Ip Table from server node
|
||||
r.POST("/IpTable", func(c *gin.Context) {
|
||||
// Getting IPV4 address of client
|
||||
var ClientHost p2p.IpAddress
|
||||
|
||||
// Receive file from POST request
|
||||
body, err := c.FormFile("json")
|
||||
if err != nil {
|
||||
c.String(http.StatusOK, fmt.Sprint(err))
|
||||
}
|
||||
if p2p.Ip4or6(c.ClientIP()) == "version 6" {
|
||||
ClientHost.Ipv6 = c.ClientIP()
|
||||
} else {
|
||||
ClientHost.Ipv4 = c.ClientIP()
|
||||
}
|
||||
|
||||
// Open file
|
||||
open, err := body.Open()
|
||||
if err != nil {
|
||||
c.String(http.StatusOK, fmt.Sprint(err))
|
||||
}
|
||||
// Variable to store IP table information
|
||||
var IPTable p2p.IpAddresses
|
||||
|
||||
// Open received file
|
||||
file, err := ioutil.ReadAll(open)
|
||||
if err != nil {
|
||||
c.String(http.StatusOK, fmt.Sprint(err))
|
||||
}
|
||||
// Receive file from POST request
|
||||
body, err := c.FormFile("json")
|
||||
if err != nil {
|
||||
c.String(http.StatusOK, fmt.Sprint(err))
|
||||
}
|
||||
|
||||
json.Unmarshal(file,&IPTable)
|
||||
// Open file
|
||||
open, err := body.Open()
|
||||
if err != nil {
|
||||
c.String(http.StatusOK, fmt.Sprint(err))
|
||||
}
|
||||
|
||||
//Add Client IP address to IPTable struct
|
||||
IPTable.IpAddress = append(IPTable.IpAddress, ClientHost)
|
||||
// Open received file
|
||||
file, err := ioutil.ReadAll(open)
|
||||
if err != nil {
|
||||
c.String(http.StatusOK, fmt.Sprint(err))
|
||||
}
|
||||
|
||||
// Runs speed test to return only servers in the IP table pingable
|
||||
err = IPTable.SpeedTestUpdatedIPTable()
|
||||
if err != nil {
|
||||
c.String(http.StatusOK, fmt.Sprint(err))
|
||||
}
|
||||
json.Unmarshal(file, &IPTable)
|
||||
|
||||
// Reads IP addresses from ip table
|
||||
IpAddresses,err := p2p.ReadIpTable()
|
||||
if err != nil {
|
||||
c.String(http.StatusOK, fmt.Sprint(err))
|
||||
}
|
||||
//Add Client IP address to IPTable struct
|
||||
IPTable.IpAddress = append(IPTable.IpAddress, ClientHost)
|
||||
|
||||
c.JSON(http.StatusOK, IpAddresses)
|
||||
})
|
||||
// Runs speed test to return only servers in the IP table pingable
|
||||
err = IPTable.SpeedTestUpdatedIPTable()
|
||||
if err != nil {
|
||||
c.String(http.StatusOK, fmt.Sprint(err))
|
||||
}
|
||||
|
||||
// Reads IP addresses from ip table
|
||||
IpAddresses, err := p2p.ReadIpTable()
|
||||
if err != nil {
|
||||
c.String(http.StatusOK, fmt.Sprint(err))
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, IpAddresses)
|
||||
})
|
||||
|
||||
// Starts docker container in server
|
||||
r.GET("/startcontainer", func(c *gin.Context) {
|
||||
// Get Number of ports to open and whether to use GPU or not
|
||||
Ports := c.DefaultQuery("ports","0")
|
||||
GPU := c.DefaultQuery("GPU","false")
|
||||
ContainerName := c.DefaultQuery("ContainerName","")
|
||||
r.GET("/startcontainer", func(c *gin.Context) {
|
||||
// Get Number of ports to open and whether to use GPU or not
|
||||
Ports := c.DefaultQuery("ports", "0")
|
||||
GPU := c.DefaultQuery("GPU", "false")
|
||||
ContainerName := c.DefaultQuery("ContainerName", "")
|
||||
var PortsInt int
|
||||
|
||||
// Convert Get Request value to int
|
||||
fmt.Sscanf(Ports, "%d", &PortsInt)
|
||||
// Convert Get Request value to int
|
||||
fmt.Sscanf(Ports, "%d", &PortsInt)
|
||||
|
||||
// Creates container and returns-back result to
|
||||
// access container
|
||||
resp, err := docker.BuildRunContainer(PortsInt,GPU,ContainerName)
|
||||
// Creates container and returns-back result to
|
||||
// access container
|
||||
resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName)
|
||||
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||
}
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, resp)
|
||||
})
|
||||
// Ensures that FRP is triggered only if a proxy address is provided
|
||||
if ProxyIpAddr.Ipv4 != "" && c.Request.Host != "localhost:"+config.ServerPort && c.Request.Host != "0.0.0.0:"+config.ServerPort {
|
||||
resp, err = frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, lowestLatencyIpAddress.ServerPort, resp)
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||
}
|
||||
fmt.Println(resp)
|
||||
}
|
||||
|
||||
//Remove container
|
||||
r.GET("/RemoveContainer", func(c *gin.Context) {
|
||||
ID := c.DefaultQuery("id","0")
|
||||
if err := docker.StopAndRemoveContainer(ID); err != nil {
|
||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||
}
|
||||
c.String(http.StatusOK, "success")
|
||||
})
|
||||
c.JSON(http.StatusOK, resp)
|
||||
})
|
||||
|
||||
//Show images available
|
||||
r.GET("/ShowImages", func(c *gin.Context) {
|
||||
resp, err := docker.ViewAllContainers()
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||
}
|
||||
c.JSON(http.StatusOK, resp)
|
||||
})
|
||||
//Remove container
|
||||
r.GET("/RemoveContainer", func(c *gin.Context) {
|
||||
ID := c.DefaultQuery("id", "0")
|
||||
if err := docker.StopAndRemoveContainer(ID); err != nil {
|
||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||
}
|
||||
c.String(http.StatusOK, "success")
|
||||
})
|
||||
|
||||
//Get Server port based on the config file
|
||||
config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//Show images available
|
||||
r.GET("/ShowImages", func(c *gin.Context) {
|
||||
resp, err := docker.ViewAllContainers()
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||
}
|
||||
c.JSON(http.StatusOK, resp)
|
||||
})
|
||||
|
||||
// Run gin server on the specified port
|
||||
err = r.Run(":" + config.ServerPort)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Request for port no from Server with address
|
||||
r.GET("/FRPPort", func(c *gin.Context) {
|
||||
port, err := frp.StartFRPProxyFromRandom()
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||
}
|
||||
|
||||
return nil
|
||||
c.String(http.StatusOK, strconv.Itoa(port))
|
||||
})
|
||||
|
||||
// If there is a proxy port specified
|
||||
// then starts the FRP server
|
||||
//if config.FRPServerPort != "0" {
|
||||
// go frp.StartFRPProxyFromRandom()
|
||||
//}
|
||||
|
||||
// TODO check if IPV6 or Proxy port is specified
|
||||
// if not update current entry as proxy address
|
||||
// with appropriate port on IP Table
|
||||
if config.BehindNAT == "True" {
|
||||
table, err := p2p.ReadIpTable()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var lowestLatency int64
|
||||
// random large number
|
||||
lowestLatency = 10000000
|
||||
|
||||
for i, _ := range table.IpAddress {
|
||||
// Checks if the ping is the lowest and if the following node is acting as a proxy
|
||||
//if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" {
|
||||
if table.IpAddress[i].Latency.Milliseconds() < lowestLatency {
|
||||
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
|
||||
lowestLatencyIpAddress = table.IpAddress[i]
|
||||
}
|
||||
}
|
||||
|
||||
// If there is an identified node
|
||||
if lowestLatency != 10000000 {
|
||||
serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Create 3 second delay to allow FRP server to start
|
||||
time.Sleep(1 * time.Second)
|
||||
// Starts FRP as a client with
|
||||
proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, serverPort, config.ServerPort, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// updating with the current proxy address
|
||||
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
|
||||
ProxyIpAddr.ServerPort = proxyPort
|
||||
ProxyIpAddr.Name = config.MachineName
|
||||
ProxyIpAddr.NAT = "False"
|
||||
ProxyIpAddr.EscapeImplementation = "FRP"
|
||||
|
||||
// append the following to the ip table
|
||||
table.IpAddress = append(table.IpAddress, ProxyIpAddr)
|
||||
// write information back to the IP Table
|
||||
table.WriteIpTable()
|
||||
// update ip table
|
||||
go clientIPTable.UpdateIpTableListClient()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Run gin server on the specified port
|
||||
go r.Run(":" + config.ServerPort)
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
32
style.css
Normal file
@@ -0,0 +1,32 @@
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
span#discordJoin {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* Dark mode */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
/* General Page Changing */
|
||||
body {
|
||||
background: #121212; /* Background Color */
|
||||
color: #FFFFFF; /* Text Color */
|
||||
}
|
||||
|
||||
a:link{ /* Unvisited Link */
|
||||
color: #03DAC5;
|
||||
}
|
||||
|
||||
a:visited { /* Visited Link */
|
||||
color: #BB86FC;
|
||||
}
|
||||
|
||||
a:hover { /* Mouse over Link */
|
||||
color: #018786;
|
||||
}
|
||||
|
||||
span#discordJoin { /* Text Color Change */
|
||||
color: #cc0227;
|
||||
}
|
||||
}
|
||||