diff --git a/client/GroupTrackContainer.go b/client/GroupTrackContainer.go index 3fb7eae..99f8710 100644 --- a/client/GroupTrackContainer.go +++ b/client/GroupTrackContainer.go @@ -1,310 +1,310 @@ package client import ( - "encoding/json" - "errors" - "github.com/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 - } + // 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 - } - // Remove Group struct from the groups variable - groups.GroupList = append(groups.GroupList[:group.index], groups.GroupList[group.index+1:]...) + // Read group information from the + //grouptrackcontainer json file + groups, err := ReadGroup() + if err != nil { + return err + } + // Gets Group struct based on group ID + // provided + group, err := GetGroup(GroupID) + if err != nil { + return err + } + // Remove Group struct from the groups variable + groups.GroupList = append(groups.GroupList[:group.index], groups.GroupList[group.index+1:]...) - // Write new groups to the grouptrackcontainer json file - err = groups.WriteGroup() - if err != nil { - return err - } + // 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 - } - // 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 - } + // Get Groups information from reading the grouptrackcontainer.json file + groups, err := ReadGroup() + if err != nil { + return nil, err + } + // Updating specific element in the group list with the added container + groups.GroupList[group.index] = group + // Write groups information on the grouptrackcontainer.json file + err = groups.WriteGroup() + if err != nil { + return nil, err + } - return group, nil + 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 - } + // 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 - } - } + // 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 - 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 - } + // Gets all group information from the + // GroupTrackContainer JSON file + groups, err := ReadGroup() + if err != nil { + return err + } + // Appending the newly created group + groups.GroupList = append(groups.GroupList, grp) + // Writing Group information to the GroupTrackContainer + // JSON file + err = groups.WriteGroup() + if err != nil { + return err + } - return nil + return nil } // ReadGroup Function reads grouptrackcontainers.json and converts // result to Groups func ReadGroup() (*Groups, error) { - // Get Path from config - config, err := config.ConfigInit(nil) - 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 + // Get Path from config + config, err := config.ConfigInit(nil, nil) + if err != nil { + return nil, err + } + jsonFile, err := os.Open(config.GroupTrackContainersPath) + // if we os.Open returns an error then handle it + if err != nil { + return nil, err + } + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() + // read our opened xmlFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) + // we initialize our Users array + var groups Groups + // we unmarshal our byteArray which contains our + // jsonFile's content into 'users' which we defined above + json.Unmarshal(byteValue, &groups) + return &groups, nil } // WriteGroup Function to write type Groups to the grouptrackcontainers.json file func (grp *Groups) WriteGroup() error { - file, err := json.MarshalIndent(grp, "", " ") - if err != nil { - return err - } - // Get Path from config - config, err := config.ConfigInit(nil) - if err != nil { - return err - } - // Writes to the appropriate file - err = ioutil.WriteFile(config.GroupTrackContainersPath, file, 0644) - if err != nil { - return err - } - return nil + file, err := json.MarshalIndent(grp, "", " ") + if err != nil { + return err + } + // Get Path from config + config, err := config.ConfigInit(nil, nil) + if err != nil { + return err + } + // Writes to the appropriate file + err = ioutil.WriteFile(config.GroupTrackContainersPath, file, 0644) + if err != nil { + return err + } + return nil } // AddContainer Adds a container to the Tracked container list of the group func (grp *Group) AddContainer(Container *TrackContainer) error { - grp.TrackContainerList = append(grp.TrackContainerList, Container) - return nil + 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 + // 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 + // 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 - } - } - } + 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 } diff --git a/client/TrackContainers.go b/client/TrackContainers.go index f313595..7310951 100644 --- a/client/TrackContainers.go +++ b/client/TrackContainers.go @@ -1,149 +1,149 @@ package client import ( - "encoding/json" - "errors" - "fmt" - "github.com/Akilan1999/p2p-rendering-computation/config" - "github.com/Akilan1999/p2p-rendering-computation/server/docker" - "io/ioutil" - "os" + "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(nil) - if err != nil { - return err - } + // 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 - } + // Getting information about the file trackcontainers.json file + stat, err := os.Stat(config.TrackContainersPath) + if err != nil { + return err + } + // Initialize variable for TrackContainers + var trackContainers TrackContainers + // If the trackcontainers.json file is not empty then + // Read from that file + if stat.Size() != 0 { + // Reads tracked container file + trackContainersFile, err := ReadTrackContainers(config.TrackContainersPath) + if err != nil { + return err + } + trackContainers = *trackContainersFile + } - // Initialize new variable with type struct TrackContainers and - // add container struct and ip address - var trackContainer TrackContainer - trackContainer.Id = d.ID - trackContainer.Container = d - trackContainer.IpAddress = ipAddress + // 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(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:]...) + //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(nil) - if err != nil { - return err, nil - } - trackedContianers, err := ReadTrackContainers(config.TrackContainersPath) - if err != nil { - return err, nil - } + 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 - } + // 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(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 - } + // 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) { - // For group checks if the 1st characters is "grp" - if ID[0:3] == "grp" { - return "group", nil - } else { - return "container", nil - } - return "", nil + // For group checks if the 1st characters is "grp" + if ID[0:3] == "grp" { + return "group", nil + } else { + return "container", nil + } + return "", nil } diff --git a/client/clientIPTable/Iptable.go b/client/clientIPTable/Iptable.go index beb0d04..db885dc 100644 --- a/client/clientIPTable/Iptable.go +++ b/client/clientIPTable/Iptable.go @@ -1,16 +1,16 @@ 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" + "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 @@ -18,136 +18,136 @@ 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) - if err != nil { - return err - } + config, err := config.ConfigInit(nil, nil) + if err != nil { + return err + } - client := http.Client{} + client := http.Client{} - var resp []byte + 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 - } - } + 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 - } + if resp == nil { + return nil + } - //resp, err := SendPostRequest("http://"+IpAddress+":8088/IpTable", - // config.IPTable, - // "json") - // - //if err != nil { - // return err - //} + //resp, err := SendPostRequest("http://"+IpAddress+":8088/IpTable", + // config.IPTable, + // "json") + // + //if err != nil { + // return err + //} - var ipStruct p2p.IpAddresses - json.Unmarshal(resp, &ipStruct) + 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 - } - } + // 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 - } + err = ipStruct.WriteIpTable() + if err != nil { + return err + } - wg.Done() + wg.Done() - return nil + 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) - if err != nil { - return err - } + // 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 - } + // 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 + // IP addresses to not append to struct due to + // duplication - Addresses, err := p2p.ReadIpTable() - var DoNotRead p2p.IpAddresses + Addresses, err := p2p.ReadIpTable() + var DoNotRead p2p.IpAddresses - currentIPV4, err := p2p.CurrentPublicIP() - if err != nil { - return err - } + currentIPV4, err := p2p.CurrentPublicIP() + if err != nil { + return err + } - var w sync.WaitGroup + 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 - } + // 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) + //DoNotRead.IpAddress = append(DoNotRead.IpAddress, PublicIP) - // Updates IP table based on server IP table - for j := range Addresses.IpAddress { + // 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 - } + 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 - } - } + // 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 - } + // 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() + 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]) - } - } + //Appends server1 IP address to variable DoNotRead + DoNotRead.IpAddress = append(DoNotRead.IpAddress, Addresses.IpAddress[j]) + } + } - return nil + return nil } // SendPostRequest Sends a file as a @@ -197,58 +197,58 @@ func UpdateIpTableListClient() error { //} func UploadMultipartFile(client http.Client, uri, key, path string) ([]byte, error) { - body, writer := io.Pipe() + body, writer := io.Pipe() - req, err := http.NewRequest(http.MethodPost, uri, body) - if err != nil { - return nil, err - } + 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()) + mwriter := multipart.NewWriter(writer) + req.Header.Add("Content-Type", mwriter.FormDataContentType()) - errchan := make(chan error) + errchan := make(chan error) - go func() { - defer close(errchan) - defer writer.Close() - defer mwriter.Close() + go func() { + defer close(errchan) + defer writer.Close() + defer mwriter.Close() - w, err := mwriter.CreateFormFile(key, path) - if err != nil { - errchan <- err - return - } + 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() + 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 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 - } - }() + if err := mwriter.Close(); err != nil { + errchan <- err + return + } + }() - resp, err := client.Do(req) - if err != nil { - return nil, err - } + resp, err := client.Do(req) + if err != nil { + return nil, err + } - content, err := ioutil.ReadAll(resp.Body) + content, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } + if err != nil { + return nil, err + } - return content, nil + return content, nil } diff --git a/cmd/action.go b/cmd/action.go index 9f012f7..559258b 100644 --- a/cmd/action.go +++ b/cmd/action.go @@ -135,7 +135,7 @@ var CliAction = func(ctx *cli.Context) error { //Sets default paths to the config file if SetDefaultConfig { - _, err := generate.SetDefaults("P2PRC", false) + _, err := generate.SetDefaults("P2PRC", false, nil, true) if err != nil { fmt.Print(err) } diff --git a/config/config.go b/config/config.go index 6b32233..91a3fa4 100644 --- a/config/config.go +++ b/config/config.go @@ -1,7 +1,8 @@ package config import ( - "github.com/spf13/viper" + "encoding/json" + "io/ioutil" "os" ) @@ -28,6 +29,7 @@ type Config struct { GroupTrackContainersPath string FRPServerPort string BehindNAT string + CustomConfig interface{} //NetworkInterface string //NetworkInterfaceIPV6Index int } @@ -41,6 +43,9 @@ func GetPathP2PRC(Envname string) (string, error) { } } curDir := os.Getenv(defaultEnvName) + if curDir == "" { + return curDir, nil + } return curDir + "/", nil } @@ -59,45 +64,93 @@ func GetEnvName() string { } // ConfigInit Pass environment name as an optional parameter -func ConfigInit(defaultsParameter map[string]interface{}, envNameOptional ...string) (*Config, error) { +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 - //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) + // 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 } - //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) + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() - if err = viper.WriteConfig(); err != nil { + byteValue, _ := ioutil.ReadAll(jsonFile) + + var config Config + json.Unmarshal(byteValue, &config) + + if CustomConfig != nil { + // Convert Custom Config to byte + customConfigByte, err := json.Marshal(config.CustomConfig) + if err != nil { return nil, err } - } - // Adds configuration to the struct - var config Config - if err := viper.Unmarshal(&config); err != nil { - return nil, err + // Again map the byte to the CustomConfig interface + json.Unmarshal(customConfigByte, &CustomConfig) } return &config, nil } + +func (c *Config) WriteConfig() error { + //Getting Current Directory from environment variable + //curDir := os.Getenv("REMOTEGAMING") + + defaultPath, err := GetPathP2PRC(defaultEnvName) + if err != nil { + return err + } + + file, _ := json.MarshalIndent(c, "", " ") + + _ = ioutil.WriteFile(defaultPath+"config.json", file, 0644) + return nil +} diff --git a/config/generate/generate.go b/config/generate/generate.go index 07278c0..6c95792 100644 --- a/config/generate/generate.go +++ b/config/generate/generate.go @@ -37,7 +37,7 @@ func GetCurrentPath() (string, error) { // SetDefaults This function to be called only during a // make install -func SetDefaults(envName string, forceDefault bool, ConfigUpdate ...*config.Config) (*config.Config, error) { +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 { @@ -68,38 +68,31 @@ func SetDefaults(envName string, forceDefault bool, ConfigUpdate ...*config.Conf // 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"] = "0" - defaults["BehindNAT"] = "True" + 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 + Defaults.MachineName = hostname } else { - defaults["IPTable"] = ConfigUpdate[0].IPTable - defaults["DefaultDockerFile"] = ConfigUpdate[0].DefaultDockerFile - defaults["DockerContainers"] = ConfigUpdate[0].DockerContainers - defaults["SpeedTestFile"] = ConfigUpdate[0].SpeedTestFile - defaults["IPV6Address"] = ConfigUpdate[0].IPV6Address - defaults["PluginPath"] = ConfigUpdate[0].PluginPath - defaults["TrackContainersPath"] = ConfigUpdate[0].TrackContainersPath - defaults["GroupTrackContainersPath"] = ConfigUpdate[0].GroupTrackContainersPath - defaults["ServerPort"] = ConfigUpdate[0].ServerPort - defaults["FRPServerPort"] = ConfigUpdate[0].FRPServerPort - defaults["BehindNAT"] = ConfigUpdate[0].BehindNAT + Defaults = *ConfigUpdate[0] } //defaults["NetworkInterface"] = "wlp0s20f3" @@ -108,22 +101,31 @@ func SetDefaults(envName string, forceDefault bool, ConfigUpdate ...*config.Conf //Paths to search for config file configPaths = append(configPaths, defaultPath) - if fileExists(defaultPath + "config.json") && forceDefault { + if fileExists(defaultPath+"config.json") && forceDefault { err := os.Remove(defaultPath + "config.json") if err != nil { return nil, err } } - //Calling configuration file - Config, err := config.ConfigInit(defaults, envName) + // write defaults to the config file + err = Defaults.WriteConfig() if err != nil { return nil, err } - err = GenerateFiles() + //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 } diff --git a/config/generate/gernerate_test.go b/config/generate/gernerate_test.go new file mode 100644 index 0000000..6437795 --- /dev/null +++ b/config/generate/gernerate_test.go @@ -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) + +} diff --git a/p2p/iptable.go b/p2p/iptable.go index 1facb68..d203c12 100644 --- a/p2p/iptable.go +++ b/p2p/iptable.go @@ -1,256 +1,257 @@ package p2p import ( - "encoding/json" - "fmt" - "github.com/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 { - 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"` + 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) { - // Get Path from config - config, err := config.ConfigInit(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 - } + // Get Path from config + 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 + PublicIP.Name = config.MachineName + PublicIP.NAT = config.BehindNAT + PublicIP.EscapeImplementation = "None" - // 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 + 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(nil) - 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("\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) + 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 { - var NoDuplicates IpAddresses - for i, _ := range table.IpAddress { - Exists := false - for k := range NoDuplicates.IpAddress { - // Statements checked for - // - duplicate IPV4 addresses [:] - // - duplicate IPV6 addresses [] - // - 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 - } - } + var NoDuplicates IpAddresses + for i, _ := range table.IpAddress { + Exists := false + for k := range NoDuplicates.IpAddress { + // Statements checked for + // - duplicate IPV4 addresses [:] + // - duplicate IPV6 addresses [] + // - 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 + } + } - if table.IpAddress[i].NAT == "True" && table.IpAddress[i].EscapeImplementation == "None" { - Exists = true - } + if table.IpAddress[i].NAT == "True" && table.IpAddress[i].EscapeImplementation == "None" { + Exists = true + } - if Exists { - continue - } - NoDuplicates.IpAddress = append(NoDuplicates.IpAddress, table.IpAddress[i]) - } + if Exists { + continue + } + NoDuplicates.IpAddress = append(NoDuplicates.IpAddress, table.IpAddress[i]) + } - table.IpAddress = NoDuplicates.IpAddress + table.IpAddress = NoDuplicates.IpAddress - return nil + 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() + 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(nil) - if err != nil { - return "", err - } + 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) 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" } diff --git a/p2p/testingMetrics.go b/p2p/testingMetrics.go index 95e3772..7ab6d7e 100644 --- a/p2p/testingMetrics.go +++ b/p2p/testingMetrics.go @@ -1,16 +1,16 @@ package p2p import ( - "bytes" - "errors" - "github.com/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} @@ -80,100 +80,100 @@ 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 - return nil + 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() + start := time.Now() - // Get upload file path from config file - // Get Path from config - config, err := config.ConfigInit(nil) - 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 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 || resp.StatusCode != 200 { - return errors.New("Node not found") - } - 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 } diff --git a/plugin/packageManager.go b/plugin/packageManager.go index c651d66..2896acc 100644 --- a/plugin/packageManager.go +++ b/plugin/packageManager.go @@ -1,64 +1,64 @@ package plugin import ( - "github.com/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(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 - } + // 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(nil) - 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 - } + // Delete the directory holding the plugin + err = os.RemoveAll(config.PluginPath + "/" + plugin.FolderName) + if err != nil { + return err + } - return nil + return nil } diff --git a/plugin/plugin.go b/plugin/plugin.go index 2dd72f2..31e0762 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -1,362 +1,362 @@ package plugin import ( - "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" + "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(nil) - if err != nil { - return nil, err - } - folders, err := ioutil.ReadDir(config.PluginPath) - if err != nil { - return nil, err - } + 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 - } + 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 - } + 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(nil) - 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") - } + 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 - } + // 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 { - return nil, err - } + // Executing the plugin + err = plugindetected.ExecutePlugin() + if err != nil { + return nil, err + } - return plugindetected, nil + 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", - } + ansiblePlaybookConnectionOptions := &options.AnsibleConnectionOptions{ + User: "master", + } - ansiblePlaybookOptions := &playbook.AnsiblePlaybookOptions{ - Inventory: p.path + "/" + p.FolderName + "/hosts", - ExtraVars: map[string]interface{}{"ansible_ssh_common_args": "-o StrictHostKeyChecking=no"}, - } + 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") - if err != nil { - 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, err := ReadHost(p.path + "/" + p.FolderName + "/hosts") + if err != nil { + 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" - // 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") - } - // Split the port no from ip address since current the IP address - // field is populated as - // : + // 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 + // : - 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 - } + 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 + } - 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 @@ -364,101 +364,101 @@ func CheckRunPlugin(PluginName string, ID string) error { // 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 - } + // 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 + 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++ - // 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) - } - } + 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 - } - // 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 - } + // 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 + } + // 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 - } + 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 } diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go index c83f4f4..ccedb57 100644 --- a/plugin/plugin_test.go +++ b/plugin/plugin_test.go @@ -1,257 +1,257 @@ package plugin import ( - "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" + "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(nil) - 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) - } + 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) + } } diff --git a/server/docker/docker.go b/server/docker/docker.go index c51cb76..987edea 100644 --- a/server/docker/docker.go +++ b/server/docker/docker.go @@ -1,64 +1,64 @@ package docker import ( - "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" + "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 = "" @@ -66,137 +66,137 @@ 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) + //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(nil) - 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() + 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 @@ -205,200 +205,200 @@ func (d *DockerVM) imageBuild(dockerClient *client.Client) error { // -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) + 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" - if d.GPU != "true" { - //Exposed ports for docker config file - var ExposedPort nat.PortSet + // 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 - 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 // 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(nil) - if err != nil { - return nil, err - } + // 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 - var Container DockerContainer + 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 - } + // 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 + } - // 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 } diff --git a/server/server.go b/server/server.go index 103bd8c..42bde5b 100644 --- a/server/server.go +++ b/server/server.go @@ -1,226 +1,226 @@ package server import ( - "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" + "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() (*gin.Engine, error) { - r := gin.Default() + r := gin.Default() - //Get Server port based on the config file - config, err := config.ConfigInit(nil) - if err != nil { - return nil, err - } + //Get Server port based on the config file + config, err := config.ConfigInit(nil, nil) + if err != nil { + return nil, err + } - // update IPTable with new port and ip address and update ip table - var ProxyIpAddr p2p.IpAddress - var lowestLatencyIpAddress p2p.IpAddress + // update IPTable with new port and ip address and update ip table + var ProxyIpAddr p2p.IpAddress + var lowestLatencyIpAddress p2p.IpAddress - // Gets default information of the server - r.GET("/server_info", func(c *gin.Context) { - c.JSON(http.StatusOK, ServerInfo()) - }) + // Gets default information of the server + r.GET("/server_info", func(c *gin.Context) { + c.JSON(http.StatusOK, ServerInfo()) + }) - // Speed test with 50 mbps - r.GET("/50", func(c *gin.Context) { - // Get Path from config - c.File(config.SpeedTestFile) - }) + // Speed test with 50 mbps + r.GET("/50", func(c *gin.Context) { + // Get Path from config + c.File(config.SpeedTestFile) + }) - // Route build to do a speed test - r.GET("/upload", func(c *gin.Context) { - file, _ := c.FormFile("file") + // Route build to do a speed test + r.GET("/upload", func(c *gin.Context) { + file, _ := c.FormFile("file") - // Upload the file to specific dst. - // c.SaveUploadedFile(file, dst) + // Upload the file to specific dst. + // c.SaveUploadedFile(file, dst) - c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename)) - }) + c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename)) + }) - //Gets Ip Table from server node - r.POST("/IpTable", func(c *gin.Context) { - // Getting IPV4 address of client - var ClientHost p2p.IpAddress + //Gets Ip Table from server node + r.POST("/IpTable", func(c *gin.Context) { + // Getting IPV4 address of client + var ClientHost p2p.IpAddress - if p2p.Ip4or6(c.ClientIP()) == "version 6" { - ClientHost.Ipv6 = c.ClientIP() - } else { - ClientHost.Ipv4 = c.ClientIP() - } + if p2p.Ip4or6(c.ClientIP()) == "version 6" { + ClientHost.Ipv6 = c.ClientIP() + } else { + ClientHost.Ipv4 = c.ClientIP() + } - // Variable to store IP table information - var IPTable p2p.IpAddresses + // Variable to store IP table information + var IPTable p2p.IpAddresses - // Receive file from POST request - body, err := c.FormFile("json") - 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)) + } - // Open file - open, err := body.Open() - if err != nil { - c.String(http.StatusOK, fmt.Sprint(err)) - } + // Open file + open, err := body.Open() + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } - // Open received file - file, err := ioutil.ReadAll(open) - if err != nil { - c.String(http.StatusOK, fmt.Sprint(err)) - } + // Open received file + file, err := ioutil.ReadAll(open) + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } - json.Unmarshal(file, &IPTable) + json.Unmarshal(file, &IPTable) - //Add Client IP address to IPTable struct - IPTable.IpAddress = append(IPTable.IpAddress, ClientHost) + //Add Client IP address to IPTable struct + IPTable.IpAddress = append(IPTable.IpAddress, ClientHost) - // 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)) - } + // 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)) - } + // 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) - }) + 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", "") - var PortsInt int + // 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", "") + 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)) + } - // 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) - } + // 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) + } - c.JSON(http.StatusOK, resp) - }) + 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") - }) + //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") + }) - //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) - }) + //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) + }) - // 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)) - } + // 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)) + } - c.String(http.StatusOK, strconv.Itoa(port)) - }) + 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() - //} + // 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 - } + // 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 + 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] - } - } + 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 - } + // 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" + // 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() - } + // 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) + // Run gin server on the specified port + go r.Run(":" + config.ServerPort) - return r, nil + return r, nil }