From 6a1e1d669d5eba0d2f0a53e8df099ff38dc062b0 Mon Sep 17 00:00:00 2001 From: Nativu5 <44155313+Nativu5@users.noreply.github.com> Date: Wed, 5 Jun 2024 22:34:45 +0800 Subject: [PATCH 1/4] Rebased --- internal/cacctmgr/CmdArgParser.go | 10 +++++++ internal/cacctmgr/cacctmgr.go | 45 +++++++++++++++++++++++++++++++ internal/ccontrol/ccontrol.go | 1 + internal/cinfo/cinfo.go | 10 +++++-- protos/Crane.proto | 2 ++ protos/PublicDefs.proto | 12 +++++++++ 6 files changed, 78 insertions(+), 2 deletions(-) diff --git a/internal/cacctmgr/CmdArgParser.go b/internal/cacctmgr/CmdArgParser.go index 2661cd16..c330fe4e 100644 --- a/internal/cacctmgr/CmdArgParser.go +++ b/internal/cacctmgr/CmdArgParser.go @@ -341,6 +341,7 @@ var ( os.Exit(err) } } + ShowUser("", FlagAccountName) }, } findQosCmd = &cobra.Command{ @@ -360,6 +361,15 @@ var ( } }, } + showEventCmd = &cobra.Command{ + Use: "event", + Short: "Display event table", + Long: "", + Run: func(cmd *cobra.Command, args []string) { + ShowEvents() + }, + } + /* --------------------------------------------------- block ---------------------------------------------------- */ blockCmd = &cobra.Command{ Use: "block", diff --git a/internal/cacctmgr/cacctmgr.go b/internal/cacctmgr/cacctmgr.go index 276b08e3..9662dbc8 100644 --- a/internal/cacctmgr/cacctmgr.go +++ b/internal/cacctmgr/cacctmgr.go @@ -28,6 +28,8 @@ import ( "strconv" "strings" + "time" + "github.com/olekukonko/tablewriter" log "github.com/sirupsen/logrus" "github.com/xlab/treeprint" @@ -278,6 +280,33 @@ func PrintAccountTable(accountList []*protos.AccountInfo) { table.Render() } +func PrintAllEvents(eventList []*protos.EventInfo) { + table := tablewriter.NewWriter(os.Stdout) //table format control + util.SetBorderTable(table) + header := []string{"Cluster", "Node", "StartTime", "EndTime", "State", "Reason", "Uid"} + tableData := make([][]string, len(eventList)) + for _, eventInfo := range eventList { + var endTime string + if eventInfo.StartTime == eventInfo.EndTime { + endTime = "Unknown" + } else { + endTime = eventInfo.EndTime.AsTime().In(time.Local).String() + } + tableData = append(tableData, []string{ + eventInfo.ClusterName, + eventInfo.NodeName, + eventInfo.StartTime.AsTime().In(time.Local).String(), + endTime, + eventInfo.State.String(), + eventInfo.Reason, + strconv.FormatUint(uint64(eventInfo.Uid), 10), + }) + } + table.SetHeader(header) + table.AppendBulk(tableData) + table.Render() +} + func PraseAccountTree(parentTreeRoot treeprint.Tree, account string, accountMap map[string]*protos.AccountInfo) { if account == "" { return @@ -571,6 +600,22 @@ func ShowAccounts() util.CraneCmdError { } } +func ShowEvents() { + var req *protos.QueryEntityInfoRequest + req = &protos.QueryEntityInfoRequest{Uid: userUid, EntityType: protos.EntityType_Event} + reply, err := stub.QueryEntityInfo(context.Background(), req) + if err != nil { + util.GrpcErrorPrintf(err, "Fail to show events") + } + + if reply.GetOk() { + PrintAllEvents(reply.EventList) + } else { + fmt.Println(reply.Reason) + } + +} + func ShowUser(name string, account string) util.CraneCmdError { req := protos.QueryEntityInfoRequest{Uid: userUid, EntityType: protos.EntityType_User, Name: name, Account: account} reply, err := stub.QueryEntityInfo(context.Background(), &req) diff --git a/internal/ccontrol/ccontrol.go b/internal/ccontrol/ccontrol.go index 471101cd..6747828b 100755 --- a/internal/ccontrol/ccontrol.go +++ b/internal/ccontrol/ccontrol.go @@ -346,6 +346,7 @@ func ChangeNodeState(nodeName string, state string, reason string) util.CraneCmd log.Errorf("Invalid state given: %s. Valid states are: drain, resume.\n", state) return util.ErrorCmdArg } + req.Uid = uint32(os.Geteuid()) reply, err := stub.ModifyNode(context.Background(), req) if err != nil { diff --git a/internal/cinfo/cinfo.go b/internal/cinfo/cinfo.go index 325b0b5d..cdfb06ae 100644 --- a/internal/cinfo/cinfo.go +++ b/internal/cinfo/cinfo.go @@ -98,9 +98,15 @@ func cinfoFunc() util.CraneCmdError { table := tablewriter.NewWriter(os.Stdout) util.SetBorderlessTable(table) var tableData [][]string - table.SetHeader([]string{"PARTITION", "AVAIL", "TIMELIMIT", "NODES", "STATE", "NODELIST"}) + table.SetHeader([]string{"PARTITION", "AVAIL", "TIMELIMIT", "NODES", "STATE", "NODELIST(REASON)"}) for _, partitionCraned := range reply.Partitions { for _, commonCranedStateList := range partitionCraned.CranedLists { + var nodelistReason string + if commonCranedStateList.State == protos.CranedState_CRANE_DRAIN { + nodelistReason = commonCranedStateList.Reason + } else { + nodelistReason = commonCranedStateList.CranedListRegex + } if commonCranedStateList.Count > 0 { tableData = append(tableData, []string{ partitionCraned.Name, @@ -108,7 +114,7 @@ func cinfoFunc() util.CraneCmdError { "infinite", strconv.FormatUint(uint64(commonCranedStateList.Count), 10), strings.ToLower(commonCranedStateList.State.String()[6:]), - commonCranedStateList.CranedListRegex, + nodelistReason, }) } } diff --git a/protos/Crane.proto b/protos/Crane.proto index 6e6fadc6..3765826c 100644 --- a/protos/Crane.proto +++ b/protos/Crane.proto @@ -284,6 +284,7 @@ message ModifyCranedStateRequest{ string craned_id = 1; CranedState new_state = 2; string reason = 3; + uint32 uid = 4; } message ModifyCranedStateReply{ @@ -370,6 +371,7 @@ message QueryEntityInfoReply { repeated UserInfo user_list = 3; repeated AccountInfo account_list = 4; repeated QosInfo qos_list = 5; + repeated EventInfo event_list =6; } message BlockAccountOrUserRequest { diff --git a/protos/PublicDefs.proto b/protos/PublicDefs.proto index 517139a9..62c2f914 100644 --- a/protos/PublicDefs.proto +++ b/protos/PublicDefs.proto @@ -241,6 +241,7 @@ message TrimmedPartitionInfo { CranedState state = 1; uint32 count = 2; string craned_list_regex = 3; + string reason =4; } string name = 1; @@ -252,6 +253,7 @@ enum EntityType { Account = 0; User = 1; Qos = 2; + Event = 3; } message AccountInfo { @@ -307,6 +309,16 @@ message QosInfo { uint64 max_time_limit_per_task = 6; } +message EventInfo { + google.protobuf.Timestamp start_time = 1; + google.protobuf.Timestamp end_time = 2; + string node_name = 3; + string cluster_name =4; + string reason = 5; + CranedState state = 6; + uint32 uid =7; +} + message TimeInterval { google.protobuf.Timestamp lower_bound = 1; google.protobuf.Timestamp upper_bound = 2; From 8531be24472f87e4458d24e4654fd533da21eed0 Mon Sep 17 00:00:00 2001 From: Nativu5 <44155313+Nativu5@users.noreply.github.com> Date: Wed, 5 Jun 2024 22:37:28 +0800 Subject: [PATCH 2/4] Refactored. --- internal/cacctmgr/cacctmgr.go | 73 +++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 20 deletions(-) diff --git a/internal/cacctmgr/cacctmgr.go b/internal/cacctmgr/cacctmgr.go index 9662dbc8..6bb8337f 100644 --- a/internal/cacctmgr/cacctmgr.go +++ b/internal/cacctmgr/cacctmgr.go @@ -280,22 +280,69 @@ func PrintAccountTable(accountList []*protos.AccountInfo) { table.Render() } +//func PrintAllEvents(eventList []*protos.EventInfo) { +// table := tablewriter.NewWriter(os.Stdout) //table format control +// util.SetBorderTable(table) +// header := []string{"Node", "StartTime", "EndTime", "State", "Reason", "Uid"} +// tableData := make([][]string, len(eventList)) +// for _, eventInfo := range eventList { +// var endTime string +// if eventInfo.StartTime == eventInfo.EndTime { +// endTime = "Unknown" +// } else { +// endTime = eventInfo.EndTime.AsTime().In(time.Local).Format("2006-01-02 15:04:05") +// } +// tableData = append(tableData, []string{ +// //eventInfo.ClusterName, +// eventInfo.NodeName, +// eventInfo.StartTime.AsTime().In(time.Local).Format("2006-01-02 15:04:05"), +// endTime, +// eventInfo.State.String(), +// eventInfo.Reason, +// strconv.FormatUint(uint64(eventInfo.Uid), 10), +// }) +// } +// table.SetHeader(header) +// table.AppendBulk(tableData) +// table.Render() +//} + +func PraseAccountTree(parentTreeRoot treeprint.Tree, account string, accountMap map[string]*protos.AccountInfo) { + if account == "" { + return + } + if len(accountMap[account].ChildAccounts) == 0 { + parentTreeRoot.AddNode(account) + } else { + branch := parentTreeRoot.AddBranch(account) + for _, child := range accountMap[account].ChildAccounts { + PraseAccountTree(branch, child, accountMap) + } + } +} + func PrintAllEvents(eventList []*protos.EventInfo) { + sort.Slice(eventList, func(i, j int) bool { + return eventList[i].StartTime.AsTime().After(eventList[j].StartTime.AsTime()) + }) + if len(eventList) > 100 { + eventList = eventList[:100] + } + table := tablewriter.NewWriter(os.Stdout) //table format control util.SetBorderTable(table) - header := []string{"Cluster", "Node", "StartTime", "EndTime", "State", "Reason", "Uid"} - tableData := make([][]string, len(eventList)) + header := []string{"Node", "StartTime", "EndTime", "State", "Reason", "Uid"} + tableData := make([][]string, 0, len(eventList)) // 根据实际事件数量初始化 for _, eventInfo := range eventList { var endTime string - if eventInfo.StartTime == eventInfo.EndTime { + if eventInfo.EndTime.AsTime().Year() == 1970 { endTime = "Unknown" } else { - endTime = eventInfo.EndTime.AsTime().In(time.Local).String() + endTime = eventInfo.EndTime.AsTime().In(time.Local).Format("2006-01-02 15:04:05") } tableData = append(tableData, []string{ - eventInfo.ClusterName, eventInfo.NodeName, - eventInfo.StartTime.AsTime().In(time.Local).String(), + eventInfo.StartTime.AsTime().In(time.Local).Format("2006-01-02 15:04:05"), endTime, eventInfo.State.String(), eventInfo.Reason, @@ -307,20 +354,6 @@ func PrintAllEvents(eventList []*protos.EventInfo) { table.Render() } -func PraseAccountTree(parentTreeRoot treeprint.Tree, account string, accountMap map[string]*protos.AccountInfo) { - if account == "" { - return - } - if len(accountMap[account].ChildAccounts) == 0 { - parentTreeRoot.AddNode(account) - } else { - branch := parentTreeRoot.AddBranch(account) - for _, child := range accountMap[account].ChildAccounts { - PraseAccountTree(branch, child, accountMap) - } - } -} - func AddAccount(account *protos.AccountInfo) util.CraneCmdError { // FIXME: Move name validation to the backend? // FIXME: Seperate this to Args of cobra package? From b02df2e40762b4d5de7dc3460eca24b0fbec6742 Mon Sep 17 00:00:00 2001 From: June19980 <946672819@qq.com> Date: Wed, 8 May 2024 02:12:00 +0800 Subject: [PATCH 3/4] show event --- internal/cacctmgr/cacctmgr.go | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/internal/cacctmgr/cacctmgr.go b/internal/cacctmgr/cacctmgr.go index 6bb8337f..a6084cbb 100644 --- a/internal/cacctmgr/cacctmgr.go +++ b/internal/cacctmgr/cacctmgr.go @@ -280,33 +280,6 @@ func PrintAccountTable(accountList []*protos.AccountInfo) { table.Render() } -//func PrintAllEvents(eventList []*protos.EventInfo) { -// table := tablewriter.NewWriter(os.Stdout) //table format control -// util.SetBorderTable(table) -// header := []string{"Node", "StartTime", "EndTime", "State", "Reason", "Uid"} -// tableData := make([][]string, len(eventList)) -// for _, eventInfo := range eventList { -// var endTime string -// if eventInfo.StartTime == eventInfo.EndTime { -// endTime = "Unknown" -// } else { -// endTime = eventInfo.EndTime.AsTime().In(time.Local).Format("2006-01-02 15:04:05") -// } -// tableData = append(tableData, []string{ -// //eventInfo.ClusterName, -// eventInfo.NodeName, -// eventInfo.StartTime.AsTime().In(time.Local).Format("2006-01-02 15:04:05"), -// endTime, -// eventInfo.State.String(), -// eventInfo.Reason, -// strconv.FormatUint(uint64(eventInfo.Uid), 10), -// }) -// } -// table.SetHeader(header) -// table.AppendBulk(tableData) -// table.Render() -//} - func PraseAccountTree(parentTreeRoot treeprint.Tree, account string, accountMap map[string]*protos.AccountInfo) { if account == "" { return @@ -329,10 +302,10 @@ func PrintAllEvents(eventList []*protos.EventInfo) { eventList = eventList[:100] } - table := tablewriter.NewWriter(os.Stdout) //table format control + table := tablewriter.NewWriter(os.Stdout) util.SetBorderTable(table) header := []string{"Node", "StartTime", "EndTime", "State", "Reason", "Uid"} - tableData := make([][]string, 0, len(eventList)) // 根据实际事件数量初始化 + tableData := make([][]string, 0, len(eventList)) for _, eventInfo := range eventList { var endTime string if eventInfo.EndTime.AsTime().Year() == 1970 { From 31ca2a72545074f2b0ff0e4b0f84e8b3d4618917 Mon Sep 17 00:00:00 2001 From: Nativu5 <44155313+Nativu5@users.noreply.github.com> Date: Wed, 5 Jun 2024 22:55:58 +0800 Subject: [PATCH 4/4] Fix minor typos --- internal/cacctmgr/CmdArgParser.go | 25 +++++++++++++------------ internal/cacctmgr/cacctmgr.go | 9 +++++---- internal/ccontrol/ccontrol.go | 6 ++++-- internal/cinfo/cinfo.go | 10 +++++----- protos/Crane.proto | 2 +- protos/PublicDefs.proto | 4 ++-- 6 files changed, 30 insertions(+), 26 deletions(-) diff --git a/internal/cacctmgr/CmdArgParser.go b/internal/cacctmgr/CmdArgParser.go index c330fe4e..a89229b8 100644 --- a/internal/cacctmgr/CmdArgParser.go +++ b/internal/cacctmgr/CmdArgParser.go @@ -299,15 +299,15 @@ var ( }, } - /* ---------------------------------------------------- find ---------------------------------------------------- */ - findCmd = &cobra.Command{ + /* ---------------------------------------------------- show/find ---------------------------------------------------- */ + showCmd = &cobra.Command{ Use: "show", Aliases: []string{"search", "query", "find"}, SilenceErrors: true, - Short: "Find a specific entity", + Short: "Show or find information of entities", Long: "", } - findAccountCmd = &cobra.Command{ + showAccountCmd = &cobra.Command{ Use: "account", Aliases: []string{"accounts"}, Short: "Find and display information of account", @@ -325,7 +325,7 @@ var ( } }, } - findUserCmd = &cobra.Command{ + showUserCmd = &cobra.Command{ Use: "user", Aliases: []string{"users"}, Short: "Find and display information of user", @@ -344,7 +344,7 @@ var ( ShowUser("", FlagAccountName) }, } - findQosCmd = &cobra.Command{ + showQosCmd = &cobra.Command{ Use: "qos [flags] name", Short: "Find and display information of a specific QoS", Long: "", @@ -578,14 +578,15 @@ func init() { } } - /* ---------------------------------------------------- find ---------------------------------------------------- */ - RootCmd.AddCommand(findCmd) + /* ---------------------------------------------------- show/find ---------------------------------------------------- */ + RootCmd.AddCommand(showCmd) { - findCmd.AddCommand(findAccountCmd) - findCmd.AddCommand(findQosCmd) - findCmd.AddCommand(findUserCmd) + showCmd.AddCommand(showAccountCmd) + showCmd.AddCommand(showQosCmd) + showCmd.AddCommand(showEventCmd) + showCmd.AddCommand(showUserCmd) { - findUserCmd.Flags().StringVarP(&FlagAccountName, "account", "A", "", "Display the user under the specified account") + showUserCmd.Flags().StringVarP(&FlagAccountName, "account", "A", "", "Display the user under the specified account") } } diff --git a/internal/cacctmgr/cacctmgr.go b/internal/cacctmgr/cacctmgr.go index a6084cbb..a1f6da10 100644 --- a/internal/cacctmgr/cacctmgr.go +++ b/internal/cacctmgr/cacctmgr.go @@ -606,20 +606,21 @@ func ShowAccounts() util.CraneCmdError { } } -func ShowEvents() { - var req *protos.QueryEntityInfoRequest - req = &protos.QueryEntityInfoRequest{Uid: userUid, EntityType: protos.EntityType_Event} +func ShowEvents() util.CraneCmdError { + req := &protos.QueryEntityInfoRequest{Uid: userUid, EntityType: protos.EntityType_Event} reply, err := stub.QueryEntityInfo(context.Background(), req) if err != nil { util.GrpcErrorPrintf(err, "Fail to show events") + return util.ErrorNetwork } if reply.GetOk() { PrintAllEvents(reply.EventList) + return util.ErrorSuccess } else { fmt.Println(reply.Reason) + return util.ErrorBackend } - } func ShowUser(name string, account string) util.CraneCmdError { diff --git a/internal/ccontrol/ccontrol.go b/internal/ccontrol/ccontrol.go index 6747828b..fe0309de 100755 --- a/internal/ccontrol/ccontrol.go +++ b/internal/ccontrol/ccontrol.go @@ -323,7 +323,10 @@ func ChangeTaskPriority(taskId uint32, priority float64) util.CraneCmdError { } func ChangeNodeState(nodeName string, state string, reason string) util.CraneCmdError { - var req = &protos.ModifyCranedStateRequest{} + req := &protos.ModifyCranedStateRequest{ + Uid: uint32(os.Getuid()), + } + if nodeName == "" { log.Errorln("No valid node name in update node command. Specify node names by -n or --name.") return util.ErrorCmdArg @@ -346,7 +349,6 @@ func ChangeNodeState(nodeName string, state string, reason string) util.CraneCmd log.Errorf("Invalid state given: %s. Valid states are: drain, resume.\n", state) return util.ErrorCmdArg } - req.Uid = uint32(os.Geteuid()) reply, err := stub.ModifyNode(context.Background(), req) if err != nil { diff --git a/internal/cinfo/cinfo.go b/internal/cinfo/cinfo.go index cdfb06ae..ef2a86d3 100644 --- a/internal/cinfo/cinfo.go +++ b/internal/cinfo/cinfo.go @@ -101,11 +101,11 @@ func cinfoFunc() util.CraneCmdError { table.SetHeader([]string{"PARTITION", "AVAIL", "TIMELIMIT", "NODES", "STATE", "NODELIST(REASON)"}) for _, partitionCraned := range reply.Partitions { for _, commonCranedStateList := range partitionCraned.CranedLists { - var nodelistReason string - if commonCranedStateList.State == protos.CranedState_CRANE_DRAIN { - nodelistReason = commonCranedStateList.Reason + nodeListReason := "" + if commonCranedStateList.Reason != "" { + nodeListReason = fmt.Sprintf("%s(%s)", commonCranedStateList.CranedListRegex, commonCranedStateList.Reason) } else { - nodelistReason = commonCranedStateList.CranedListRegex + nodeListReason = commonCranedStateList.CranedListRegex } if commonCranedStateList.Count > 0 { tableData = append(tableData, []string{ @@ -114,7 +114,7 @@ func cinfoFunc() util.CraneCmdError { "infinite", strconv.FormatUint(uint64(commonCranedStateList.Count), 10), strings.ToLower(commonCranedStateList.State.String()[6:]), - nodelistReason, + nodeListReason, }) } } diff --git a/protos/Crane.proto b/protos/Crane.proto index 3765826c..d0258323 100644 --- a/protos/Crane.proto +++ b/protos/Crane.proto @@ -371,7 +371,7 @@ message QueryEntityInfoReply { repeated UserInfo user_list = 3; repeated AccountInfo account_list = 4; repeated QosInfo qos_list = 5; - repeated EventInfo event_list =6; + repeated EventInfo event_list = 6; } message BlockAccountOrUserRequest { diff --git a/protos/PublicDefs.proto b/protos/PublicDefs.proto index 62c2f914..6ac50187 100644 --- a/protos/PublicDefs.proto +++ b/protos/PublicDefs.proto @@ -241,7 +241,7 @@ message TrimmedPartitionInfo { CranedState state = 1; uint32 count = 2; string craned_list_regex = 3; - string reason =4; + string reason = 4; } string name = 1; @@ -316,7 +316,7 @@ message EventInfo { string cluster_name =4; string reason = 5; CranedState state = 6; - uint32 uid =7; + uint32 uid = 7; } message TimeInterval {