Merge branch 'master' of github.com:Akilan1999/p2p-rendering-computation into package-manager

This commit is contained in:
2021-10-09 18:03:12 +04:00
3 changed files with 143 additions and 17 deletions

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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()