From fd9610fcf9be9dbf0acbbca1a2f83079e361cd08 Mon Sep 17 00:00:00 2001 From: Yongkun Li <44155313+Nativu5@users.noreply.github.com> Date: Fri, 27 Dec 2024 17:28:01 +0800 Subject: [PATCH 1/3] feat: Add STRIP option in Makefile (#231) --- Makefile | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 4120d3ce..702415f1 100644 --- a/Makefile +++ b/Makefile @@ -27,9 +27,19 @@ GIT_COMMIT_HASH := $(shell git rev-parse --short HEAD) VERSION_FILE := VERSION VERSION := $(shell [ -f $(VERSION_FILE) ] && cat $(VERSION_FILE) || echo $(GIT_COMMIT_HASH)) BUILD_TIME := $(shell date +'%a, %d %b %Y %H:%M:%S %z') -LDFLAGS := -ldflags \ - "-X 'CraneFrontEnd/internal/util.VERSION=$(VERSION)' \ - -X 'CraneFrontEnd/internal/util.BUILD_TIME=$(BUILD_TIME)'" +STRIP ?= false + +# LDFLAGS adjustments based on STRIP +ifeq ($(STRIP), true) + LDFLAGS := -ldflags \ + "-s -w -X 'CraneFrontEnd/internal/util.VERSION=$(VERSION)' \ + -X 'CraneFrontEnd/internal/util.BUILD_TIME=$(BUILD_TIME)'" +else + LDFLAGS := -ldflags \ + "-X 'CraneFrontEnd/internal/util.VERSION=$(VERSION)' \ + -X 'CraneFrontEnd/internal/util.BUILD_TIME=$(BUILD_TIME)'" +endif + BIN_DIR := build/bin PLUGIN_DIR := build/plugin @@ -74,7 +84,7 @@ build: plugin: plugin-energy plugin-other plugin-energy: - @echo "Building energy plugin with $(GO_VERSION)..." + @echo "- Building energy plugin with $(GO_VERSION)..." @mkdir -p $(PLUGIN_DIR) @cd plugin/energy && \ if [ -n "$(CHECK_GPU)" ]; then \ @@ -90,11 +100,11 @@ plugin-energy: fi plugin-other: - @echo " - Building other plugins..." + @echo "- Building other plugins..." @mkdir -p $(PLUGIN_DIR) @for dir in plugin/*/ ; do \ if [ "$$(basename $$dir)" != "energy" ]; then \ - echo " - Building: $$(basename $$dir).so"; \ + echo " - Building: $$(basename $$dir).so"; \ (cd $$dir && $(COMMON_ENV) $(GO) build $(BUILD_FLAGS) $(LDFLAGS) \ -buildmode=plugin -o ../../$(PLUGIN_DIR)/$$(basename $$dir).so) || exit 1; \ fi \ From 2832d149ef6e36f8aa03adce422f8356fed29ce8 Mon Sep 17 00:00:00 2001 From: Yongkun Li <44155313+Nativu5@users.noreply.github.com> Date: Sat, 28 Dec 2024 00:53:31 +0800 Subject: [PATCH 2/3] feat: Add multiple GID support (#229) * feat: Get egid when submitting task * chore: Sync protos * chore: Sync protos * fix: Fix bug in proto jsonify --- .gitignore | 1 + internal/cacctmgr/CmdArgParser.go | 4 ++-- internal/cacctmgr/cacctmgr.go | 2 +- internal/calloc/calloc.go | 4 ++++ internal/cbatch/CmdArgParser.go | 1 + internal/ccontrol/ccontrol.go | 32 +++++++++++++++---------------- internal/cqueue/cqueue.go | 2 +- internal/crun/crun.go | 2 ++ internal/util/formatter.go | 7 ++++++- internal/util/string.go | 14 +++++++------- internal/util/util.go | 9 ++++++--- protos/PublicDefs.proto | 22 +++++++++++---------- 12 files changed, 58 insertions(+), 42 deletions(-) diff --git a/.gitignore b/.gitignore index ae15be48..e98cbb23 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ bin # Testing testcase +*.out diff --git a/internal/cacctmgr/CmdArgParser.go b/internal/cacctmgr/CmdArgParser.go index 69e42216..66c37a7c 100644 --- a/internal/cacctmgr/CmdArgParser.go +++ b/internal/cacctmgr/CmdArgParser.go @@ -487,7 +487,7 @@ func init() { addQosCmd.Flags().Uint32VarP(&FlagQos.Priority, "priority", "P", 0, "Set job priority of the QoS") addQosCmd.Flags().Uint32VarP(&FlagQos.MaxJobsPerUser, "max-jobs-per-user", "J", math.MaxUint32, "Set the maximum number of jobs per user") addQosCmd.Flags().Uint32VarP(&FlagQos.MaxCpusPerUser, "max-cpus-per-user", "c", math.MaxUint32, "Set the maximum number of CPUs per user") - addQosCmd.Flags().Uint64VarP(&FlagQos.MaxTimeLimitPerTask, "max-time-limit-per-task", "T", uint64(util.InvalidDuration().Seconds), "Set the maximum time limit per job (in seconds)") + addQosCmd.Flags().Uint64VarP(&FlagQos.MaxTimeLimitPerTask, "max-time-limit-per-task", "T", util.MaxJobTimeLimit, "Set the maximum time limit per job (in seconds)") if err := addQosCmd.MarkFlagRequired("name"); err != nil { log.Fatalln("Can't mark 'name' flag required") } @@ -599,7 +599,7 @@ func init() { modifyQosCmd.Flags().Uint32VarP(&FlagQos.Priority, "priority", "P", 0, "Set job priority of the QoS") modifyQosCmd.Flags().Uint32VarP(&FlagQos.MaxJobsPerUser, "max-jobs-per-user", "J", math.MaxUint32, "Set the maximum number of jobs per user") modifyQosCmd.Flags().Uint32VarP(&FlagQos.MaxCpusPerUser, "max-cpus-per-user", "c", math.MaxUint32, "Set the maximum number of CPUs per user") - modifyQosCmd.Flags().Uint64VarP(&FlagQos.MaxTimeLimitPerTask, "max-time-limit-per-task", "T", uint64(util.InvalidDuration().Seconds), "Set the maximum time limit per job (in seconds)") + modifyQosCmd.Flags().Uint64VarP(&FlagQos.MaxTimeLimitPerTask, "max-time-limit-per-task", "T", util.MaxJobTimeLimit, "Set the maximum time limit per job (in seconds)") // Rules if err := modifyQosCmd.MarkFlagRequired("name"); err != nil { diff --git a/internal/cacctmgr/cacctmgr.go b/internal/cacctmgr/cacctmgr.go index 64409829..df6c82bb 100644 --- a/internal/cacctmgr/cacctmgr.go +++ b/internal/cacctmgr/cacctmgr.go @@ -133,7 +133,7 @@ func PrintAllQos(qosList []*protos.QosInfo) { tableData := make([][]string, len(qosList)) for _, info := range qosList { var timeLimitStr string - if info.MaxTimeLimitPerTask >= uint64(util.InvalidDuration().Seconds) { + if info.MaxTimeLimitPerTask >= util.MaxJobTimeLimit { timeLimitStr = "unlimited" } else { timeLimitStr = util.SecondTimeFormat(int64(info.MaxTimeLimitPerTask)) diff --git a/internal/calloc/calloc.go b/internal/calloc/calloc.go index 63dbd6e3..9b1e0a26 100644 --- a/internal/calloc/calloc.go +++ b/internal/calloc/calloc.go @@ -351,6 +351,9 @@ func MainCalloc(cmd *cobra.Command, args []string) util.CraneCmdError { return util.ErrorBackend } + // Get egid using os.Getgid() instead of using user.Current() + gid := os.Getgid() + uid, err := strconv.Atoi(gVars.user.Uid) if err != nil { log.Errorf("Failed to convert uid to int: %s", err.Error()) @@ -376,6 +379,7 @@ func MainCalloc(cmd *cobra.Command, args []string) util.CraneCmdError { }, Type: protos.TaskType_Interactive, Uid: uint32(uid), + Gid: uint32(gid), NodeNum: 1, NtasksPerNode: 1, CpusPerTask: 1, diff --git a/internal/cbatch/CmdArgParser.go b/internal/cbatch/CmdArgParser.go index 434d2a93..db28d24c 100644 --- a/internal/cbatch/CmdArgParser.go +++ b/internal/cbatch/CmdArgParser.go @@ -101,6 +101,7 @@ var ( task.GetBatchMeta().ShScript = shScript task.Uid = uint32(os.Getuid()) + task.Gid = uint32(os.Getgid()) task.CmdLine = strings.Join(os.Args, " ") // Process the content of --get-user-env diff --git a/internal/ccontrol/ccontrol.go b/internal/ccontrol/ccontrol.go index 992df183..8cb9e1df 100755 --- a/internal/ccontrol/ccontrol.go +++ b/internal/ccontrol/ccontrol.go @@ -284,44 +284,42 @@ func ShowJobs(jobIds string, queryAll bool) util.CraneCmdError { timeStartStr := "unknown" timeEndStr := "unknown" runTimeStr := "unknown" + resourcesType := "ReqRes" var timeLimitStr string + // submit_time timeSubmit := taskInfo.SubmitTime.AsTime() if !timeSubmit.Before(time.Date(1980, 1, 1, 0, 0, 0, 0, time.UTC)) { timeSubmitStr = timeSubmit.In(time.Local).Format("2006-01-02 15:04:05") } + // start_time timeStart := taskInfo.StartTime.AsTime() if !timeStart.Before(time.Date(1980, 1, 1, 0, 0, 0, 0, time.UTC)) { timeStartStr = timeStart.In(time.Local).Format("2006-01-02 15:04:05") } + // end_time timeEnd := taskInfo.EndTime.AsTime() - if timeEnd.After(timeStart) { + if !timeEnd.Before(timeStart) && timeEnd.Second() < util.MaxJobTimeStamp { timeEndStr = timeEnd.In(time.Local).Format("2006-01-02 15:04:05") } - var resourcesType = "ReqRes" - if taskInfo.Status == protos.TaskStatus_Running { - timeEndStr = timeStart.Add(taskInfo.TimeLimit.AsDuration()).In(time.Local).Format("2006-01-02 15:04:05") - - runTimeDuration := taskInfo.ElapsedTime.AsDuration() - - days := int(runTimeDuration.Hours()) / 24 - hours := int(runTimeDuration.Hours()) % 24 - minutes := int(runTimeDuration.Minutes()) % 60 - seconds := int(runTimeDuration.Seconds()) % 60 - - runTimeStr = fmt.Sprintf("%d-%02d:%02d:%02d", days, hours, minutes, seconds) - resourcesType = "AllocRes" - } - if taskInfo.TimeLimit.Seconds >= util.InvalidDuration().Seconds { + // time_limit + if taskInfo.TimeLimit.Seconds >= util.MaxJobTimeLimit { timeLimitStr = "unlimited" - timeEndStr = "unknown" } else { timeLimitStr = util.SecondTimeFormat(taskInfo.TimeLimit.Seconds) } + + // elapsed_time and resources + if taskInfo.Status == protos.TaskStatus_Running { + runTimeStr = util.SecondTimeFormat(taskInfo.ElapsedTime.Seconds) + resourcesType = "AllocRes" + } + + // uid and gid (egid) craneUser, err := user.LookupId(strconv.Itoa(int(taskInfo.Uid))) if err != nil { log.Errorf("Failed to get username for UID %d: %s\n", taskInfo.Uid, err) diff --git a/internal/cqueue/cqueue.go b/internal/cqueue/cqueue.go index 98d697ab..33b3adc2 100644 --- a/internal/cqueue/cqueue.go +++ b/internal/cqueue/cqueue.go @@ -132,7 +132,7 @@ func QueryTableOutput(reply *protos.QueryTasksInfoReply) util.CraneCmdError { tableData := make([][]string, len(reply.TaskInfoList)) for i := 0; i < len(reply.TaskInfoList); i++ { var timeLimitStr string - if reply.TaskInfoList[i].TimeLimit.Seconds >= util.InvalidDuration().Seconds { + if reply.TaskInfoList[i].TimeLimit.Seconds >= util.MaxJobTimeLimit { timeLimitStr = "unlimited" } else { timeLimitStr = util.SecondTimeFormat(reply.TaskInfoList[i].TimeLimit.Seconds) diff --git a/internal/crun/crun.go b/internal/crun/crun.go index 9f51985c..1dd732f8 100644 --- a/internal/crun/crun.go +++ b/internal/crun/crun.go @@ -23,6 +23,7 @@ import "C" import ( "CraneFrontEnd/generated/protos" "CraneFrontEnd/internal/util" + "github.com/pkg/term/termios" "golang.org/x/sys/unix" @@ -615,6 +616,7 @@ func MainCrun(cmd *cobra.Command, args []string) util.CraneCmdError { }, Type: protos.TaskType_Interactive, Uid: uint32(os.Getuid()), + Gid: uint32(os.Getgid()), NodeNum: 1, NtasksPerNode: 1, CpusPerTask: 1, diff --git a/internal/util/formatter.go b/internal/util/formatter.go index 76c54c98..f6f6e71d 100644 --- a/internal/util/formatter.go +++ b/internal/util/formatter.go @@ -41,9 +41,14 @@ var mo = protojson.MarshalOptions{ func (f FormatterJson) FormatReply(reply interface{}) string { if msg, ok := reply.(protoreflect.ProtoMessage); ok { - output, _ := mo.Marshal(msg) + output, err := mo.Marshal(msg) + if err != nil { + log.Errorf("Failed to marshal proto message: %v\n", err) + os.Exit(ErrorInvalidFormat) + } return string(output) } else { + // This should never happen log.Errorf("Type %T is not ProtoMessage.\n", reply) os.Exit(ErrorInvalidFormat) } diff --git a/internal/util/string.go b/internal/util/string.go index 7ed9ebc7..014e85f9 100644 --- a/internal/util/string.go +++ b/internal/util/string.go @@ -287,22 +287,22 @@ func CheckFileLength(filepath string) error { func CheckTaskArgs(task *protos.TaskToCtld) error { if task.CpusPerTask <= 0 { - return fmt.Errorf("Invalid --cpus-per-task") + return fmt.Errorf("invalid --cpus-per-task") } if task.NtasksPerNode <= 0 { - return fmt.Errorf("Invalid --ntasks-per-node") + return fmt.Errorf("invalid --ntasks-per-node") } if task.NodeNum <= 0 { - return fmt.Errorf("Invalid --nodes") + return fmt.Errorf("invalid --nodes") } if task.TimeLimit.AsDuration() <= 0 { - return fmt.Errorf("Invalid --time") + return fmt.Errorf("invalid --time") } if !CheckNodeList(task.Nodelist) { - return fmt.Errorf("Invalid --nodelist") + return fmt.Errorf("invalid --nodelist") } if !CheckNodeList(task.Excludes) { - return fmt.Errorf("Invalid --exclude") + return fmt.Errorf("invalid --exclude") } return nil } @@ -431,7 +431,7 @@ func ParseNodeList(nodeStr string) ([]string, bool) { func InvalidDuration() *durationpb.Duration { return &durationpb.Duration{ - Seconds: 315576000000, + Seconds: MaxJobTimeLimit, Nanos: 0, } } diff --git a/internal/util/util.go b/internal/util/util.go index a7e219ae..882b13f5 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -19,8 +19,8 @@ package util import ( - "CraneFrontEnd/generated/protos" "CraneFrontEnd/api" + "CraneFrontEnd/generated/protos" "os" "strings" ) @@ -35,8 +35,8 @@ type Config struct { CaCertFilePath string `yaml:"CaCertFilePath"` DomainSuffix string `yaml:"DomainSuffix"` - CraneBaseDir string `yaml:"CraneBaseDir"` - CranedCforedSockPath string `yaml:"CranedCforedSockPath"` + CraneBaseDir string `yaml:"CraneBaseDir"` + CranedCforedSockPath string `yaml:"CranedCforedSockPath"` Plugin PluginConfig `yaml:"Plugin"` } @@ -62,6 +62,9 @@ const ( MaxJobFileNameLength = 127 MaxJobFilePathLengthForWindows = 260 - MaxJobFileNameLength MaxJobFilePathLengthForUnix = 4096 - MaxJobFileNameLength + + MaxJobTimeLimit = 315576000000 // 10000 years + MaxJobTimeStamp = 253402300799 // 9999-12-31 23:59:59 ) func SplitEnvironEntry(env *string) (string, string, bool) { diff --git a/protos/PublicDefs.proto b/protos/PublicDefs.proto index 7693169a..a635191e 100644 --- a/protos/PublicDefs.proto +++ b/protos/PublicDefs.proto @@ -131,6 +131,8 @@ message TaskToCtld { bool requeue_if_failed = 12; bool get_user_env = 13; + uint32 gid = 14; // egid + oneof payload { BatchTaskAdditionalMeta batch_meta = 21; InteractiveTaskAdditionalMeta interactive_meta = 22; @@ -155,7 +157,6 @@ message RuntimeAttrOfTask { // Fields that won't change after this task is accepted. uint32 task_id = 1; int64 task_db_id = 3; - int32 gid = 4; string username = 5; // Fields that will change after this task is accepted. @@ -187,20 +188,21 @@ message TaskToD { string partition = 8; uint32 uid = 9; + uint32 gid = 10; oneof payload { - BatchTaskAdditionalMeta batch_meta = 10; - InteractiveTaskAdditionalMeta interactive_meta = 11; + BatchTaskAdditionalMeta batch_meta = 11; + InteractiveTaskAdditionalMeta interactive_meta = 12; } - map env = 12; - string cwd = 13; + map env = 13; + string cwd = 14; - repeated string allocated_nodes = 14; + repeated string allocated_nodes = 15; - string name = 15; - string account = 16; - string qos = 17; + string name = 16; + string account = 17; + string qos = 18; repeated string excludes = 19; repeated string nodelist = 20; @@ -324,7 +326,7 @@ enum ErrCode { ERR_INVALID_OP_USER = 10002; // Invalid operation user ERR_INVALID_USER = 10003; // Invalid user ERR_PERMISSION_USER = 10004; // User permissions too low, no permission to operate - ERR_USER_DUPLICATE_ACCOUNT= 10005; // User duplicate account insertion + ERR_USER_DUPLICATE_ACCOUNT = 10005; // User duplicate account insertion ERR_USER_ALLOWED_ACCOUNT = 10006; // User does not have permission for the account ERR_INVALID_ADMIN_LEVEL = 10007; // Invalid permission level ERR_USER_ACCOUNT_MISMATCH = 10008; // User does not belong to the account From cbae0f050600cec902d6aea5f8d79a32272dc900 Mon Sep 17 00:00:00 2001 From: Yongkun Li <44155313+Nativu5@users.noreply.github.com> Date: Fri, 3 Jan 2025 15:15:50 +0800 Subject: [PATCH 3/3] feat: Unify the arg checking and logging (#233) --- internal/calloc/calloc.go | 10 ++++---- internal/cbatch/CmdArgParser.go | 2 +- internal/cbatch/cbatch.go | 44 ++++++++++++++++----------------- internal/crun/crun.go | 10 ++++---- internal/util/string.go | 14 +++++------ 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/internal/calloc/calloc.go b/internal/calloc/calloc.go index 9b1e0a26..ce5869ba 100644 --- a/internal/calloc/calloc.go +++ b/internal/calloc/calloc.go @@ -403,14 +403,14 @@ func MainCalloc(cmd *cobra.Command, args []string) util.CraneCmdError { if FlagTime != "" { ok := util.ParseDuration(FlagTime, task.TimeLimit) if !ok { - log.Errorln("Invalid --time format.") + log.Errorln("Invalid argument: invalid format for --time") return util.ErrorCmdArg } } if FlagMem != "" { memInByte, err := util.ParseMemStringAsByte(FlagMem) if err != nil { - log.Errorln(err) + log.Errorf("Invalid argument: %v", err) return util.ErrorCmdArg } task.Resources.AllocatableRes.MemoryLimitBytes = memInByte @@ -446,17 +446,17 @@ func MainCalloc(cmd *cobra.Command, args []string) util.CraneCmdError { // Check the validity of the parameters if len(task.Name) > util.MaxJobNameLength { - log.Errorf("Job name exceeds %v characters.", util.MaxJobNameLength) + log.Errorf("Invalid argument: job name exceeds %v characters.", util.MaxJobNameLength) return util.ErrorCmdArg } if err := util.CheckTaskArgs(task); err != nil { - log.Errorln(err) + log.Errorf("Invalid argument: %v", err) return util.ErrorCmdArg } util.SetPropagatedEnviron(task) task.Resources.AllocatableRes.CpuCoreLimit = task.CpusPerTask * float64(task.NtasksPerNode) if task.Resources.AllocatableRes.CpuCoreLimit > 1e6 { - log.Errorf("Request too many CPUs: %v", task.Resources.AllocatableRes.CpuCoreLimit) + log.Errorf("Invalid argument: requesting too many CPUs: %v", task.Resources.AllocatableRes.CpuCoreLimit) return util.ErrorCmdArg } diff --git a/internal/cbatch/CmdArgParser.go b/internal/cbatch/CmdArgParser.go index db28d24c..65653b62 100644 --- a/internal/cbatch/CmdArgParser.go +++ b/internal/cbatch/CmdArgParser.go @@ -77,7 +77,7 @@ var ( }, Run: func(cmd *cobra.Command, args []string) { if FlagRepeat == 0 { - log.Error("--repeat must > 0.") + log.Error("Invalid argument: --repeat must > 0.") os.Exit(util.ErrorCmdArg) } diff --git a/internal/cbatch/cbatch.go b/internal/cbatch/cbatch.go index 00025029..590316a8 100644 --- a/internal/cbatch/cbatch.go +++ b/internal/cbatch/cbatch.go @@ -68,14 +68,14 @@ func ProcessCbatchArgs(cmd *cobra.Command, args []CbatchArg) (bool, *protos.Task case "--nodes", "-N": num, err := strconv.ParseUint(arg.val, 10, 32) if err != nil { - log.Print("Invalid " + arg.name) + log.Error("Invalid argument: " + arg.name) return false, nil } task.NodeNum = uint32(num) case "--cpus-per-task", "-c": num, err := util.ParseFloatWithPrecision(arg.val, 10) if err != nil { - log.Print("Invalid " + arg.name) + log.Error("Invalid argument: " + arg.name) return false, nil } task.CpusPerTask = num @@ -85,20 +85,20 @@ func ProcessCbatchArgs(cmd *cobra.Command, args []CbatchArg) (bool, *protos.Task case "--ntasks-per-node": num, err := strconv.ParseUint(arg.val, 10, 32) if err != nil { - log.Print("Invalid " + arg.name) + log.Error("Invalid argument: " + arg.name) return false, nil } task.NtasksPerNode = uint32(num) case "--time", "-t": ok := util.ParseDuration(arg.val, task.TimeLimit) if !ok { - log.Print("Invalid " + arg.name) + log.Error("Invalid argument: " + arg.name) return false, nil } case "--mem": memInByte, err := util.ParseMemStringAsByte(arg.val) if err != nil { - log.Error(err) + log.Errorf("Invalid argument: %v", err) return false, nil } task.Resources.AllocatableRes.MemoryLimitBytes = memInByte @@ -123,7 +123,7 @@ func ProcessCbatchArgs(cmd *cobra.Command, args []CbatchArg) (bool, *protos.Task } else { val, err := strconv.ParseBool(arg.val) if err != nil { - log.Print("Invalid " + arg.name) + log.Error("Invalid argument: " + arg.name) return false, nil } task.GetUserEnv = val @@ -137,26 +137,26 @@ func ProcessCbatchArgs(cmd *cobra.Command, args []CbatchArg) (bool, *protos.Task case "--extra-attr": // Merge the extra attributes read from the file with the existing ones. if !util.CheckTaskExtraAttr(arg.val) { - log.Errorln("Invalid extra attributes: invalid JSON string.") + log.Errorln("Invalid argument: invalid JSON string in extra attributes. ") return false, nil } task.ExtraAttr = util.AmendTaskExtraAttr(task.ExtraAttr, arg.val) case "--mail-type": extra, err := sjson.Set(task.ExtraAttr, "mail.type", arg.val) if err != nil { - log.Errorf("Invalid mail type: %v.\n", err) + log.Errorf("Invalid argument: invalid --mail-type: %v", err) return false, nil } task.ExtraAttr = extra case "--mail-user": extra, err := sjson.Set(task.ExtraAttr, "mail.user", arg.val) if err != nil { - log.Errorf("Invalid mail user: %v.\n", err) + log.Errorf("Invalid argument: invalid --mail-user: %v", err) return false, nil } task.ExtraAttr = extra default: - log.Errorf("Invalid parameter '%s' given in the script file.\n", arg.name) + log.Errorf("Invalid argument: unrecognized '%s' is given in the script file", arg.name) return false, nil } } @@ -182,14 +182,14 @@ func ProcessCbatchArgs(cmd *cobra.Command, args []CbatchArg) (bool, *protos.Task if FlagTime != "" { ok := util.ParseDuration(FlagTime, task.TimeLimit) if !ok { - log.Errorln("Invalid --time") + log.Errorln("Invalid argument: invalid format for --time") return false, nil } } if FlagMem != "" { memInByte, err := util.ParseMemStringAsByte(FlagMem) if err != nil { - log.Errorln(err) + log.Errorf("Invalid argument: %v", err) return false, nil } task.Resources.AllocatableRes.MemoryLimitBytes = memInByte @@ -233,7 +233,7 @@ func ProcessCbatchArgs(cmd *cobra.Command, args []CbatchArg) (bool, *protos.Task if FlagExtraAttr != "" { // Merge the extra attributes read from the file with the existing ones. if !util.CheckTaskExtraAttr(FlagExtraAttr) { - log.Errorln("Invalid extra attributes: invalid JSON string.") + log.Errorln("Invalid argument: invalid JSON string in --extra-attr.") return false, nil } task.ExtraAttr = util.AmendTaskExtraAttr(task.ExtraAttr, FlagExtraAttr) @@ -241,7 +241,7 @@ func ProcessCbatchArgs(cmd *cobra.Command, args []CbatchArg) (bool, *protos.Task if FlagMailType != "" { extra, err := sjson.Set(task.ExtraAttr, "mail.type", FlagMailType) if err != nil { - log.Errorf("Invalid mail type: %v.\n", err) + log.Errorf("Invalid argument: invalid --mail-type: %v", err) return false, nil } task.ExtraAttr = extra @@ -249,7 +249,7 @@ func ProcessCbatchArgs(cmd *cobra.Command, args []CbatchArg) (bool, *protos.Task if FlagMailUser != "" { extra, err := sjson.Set(task.ExtraAttr, "mail.user", FlagMailUser) if err != nil { - log.Errorf("Invalid mail user: %v.\n", err) + log.Errorf("Invalid argument: invalid --mail-user: %v", err) return false, nil } task.ExtraAttr = extra @@ -257,19 +257,19 @@ func ProcessCbatchArgs(cmd *cobra.Command, args []CbatchArg) (bool, *protos.Task // Check the validity of the parameters if len(task.Name) > util.MaxJobNameLength { - log.Errorf("Job name exceeds %v characters.", util.MaxJobNameLength) + log.Errorf("Invalid argument: job name exceeds %v characters.", util.MaxJobNameLength) return false, nil } if err := util.CheckFileLength(task.GetBatchMeta().OutputFilePattern); err != nil { - log.Errorf("Invalid output file path: %v", err) + log.Errorf("Invalid argument: invalid output file path: %v", err) return false, nil } if err := util.CheckFileLength(task.GetBatchMeta().ErrorFilePattern); err != nil { - log.Errorf("Invalid error file path: %v", err) + log.Errorf("Invalid argument: invalid error file path: %v", err) return false, nil } if err := util.CheckTaskArgs(task); err != nil { - log.Errorln(err) + log.Errorf("Invalid argument: %v", err) return false, nil } if task.ExtraAttr != "" { @@ -277,18 +277,18 @@ func ProcessCbatchArgs(cmd *cobra.Command, args []CbatchArg) (bool, *protos.Task mailtype := gjson.Get(task.ExtraAttr, "mail.type") mailuser := gjson.Get(task.ExtraAttr, "mail.user") if mailtype.Exists() != mailuser.Exists() { - log.Errorln("Incomplete mail arguments") + log.Errorln("Invalid argument: incomplete mail arguments") return false, nil } if mailtype.Exists() && !util.CheckMailType(mailtype.String()) { - log.Errorln("Invalid --mail-type") + log.Errorln("Invalid argument: invalid --mail-type") return false, nil } } task.Resources.AllocatableRes.CpuCoreLimit = task.CpusPerTask * float64(task.NtasksPerNode) if task.Resources.AllocatableRes.CpuCoreLimit > 1e6 { - log.Errorf("Request too many CPUs: %v", task.Resources.AllocatableRes.CpuCoreLimit) + log.Errorf("Invalid argument: requesting too many CPUs: %v", task.Resources.AllocatableRes.CpuCoreLimit) return false, nil } diff --git a/internal/crun/crun.go b/internal/crun/crun.go index 1dd732f8..8f04c66c 100644 --- a/internal/crun/crun.go +++ b/internal/crun/crun.go @@ -638,14 +638,14 @@ func MainCrun(cmd *cobra.Command, args []string) util.CraneCmdError { if FlagTime != "" { ok := util.ParseDuration(FlagTime, task.TimeLimit) if !ok { - log.Errorln("Invalid --time") + log.Errorln("Invalid argument: invalid format for --time") return util.ErrorCmdArg } } if FlagMem != "" { memInByte, err := util.ParseMemStringAsByte(FlagMem) if err != nil { - log.Errorln(err) + log.Errorf("Invalid argument: %v", err) return util.ErrorCmdArg } task.Resources.AllocatableRes.MemoryLimitBytes = memInByte @@ -685,19 +685,19 @@ func MainCrun(cmd *cobra.Command, args []string) util.CraneCmdError { // Check the validity of the parameters if len(task.Name) > util.MaxJobNameLength { - log.Errorf("Job name exceeds %v characters.", util.MaxJobNameLength) + log.Errorf("Invalid argument: job name exceeds %v characters.", util.MaxJobNameLength) return util.ErrorCmdArg } if err := util.CheckTaskArgs(task); err != nil { - log.Errorln(err) + log.Errorf("Invalid argument: %v", err) return util.ErrorCmdArg } util.SetPropagatedEnviron(task) task.Resources.AllocatableRes.CpuCoreLimit = task.CpusPerTask * float64(task.NtasksPerNode) if task.Resources.AllocatableRes.CpuCoreLimit > 1e6 { - log.Errorf("Request too many cpus: %f", task.Resources.AllocatableRes.CpuCoreLimit) + log.Errorf("Invalid argument: requesting too many CPUs: %v", task.Resources.AllocatableRes.CpuCoreLimit) return util.ErrorCmdArg } interactiveMeta := task.GetInteractiveMeta() diff --git a/internal/util/string.go b/internal/util/string.go index 014e85f9..2ada24b0 100644 --- a/internal/util/string.go +++ b/internal/util/string.go @@ -287,22 +287,22 @@ func CheckFileLength(filepath string) error { func CheckTaskArgs(task *protos.TaskToCtld) error { if task.CpusPerTask <= 0 { - return fmt.Errorf("invalid --cpus-per-task") + return fmt.Errorf("--cpus-per-task must > 0") } if task.NtasksPerNode <= 0 { - return fmt.Errorf("invalid --ntasks-per-node") + return fmt.Errorf("--ntasks-per-node must > 0") } if task.NodeNum <= 0 { - return fmt.Errorf("invalid --nodes") + return fmt.Errorf("--nodes must > 0") } if task.TimeLimit.AsDuration() <= 0 { - return fmt.Errorf("invalid --time") + return fmt.Errorf("--time must > 0") } if !CheckNodeList(task.Nodelist) { - return fmt.Errorf("invalid --nodelist") + return fmt.Errorf("invalid format for --nodelist") } if !CheckNodeList(task.Excludes) { - return fmt.Errorf("invalid --exclude") + return fmt.Errorf("invalid format for --exclude") } return nil } @@ -648,7 +648,7 @@ func ParseGres(gres string) *protos.DeviceMap { result.NameTypeMap[name].TypeCountMap[gresType] = count } } else { - log.Errorf("Error parsing gres : %s\n", g) + log.Errorf("Error parsing gres: %s\n", g) } }