Merge branch 'master' of github.com:Akilan1999/p2p-rendering-computation into package-manager
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
2. [Site.yml](#site-File-Template)
|
||||
3. [Host](#hosts-file)
|
||||
4. [Description](#description-file)
|
||||
5. [Automatic port allocations](#automatic-port-allocations)
|
||||
6. [Sample plugins implemented](#sample-plugins-implemented)
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -85,3 +87,49 @@ Ex: When the flag ```--ViewPlugins``` or ```--vp``` is called
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Automatic port allocations
|
||||
P2PRC would be in-charge to set to the ports to various TCP ports
|
||||
opened. Due to this implementation the plugin being executed is
|
||||
copied to the tmp directory with a unique UUID.
|
||||
```
|
||||
Command: ls /tmp
|
||||
output: Semantic <UUID>_<Plugin Name>
|
||||
2e6d76c4-0ed1-4b55-9385-79a58d4f0492_p2prc-vscode-browser
|
||||
7b631e08-62ee-4c1c-a2a4-c05857b9aa7d_p2prc-vscode-browser
|
||||
```
|
||||
Once the copy of the plugin is added to the /tmp directory
|
||||
the site.yml file inside the appropriate yaml is modified
|
||||
with the appropriate ports assigned to the container.
|
||||
|
||||
### Ex:
|
||||
1. Create container called c1 with an automatic generated TCP port
|
||||
3313 (external) - 3313 (internal)
|
||||
2. Assumption of plugin p1 exists. p1 has one server which needs to
|
||||
be mapped to a free open TCP port in container c1. Below shows
|
||||
an implementation of a sample site.yml file.
|
||||
```
|
||||
---
|
||||
- hosts: all
|
||||
tasks:
|
||||
- name: start vscode code server
|
||||
shell: sh server.sh 0.0.0.0:{{index . 0}}
|
||||
```
|
||||
Notice there is the following {{index . 0}}. {{index . 0}} does not belong to
|
||||
Ansible but rather is a way to mention where to add the external free port
|
||||
of the container. We use the golang [template library](https://pkg.go.dev/text/template)
|
||||
to parse and populate the site.yml with the appropriate open ports. An array of ints
|
||||
which consists of open free ports are sent to the site.yml. 0 in {{index . 0}} refers
|
||||
to the index in the int array passed on.
|
||||
|
||||
After the port is automatically it's ready to run !
|
||||
```
|
||||
---
|
||||
- hosts: all
|
||||
tasks:
|
||||
- name: start vscode code server
|
||||
shell: sh server.sh 0.0.0.0:3313
|
||||
```
|
||||
|
||||
### Sample plugins implemented:
|
||||
- [VSCode Plugin](https://github.com/Akilan1999/p2prc-vscode-browser)
|
||||
|
||||
107
plugin/plugin.go
107
plugin/plugin.go
@@ -6,14 +6,18 @@ import (
|
||||
"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"
|
||||
|
||||
"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
|
||||
@@ -25,11 +29,13 @@ type Plugins struct {
|
||||
type Plugin struct {
|
||||
FolderName string
|
||||
PluginDescription string
|
||||
path string
|
||||
Execute []*ExecuteIP
|
||||
}
|
||||
|
||||
// ExecuteIP IP Address to execute Ansible instruction
|
||||
type ExecuteIP struct {
|
||||
ContainerID string
|
||||
IPAddress string
|
||||
SSHPortNo string
|
||||
Success bool
|
||||
@@ -124,6 +130,12 @@ func RunPlugin(pluginName string ,IPAddresses []*ExecuteIP) (*Plugin,error) {
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -132,6 +144,14 @@ func RunPlugin(pluginName string ,IPAddresses []*ExecuteIP) (*Plugin,error) {
|
||||
return nil, errors.New("Plugin not detected")
|
||||
}
|
||||
|
||||
|
||||
// Create copy of the plugin the tmp directory
|
||||
// To ensure we execute the plugin from there
|
||||
err = plugindetected.CopyToTmpPlugin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Executing the plugin
|
||||
err = plugindetected.ExecutePlugin()
|
||||
if err != nil {
|
||||
@@ -143,21 +163,20 @@ func RunPlugin(pluginName string ,IPAddresses []*ExecuteIP) (*Plugin,error) {
|
||||
|
||||
// ExecutePlugin Function to execute plugins that are called
|
||||
func (p *Plugin) ExecutePlugin() error {
|
||||
// Get Execute plugin path from config file
|
||||
config, err:= config.ConfigInit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Run ip address to execute ansible inside
|
||||
for _,execute := range p.Execute {
|
||||
// Modify ansible hosts before executing
|
||||
err = execute.ModifyHost(p,config.PluginPath)
|
||||
err := execute.ModifyHost(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = execute.RunAnsible(p,config.PluginPath)
|
||||
// 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
|
||||
}
|
||||
@@ -168,13 +187,13 @@ func (p *Plugin) ExecutePlugin() error {
|
||||
}
|
||||
|
||||
// RunAnsible Executes based on credentials on the struct
|
||||
func (e *ExecuteIP)RunAnsible(p *Plugin,path string) error {
|
||||
func (e *ExecuteIP)RunAnsible(p *Plugin) error {
|
||||
ansiblePlaybookConnectionOptions := &options.AnsibleConnectionOptions{
|
||||
User: "master",
|
||||
}
|
||||
|
||||
ansiblePlaybookOptions := &playbook.AnsiblePlaybookOptions{
|
||||
Inventory: path + "/" + p.FolderName + "/hosts",
|
||||
Inventory: p.path + "/" + p.FolderName + "/hosts",
|
||||
ExtraVars: map[string]interface{}{"host_key_checking":"false"},
|
||||
}
|
||||
|
||||
@@ -183,7 +202,7 @@ func (e *ExecuteIP)RunAnsible(p *Plugin,path string) error {
|
||||
}
|
||||
|
||||
playbook := &playbook.AnsiblePlaybookCmd{
|
||||
Playbooks: []string{path + "/" + p.FolderName + "/site.yml"},
|
||||
Playbooks: []string{p.path + "/" + p.FolderName + "/site.yml"},
|
||||
ConnectionOptions: ansiblePlaybookConnectionOptions,
|
||||
PrivilegeEscalationOptions: ansiblePlaybookPrivilegeEscalationOptions,
|
||||
Options: ansiblePlaybookOptions,
|
||||
@@ -203,8 +222,8 @@ func (e *ExecuteIP)RunAnsible(p *Plugin,path string) error {
|
||||
}
|
||||
|
||||
// ModifyHost adds IP address , port no to the config file
|
||||
func (e *ExecuteIP)ModifyHost(p *Plugin, path string) error {
|
||||
host,err := ReadHost(path + "/" + p.FolderName + "/hosts")
|
||||
func (e *ExecuteIP)ModifyHost(p *Plugin) error {
|
||||
host,err := ReadHost(p.path + "/" + p.FolderName + "/hosts")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -227,7 +246,7 @@ func (e *ExecuteIP)ModifyHost(p *Plugin, path string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(path + "/" + p.FolderName + "/hosts",data,0777)
|
||||
err = ioutil.WriteFile(p.path + "/" + p.FolderName + "/hosts",data,0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -250,7 +269,7 @@ func ReadHost(filename string) (*Host, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// RunPluginContainer Runs ansible plugin based on plugin name and contianer name which
|
||||
// RunPluginContainer Runs ansible plugin based on plugin name and container name which
|
||||
// is derived from the tracked containers file
|
||||
func RunPluginContainer(PluginName string, ContainerID string) error {
|
||||
// Gets container information based on container ID
|
||||
@@ -275,6 +294,8 @@ func RunPluginContainer(PluginName string, ContainerID string) error {
|
||||
}
|
||||
// IP address of the container
|
||||
ExecuteIP.IPAddress = ContainerInformation.IpAddress
|
||||
// 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
|
||||
@@ -319,3 +340,59 @@ func CheckRunPlugin(PluginName string, ID string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CopyToTmpPlugin This function would ensure that we create a copy of the
|
||||
// plugin in the tmp directory, and it would be executed
|
||||
// from there. This due to the reason of automating port allocation
|
||||
// when running plugins
|
||||
func (p *Plugin)CopyToTmpPlugin() error {
|
||||
// generate rand to UUID this is debug the ansible file if needed
|
||||
id := uuid.New()
|
||||
// copies the plugin to the tmp directory
|
||||
err := copy.Copy(p.path+"/"+p.FolderName, "/tmp/"+ id.String() + "_" + p.FolderName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the plugin execution to the tmp location
|
||||
p.path = "/tmp"
|
||||
p.FolderName = id.String() + "_" + p.FolderName
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AutoSetPorts Automatically maps free ports to site.yml file
|
||||
func (p *Plugin)AutoSetPorts(containerID string) error {
|
||||
container , err := client.GetContainerInformation(containerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// variable that would have a list of ports
|
||||
// to be allocated to the plugin system
|
||||
var ports []int
|
||||
// setting all external ports available in an array
|
||||
for _, port := range container.Container.Ports.PortSet {
|
||||
if port.InternalPort == port.ExternalPort {
|
||||
ports = append(ports, port.ExternalPort)
|
||||
}
|
||||
}
|
||||
// parses the site.yml file in the tmp directory
|
||||
t, err := template.ParseFiles(p.path + "/" + p.FolderName + "/site.yml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// opens the output file
|
||||
f, err := os.Create(p.path + "/" + p.FolderName + "/site.yml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// sends the ports to the site.yml file to populate them
|
||||
err = t.Execute(f,ports)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -80,12 +80,13 @@ func TestExecuteIP_ModifyHost(t *testing.T) {
|
||||
}
|
||||
//Set plugin name
|
||||
plugin.FolderName = "TestAnsible"
|
||||
plugin.path = Config.PluginPath
|
||||
|
||||
//Test IP 1 configuration
|
||||
testip.IPAddress = "0.0.0.0"
|
||||
testip.SSHPortNo = "41289"
|
||||
|
||||
err = testip.ModifyHost(&plugin,Config.PluginPath)
|
||||
err = testip.ModifyHost(&plugin)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
|
||||
Reference in New Issue
Block a user