Skip to content

Commit

Permalink
Merge branch 'master' into dev/cqueue
Browse files Browse the repository at this point in the history
  • Loading branch information
1daidai1 authored Jan 7, 2025
2 parents 2f0ba44 + cbae0f0 commit fea03a7
Show file tree
Hide file tree
Showing 14 changed files with 108 additions and 81 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ bin

# Testing
testcase
*.out
22 changes: 16 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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 \
Expand All @@ -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 \
Expand Down
4 changes: 2 additions & 2 deletions internal/cacctmgr/CmdArgParser.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion internal/cacctmgr/cacctmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
14 changes: 9 additions & 5 deletions internal/calloc/calloc.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand All @@ -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,
Expand All @@ -399,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
Expand Down Expand Up @@ -442,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
}

Expand Down
3 changes: 2 additions & 1 deletion internal/cbatch/CmdArgParser.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand All @@ -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
Expand Down
44 changes: 22 additions & 22 deletions internal/cbatch/cbatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
}
}
Expand All @@ -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
Expand Down Expand Up @@ -233,62 +233,62 @@ 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)
}
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
}
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
}

// 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 != "" {
// Check attrs in task.ExtraAttr, e.g., mail.type, mail.user
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
}

Expand Down
32 changes: 15 additions & 17 deletions internal/ccontrol/ccontrol.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions internal/cqueue/cqueue.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func QueryTableOutput(reply *protos.QueryTasksInfoReply) util.CraneCmdError {
util.SetBorderlessTable(table)
var header []string
tableData := make([][]string, len(reply.TaskInfoList))

if FlagFull {
header = []string{"JobId", "JobName", "UserName", "Partition",
"Account", "NodeNum", "AllocCPUs", "MemPerNode", "Status", "Time", "TimeLimit",
Expand Down
Loading

0 comments on commit fea03a7

Please sign in to comment.