diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b89f7722..7112ac11f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * The update command has been removed. It was non-functional, so this should not affect anyone * The adhoc, ping and playbook commands have been removed. These were ansible and vagrant commands that were not widely used. * Make the art command hidden, doesn't need to be removed, leave it as an easter egg +* Move ziti ps command under ziti agent. Remove all ziti ps subcommands, as they already exist as ziti agent subcommands # Release 0.26.11 diff --git a/ziti/cmd/ziti/cmd/agent.go b/ziti/cmd/ziti/cmd/agent.go deleted file mode 100644 index 932585ac7..000000000 --- a/ziti/cmd/ziti/cmd/agent.go +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright NetFoundry Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package cmd - -import ( - "github.com/openziti/edge/router/debugops" - "github.com/openziti/fabric/controller" - "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/fabric/router" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" - cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" - "github.com/spf13/cobra" -) - -type AgentAppId byte - -const ( - AgentAppController = AgentAppId(controller.AgentAppId) - AgentAppRouter = AgentAppId(router.AgentAppId) -) - -func NewAgentCmd(p common.OptionsProvider) *cobra.Command { - agentCmd := agentcli.NewAgentCmd(p) - - ctrlCmd := &cobra.Command{ - Use: "controller", - Aliases: []string{"c"}, - Short: "Interact with a ziti-controller process using the IPC agent", - Run: func(cmd *cobra.Command, args []string) { - cmdhelper.CheckErr(cmd.Help()) - }, - } - - agentCmd.AddCommand(ctrlCmd) - ctrlCmd.AddCommand(NewSimpleChAgentCustomCmd("snapshot-db", AgentAppController, int32(mgmt_pb.ContentType_SnapshotDbRequestType), p)) - ctrlCmd.AddCommand(NewAgentCtrlRaftJoin(p)) - ctrlCmd.AddCommand(NewAgentCtrlRaftList(p)) - ctrlCmd.AddCommand(NewAgentCtrlInit(p)) - - routerCmd := &cobra.Command{ - Use: "router", - Aliases: []string{"r"}, - Short: "Interact with a ziti-router process using the IPC agent", - Run: func(cmd *cobra.Command, args []string) { - cmdhelper.CheckErr(cmd.Help()) - }, - } - - agentCmd.AddCommand(routerCmd) - - routerCmd.AddCommand(NewRouteCmd(p)) - routerCmd.AddCommand(NewSimpleAgentCustomCmd("dump-routes", AgentAppRouter, router.DumpForwarderTables, p)) - routerCmd.AddCommand(NewSimpleAgentCustomCmd("disconnect", AgentAppRouter, router.CloseControlChannel, p)) - routerCmd.AddCommand(NewSimpleAgentCustomCmd("reconnect", AgentAppRouter, router.OpenControlChannel, p)) - routerCmd.AddCommand(NewSimpleAgentCustomCmd("dump-api-sessions", AgentAppRouter, debugops.DumpApiSessions, p)) - routerCmd.AddCommand(NewSimpleAgentCustomCmd("dump-links", AgentAppRouter, router.DumpLinks, p)) - routerCmd.AddCommand(NewForgetLinkAgentCmd(p)) - - return agentCmd -} diff --git a/ziti/cmd/ziti/cmd/agentcli/agent.go b/ziti/cmd/ziti/cmd/agentcli/agent.go index 1a2920072..6c39b6ea7 100644 --- a/ziti/cmd/ziti/cmd/agentcli/agent.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent.go @@ -1,8 +1,12 @@ package agentcli import ( - "github.com/openziti/channel/v2" "github.com/openziti/agent" + "github.com/openziti/channel/v2" + "github.com/openziti/edge/router/debugops" + "github.com/openziti/fabric/controller" + "github.com/openziti/fabric/pb/mgmt_pb" + "github.com/openziti/fabric/router" "github.com/openziti/identity" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" @@ -11,6 +15,13 @@ import ( "time" ) +type AgentAppId byte + +const ( + AgentAppController = AgentAppId(controller.AgentAppId) + AgentAppRouter = AgentAppId(router.AgentAppId) +) + func NewAgentCmd(p common.OptionsProvider) *cobra.Command { agentCmd := &cobra.Command{ Use: "agent", @@ -20,6 +31,7 @@ func NewAgentCmd(p common.OptionsProvider) *cobra.Command { }, } + agentCmd.AddCommand(NewPsCmd(p)) agentCmd.AddCommand(NewGoVersionCmd(p)) agentCmd.AddCommand(NewGcCmd(p)) agentCmd.AddCommand(NewSetGcCmd(p)) @@ -33,6 +45,40 @@ func NewAgentCmd(p common.OptionsProvider) *cobra.Command { agentCmd.AddCommand(NewSetChannelLogLevelCmd(p)) agentCmd.AddCommand(NewClearChannelLogLevelCmd(p)) + ctrlCmd := &cobra.Command{ + Use: "controller", + Aliases: []string{"c"}, + Short: "Interact with a ziti-controller process using the IPC agent", + Run: func(cmd *cobra.Command, args []string) { + cmdhelper.CheckErr(cmd.Help()) + }, + } + + agentCmd.AddCommand(ctrlCmd) + ctrlCmd.AddCommand(NewSimpleChAgentCustomCmd("snapshot-db", AgentAppController, int32(mgmt_pb.ContentType_SnapshotDbRequestType), p)) + ctrlCmd.AddCommand(NewAgentCtrlRaftJoin(p)) + ctrlCmd.AddCommand(NewAgentCtrlRaftList(p)) + ctrlCmd.AddCommand(NewAgentCtrlInit(p)) + + routerCmd := &cobra.Command{ + Use: "router", + Aliases: []string{"r"}, + Short: "Interact with a ziti-router process using the IPC agent", + Run: func(cmd *cobra.Command, args []string) { + cmdhelper.CheckErr(cmd.Help()) + }, + } + + agentCmd.AddCommand(routerCmd) + + routerCmd.AddCommand(NewRouteCmd(p)) + routerCmd.AddCommand(NewSimpleAgentCustomCmd("dump-routes", AgentAppRouter, router.DumpForwarderTables, p)) + routerCmd.AddCommand(NewSimpleAgentCustomCmd("disconnect", AgentAppRouter, router.CloseControlChannel, p)) + routerCmd.AddCommand(NewSimpleAgentCustomCmd("reconnect", AgentAppRouter, router.OpenControlChannel, p)) + routerCmd.AddCommand(NewSimpleAgentCustomCmd("dump-api-sessions", AgentAppRouter, debugops.DumpApiSessions, p)) + routerCmd.AddCommand(NewSimpleAgentCustomCmd("dump-links", AgentAppRouter, router.DumpLinks, p)) + routerCmd.AddCommand(NewForgetLinkAgentCmd(p)) + return agentCmd } diff --git a/ziti/cmd/ziti/cmd/agent_ch_simple.go b/ziti/cmd/ziti/cmd/agentcli/agent_ch_simple.go similarity index 94% rename from ziti/cmd/ziti/cmd/agent_ch_simple.go rename to ziti/cmd/ziti/cmd/agentcli/agent_ch_simple.go index be69c8fd8..a95323274 100644 --- a/ziti/cmd/ziti/cmd/agent_ch_simple.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_ch_simple.go @@ -14,14 +14,13 @@ limitations under the License. */ -package cmd +package agentcli import ( "fmt" - "github.com/openziti/channel/v2" "github.com/openziti/agent" + "github.com/openziti/channel/v2" "github.com/openziti/identity" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" @@ -30,13 +29,13 @@ import ( ) type SimpleChAgentCmdOptions struct { - agentcli.AgentOptions + AgentOptions requestType int32 } func NewSimpleChAgentCustomCmd(name string, appId AgentAppId, op int32, p common.OptionsProvider) *cobra.Command { options := &SimpleChAgentCmdOptions{ - AgentOptions: agentcli.AgentOptions{ + AgentOptions: AgentOptions{ CommonOptions: p(), }, requestType: op, diff --git a/ziti/cmd/ziti/cmd/agent_controller_init.go b/ziti/cmd/ziti/cmd/agentcli/agent_controller_init.go similarity index 95% rename from ziti/cmd/ziti/cmd/agent_controller_init.go rename to ziti/cmd/ziti/cmd/agentcli/agent_controller_init.go index f67f8e96f..bf3dc5779 100644 --- a/ziti/cmd/ziti/cmd/agent_controller_init.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_controller_init.go @@ -14,7 +14,7 @@ limitations under the License. */ -package cmd +package agentcli import ( "fmt" @@ -23,7 +23,6 @@ import ( "github.com/openziti/channel/v2/protobufs" "github.com/openziti/edge/pb/edge_mgmt_pb" "github.com/openziti/identity" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" @@ -32,12 +31,12 @@ import ( ) type AgentCtrlInitOptions struct { - agentcli.AgentOptions + AgentOptions } func NewAgentCtrlInit(p common.OptionsProvider) *cobra.Command { options := &AgentCtrlInitOptions{ - AgentOptions: agentcli.AgentOptions{ + AgentOptions: AgentOptions{ CommonOptions: p(), }, } diff --git a/ziti/cmd/ziti/cmd/agent_controller_raft_join.go b/ziti/cmd/ziti/cmd/agentcli/agent_controller_raft_join.go similarity index 95% rename from ziti/cmd/ziti/cmd/agent_controller_raft_join.go rename to ziti/cmd/ziti/cmd/agentcli/agent_controller_raft_join.go index 8aa981b28..d53141001 100644 --- a/ziti/cmd/ziti/cmd/agent_controller_raft_join.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_controller_raft_join.go @@ -14,7 +14,7 @@ limitations under the License. */ -package cmd +package agentcli import ( "fmt" @@ -23,7 +23,6 @@ import ( "github.com/openziti/fabric/controller" "github.com/openziti/fabric/pb/mgmt_pb" "github.com/openziti/identity" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" @@ -32,14 +31,14 @@ import ( ) type AgentCtrlRaftJoinOptions struct { - agentcli.AgentOptions + AgentOptions Voter bool MemberId string } func NewAgentCtrlRaftJoin(p common.OptionsProvider) *cobra.Command { options := &AgentCtrlRaftJoinOptions{ - AgentOptions: agentcli.AgentOptions{ + AgentOptions: AgentOptions{ CommonOptions: p(), }, } diff --git a/ziti/cmd/ziti/cmd/agent_controller_raft_list.go b/ziti/cmd/ziti/cmd/agentcli/agent_controller_raft_list.go similarity index 95% rename from ziti/cmd/ziti/cmd/agent_controller_raft_list.go rename to ziti/cmd/ziti/cmd/agentcli/agent_controller_raft_list.go index 46ff2e6d0..c615fe2fc 100644 --- a/ziti/cmd/ziti/cmd/agent_controller_raft_list.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_controller_raft_list.go @@ -14,16 +14,15 @@ limitations under the License. */ -package cmd +package agentcli import ( "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/agent" "github.com/openziti/channel/v2" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/agent" "github.com/openziti/identity" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" @@ -32,12 +31,12 @@ import ( ) type AgentCtrlRaftListOptions struct { - agentcli.AgentOptions + AgentOptions } func NewAgentCtrlRaftList(p common.OptionsProvider) *cobra.Command { options := &AgentCtrlRaftListOptions{ - AgentOptions: agentcli.AgentOptions{ + AgentOptions: AgentOptions{ CommonOptions: p(), }, } diff --git a/ziti/cmd/ziti/cmd/agentcli/agent_ps.go b/ziti/cmd/ziti/cmd/agentcli/agent_ps.go new file mode 100644 index 000000000..f29666c8c --- /dev/null +++ b/ziti/cmd/ziti/cmd/agentcli/agent_ps.go @@ -0,0 +1,262 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package agentcli + +import ( + "bytes" + "fmt" + "github.com/keybase/go-ps" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + "github.com/pkg/errors" + "github.com/spf13/cobra" + "os" + "os/user" + "path/filepath" + "regexp" + goversion "rsc.io/goversion/version" + "runtime" + "strconv" + "strings" + "sync" + + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" +) + +type AgentPsAction struct { + AgentOptions +} + +// NewPsCmd Pss a command object for the "Ps" command +func NewPsCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentPsAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), + }, + } + + cmd := &cobra.Command{ + Use: "ps", + Short: "Show Ziti process info", + Long: "Show information about currently running Ziti processes", + Run: func(cmd *cobra.Command, args []string) { + action.Cmd = cmd + action.Args = args + err := action.Run() + cmdhelper.CheckErr(err) + }, + } + + return cmd +} + +// Run implements this command +func (self *AgentPsAction) Run() error { + fmt.Println("ps is running") + ps := FindAll() + + var maxPID, maxPPID, maxExec, maxVersion int + for i, p := range ps { + + fmt.Println("p.Path is: " + p.Path) + + ps[i].BuildVersion = shortenVersion(p.BuildVersion) + maxPID = max(maxPID, len(strconv.Itoa(p.PID))) + maxPPID = max(maxPPID, len(strconv.Itoa(p.PPID))) + maxExec = max(maxExec, len(p.Exec)) + maxVersion = max(maxVersion, len(ps[i].BuildVersion)) + + } + + for _, p := range ps { + buf := bytes.NewBuffer(nil) + pid := strconv.Itoa(p.PID) + fmt.Fprint(buf, pad(pid, maxPID)) + fmt.Fprint(buf, " ") + + ppid := strconv.Itoa(p.PPID) + fmt.Fprint(buf, pad(ppid, maxPPID)) + fmt.Fprint(buf, " ") + + fmt.Fprint(buf, pad(p.Exec, maxExec)) + + if p.Agent { + fmt.Fprint(buf, "*") + } else { + fmt.Fprint(buf, " ") + } + fmt.Fprint(buf, " ") + + fmt.Fprint(buf, pad(p.BuildVersion, maxVersion)) + fmt.Fprint(buf, " ") + + fmt.Fprint(buf, p.Path) + fmt.Fprintln(buf) + buf.WriteTo(os.Stdout) + } + + return nil +} + +var develRe = regexp.MustCompile(`devel\s+\+\w+`) + +func shortenVersion(v string) string { + if !strings.HasPrefix(v, "devel") { + return v + } + results := develRe.FindAllString(v, 1) + if len(results) == 0 { + return v + } + return results[0] +} + +func pad(s string, total int) string { + if len(s) >= total { + return s + } + return s + strings.Repeat(" ", total-len(s)) +} + +func max(i, j int) int { + if i > j { + return i + } + return j +} + +// P represents a Go process. +type P struct { + PID int + PPID int + Exec string + Path string + BuildVersion string + Agent bool +} + +// FindAll returns all the Ziti processes currently running on this host. +func FindAll() []P { + pss, err := ps.Processes() + // fmt.Println("FindAll, err is: %s", err) + + if err != nil { + return nil + } + + var wg sync.WaitGroup + wg.Add(len(pss)) + found := make(chan P) + + for _, pr := range pss { + pr := pr + go func() { + defer wg.Done() + + path, version, agent, ok, err := isGo(pr) + if err != nil { + // TODO(jbd): Return a list of errors. + } + if !ok { + return + } + if isZiti(pr) { + found <- P{ + PID: pr.Pid(), + PPID: pr.PPid(), + Exec: pr.Executable(), + Path: path, + BuildVersion: version, + Agent: agent, + } + } + }() + } + go func() { + wg.Wait() + close(found) + }() + var results []P + for p := range found { + results = append(results, p) + } + return results +} + +// isGo looks up the runtime.buildVersion symbol +// in the process' binary and determines if the process +// if a Go process or not. If the process is a Go process, +// it reports PID, binary name and full path of the binary. +func isGo(pr ps.Process) (path, version string, agent, ok bool, err error) { + if pr.Pid() == 0 { + // ignore system process + return + } + path, err = pr.Path() + if err != nil { + return + } + var versionInfo goversion.Version + versionInfo, err = goversion.ReadExe(path) + if err != nil { + return + } + ok = true + version = versionInfo.Release + pidfile, err := PIDFile(pr.Pid()) + if err == nil { + _, err := os.Stat(pidfile) + agent = err == nil + } + return path, version, agent, ok, nil +} + +const gopsConfigDirEnvKey = "GOPS_CONFIG_DIR" + +func ConfigDir() (string, error) { + if configDir := os.Getenv(gopsConfigDirEnvKey); configDir != "" { + return configDir, nil + } + + if runtime.GOOS == "windows" { + return filepath.Join(os.Getenv("APPDATA"), "gops"), nil + } + homeDir := guessUnixHomeDir() + if homeDir == "" { + return "", errors.New("unable to get current user home directory: os/user lookup failed; $HOME is empty") + } + return filepath.Join(homeDir, ".config", "gops"), nil +} + +func guessUnixHomeDir() string { + usr, err := user.Current() + if err == nil { + return usr.HomeDir + } + return os.Getenv("HOME") +} + +func PIDFile(pid int) (string, error) { + gopsdir, err := ConfigDir() + if err != nil { + return "", err + } + return fmt.Sprintf("%s/%d", gopsdir, pid), nil +} + +func isZiti(pr ps.Process) (ok bool) { + return strings.HasPrefix(pr.Executable(), "ziti") +} diff --git a/ziti/cmd/ziti/cmd/agent_router_add_route.go b/ziti/cmd/ziti/cmd/agentcli/agent_router_add_route.go similarity index 94% rename from ziti/cmd/ziti/cmd/agent_router_add_route.go rename to ziti/cmd/ziti/cmd/agentcli/agent_router_add_route.go index 5277ae8b4..c604c20ae 100644 --- a/ziti/cmd/ziti/cmd/agent_router_add_route.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_router_add_route.go @@ -14,29 +14,28 @@ limitations under the License. */ -package cmd +package agentcli import ( "encoding/binary" - "google.golang.org/protobuf/proto" + "github.com/openziti/agent" "github.com/openziti/fabric/pb/ctrl_pb" "github.com/openziti/fabric/router" - "github.com/openziti/agent" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" + "google.golang.org/protobuf/proto" "os" ) type AgentRouteAction struct { - agentcli.AgentOptions + AgentOptions CtrlListener string } func NewRouteCmd(p common.OptionsProvider) *cobra.Command { options := &AgentRouteAction{ - AgentOptions: agentcli.AgentOptions{ + AgentOptions: AgentOptions{ CommonOptions: p(), }, } diff --git a/ziti/cmd/ziti/cmd/agent_router_forget_link.go b/ziti/cmd/ziti/cmd/agentcli/agent_router_forget_link.go similarity index 95% rename from ziti/cmd/ziti/cmd/agent_router_forget_link.go rename to ziti/cmd/ziti/cmd/agentcli/agent_router_forget_link.go index e8a7e70dd..8895ac0fd 100644 --- a/ziti/cmd/ziti/cmd/agent_router_forget_link.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_router_forget_link.go @@ -14,16 +14,15 @@ limitations under the License. */ -package cmd +package agentcli import ( "fmt" + "github.com/openziti/agent" "github.com/openziti/channel/v2" "github.com/openziti/fabric/pb/mgmt_pb" "github.com/openziti/fabric/router" - "github.com/openziti/agent" "github.com/openziti/identity" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" @@ -32,12 +31,12 @@ import ( ) type ForgetLinkAgentAction struct { - agentcli.AgentOptions + AgentOptions } func NewForgetLinkAgentCmd(p common.OptionsProvider) *cobra.Command { options := &ForgetLinkAgentAction{ - AgentOptions: agentcli.AgentOptions{ + AgentOptions: AgentOptions{ CommonOptions: p(), }, } diff --git a/ziti/cmd/ziti/cmd/agent_simple.go b/ziti/cmd/ziti/cmd/agentcli/agent_simple.go similarity index 92% rename from ziti/cmd/ziti/cmd/agent_simple.go rename to ziti/cmd/ziti/cmd/agentcli/agent_simple.go index 7aa4e20ad..a0fbded07 100644 --- a/ziti/cmd/ziti/cmd/agent_simple.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_simple.go @@ -14,11 +14,10 @@ limitations under the License. */ -package cmd +package agentcli import ( "github.com/openziti/agent" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" @@ -26,12 +25,12 @@ import ( ) type SimpleAgentAction struct { - agentcli.AgentOptions + AgentOptions } func NewSimpleAgentCustomCmd(name string, appId AgentAppId, op byte, p common.OptionsProvider) *cobra.Command { action := &SimpleAgentAction{ - AgentOptions: agentcli.AgentOptions{ + AgentOptions: AgentOptions{ CommonOptions: p(), }, } diff --git a/ziti/cmd/ziti/cmd/cmd.go b/ziti/cmd/ziti/cmd/cmd.go index 7ff1a2cb6..d2c1bffa1 100644 --- a/ziti/cmd/ziti/cmd/cmd.go +++ b/ziti/cmd/ziti/cmd/cmd.go @@ -19,6 +19,7 @@ package cmd import ( goflag "flag" "fmt" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" "io" "os" "path/filepath" @@ -124,8 +125,7 @@ func NewCmdRoot(in io.Reader, out, err io.Writer, cmd *cobra.Command) *cobra.Com initCommands := NewCmdInit(out, err) createCommands := NewCmdCreate(out, err) executeCommands := NewCmdExecute(out, err) - agentCommands := NewAgentCmd(p) - psCommands := NewCmdPs(p) + agentCommands := agentcli.NewAgentCmd(p) pkiCommands := NewCmdPKI(out, err) fabricCommand := fabric.NewFabricCmd(p) edgeCommand := edge.NewCmdEdge(out, err) @@ -158,7 +158,6 @@ func NewCmdRoot(in io.Reader, out, err io.Writer, cmd *cobra.Command) *cobra.Com Commands: []*cobra.Command{ executeCommands, agentCommands, - psCommands, pkiCommands, unwrapIdentityFileCommand, }, diff --git a/ziti/cmd/ziti/cmd/ps.go b/ziti/cmd/ziti/cmd/ps.go deleted file mode 100644 index b4ebb67b6..000000000 --- a/ziti/cmd/ziti/cmd/ps.go +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright NetFoundry Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package cmd - -import ( - "bytes" - "fmt" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" - "github.com/spf13/cobra" - "os" - "regexp" - "strconv" - "strings" - - cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" - "github.com/openziti/ziti/ziti/goprocess" -) - -type PsAction struct { - agentcli.AgentOptions -} - -// NewCmdPs Pss a command object for the "Ps" command -func NewCmdPs(p common.OptionsProvider) *cobra.Command { - action := &PsAction{ - AgentOptions: agentcli.AgentOptions{ - CommonOptions: p(), - }, - } - - cmd := &cobra.Command{ - Use: "ps", - Short: "Show Ziti process info", - Long: "Show information about currently running Ziti preocesses", - Run: func(cmd *cobra.Command, args []string) { - action.Cmd = cmd - action.Args = args - err := action.Run() - cmdhelper.CheckErr(err) - }, - } - - cmd.AddCommand(agentcli.NewGetCmd(p)) - cmd.AddCommand(agentcli.NewGoVersionCmd(p)) - cmd.AddCommand(agentcli.NewGcCmd(p)) - cmd.AddCommand(agentcli.NewSetGcCmd(p)) - cmd.AddCommand(agentcli.NewStackCmd(p)) - cmd.AddCommand(agentcli.NewMemstatsCmd(p)) - cmd.AddCommand(agentcli.NewStatsCmd(p)) - cmd.AddCommand(agentcli.NewPprofHeapCmd(p)) - cmd.AddCommand(agentcli.NewPprofCpuCmd(p)) - cmd.AddCommand(agentcli.NewTraceCmd(p)) - cmd.AddCommand(agentcli.NewSetLogLevelCmd(p)) - cmd.AddCommand(agentcli.NewSetChannelLogLevelCmd(p)) - cmd.AddCommand(agentcli.NewClearChannelLogLevelCmd(p)) - - return cmd -} - -// Run implements this command -func (self *PsAction) Run() error { - fmt.Println("ps is running") - ps := goprocess.FindAll() - - var maxPID, maxPPID, maxExec, maxVersion int - for i, p := range ps { - - fmt.Println("p.Path is: " + p.Path) - - ps[i].BuildVersion = shortenVersion(p.BuildVersion) - maxPID = max(maxPID, len(strconv.Itoa(p.PID))) - maxPPID = max(maxPPID, len(strconv.Itoa(p.PPID))) - maxExec = max(maxExec, len(p.Exec)) - maxVersion = max(maxVersion, len(ps[i].BuildVersion)) - - } - - for _, p := range ps { - buf := bytes.NewBuffer(nil) - pid := strconv.Itoa(p.PID) - fmt.Fprint(buf, pad(pid, maxPID)) - fmt.Fprint(buf, " ") - - ppid := strconv.Itoa(p.PPID) - fmt.Fprint(buf, pad(ppid, maxPPID)) - fmt.Fprint(buf, " ") - - fmt.Fprint(buf, pad(p.Exec, maxExec)) - - if p.Agent { - fmt.Fprint(buf, "*") - } else { - fmt.Fprint(buf, " ") - } - fmt.Fprint(buf, " ") - - fmt.Fprint(buf, pad(p.BuildVersion, maxVersion)) - fmt.Fprint(buf, " ") - - fmt.Fprint(buf, p.Path) - fmt.Fprintln(buf) - buf.WriteTo(os.Stdout) - } - - return nil -} - -var develRe = regexp.MustCompile(`devel\s+\+\w+`) - -func shortenVersion(v string) string { - if !strings.HasPrefix(v, "devel") { - return v - } - results := develRe.FindAllString(v, 1) - if len(results) == 0 { - return v - } - return results[0] -} - -func pad(s string, total int) string { - if len(s) >= total { - return s - } - return s + strings.Repeat(" ", total-len(s)) -} - -func max(i, j int) int { - if i > j { - return i - } - return j -} diff --git a/ziti/goprocess/gp.go b/ziti/goprocess/gp.go deleted file mode 100644 index 65ea71b4f..000000000 --- a/ziti/goprocess/gp.go +++ /dev/null @@ -1,141 +0,0 @@ -/* - Copyright NetFoundry Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package goprocess - -import ( - // "fmt" - "os" - "strings" - "sync" - - goversion "rsc.io/goversion/version" - - "github.com/openziti/ziti/ziti/util" - ps "github.com/keybase/go-ps" -) - -// P represents a Go process. -type P struct { - PID int - PPID int - Exec string - Path string - BuildVersion string - Agent bool -} - -// FindAll returns all the Ziti processes currently running on this host. -func FindAll() []P { - pss, err := ps.Processes() - // fmt.Println("FindAll, err is: %s", err) - - if err != nil { - return nil - } - - var wg sync.WaitGroup - wg.Add(len(pss)) - found := make(chan P) - - for _, pr := range pss { - pr := pr - go func() { - defer wg.Done() - - path, version, agent, ok, err := isGo(pr) - if err != nil { - // TODO(jbd): Return a list of errors. - } - if !ok { - return - } - if isZiti(pr) { - found <- P{ - PID: pr.Pid(), - PPID: pr.PPid(), - Exec: pr.Executable(), - Path: path, - BuildVersion: version, - Agent: agent, - } - } - }() - } - go func() { - wg.Wait() - close(found) - }() - var results []P - for p := range found { - results = append(results, p) - } - return results -} - -// Find finds info about the process identified with the given PID. -func Find(pid int) (p P, ok bool, err error) { - pr, err := ps.FindProcess(pid) - if err != nil { - return P{}, false, err - } - path, version, agent, ok, err := isGo(pr) - if !ok { - return P{}, false, nil - } - return P{ - PID: pr.Pid(), - PPID: pr.PPid(), - Exec: pr.Executable(), - Path: path, - BuildVersion: version, - Agent: agent, - }, true, nil -} - -// isGo looks up the runtime.buildVersion symbol -// in the process' binary and determines if the process -// if a Go process or not. If the process is a Go process, -// it reports PID, binary name and full path of the binary. -func isGo(pr ps.Process) (path, version string, agent, ok bool, err error) { - if pr.Pid() == 0 { - // ignore system process - return - } - path, err = pr.Path() - if err != nil { - return - } - var versionInfo goversion.Version - versionInfo, err = goversion.ReadExe(path) - if err != nil { - return - } - ok = true - version = versionInfo.Release - pidfile, err := util.PIDFile(pr.Pid()) - if err == nil { - _, err := os.Stat(pidfile) - agent = err == nil - } - return path, version, agent, ok, nil -} - -func isZiti(pr ps.Process) (ok bool) { - // fmt.Println("isZiti, pr.Executable(): %s", pr.Executable()) - - return strings.HasPrefix(pr.Executable(), "ziti-") -} diff --git a/ziti/util/util.go b/ziti/util/util.go deleted file mode 100644 index e20959678..000000000 --- a/ziti/util/util.go +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright NetFoundry Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package util - -import ( - "errors" - "fmt" - "io/ioutil" - "os" - "os/user" - "path/filepath" - "runtime" - "strings" -) - -const gopsConfigDirEnvKey = "GOPS_CONFIG_DIR" - -func ConfigDir() (string, error) { - if configDir := os.Getenv(gopsConfigDirEnvKey); configDir != "" { - return configDir, nil - } - - if runtime.GOOS == "windows" { - return filepath.Join(os.Getenv("APPDATA"), "gops"), nil - } - homeDir := guessUnixHomeDir() - if homeDir == "" { - return "", errors.New("unable to get current user home directory: os/user lookup failed; $HOME is empty") - } - return filepath.Join(homeDir, ".config", "gops"), nil -} - -func guessUnixHomeDir() string { - usr, err := user.Current() - if err == nil { - return usr.HomeDir - } - return os.Getenv("HOME") -} - -func PIDFile(pid int) (string, error) { - gopsdir, err := ConfigDir() - if err != nil { - return "", err - } - return fmt.Sprintf("%s/%d", gopsdir, pid), nil -} - -func GetPort(pid int) (string, error) { - portfile, err := PIDFile(pid) - if err != nil { - return "", err - } - b, err := ioutil.ReadFile(portfile) - if err != nil { - return "", err - } - port := strings.TrimSpace(string(b)) - return port, nil -}