@@ -2242,7 +2242,7 @@ func (c *CommandLineQConf) ShowUserSetLists() ([]string, error) {
22422242}
22432243
22442244// ClearUsage clears all user/project sharetree usage.
2245- func (c * CommandLineQConf ) ClearUsage () error {
2245+ func (c * CommandLineQConf ) ClearShareTreeUsage () error {
22462246 _ , err := c .RunCommand ("-clearusage" )
22472247 return err
22482248}
@@ -3152,3 +3152,137 @@ func (c *CommandLineQConf) ModifySchedulerConfig(cfg SchedulerConfig) error {
31523152 _ , err = c .RunCommand ("-Msconf" , file .Name ())
31533153 return err
31543154}
3155+
3156+ // ShowShareTree retrieves the entire share tree structure
3157+ func (c * CommandLineQConf ) ShowShareTree () (string , error ) {
3158+ stree , err := c .RunCommand ("-sstree" )
3159+ if err != nil {
3160+ if strings .Contains (err .Error (), "no sharetree" ) {
3161+ return "" , fmt .Errorf ("no sharetree defined" )
3162+ }
3163+ return "" , err
3164+ }
3165+ return stree , nil
3166+ }
3167+
3168+ // ModifyShareTreeNodes modifies the share of specified nodes in the share tree
3169+ func (c * CommandLineQConf ) ModifyShareTreeNodes (nodeShareList []ShareTreeNode ) error {
3170+ var nodeShares []string
3171+ for _ , node := range nodeShareList {
3172+ nodeShares = append (nodeShares , fmt .Sprintf ("%s=%d" , node .Node , node .Share ))
3173+ }
3174+ _ , err := c .RunCommand ("-mstnode" , strings .Join (nodeShares , "," ))
3175+ return err
3176+ }
3177+
3178+ // DeleteShareTreeNodes removes specified nodes from the share tree
3179+ func (c * CommandLineQConf ) DeleteShareTreeNodes (nodeList []string ) error {
3180+ _ , err := c .RunCommand (append ([]string {"-dstnode" }, nodeList ... )... )
3181+ return err
3182+ }
3183+
3184+ // AddShareTreeNode adds a new node to the share tree. The node must be a full
3185+ // path, like /P1.
3186+ func (c * CommandLineQConf ) AddShareTreeNode (node ShareTreeNode ) error {
3187+ _ , err := c .RunCommand ("-astnode" , fmt .Sprintf ("%s=%d" , node .Node , node .Share ))
3188+ return err
3189+ }
3190+
3191+ // ShowShareTreeNodes retrieves information about specified nodes or all
3192+ // nodes in the share tree. The node contains the full path, like /P1.
3193+ func (c * CommandLineQConf ) ShowShareTreeNodes (nodeList []string ) ([]ShareTreeNode , error ) {
3194+ // if nodeList is empty, show all nodes
3195+ args := []string {"-sstnode" }
3196+ if len (nodeList ) == 0 {
3197+ args = append (args , "/" )
3198+ } else {
3199+ args = append (args , nodeList ... )
3200+ }
3201+ output , err := c .RunCommand (args ... )
3202+ if err != nil {
3203+ return nil , err
3204+ }
3205+ return parseShareTreeNodes (output ), nil
3206+ }
3207+
3208+ // ModifyShareTree modifies the entire share tree configuration. If the
3209+ // shareTreeConfig is empty, the share tree is deleted.
3210+ // A share tree has typically the following format:
3211+ // id=0
3212+ // name=Root
3213+ // type=0
3214+ // shares=1
3215+ // childnodes=1,2,3
3216+ // where childnodes is a comma separated list of child nodes.
3217+ func (c * CommandLineQConf ) ModifyShareTree (shareTreeConfig string ) error {
3218+ // if shareTreeConfig is empty, delete the share tree
3219+ if shareTreeConfig == "" {
3220+ // qconf -dstree
3221+ _ , err := c .RunCommand ("-dstree" )
3222+ if err != nil {
3223+ // Ignore "sharetree does not exist"
3224+ if ! strings .Contains (err .Error (), "sharetree does not exist" ) {
3225+ return err
3226+ }
3227+ }
3228+ return nil
3229+ }
3230+
3231+ file , err := createTempDirWithFileName ("sharetree" )
3232+ if err != nil {
3233+ return err
3234+ }
3235+ defer os .RemoveAll (filepath .Dir (file .Name ()))
3236+
3237+ _ , err = file .WriteString (shareTreeConfig )
3238+ if err != nil {
3239+ return err
3240+ }
3241+ file .Close ()
3242+
3243+ _ , err = c .RunCommand ("-Mstree" , file .Name ())
3244+ return err
3245+ }
3246+
3247+ // DeleteShareTree deletes the share tree
3248+ func (c * CommandLineQConf ) DeleteShareTree () error {
3249+ // check if share tree exists
3250+ _ , err := c .ShowShareTree ()
3251+ if err != nil {
3252+ if ! strings .Contains (err .Error (), "no sharetree" ) {
3253+ return err
3254+ }
3255+ return nil
3256+ }
3257+ _ , err = c .RunCommand ("-dstree" )
3258+ return err
3259+ }
3260+
3261+ // Helper function to parse the output of ShowShareTreeNodes,
3262+ // like:
3263+ // /=1
3264+ // /default=10
3265+ // /P2=11
3266+ // /P1=11
3267+ func parseShareTreeNodes (output string ) []ShareTreeNode {
3268+ lines := strings .Split (output , "\n " )
3269+ var nodes []ShareTreeNode
3270+ for _ , line := range lines {
3271+ parts := strings .Split (line , "=" )
3272+ if len (parts ) >= 2 {
3273+ share , _ := strconv .Atoi (parts [1 ])
3274+ // convert node path to node name, like /P1 to P1
3275+ // always after the last /
3276+ /*node := parts[0]
3277+ slashIndex := strings.LastIndex(node, "/")
3278+ if slashIndex != -1 && slashIndex < len(node)-1 {
3279+ node = node[slashIndex+1:]
3280+ }*/
3281+ nodes = append (nodes , ShareTreeNode {
3282+ Node : parts [0 ],
3283+ Share : share ,
3284+ })
3285+ }
3286+ }
3287+ return nodes
3288+ }
0 commit comments