From 1cd4fa87d7b85f27d67f8b015b783f9f20daa872 Mon Sep 17 00:00:00 2001 From: Akilan Date: Tue, 17 Jan 2023 18:14:47 +0000 Subject: [PATCH] added route to auto create FRP port --- cmd/action.go | 529 +++++++++++++++++++++++----------------------- cmd/flags.go | 450 +++++++++++++++++++-------------------- p2p/frp/server.go | 85 ++++---- server/server.go | 347 +++++++++++++++--------------- 4 files changed, 709 insertions(+), 702 deletions(-) diff --git a/cmd/action.go b/cmd/action.go index e6fa73a..c30c263 100644 --- a/cmd/action.go +++ b/cmd/action.go @@ -1,304 +1,303 @@ package cmd import ( - "fmt" - "git.sr.ht/~akilan1999/p2p-rendering-computation/client" - "git.sr.ht/~akilan1999/p2p-rendering-computation/config" - "git.sr.ht/~akilan1999/p2p-rendering-computation/generate" - "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" - "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p/frp" - "git.sr.ht/~akilan1999/p2p-rendering-computation/plugin" - "git.sr.ht/~akilan1999/p2p-rendering-computation/server" - "github.com/urfave/cli/v2" + "fmt" + "git.sr.ht/~akilan1999/p2p-rendering-computation/client" + "git.sr.ht/~akilan1999/p2p-rendering-computation/config" + "git.sr.ht/~akilan1999/p2p-rendering-computation/generate" + "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" + "git.sr.ht/~akilan1999/p2p-rendering-computation/plugin" + "git.sr.ht/~akilan1999/p2p-rendering-computation/server" + "github.com/urfave/cli/v2" ) var CliAction = func(ctx *cli.Context) error { - if Server { - err := server.Server() - if err != nil { - fmt.Print(err) - } - //server.Rpc() - } + if Server { + err := server.Server() + if err != nil { + fmt.Print(err) + } + //server.Rpc() + } - //Listing servers and also updates IP tables (Default 3 hops) - if UpdateServerList { - err := client.UpdateIpTableListClient() - if err != nil { - fmt.Print(err) - } - // Reads from ip table and passes it - // on to struct print function - //Servers, err := p2p.ReadIpTable() - //if err != nil { - // return err - //} - //client.PrettyPrint(Servers) - p2p.PrintIpTable() - } + //Listing servers and also updates IP tables (Default 3 hops) + if UpdateServerList { + err := client.UpdateIpTableListClient() + if err != nil { + fmt.Print(err) + } + // Reads from ip table and passes it + // on to struct print function + //Servers, err := p2p.ReadIpTable() + //if err != nil { + // return err + //} + //client.PrettyPrint(Servers) + p2p.PrintIpTable() + } - // Displays the IP table - if ServerList { - // Reads from ip table and passes it - // on to struct print function - //Servers, err := p2p.ReadIpTable() - //if err != nil { - // return err - //} - p2p.PrintIpTable() - } + // Displays the IP table + if ServerList { + // Reads from ip table and passes it + // on to struct print function + //Servers, err := p2p.ReadIpTable() + //if err != nil { + // return err + //} + p2p.PrintIpTable() + } - // Add provided IP to the IP table - if AddServer != "" { - res, err := p2p.ReadIpTable() - if err != nil { - fmt.Println(err) - } + // Add provided IP to the IP table + if AddServer != "" { + res, err := p2p.ReadIpTable() + if err != nil { + fmt.Println(err) + } - //Create variable of type IpAddress and set IP address - // to it - var IpAddr p2p.IpAddress + //Create variable of type IpAddress and set IP address + // to it + var IpAddr p2p.IpAddress - //Checking if the address is a ipv4 - // or ipv6 address - ip4Orip6 := p2p.Ip4or6(AddServer) - if ip4Orip6 == "version 6" { - IpAddr.Ipv6 = AddServer - } else { - IpAddr.Ipv4 = AddServer - } + //Checking if the address is a ipv4 + // or ipv6 address + ip4Orip6 := p2p.Ip4or6(AddServer) + if ip4Orip6 == "version 6" { + IpAddr.Ipv6 = AddServer + } else { + IpAddr.Ipv4 = AddServer + } - // If a server port is provided then set it - if Ports != "" { - IpAddr.ServerPort = Ports - } else { - IpAddr.ServerPort = "8088" - } - // Append IP address to variable result which - // is a list - res.IpAddress = append(res.IpAddress, IpAddr) - // Adds the new server IP to the iptable - res.WriteIpTable() + // If a server port is provided then set it + if Ports != "" { + IpAddr.ServerPort = Ports + } else { + IpAddr.ServerPort = "8088" + } + // Append IP address to variable result which + // is a list + res.IpAddress = append(res.IpAddress, IpAddr) + // Adds the new server IP to the iptable + res.WriteIpTable() - } + } - // Displays all images available on the server side - if ViewImages != "" { - imageRes, err := client.ViewContainers(ViewImages) + // Displays all images available on the server side + if ViewImages != "" { + imageRes, err := client.ViewContainers(ViewImages) - if err != nil { - fmt.Print(err) - } - client.PrettyPrint(imageRes) - } + if err != nil { + fmt.Print(err) + } + client.PrettyPrint(imageRes) + } - // Function called to stop and remove server from Docker - if RemoveVM != "" && ID != "" { - err := client.RemoveContianer(RemoveVM, ID) - if err != nil { - fmt.Print(err) - } - } + // Function called to stop and remove server from Docker + if RemoveVM != "" && ID != "" { + err := client.RemoveContianer(RemoveVM, ID) + if err != nil { + fmt.Print(err) + } + } - //Call function to create Docker container - if CreateVM != "" { + //Call function to create Docker container + if CreateVM != "" { - var PortsInt int + var PortsInt int - if Ports != "" { - // Convert Get Request value to int - fmt.Sscanf(Ports, "%d", &PortsInt) - } + if Ports != "" { + // Convert Get Request value to int + fmt.Sscanf(Ports, "%d", &PortsInt) + } - // Calls function to do Api call to start the container on the server side - imageRes, err := client.StartContainer(CreateVM, PortsInt, GPU, ContainerName) + // Calls function to do Api call to start the container on the server side + imageRes, err := client.StartContainer(CreateVM, PortsInt, GPU, ContainerName) - if err != nil { - fmt.Print(err) - } - client.PrettyPrint(imageRes) - } + if err != nil { + fmt.Print(err) + } + client.PrettyPrint(imageRes) + } - //Call if specs flag is called - if Specs != "" { - specs, err := client.GetSpecs(Specs) - if err != nil { - return err - } + //Call if specs flag is called + if Specs != "" { + specs, err := client.GetSpecs(Specs) + if err != nil { + return err + } - // Pretty print - client.PrettyPrint(specs) - } + // Pretty print + client.PrettyPrint(specs) + } - //Sets default paths to the config file - if SetDefaultConfig { - err := config.SetDefaults() - if err != nil { - fmt.Print(err) - } - } + //Sets default paths to the config file + if SetDefaultConfig { + err := config.SetDefaults() + if err != nil { + fmt.Print(err) + } + } - //If the network interface flag is called - // Then all the network interfaces are displayed - if NetworkInterface { - err := p2p.ViewNetworkInterface() - if err != nil { - fmt.Print(err) - } - } + //If the network interface flag is called + // Then all the network interfaces are displayed + if NetworkInterface { + err := p2p.ViewNetworkInterface() + if err != nil { + fmt.Print(err) + } + } - // If the view plugin flag is called then display all - // plugins available - if ViewPlugin { - plugins, err := plugin.DetectPlugins() - if err != nil { - fmt.Print(err) - } - client.PrettyPrint(plugins) - } + // If the view plugin flag is called then display all + // plugins available + if ViewPlugin { + plugins, err := plugin.DetectPlugins() + if err != nil { + fmt.Print(err) + } + client.PrettyPrint(plugins) + } - // If the flag Tracked Container is called or the flag - // --tc - if TrackedContainers { - err, trackedContainers := client.ViewTrackedContainers() - if err != nil { - fmt.Print(err) - } - client.PrettyPrint(trackedContainers) - } + // If the flag Tracked Container is called or the flag + // --tc + if TrackedContainers { + err, trackedContainers := client.ViewTrackedContainers() + if err != nil { + fmt.Print(err) + } + client.PrettyPrint(trackedContainers) + } - //Executing plugin when the plugin flag is called - // --plugin - if ExecutePlugin != "" { - // To execute plugin requires the container ID or group ID provided when being executed - if ID != "" { - err := plugin.CheckRunPlugin(ExecutePlugin, ID) - if err != nil { - fmt.Println(err) - } else { - fmt.Println("Success") - } - } else { - fmt.Println("provide container ID") - } + //Executing plugin when the plugin flag is called + // --plugin + if ExecutePlugin != "" { + // To execute plugin requires the container ID or group ID provided when being executed + if ID != "" { + err := plugin.CheckRunPlugin(ExecutePlugin, ID) + if err != nil { + fmt.Println(err) + } else { + fmt.Println("Success") + } + } else { + fmt.Println("provide container ID") + } - } + } - // Executing function to create new group - // Creates new group and outputs JSON file - if CreateGroup { - group, err := client.CreateGroup() - if err != nil { - return err - } - client.PrettyPrint(group) - } + // Executing function to create new group + // Creates new group and outputs JSON file + if CreateGroup { + group, err := client.CreateGroup() + if err != nil { + return err + } + client.PrettyPrint(group) + } - // Actions to be performed when the - // group flag is called - // --group - if Group != "" { - // Remove container from group based on group ID provided - // --rmcgroup --id - if RemoveContainerGroup && ID != "" { - group, err := client.RemoveContainerGroup(ID, Group) - if err != nil { - fmt.Println(err) - } else { - client.PrettyPrint(group) - } - } else if ID != "" { // Add container to group based on group ID provided - // --id - group, err := client.AddContainerToGroup(ID, Group) - if err != nil { - fmt.Println(err) - } else { - client.PrettyPrint(group) - } - } else { // View all information about current group - group, err := client.GetGroup(Group) - if err != nil { - fmt.Println(err) - } else { - client.PrettyPrint(group) - } - } - } + // Actions to be performed when the + // group flag is called + // --group + if Group != "" { + // Remove container from group based on group ID provided + // --rmcgroup --id + if RemoveContainerGroup && ID != "" { + group, err := client.RemoveContainerGroup(ID, Group) + if err != nil { + fmt.Println(err) + } else { + client.PrettyPrint(group) + } + } else if ID != "" { // Add container to group based on group ID provided + // --id + group, err := client.AddContainerToGroup(ID, Group) + if err != nil { + fmt.Println(err) + } else { + client.PrettyPrint(group) + } + } else { // View all information about current group + group, err := client.GetGroup(Group) + if err != nil { + fmt.Println(err) + } else { + client.PrettyPrint(group) + } + } + } - // Execute function to remove entire group - // when remove group flag is called - // --rmgroup - if RemoveGroup != "" { - err := client.RemoveGroup(RemoveGroup) - if err != nil { - fmt.Println(err) - } else { - fmt.Println("Group Removed") - } - } + // Execute function to remove entire group + // when remove group flag is called + // --rmgroup + if RemoveGroup != "" { + err := client.RemoveGroup(RemoveGroup) + if err != nil { + fmt.Println(err) + } else { + fmt.Println("Group Removed") + } + } - // Execute Function to view all groups - if Groups { - groups, err := client.ReadGroup() - if err != nil { - fmt.Println(err) - } else { - client.PrettyPrint(groups) - } - } + // Execute Function to view all groups + if Groups { + groups, err := client.ReadGroup() + if err != nil { + fmt.Println(err) + } else { + client.PrettyPrint(groups) + } + } - // Starts server as a reverse proxy so that - // nodes can connect to each other behind NAT - if FRPProxy { - err := frp.StartFRPProxyFromConfig() - if err != nil { - fmt.Println(err) - } - } + // Starts server as a reverse proxy so that + // nodes can connect to each other behind NAT + //if FRPProxy { + // err := frp.StartFRPProxyFromRandom() + // if err != nil { + // fmt.Println(err) + // } + //} - // -- REMOVE ON REGULAR RELEASE -- - // when flag --gen is called an extension - // of the project is created to repurpose - // the project for custom purpose - if Generate != "" { - var err error - // If the module name is provided - if Modulename != "" { - err = generate.GenerateNewProject(Generate, Modulename) - } else { - err = generate.GenerateNewProject(Generate, Generate) - } - if err != nil { - fmt.Println(err) - } else { - fmt.Println("Created new folder: " + Generate) - fmt.Println("1. Enter inside " + Generate + " directory") - fmt.Println("2. git remote add " + Generate + " ") - fmt.Println("3. git push " + Generate + " ") - fmt.Println("4. go mod tidy") - fmt.Println("5. sh install.sh " + Generate) - fmt.Println("6. ./" + Generate + " -h (This is to test if the binary is working)") - } - } - //-------------------------------- + // -- REMOVE ON REGULAR RELEASE -- + // when flag --gen is called an extension + // of the project is created to repurpose + // the project for custom purpose + if Generate != "" { + var err error + // If the module name is provided + if Modulename != "" { + err = generate.GenerateNewProject(Generate, Modulename) + } else { + err = generate.GenerateNewProject(Generate, Generate) + } + if err != nil { + fmt.Println(err) + } else { + fmt.Println("Created new folder: " + Generate) + fmt.Println("1. Enter inside " + Generate + " directory") + fmt.Println("2. git remote add " + Generate + " ") + fmt.Println("3. git push " + Generate + " ") + fmt.Println("4. go mod tidy") + fmt.Println("5. sh install.sh " + Generate) + fmt.Println("6. ./" + Generate + " -h (This is to test if the binary is working)") + } + } + //-------------------------------- - if PullPlugin != "" { - err := plugin.DownloadPlugin(PullPlugin) - if err != nil { - fmt.Println(err) - } else { - fmt.Println("Success") - } - } + if PullPlugin != "" { + err := plugin.DownloadPlugin(PullPlugin) + if err != nil { + fmt.Println(err) + } else { + fmt.Println("Success") + } + } - if RemovePlugin != "" { - err := plugin.DeletePlugin(RemovePlugin) - if err != nil { - fmt.Println(err) - } else { - fmt.Println("Success") - } - } + if RemovePlugin != "" { + err := plugin.DeletePlugin(RemovePlugin) + if err != nil { + fmt.Println(err) + } else { + fmt.Println("Success") + } + } - return nil + return nil } diff --git a/cmd/flags.go b/cmd/flags.go index eeb3686..35c8c5a 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -1,236 +1,236 @@ package cmd import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v2" ) // Variables declared for CLI var ( - AddServer string - ViewImages string - CreateVM string - ContainerName string - Ports string - Server bool - RemoveVM string - ID string - Specs string - GPU bool - UpdateServerList bool - ServerList bool - SetDefaultConfig bool - NetworkInterface bool - ViewPlugin bool - TrackedContainers bool - ExecutePlugin string - CreateGroup bool - Group string - Groups bool - RemoveContainerGroup bool - RemoveGroup string - FRPProxy bool - // Generate only allowed in dev release - // -- REMOVE ON REGULAR RELEASE -- - Generate string - Modulename string - //-------------------------------- - PullPlugin string - RemovePlugin string + AddServer string + ViewImages string + CreateVM string + ContainerName string + Ports string + Server bool + RemoveVM string + ID string + Specs string + GPU bool + UpdateServerList bool + ServerList bool + SetDefaultConfig bool + NetworkInterface bool + ViewPlugin bool + TrackedContainers bool + ExecutePlugin string + CreateGroup bool + Group string + Groups bool + RemoveContainerGroup bool + RemoveGroup string + //FRPProxy bool + // Generate only allowed in dev release + // -- REMOVE ON REGULAR RELEASE -- + Generate string + Modulename string + //-------------------------------- + PullPlugin string + RemovePlugin string ) var AppConfigFlags = []cli.Flag{ - // Deprecated to be implemented using GRPC - &cli.BoolFlag{ - Name: "Server", - Aliases: []string{"s"}, - Usage: "Starts server", - EnvVars: []string{"SERVER"}, - Destination: &Server, - }, - &cli.BoolFlag{ - Name: "UpdateServerList", - Aliases: []string{"us"}, - Usage: "Update List of Server available based on servers iptables", - EnvVars: []string{"UPDATE_SERVER_LIST"}, - Destination: &UpdateServerList, - }, - &cli.BoolFlag{ - Name: "ListServers", - Aliases: []string{"ls"}, - Usage: "List servers which can render tasks", - EnvVars: []string{"LIST_SERVERS"}, - Destination: &ServerList, - }, - &cli.StringFlag{ - Name: "AddServer", - Aliases: []string{"as"}, - Usage: "Adds server IP address to iptables", - EnvVars: []string{"ADD_SERVER"}, - Destination: &AddServer, - }, - &cli.StringFlag{ - Name: "ViewImages", - Aliases: []string{"vi"}, - Usage: "View images available on the server IP address", - EnvVars: []string{"VIEW_IMAGES"}, - Destination: &ViewImages, - }, - &cli.StringFlag{ - Name: "CreateVM", - Aliases: []string{"touch"}, - Usage: "Creates Docker container on the selected server", - EnvVars: []string{"CREATE_VM"}, - Destination: &CreateVM, - }, - &cli.StringFlag{ - Name: "ContainerName", - Aliases: []string{"cn"}, - Usage: "Specifying the container run on the server side", - EnvVars: []string{"CONTAINER_NAME"}, - Destination: &ContainerName, - }, - &cli.StringFlag{ - Name: "RemoveVM", - Aliases: []string{"rm"}, - Usage: "Stop and Remove Docker container", - EnvVars: []string{"REMOVE_VM"}, - Destination: &RemoveVM, - }, - &cli.StringFlag{ - Name: "ID", - Aliases: []string{"id"}, - Usage: "Docker Container ID", - EnvVars: []string{"ID"}, - Destination: &ID, - }, - &cli.StringFlag{ - Name: "Ports", - Aliases: []string{"p"}, - Usage: "Number of ports to open for the Docker Container", - EnvVars: []string{"NUM_PORTS"}, - Destination: &Ports, - }, - &cli.BoolFlag{ - Name: "GPU", - Aliases: []string{"gpu"}, - Usage: "Create Docker Containers to access GPU", - EnvVars: []string{"USE_GPU"}, - Destination: &GPU, - }, - &cli.StringFlag{ - Name: "Specification", - Aliases: []string{"specs"}, - Usage: "Specs of the server node", - EnvVars: []string{"SPECS"}, - Destination: &Specs, - }, - &cli.BoolFlag{ - Name: "SetDefaultConfig", - Aliases: []string{"dc"}, - Usage: "Sets a default configuration file", - EnvVars: []string{"SET_DEFAULT_CONFIG"}, - Destination: &SetDefaultConfig, - }, - &cli.BoolFlag{ - Name: "NetworkInterfaces", - Aliases: []string{"ni"}, - Usage: "Shows the network interface in your computer", - EnvVars: []string{"NETWORK_INTERFACE"}, - Destination: &NetworkInterface, - }, - &cli.BoolFlag{ - Name: "ViewPlugins", - Aliases: []string{"vp"}, - Usage: "Shows plugins available to be executed", - EnvVars: []string{"VIEW_PLUGIN"}, - Destination: &ViewPlugin, - }, - &cli.BoolFlag{ - Name: "TrackedContainers", - Aliases: []string{"tc"}, - Usage: "View containers which have " + - "been created from the client side ", - EnvVars: []string{"TRACKED_CONTAINERS"}, - Destination: &TrackedContainers, - }, - &cli.StringFlag{ - Name: "ExecutePlugin", - Aliases: []string{"plugin"}, - Usage: "Plugin which needs to be executed", - EnvVars: []string{"EXECUTE_PLUGIN"}, - Destination: &ExecutePlugin, - }, - &cli.BoolFlag{ - Name: "CreateGroup", - Aliases: []string{"cgroup"}, - Usage: "Creates a new group", - EnvVars: []string{"CREATE_GROUP"}, - Destination: &CreateGroup, - }, - &cli.StringFlag{ - Name: "Group", - Aliases: []string{"group"}, - Usage: "group flag with argument group ID", - EnvVars: []string{"GROUP"}, - Destination: &Group, - }, - &cli.BoolFlag{ - Name: "Groups", - Aliases: []string{"groups"}, - Usage: "View all groups", - EnvVars: []string{"GROUPS"}, - Destination: &Groups, - }, - &cli.BoolFlag{ - Name: "RemoveContainerGroup", - Aliases: []string{"rmcgroup"}, - Usage: "Remove specific container in the group", - EnvVars: []string{"REMOVE_CONTAINER_GROUP"}, - Destination: &RemoveContainerGroup, - }, - &cli.StringFlag{ - Name: "RemoveGroup", - Aliases: []string{"rmgroup"}, - Usage: "Removes the entire group", - EnvVars: []string{"REMOVE_GROUP"}, - Destination: &RemoveGroup, - }, - // Generate only allowed in dev release - // -- REMOVE ON REGULAR RELEASE -- - &cli.StringFlag{ - Name: "Generate", - Aliases: []string{"gen"}, - Usage: "Generates a new copy of P2PRC which can be modified based on your needs", - EnvVars: []string{"GENERATE"}, - Destination: &Generate, - }, - &cli.StringFlag{ - Name: "ModuleName", - Aliases: []string{"mod"}, - Usage: "New go project module name", - EnvVars: []string{"MODULENAME"}, - Destination: &Modulename, - }, - &cli.BoolFlag{ - Name: "FRPServerProxy", - Aliases: []string{"proxy"}, - Usage: "Starts proxy for server", - EnvVars: []string{"FRPSERVERPROXY"}, - Destination: &FRPProxy, - }, - //-------------------------------- - &cli.StringFlag{ - Name: "PullPlugin", - Aliases: []string{"pp"}, - Usage: "Pulls plugin from git repos", - EnvVars: []string{"PULLPLUGIN"}, - Destination: &PullPlugin, - }, - &cli.StringFlag{ - Name: "RemovePlugin", - Aliases: []string{"rp"}, - Usage: "Removes plugin", - EnvVars: []string{"REMOVEPLUGIN"}, - Destination: &RemovePlugin, - }, + // Deprecated to be implemented using GRPC + &cli.BoolFlag{ + Name: "Server", + Aliases: []string{"s"}, + Usage: "Starts server", + EnvVars: []string{"SERVER"}, + Destination: &Server, + }, + &cli.BoolFlag{ + Name: "UpdateServerList", + Aliases: []string{"us"}, + Usage: "Update List of Server available based on servers iptables", + EnvVars: []string{"UPDATE_SERVER_LIST"}, + Destination: &UpdateServerList, + }, + &cli.BoolFlag{ + Name: "ListServers", + Aliases: []string{"ls"}, + Usage: "List servers which can render tasks", + EnvVars: []string{"LIST_SERVERS"}, + Destination: &ServerList, + }, + &cli.StringFlag{ + Name: "AddServer", + Aliases: []string{"as"}, + Usage: "Adds server IP address to iptables", + EnvVars: []string{"ADD_SERVER"}, + Destination: &AddServer, + }, + &cli.StringFlag{ + Name: "ViewImages", + Aliases: []string{"vi"}, + Usage: "View images available on the server IP address", + EnvVars: []string{"VIEW_IMAGES"}, + Destination: &ViewImages, + }, + &cli.StringFlag{ + Name: "CreateVM", + Aliases: []string{"touch"}, + Usage: "Creates Docker container on the selected server", + EnvVars: []string{"CREATE_VM"}, + Destination: &CreateVM, + }, + &cli.StringFlag{ + Name: "ContainerName", + Aliases: []string{"cn"}, + Usage: "Specifying the container run on the server side", + EnvVars: []string{"CONTAINER_NAME"}, + Destination: &ContainerName, + }, + &cli.StringFlag{ + Name: "RemoveVM", + Aliases: []string{"rm"}, + Usage: "Stop and Remove Docker container", + EnvVars: []string{"REMOVE_VM"}, + Destination: &RemoveVM, + }, + &cli.StringFlag{ + Name: "ID", + Aliases: []string{"id"}, + Usage: "Docker Container ID", + EnvVars: []string{"ID"}, + Destination: &ID, + }, + &cli.StringFlag{ + Name: "Ports", + Aliases: []string{"p"}, + Usage: "Number of ports to open for the Docker Container", + EnvVars: []string{"NUM_PORTS"}, + Destination: &Ports, + }, + &cli.BoolFlag{ + Name: "GPU", + Aliases: []string{"gpu"}, + Usage: "Create Docker Containers to access GPU", + EnvVars: []string{"USE_GPU"}, + Destination: &GPU, + }, + &cli.StringFlag{ + Name: "Specification", + Aliases: []string{"specs"}, + Usage: "Specs of the server node", + EnvVars: []string{"SPECS"}, + Destination: &Specs, + }, + &cli.BoolFlag{ + Name: "SetDefaultConfig", + Aliases: []string{"dc"}, + Usage: "Sets a default configuration file", + EnvVars: []string{"SET_DEFAULT_CONFIG"}, + Destination: &SetDefaultConfig, + }, + &cli.BoolFlag{ + Name: "NetworkInterfaces", + Aliases: []string{"ni"}, + Usage: "Shows the network interface in your computer", + EnvVars: []string{"NETWORK_INTERFACE"}, + Destination: &NetworkInterface, + }, + &cli.BoolFlag{ + Name: "ViewPlugins", + Aliases: []string{"vp"}, + Usage: "Shows plugins available to be executed", + EnvVars: []string{"VIEW_PLUGIN"}, + Destination: &ViewPlugin, + }, + &cli.BoolFlag{ + Name: "TrackedContainers", + Aliases: []string{"tc"}, + Usage: "View containers which have " + + "been created from the client side ", + EnvVars: []string{"TRACKED_CONTAINERS"}, + Destination: &TrackedContainers, + }, + &cli.StringFlag{ + Name: "ExecutePlugin", + Aliases: []string{"plugin"}, + Usage: "Plugin which needs to be executed", + EnvVars: []string{"EXECUTE_PLUGIN"}, + Destination: &ExecutePlugin, + }, + &cli.BoolFlag{ + Name: "CreateGroup", + Aliases: []string{"cgroup"}, + Usage: "Creates a new group", + EnvVars: []string{"CREATE_GROUP"}, + Destination: &CreateGroup, + }, + &cli.StringFlag{ + Name: "Group", + Aliases: []string{"group"}, + Usage: "group flag with argument group ID", + EnvVars: []string{"GROUP"}, + Destination: &Group, + }, + &cli.BoolFlag{ + Name: "Groups", + Aliases: []string{"groups"}, + Usage: "View all groups", + EnvVars: []string{"GROUPS"}, + Destination: &Groups, + }, + &cli.BoolFlag{ + Name: "RemoveContainerGroup", + Aliases: []string{"rmcgroup"}, + Usage: "Remove specific container in the group", + EnvVars: []string{"REMOVE_CONTAINER_GROUP"}, + Destination: &RemoveContainerGroup, + }, + &cli.StringFlag{ + Name: "RemoveGroup", + Aliases: []string{"rmgroup"}, + Usage: "Removes the entire group", + EnvVars: []string{"REMOVE_GROUP"}, + Destination: &RemoveGroup, + }, + // Generate only allowed in dev release + // -- REMOVE ON REGULAR RELEASE -- + &cli.StringFlag{ + Name: "Generate", + Aliases: []string{"gen"}, + Usage: "Generates a new copy of P2PRC which can be modified based on your needs", + EnvVars: []string{"GENERATE"}, + Destination: &Generate, + }, + &cli.StringFlag{ + Name: "ModuleName", + Aliases: []string{"mod"}, + Usage: "New go project module name", + EnvVars: []string{"MODULENAME"}, + Destination: &Modulename, + }, + //&cli.BoolFlag{ + // Name: "FRPServerProxy", + // Aliases: []string{"proxy"}, + // Usage: "Starts proxy for server", + // EnvVars: []string{"FRPSERVERPROXY"}, + // Destination: &FRPProxy, + //}, + //-------------------------------- + &cli.StringFlag{ + Name: "PullPlugin", + Aliases: []string{"pp"}, + Usage: "Pulls plugin from git repos", + EnvVars: []string{"PULLPLUGIN"}, + Destination: &PullPlugin, + }, + &cli.StringFlag{ + Name: "RemovePlugin", + Aliases: []string{"rp"}, + Usage: "Removes plugin", + EnvVars: []string{"REMOVEPLUGIN"}, + Destination: &RemovePlugin, + }, } diff --git a/p2p/frp/server.go b/p2p/frp/server.go index 4c435df..bf4ed7a 100644 --- a/p2p/frp/server.go +++ b/p2p/frp/server.go @@ -1,48 +1,45 @@ package frp import ( - configP2PRC "git.sr.ht/~akilan1999/p2p-rendering-computation/config" - "github.com/fatedier/frp/pkg/config" - "github.com/fatedier/frp/server" - "strconv" + "github.com/fatedier/frp/pkg/config" + "github.com/fatedier/frp/server" + "github.com/phayes/freeport" ) // TODO: Implement a way to // check if ports are taken type Server struct { - address string - port int + address string + port int } -// StartFRPProxyFromConfig starts +// StartFRPProxyFromRandom starts // reverse proxy server based on -// the port provided in the config file -// field FRPServerPort. -func StartFRPProxyFromConfig() error { - // gets current configuration - config, err := configP2PRC.ConfigInit() - if err != nil { - return err - } +// a random port generated +func StartFRPProxyFromRandom() (int, error) { + // gets current configuration + //config, err := configP2PRC.ConfigInit() + //if err != nil { + // return err + //} - var s Server - s.address = "0.0.0.0" - // Converting config port to int - port, err := strconv.Atoi(config.FRPServerPort) - if err != nil { - return err - } - s.port = port + var s Server + s.address = "0.0.0.0" - // start FRP server + // use random port + OpenPorts, err := freeport.GetFreePorts(1) + if err != nil { + return 0, err + } - err = s.StartFRPServer() - if err != nil { - return err - } + s.port = OpenPorts[0] - return nil + // start FRP server + + go s.StartFRPServer() + + return OpenPorts[0], nil } @@ -51,22 +48,22 @@ func StartFRPProxyFromConfig() error { // This function starts a server that can act as a reverse // proxy for nodes behind NAT. func (s *Server) StartFRPServer() error { - baseConfig := config.GetDefaultServerConf() - baseConfig.BindAddr = s.address + baseConfig := config.GetDefaultServerConf() + baseConfig.BindAddr = s.address - //TODO look into later for dashboard - //baseConfig.DashboardAddr = "127.0.0.1" - //baseConfig.DashboardPort = 8754 - //baseConfig.DashboardUser = "admin" - //baseConfig.DashboardPwd = "admin" + //TODO look into later for dashboard + //baseConfig.DashboardAddr = "127.0.0.1" + //baseConfig.DashboardPort = 8754 + //baseConfig.DashboardUser = "admin" + //baseConfig.DashboardPwd = "admin" - // todo change to make it a dynamic port - baseConfig.BindPort = s.port - service, err := server.NewService(baseConfig) - if err != nil { - return err - } + // todo change to make it a dynamic port + baseConfig.BindPort = s.port + service, err := server.NewService(baseConfig) + if err != nil { + return err + } - service.Run() - return nil + service.Run() + return nil } diff --git a/server/server.go b/server/server.go index d1a9f97..5d41c8a 100644 --- a/server/server.go +++ b/server/server.go @@ -1,211 +1,222 @@ package server import ( - "encoding/json" - "fmt" - "git.sr.ht/~akilan1999/p2p-rendering-computation/config" - "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" - "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p/frp" - "git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" - "github.com/gin-gonic/gin" - "io/ioutil" - "net/http" + "encoding/json" + "fmt" + "git.sr.ht/~akilan1999/p2p-rendering-computation/config" + "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" + "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p/frp" + "git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" + "github.com/gin-gonic/gin" + "io/ioutil" + "net/http" + "strconv" ) func Server() error { - r := gin.Default() + r := gin.Default() - // update IPTable with new port and ip address and update ip table - var ProxyIpAddr p2p.IpAddress + // update IPTable with new port and ip address and update ip table + var ProxyIpAddr 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 - config, err := config.ConfigInit() - if err != nil { - c.String(http.StatusOK, fmt.Sprint(err)) - } - c.File(config.SpeedTestFile) - }) + // Speed test with 50 mbps + r.GET("/50", func(c *gin.Context) { + // Get Path from config + config, err := config.ConfigInit() + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } + c.File(config.SpeedTestFile) + }) - // 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)) + } - if ProxyIpAddr.Ipv4 != "" { - err := frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, ProxyIpAddr.ProxyPort, resp) - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } - } + if ProxyIpAddr.Ipv4 != "" { + err := frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, ProxyIpAddr.ProxyPort, resp) + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } + } - 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) + }) - //Get Server port based on the config file - config, err := config.ConfigInit() - if err != nil { - return err - } + // Request for port no from Server with address + r.GET("/FRPPort", func(c *gin.Context) { + port, err := frp.StartFRPProxyFromRandom() + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } - // If there is a proxy port specified - // then starts the FRP server - if config.FRPServerPort != "0" { - go frp.StartFRPProxyFromConfig() - } + c.String(http.StatusOK, strconv.Itoa(port)) + }) - // 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 err - } + //Get Server port based on the config file + config, err := config.ConfigInit() + if err != nil { + return err + } - var lowestLatency int64 - // random large number - lowestLatency = 10000000 - var lowestLatencyIpAddress p2p.IpAddress - 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 != "" { - lowestLatency = table.IpAddress[i].Latency.Milliseconds() - lowestLatencyIpAddress = table.IpAddress[i] - } - } + // If there is a proxy port specified + // then starts the FRP server + if config.FRPServerPort != "0" { + go frp.StartFRPProxyFromRandom() + } - // If there is an identified node - if lowestLatency != 10000000 { - // Starts FRP as a client with - proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, lowestLatencyIpAddress.ProxyPort, config.ServerPort) - if err != nil { - return 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 err + } - fmt.Println(proxyPort) + var lowestLatency int64 + // random large number + lowestLatency = 10000000 + var lowestLatencyIpAddress p2p.IpAddress + 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 != "" { + lowestLatency = table.IpAddress[i].Latency.Milliseconds() + lowestLatencyIpAddress = table.IpAddress[i] + } + } - // updating with the current proxy address - ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4 - ProxyIpAddr.ServerPort = proxyPort - ProxyIpAddr.ProxyPort = lowestLatencyIpAddress.ProxyPort - ProxyIpAddr.Name = config.MachineName + // If there is an identified node + if lowestLatency != 10000000 { + // Starts FRP as a client with + proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, lowestLatencyIpAddress.ProxyPort, config.ServerPort) + if err != nil { + return err + } - // 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 table.SpeedTest() - } + fmt.Println(proxyPort) - } + // updating with the current proxy address + ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4 + ProxyIpAddr.ServerPort = proxyPort + ProxyIpAddr.ProxyPort = lowestLatencyIpAddress.ProxyPort + ProxyIpAddr.Name = config.MachineName - // Run gin server on the specified port - err = r.Run(":" + config.ServerPort) - if err != nil { - return err - } + // 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 table.SpeedTest() + } - return nil + } + + // Run gin server on the specified port + err = r.Run(":" + config.ServerPort) + if err != nil { + return err + } + + return nil }