Skip to content

Commit a59463d

Browse files
authored
Add sharetree configuration (#15)
* Adding hosts in Simulator * Add sharetree configuration
1 parent de19031 commit a59463d

File tree

4 files changed

+250
-8
lines changed

4 files changed

+250
-8
lines changed

pkg/qconf/qconf.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,14 @@ type QConf interface {
106106
DeleteSubmitHost(hostnames []string) error
107107
ShowSubmitHosts() ([]string, error)
108108

109-
/* TODO: implement
110-
AddShareTreeNode(nodeShareList string) (string, error)
111-
DeleteShareTreeNode(nodeList string) (string, error)
112-
ShowShareTreeNodes(nodeList string) ([]string, error)
109+
ModifyShareTreeNodes(nodeShareList []ShareTreeNode) error
110+
DeleteShareTreeNodes(nodeList []string) error
111+
AddShareTreeNode(node ShareTreeNode) error
112+
ShowShareTreeNodes(nodeList []string) ([]ShareTreeNode, error)
113113
ShowShareTree() (string, error)
114-
ModifyShareTree(shareTreeConfig ShareTreeConfig) (string, error)
115-
*/
114+
ModifyShareTree(shareTreeConfig string) error
115+
DeleteShareTree() error
116+
ClearShareTreeUsage() error
116117

117118
AddUserSetList(listnameList string, u UserSetListConfig) error
118119
AddUserToUserSetList(userList, listnameList string) error
@@ -128,7 +129,6 @@ type QConf interface {
128129
ShowUsers() ([]string, error)
129130
ModifyUser(userName string, u UserConfig) error
130131

131-
ClearUsage() error
132132
CleanQueue(destinID []string) error
133133
ShutdownExecDaemons(hosts []string) error
134134
ShutdownMasterDaemon() error

pkg/qconf/qconf_impl.go

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
}

pkg/qconf/qconf_impl_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,108 @@ gid_range 20000-20100`, "\n")
14231423

14241424
})
14251425

1426+
Context("Share Tree Modification", func() {
1427+
1428+
var qc *qconf.CommandLineQConf
1429+
var err error
1430+
1431+
var originalShareTree string
1432+
1433+
BeforeEach(func() {
1434+
qc, err = qconf.NewCommandLineQConf(
1435+
qconf.CommandLineQConfConfig{Executable: "qconf"})
1436+
Expect(err).To(BeNil())
1437+
originalShareTree, _ = qc.ShowShareTree()
1438+
1439+
// Add projects P1 and P2
1440+
qc.AddProject(qconf.ProjectConfig{Name: "P10"})
1441+
qc.AddProject(qconf.ProjectConfig{Name: "P20"})
1442+
})
1443+
1444+
AfterEach(func() {
1445+
err = qc.ModifyShareTree(originalShareTree)
1446+
Expect(err).To(BeNil())
1447+
err = qc.DeleteProject([]string{"P10", "P20"})
1448+
Expect(err).To(BeNil())
1449+
})
1450+
1451+
It("should modify the share tree", func() {
1452+
shareTreeConfig := `id=0
1453+
name=Root
1454+
type=0
1455+
shares=1
1456+
childnodes=1,2,3
1457+
id=1
1458+
name=default
1459+
type=0
1460+
shares=10
1461+
childnodes=NONE
1462+
id=2
1463+
name=P20
1464+
type=1
1465+
shares=11
1466+
childnodes=NONE
1467+
id=3
1468+
name=P10
1469+
type=1
1470+
shares=11
1471+
childnodes=NONE
1472+
`
1473+
err = qc.ModifyShareTree(shareTreeConfig)
1474+
Expect(err).To(BeNil())
1475+
1476+
modifiedShareTree, err := qc.ShowShareTree()
1477+
Expect(err).To(BeNil())
1478+
Expect(modifiedShareTree).To(Equal(shareTreeConfig))
1479+
1480+
nodes, err := qc.ShowShareTreeNodes(nil)
1481+
Expect(err).To(BeNil())
1482+
Expect(nodes).To(ContainElement(
1483+
qconf.ShareTreeNode{
1484+
Node: "/P10", Share: 11}))
1485+
1486+
err = qc.DeleteShareTreeNodes([]string{"P10"})
1487+
Expect(err).To(BeNil())
1488+
1489+
nodes, err = qc.ShowShareTreeNodes(nil)
1490+
Expect(err).To(BeNil())
1491+
Expect(nodes).NotTo(ContainElement(
1492+
qconf.ShareTreeNode{
1493+
Node: "/P10", Share: 11}))
1494+
1495+
err = qc.AddShareTreeNode(
1496+
qconf.ShareTreeNode{
1497+
Node: "/P10",
1498+
Share: 11,
1499+
})
1500+
Expect(err).To(BeNil())
1501+
1502+
err = qc.ModifyShareTreeNodes(
1503+
[]qconf.ShareTreeNode{
1504+
{Node: "/P10", Share: 12},
1505+
})
1506+
Expect(err).To(BeNil())
1507+
1508+
nodes, err = qc.ShowShareTreeNodes(nil)
1509+
Expect(err).To(BeNil())
1510+
Expect(nodes).To(ContainElement(
1511+
qconf.ShareTreeNode{
1512+
Node: "/P10", Share: 12}))
1513+
1514+
err = qc.DeleteShareTree()
1515+
Expect(err).To(BeNil())
1516+
1517+
_, err = qc.ShowShareTree()
1518+
Expect(err).To(HaveOccurred())
1519+
})
1520+
1521+
It("should clear the share tree usage", func() {
1522+
err = qc.ClearShareTreeUsage()
1523+
Expect(err).To(BeNil())
1524+
})
1525+
1526+
})
1527+
14261528
/*
14271529
Context("Cluster Control Operations", func() {
14281530

pkg/qconf/types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,3 +322,9 @@ type SchedulerConfig struct {
322322
MaxReservation int `json:"max_reservation"`
323323
DefaultDuration string `json:"default_duration"`
324324
}
325+
326+
// ShareTreeNodeShare represents a node in the share tree with its share value
327+
type ShareTreeNode struct {
328+
Node string
329+
Share int
330+
}

0 commit comments

Comments
 (0)