mirror of
https://github.com/F1bonacc1/process-compose.git
synced 2024-09-11 11:35:26 +03:00
Get Process Ports
This commit is contained in:
parent
43ac3cc86f
commit
c51b8a7d39
4
go.mod
4
go.mod
@ -5,6 +5,7 @@ go 1.20
|
|||||||
require (
|
require (
|
||||||
github.com/InVisionApp/go-health/v2 v2.1.3
|
github.com/InVisionApp/go-health/v2 v2.1.3
|
||||||
github.com/adrg/xdg v0.4.0
|
github.com/adrg/xdg v0.4.0
|
||||||
|
github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5
|
||||||
github.com/f1bonacc1/glippy v0.0.0-20230203184233-82c6562cecd1
|
github.com/f1bonacc1/glippy v0.0.0-20230203184233-82c6562cecd1
|
||||||
github.com/fatih/color v1.15.0
|
github.com/fatih/color v1.15.0
|
||||||
github.com/gdamore/tcell/v2 v2.6.0
|
github.com/gdamore/tcell/v2 v2.6.0
|
||||||
@ -16,10 +17,13 @@ require (
|
|||||||
github.com/spf13/cobra v1.7.0
|
github.com/spf13/cobra v1.7.0
|
||||||
github.com/swaggo/swag v1.16.1
|
github.com/swaggo/swag v1.16.1
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
|
//github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/InVisionApp/go-health/v2 => github.com/f1bonacc1/go-health/v2 v2.1.3
|
replace github.com/InVisionApp/go-health/v2 => github.com/f1bonacc1/go-health/v2 v2.1.3
|
||||||
|
|
||||||
|
replace github.com/cakturk/go-netstat => github.com/mololab/netstat v0.0.0-20221129160431-27c9226a45b1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/InVisionApp/go-logger v1.0.1 // indirect
|
github.com/InVisionApp/go-logger v1.0.1 // indirect
|
||||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||||
|
6
go.sum
6
go.sum
@ -4,6 +4,8 @@ github.com/InVisionApp/go-logger v1.0.1 h1:WFL19PViM1mHUmUWfsv5zMo379KSWj2MRmBlz
|
|||||||
github.com/InVisionApp/go-logger v1.0.1/go.mod h1:+cGTDSn+P8105aZkeOfIhdd7vFO5X1afUHcjvanY0L8=
|
github.com/InVisionApp/go-logger v1.0.1/go.mod h1:+cGTDSn+P8105aZkeOfIhdd7vFO5X1afUHcjvanY0L8=
|
||||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||||
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
|
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
|
||||||
github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=
|
github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=
|
||||||
@ -14,6 +16,8 @@ github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQ
|
|||||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||||
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
||||||
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||||
|
github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5 h1:BjkPE3785EwPhhyuFkbINB+2a1xATwk8SNDWnJiD41g=
|
||||||
|
github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5/go.mod h1:jtAfVaU/2cu1+wdSRPWE2c1N2qeAA3K4RH9pYgqwets=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||||
@ -128,6 +132,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/mololab/netstat v0.0.0-20221129160431-27c9226a45b1 h1:3k8Fbl7pFlde2/847ox7l/Wqql9Ww644JsQoPaY3/1o=
|
||||||
|
github.com/mololab/netstat v0.0.0-20221129160431-27c9226a45b1/go.mod h1:jtAfVaU/2cu1+wdSRPWE2c1N2qeAA3K4RH9pYgqwets=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
|
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
@ -84,36 +84,8 @@ processes:
|
|||||||
success_threshold: 1
|
success_threshold: 1
|
||||||
failure_threshold: 3
|
failure_threshold: 3
|
||||||
|
|
||||||
# nginx:
|
server:
|
||||||
# command: "docker run -d --rm -p80:80 --name nginx_test nginx"
|
command: "python3 -m http.server 4040"
|
||||||
# # availability:
|
|
||||||
# # restart: on_failure
|
|
||||||
# is_daemon: true
|
|
||||||
# shutdown:
|
|
||||||
# command: "docker stop nginx_test"
|
|
||||||
# signal: 15
|
|
||||||
# timeout_seconds: 5
|
|
||||||
# liveness_probe:
|
|
||||||
# exec:
|
|
||||||
# command: "[ $(docker inspect -f '{{.State.Running}}' nginx_test) = 'true' ]"
|
|
||||||
# initial_delay_seconds: 5
|
|
||||||
# period_seconds: 2
|
|
||||||
# timeout_seconds: 5
|
|
||||||
# success_threshold: 1
|
|
||||||
# failure_threshold: 3
|
|
||||||
# readiness_probe:
|
|
||||||
# http_get:
|
|
||||||
# host: 127.0.0.1
|
|
||||||
# path: "/"
|
|
||||||
# port: 80
|
|
||||||
# initial_delay_seconds: 5
|
|
||||||
# period_seconds: 10
|
|
||||||
# timeout_seconds: 5
|
|
||||||
# success_threshold: 1
|
|
||||||
# failure_threshold: 3
|
|
||||||
# availability:
|
|
||||||
# restart: "always"
|
|
||||||
# backoff_seconds: 2
|
|
||||||
|
|
||||||
kcalc:
|
kcalc:
|
||||||
command: "kcalc"
|
command: "kcalc"
|
||||||
|
@ -215,3 +215,23 @@ func (api *PcApi) GetHostName(c *gin.Context) {
|
|||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{"name": name})
|
c.JSON(http.StatusOK, gin.H{"name": name})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Schemes
|
||||||
|
// @Description Retrieves process open ports
|
||||||
|
// @Tags Process
|
||||||
|
// @Summary Get process ports
|
||||||
|
// @Produce json
|
||||||
|
// @Param name path string true "Process Name"
|
||||||
|
// @Success 200 {object} object "Process Ports"
|
||||||
|
// @Router /process/ports/{name} [get]
|
||||||
|
func (api *PcApi) GetProcessPorts(c *gin.Context) {
|
||||||
|
name := c.Param("name")
|
||||||
|
|
||||||
|
ports, err := api.project.GetProcessPorts(name)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, ports)
|
||||||
|
}
|
||||||
|
@ -43,6 +43,7 @@ func InitRoutes(useLogger bool, handler *PcApi) *gin.Engine {
|
|||||||
r.GET("/processes", handler.GetProcesses)
|
r.GET("/processes", handler.GetProcesses)
|
||||||
r.GET("/process/:name", handler.GetProcess)
|
r.GET("/process/:name", handler.GetProcess)
|
||||||
r.GET("/process/info/:name", handler.GetProcessInfo)
|
r.GET("/process/info/:name", handler.GetProcessInfo)
|
||||||
|
r.GET("/process/ports/:name", handler.GetProcessPorts)
|
||||||
r.GET("/process/logs/:name/:endOffset/:limit", handler.GetProcessLogs)
|
r.GET("/process/logs/:name/:endOffset/:limit", handler.GetProcessLogs)
|
||||||
r.PATCH("/process/stop/:name", handler.StopProcess)
|
r.PATCH("/process/stop/:name", handler.StopProcess)
|
||||||
r.POST("/process/start/:name", handler.StartProcess)
|
r.POST("/process/start/:name", handler.StartProcess)
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/cakturk/go-netstat/netstat"
|
||||||
"github.com/f1bonacc1/process-compose/src/types"
|
"github.com/f1bonacc1/process-compose/src/types"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@ -160,7 +161,7 @@ func (p *Process) getBackoff() time.Duration {
|
|||||||
|
|
||||||
func (p *Process) getProcessEnvironment() []string {
|
func (p *Process) getProcessEnvironment() []string {
|
||||||
env := []string{
|
env := []string{
|
||||||
"PC_PROC_NAME=" + p.getName(),
|
"PC_PROC_NAME=" + p.procConf.Name,
|
||||||
"PC_REPLICA_NUM=" + strconv.Itoa(p.procConf.ReplicaNum),
|
"PC_REPLICA_NUM=" + strconv.Itoa(p.procConf.ReplicaNum),
|
||||||
}
|
}
|
||||||
env = append(env, os.Environ()...)
|
env = append(env, os.Environ()...)
|
||||||
@ -528,3 +529,20 @@ func (p *Process) validateProcess() error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Process) getOpenPorts(ports *types.ProcessPorts) error {
|
||||||
|
socks, err := netstat.TCPSocks(func(s *netstat.SockTabEntry) bool {
|
||||||
|
return s.State == netstat.Listen
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Err(err).Msgf("failed to get open ports for %s", p.getName())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, e := range socks {
|
||||||
|
if e.Process != nil && e.Process.Pid == p.procState.Pid {
|
||||||
|
log.Debug().Msgf("%s is listening on %d", p.getName(), e.LocalAddr.Port)
|
||||||
|
ports.TcpPorts = append(ports.TcpPorts, e.LocalAddr.Port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -25,4 +25,5 @@ type IProject interface {
|
|||||||
StartProcess(name string) error
|
StartProcess(name string) error
|
||||||
RestartProcess(name string) error
|
RestartProcess(name string) error
|
||||||
ScaleProcess(name string, scale int) error
|
ScaleProcess(name string, scale int) error
|
||||||
|
GetProcessPorts(name string) (*types.ProcessPorts, error)
|
||||||
}
|
}
|
||||||
|
@ -260,6 +260,24 @@ func (p *ProjectRunner) GetProcessInfo(name string) (*types.ProcessConfig, error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *ProjectRunner) GetProcessPorts(name string) (*types.ProcessPorts, error) {
|
||||||
|
proc := p.getRunningProcess(name)
|
||||||
|
if proc == nil {
|
||||||
|
return nil, fmt.Errorf("can't get ports: process %s is not running", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
ports := &types.ProcessPorts{
|
||||||
|
Name: name,
|
||||||
|
TcpPorts: make([]uint16, 0),
|
||||||
|
UdpPorts: make([]uint16, 0),
|
||||||
|
}
|
||||||
|
err := proc.getOpenPorts(ports)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ports, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *ProjectRunner) ShutDownProject() {
|
func (p *ProjectRunner) ShutDownProject() {
|
||||||
p.runProcMutex.Lock()
|
p.runProcMutex.Lock()
|
||||||
defer p.runProcMutex.Unlock()
|
defer p.runProcMutex.Unlock()
|
||||||
|
@ -72,8 +72,11 @@ func (p *PcClient) GetLexicographicProcessNames() ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PcClient) GetProcessInfo(name string) (*types.ProcessConfig, error) {
|
func (p *PcClient) GetProcessInfo(name string) (*types.ProcessConfig, error) {
|
||||||
config, err := GetProcessInfo(p.address, p.port, name)
|
return GetProcessInfo(p.address, p.port, name)
|
||||||
return config, err
|
}
|
||||||
|
|
||||||
|
func (p *PcClient) GetProcessPorts(name string) (*types.ProcessPorts, error) {
|
||||||
|
return GetProcessPorts(p.address, p.port, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PcClient) GetProcessState(name string) (*types.ProcessState, error) {
|
func (p *PcClient) GetProcessState(name string) (*types.ProcessState, error) {
|
||||||
|
@ -65,7 +65,6 @@ func GetProcessInfo(address string, port int, name string) (*types.ProcessConfig
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
//Create a variable of the same type as our model
|
|
||||||
var sResp types.ProcessConfig
|
var sResp types.ProcessConfig
|
||||||
|
|
||||||
//Decode the data
|
//Decode the data
|
||||||
@ -76,3 +75,21 @@ func GetProcessInfo(address string, port int, name string) (*types.ProcessConfig
|
|||||||
|
|
||||||
return &sResp, nil
|
return &sResp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetProcessPorts(address string, port int, name string) (*types.ProcessPorts, error) {
|
||||||
|
url := fmt.Sprintf("http://%s:%d/process/ports/%s", address, port, name)
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
var sResp types.ProcessPorts
|
||||||
|
|
||||||
|
//Decode the data
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&sResp); err != nil {
|
||||||
|
log.Err(err).Msgf("what I got: %s", err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &sResp, nil
|
||||||
|
}
|
||||||
|
30
src/cmd/ports.go
Normal file
30
src/cmd/ports.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/f1bonacc1/process-compose/src/client"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// portsCmd represents the ports command
|
||||||
|
var portsCmd = &cobra.Command{
|
||||||
|
Use: "ports [PROCESS]",
|
||||||
|
Short: "Get the ports that a process is listening on",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
name := args[0]
|
||||||
|
ports, err := client.GetProcessPorts(pcAddress, port, name)
|
||||||
|
if err != nil {
|
||||||
|
logFatal(err, "failed to get process %s ports", name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Info().Msgf("Process %s TCP ports: %v", name, ports.TcpPorts)
|
||||||
|
fmt.Printf("Process %s TCP ports: %v\n", name, ports.TcpPorts)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
processCmd.AddCommand(portsCmd)
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/f1bonacc1/process-compose/src/api"
|
"github.com/f1bonacc1/process-compose/src/api"
|
||||||
"github.com/f1bonacc1/process-compose/src/loader"
|
"github.com/f1bonacc1/process-compose/src/loader"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
@ -79,3 +80,10 @@ func getConfigDefault() []string {
|
|||||||
}
|
}
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func logFatal(err error, format string, args ...interface{}) {
|
||||||
|
fmt.Printf(format, args...)
|
||||||
|
fmt.Printf(": %v\n", err)
|
||||||
|
log.Err(err).Msgf(format, args...)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
@ -122,6 +122,35 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/process/ports/{name}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Retrieves process open ports",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Process"
|
||||||
|
],
|
||||||
|
"summary": "Get process ports",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Process Name",
|
||||||
|
"name": "name",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Process Ports",
|
||||||
|
"schema": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/process/restart/{name}": {
|
"/process/restart/{name}": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Restarts the process",
|
"description": "Restarts the process",
|
||||||
|
@ -110,6 +110,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/process/ports/{name}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Retrieves process open ports",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Process"
|
||||||
|
],
|
||||||
|
"summary": "Get process ports",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Process Name",
|
||||||
|
"name": "name",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Process Ports",
|
||||||
|
"schema": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/process/restart/{name}": {
|
"/process/restart/{name}": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Restarts the process",
|
"description": "Restarts the process",
|
||||||
|
@ -90,6 +90,25 @@ paths:
|
|||||||
summary: Get process logs
|
summary: Get process logs
|
||||||
tags:
|
tags:
|
||||||
- Process
|
- Process
|
||||||
|
/process/ports/{name}:
|
||||||
|
get:
|
||||||
|
description: Retrieves process open ports
|
||||||
|
parameters:
|
||||||
|
- description: Process Name
|
||||||
|
in: path
|
||||||
|
name: name
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Process Ports
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
summary: Get process ports
|
||||||
|
tags:
|
||||||
|
- Process
|
||||||
/process/restart/{name}:
|
/process/restart/{name}:
|
||||||
post:
|
post:
|
||||||
description: Restarts the process
|
description: Restarts the process
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (pv *pcView) createProcInfoForm(info *types.ProcessConfig) *tview.Form {
|
func (pv *pcView) createProcInfoForm(info *types.ProcessConfig, ports *types.ProcessPorts) *tview.Form {
|
||||||
f := tview.NewForm()
|
f := tview.NewForm()
|
||||||
f.SetCancelFunc(func() {
|
f.SetCancelFunc(func() {
|
||||||
pv.pages.RemovePage(PageDialog)
|
pv.pages.RemovePage(PageDialog)
|
||||||
@ -23,8 +23,11 @@ func (pv *pcView) createProcInfoForm(info *types.ProcessConfig) *tview.Form {
|
|||||||
addStringIfNotEmpty("Working Directory:", info.WorkingDir, f)
|
addStringIfNotEmpty("Working Directory:", info.WorkingDir, f)
|
||||||
addStringIfNotEmpty("Log Location:", info.LogLocation, f)
|
addStringIfNotEmpty("Log Location:", info.LogLocation, f)
|
||||||
f.AddInputField("Replica:", fmt.Sprintf("%d/%d", info.ReplicaNum+1, info.Replicas), 0, nil, nil)
|
f.AddInputField("Replica:", fmt.Sprintf("%d/%d", info.ReplicaNum+1, info.Replicas), 0, nil, nil)
|
||||||
addSliceIfNotEmpty("Environment:", info.Environment, f)
|
addDropDownIfNotEmpty("Environment:", info.Environment, f)
|
||||||
addSliceIfNotEmpty("Depends On:", mapKeysToSlice(info.DependsOn), f)
|
addCSVIfNotEmpty("Depends On:", mapKeysToSlice(info.DependsOn), f)
|
||||||
|
if ports != nil {
|
||||||
|
addCSVIfNotEmpty("TCP Ports:", ports.TcpPorts, f)
|
||||||
|
}
|
||||||
f.AddCheckbox("Is Disabled:", info.Disabled, nil)
|
f.AddCheckbox("Is Disabled:", info.Disabled, nil)
|
||||||
f.AddCheckbox("Is Daemon:", info.IsDaemon, nil)
|
f.AddCheckbox("Is Daemon:", info.IsDaemon, nil)
|
||||||
f.AddButton("Close", func() {
|
f.AddButton("Close", func() {
|
||||||
@ -40,12 +43,19 @@ func addStringIfNotEmpty(label, value string, f *tview.Form) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addSliceIfNotEmpty(label string, value []string, f *tview.Form) {
|
func addDropDownIfNotEmpty(label string, value []string, f *tview.Form) {
|
||||||
if len(value) > 0 {
|
if len(value) > 0 {
|
||||||
f.AddDropDown(label, value, 0, nil)
|
f.AddDropDown(label, value, 0, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addCSVIfNotEmpty[K comparable](label string, value []K, f *tview.Form) {
|
||||||
|
if len(value) > 0 {
|
||||||
|
csvPorts := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(value)), ":"), "[]")
|
||||||
|
f.AddInputField(label, csvPorts, 0, nil, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// mapKeysToSlice extract keys of map as slice,
|
// mapKeysToSlice extract keys of map as slice,
|
||||||
func mapKeysToSlice[K comparable, V any](m map[K]V) []K {
|
func mapKeysToSlice[K comparable, V any](m map[K]V) []K {
|
||||||
keys := make([]K, len(m))
|
keys := make([]K, len(m))
|
||||||
|
@ -246,7 +246,8 @@ func (pv *pcView) showInfo() {
|
|||||||
pv.showError(err.Error())
|
pv.showError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
form := pv.createProcInfoForm(info)
|
ports, _ := pv.project.GetProcessPorts(name)
|
||||||
|
form := pv.createProcInfoForm(info, ports)
|
||||||
pv.showDialog(form, 0, 0)
|
pv.showDialog(form, 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +83,12 @@ type ProcessState struct {
|
|||||||
IsRunning bool
|
IsRunning bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProcessPorts struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
TcpPorts []uint16 `json:"tcp_ports"`
|
||||||
|
UdpPorts []uint16 `json:"udp_ports"`
|
||||||
|
}
|
||||||
|
|
||||||
type ProcessesState struct {
|
type ProcessesState struct {
|
||||||
States []ProcessState `json:"data"`
|
States []ProcessState `json:"data"`
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user