diff --git a/Docs/PluginImplementation.md b/Docs/PluginImplementation.md index d3c81dd..5975611 100644 --- a/Docs/PluginImplementation.md +++ b/Docs/PluginImplementation.md @@ -26,6 +26,7 @@ plugin |___ |___ site.yml |___ hosts + |___ ports.json |___ description.txt . . @@ -70,6 +71,16 @@ main: ansible_sudo_pass: password ``` +## Ports.json +The ```ports.json``` file is intended to mention the number of ports required +by the plugin. + +``` +{ + "NumOfPorts": +} +``` + ## Description file This is a simple text file used to describe what the module does. When the client is looking at various commands via the ClI. diff --git a/Docs/ServerImplementation.md b/Docs/ServerImplementation.md index 8e63354..045ec10 100644 --- a/Docs/ServerImplementation.md +++ b/Docs/ServerImplementation.md @@ -178,6 +178,8 @@ Format of the ports.json file "PortName": "", "InternalPort": , "Type": "", + "ExternalPort": , + "IsUsed": "", "Description": "" }, ... n ] diff --git a/client/GroupTrackContainer.go b/client/GroupTrackContainer.go index 9cbfb71..908b287 100644 --- a/client/GroupTrackContainer.go +++ b/client/GroupTrackContainer.go @@ -278,5 +278,34 @@ func (grp *Groups)RemoveContainerGroups(Container *TrackContainer) error { // Set group information to list groups grp.GroupList[i] = group } + return nil +} + +// ModifyContainerGroups Modifies container information is all groups +// available +func (TC *TrackContainer)ModifyContainerGroups() error { + group, err := ReadGroup() + if err != nil { + return err + } + // Iterate though all groups and modify the container + // information in groups where the modified container + // ID matches + for i, _ := range group.GroupList { + // Checking in each group if the modified container ID exists + for j, _:= range group.GroupList[i].TrackContainerList { + // If there is match then change them + if group.GroupList[i].TrackContainerList[j].Id == TC.Id { + group.GroupList[i].TrackContainerList[j] = TC + } + } + } + + // Write modified result to the Groups track container JSON file + err = group.WriteGroup() + if err != nil { + return err + } + return nil } \ No newline at end of file diff --git a/client/TrackContainers.go b/client/TrackContainers.go index b61d7f2..ca83594 100644 --- a/client/TrackContainers.go +++ b/client/TrackContainers.go @@ -146,6 +146,8 @@ func ReadTrackContainers(filename string) (*TrackContainers, error) { return c, nil } +//func ModifyTrackContainers() + // GetContainerInformation gets information about container based on // container ID provided func GetContainerInformation(ID string) (*TrackContainer, error) { @@ -164,6 +166,48 @@ func GetContainerInformation(ID string) (*TrackContainer, error) { return nil, errors.New("Container not found. ") } +// ModifyContainerInformation Modifies information inside the container +func (TC *TrackContainer)ModifyContainerInformation() error { + // Gets all the information of tracker containers + err, t := ViewTrackedContainers() + if err != nil { + return err + } + // Find the element where the containers match and + // change them + for i, container := range t.TrackContainerList { + if TC.Id == container.Id { + t.TrackContainerList[i] = *TC + break + } + } + // Write the modified information to the file + // write modified information to the tracked json file + err = t.WriteContainers() + if err != nil { + return err + } + + return nil +} + +// WriteContainers Write information back to the config file +func (TC *TrackContainers)WriteContainers() error { + // Initialize config file + config,err := config.ConfigInit() + // write modified information to the tracked json file + data,err := json.MarshalIndent(TC, "", "\t") + if err != nil { + return err + } + err = ioutil.WriteFile(config.TrackContainersPath,data,0777) + if err != nil { + return err + } + + return nil +} + // CheckID Checks if the ID belongs to a group or a single container func CheckID(ID string) (string,error) { // For group checks if the 1st characters is "grp" diff --git a/plugin/plugin.go b/plugin/plugin.go index 2377c49..cdef950 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -2,6 +2,7 @@ package plugin import ( "context" + "encoding/json" "errors" "fmt" "git.sr.ht/~akilan1999/p2p-rendering-computation/client" @@ -31,6 +32,7 @@ type Plugin struct { PluginDescription string path string Execute []*ExecuteIP + NumOfPorts int } // ExecuteIP IP Address to execute Ansible instruction @@ -91,8 +93,15 @@ func DetectPlugins()(*Plugins,error){ // 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 + } } } @@ -271,6 +280,7 @@ func ReadHost(filename string) (*Host, error) { // RunPluginContainer Runs ansible plugin based on plugin name and container name which // is derived from the tracked containers file +// We pass in the group ID as a parameter because when we modify the ports taken func RunPluginContainer(PluginName string, ContainerID string) error { // Gets container information based on container ID ContainerInformation, err := client.GetContainerInformation(ContainerID) @@ -370,12 +380,24 @@ func (p *Plugin)AutoSetPorts(containerID string) error { // 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 _, port := range container.Container.Ports.PortSet { - if port.InternalPort == port.ExternalPort { + 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) } } + // parses the site.yml file in the tmp directory t, err := template.ParseFiles(p.path + "/" + p.FolderName + "/site.yml") if err != nil { @@ -391,8 +413,40 @@ func (p *Plugin)AutoSetPorts(containerID string) error { if err != nil { return err } + // Once the following is done set port to taken + // n tracked container list + err = container.ModifyContainerInformation() + if err != nil { + return err + } + // Once the following is done set port to taken + // I(Groups) + err = container.ModifyContainerGroups() + if err != nil { + return err + } + + return nil +} + +// NumPorts Gets the Number the ports the +// plugin requires +func (p *Plugin)NumPorts() error { + jsonFile, err := os.Open(p.path + "/ports.json") + // if we os.Open returns an error then handle it + if err != nil { + return err + } + + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() + + // read our opened xmlFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) + + // we unmarshal our byteArray which contains our + // jsonFile's content into 'users' which we defined above + json.Unmarshal(byteValue, &p) return nil - - } diff --git a/server/docker/docker.go b/server/docker/docker.go index 7a20ebc..e101e15 100644 --- a/server/docker/docker.go +++ b/server/docker/docker.go @@ -48,6 +48,7 @@ type Port struct { InternalPort int `json:"InternalPort"` Type string `json:"Type"` ExternalPort int `json:"ExternalPort"` + IsUsed bool `json:"IsUsed"` Description string `json:"Description"` } @@ -124,7 +125,9 @@ func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerV } // 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) @@ -136,6 +139,7 @@ func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerV 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) }