Skip to content

Commit 9e36c0d

Browse files
committed
EH: CS-1056 User friendly basic sharetree editor
1 parent f0fb0e7 commit 9e36c0d

File tree

18 files changed

+3352
-0
lines changed

18 files changed

+3352
-0
lines changed

cmd/sharetree/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sharetree

cmd/sharetree/README.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Simple Sharetree Editor
2+
3+
A web-based visualization and editing tool for Open Cluster
4+
Scheduler (OCS) and Gridware Cluster Scheduler (GCS) sharetree
5+
configurations.
6+
7+
## Overview
8+
9+
Sharetree Editor provides a simple interface for creating,
10+
viewing, and modifying sharetree hierarchies used by the
11+
Open Cluster Scheduler (OCS) and Gridware Cluster Scheduler
12+
(GCS). This tool is designed to make managing complex
13+
sharetree structures more intuitive through a visual tree
14+
representation.
15+
16+
> **Note:** This is a very basic share tree editor currently
17+
not making any interaction with Cluster Scheduler. Based on
18+
feedback, more functionalities are being added.
19+
20+
## Features
21+
22+
- Visual tree representation of sharetree structures
23+
- Create, edit, and delete sharetree nodes
24+
- Automatic calculation of level and total percentages
25+
- Support for both user and project node types
26+
- Upload and download sharetree configurations in SGE format
27+
- Real-time validation of sharetree structures
28+
- Temporary file storage for session persistence
29+
30+
## Installation
31+
32+
### Prerequisites
33+
34+
- Go 1.23 or higher
35+
- Web browser with JavaScript enabled
36+
37+
### Setup
38+
39+
1. Clone the repository:
40+
41+
```bash
42+
git clone https://github.com/hpc-gridware/go-clusterscheduler.git
43+
```
44+
45+
2. Build and run the application:
46+
47+
```bash
48+
cd go-clusterscheduler/cmd/sharetree
49+
go run main.go
50+
```
51+
52+
3. Open your browser and navigate to:
53+
54+
```
55+
http://localhost:8080
56+
```
57+
58+
## Usage
59+
60+
### Creating a New Sharetree
61+
62+
- Click "New Sharetree" to start with a clean Root node
63+
- Use the "Add Child Node" button to add nodes under the currently selected node
64+
- Use the "Add Sibling Node" to add nodes at the same level
65+
66+
### Editing Nodes
67+
68+
- Click on any node to select it and view its properties in the right panel
69+
- Modify node properties (name, type, shares) and click "Save Node"
70+
71+
### Uploading and Downloading
72+
73+
- Click "Upload" to import an existing SGE format sharetree file (`qconf -sstree > <sharetree_file>`)
74+
- Click "Download Sharetree" to export your current sharetree configuration
75+
(after storing the original sharetree configuration it can be applied
76+
with `qconf -Astree <sharetree_file>`)
77+
78+
## Development
79+
80+
### Project Structure
81+
82+
- `/pkg/sharetree` - Core sharetree data structure and validation logic
83+
- `/pkg/app` - Application state management
84+
- `/pkg/api` - API handlers for the web interface
85+
- `/templates` - HTML templates for the web UI
86+
- `/static` - Static assets for the web UI
87+
88+
### Running Tests
89+
90+
```bash
91+
go test ./...
92+
```
93+
94+
### Possible Improvements
95+
96+
- Load sharetree directly from Gridware Cluster Scheduler
97+
- Load users and projects from Gridware Cluster Scheduler.
98+
- Use $SGE_ROOT/utilbin/lx-amd64/sge_share_mon for retrieving the sharetree usage.
99+
- Semantic validation of the sharetree configuration.

cmd/sharetree/example.sge

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# OCS Sharetree Configuration
2+
# Generated on 2025-03-03T10:31:41+01:00
3+
4+
id=0
5+
name=Root
6+
type=0
7+
shares=1
8+
childnodes=1,2,3
9+
10+
id=1
11+
name=P1
12+
type=1
13+
shares=50
14+
childnodes=NONE
15+
16+
id=2
17+
name=P2
18+
type=1
19+
shares=50
20+
childnodes=NONE
21+
22+
id=3
23+
name=default
24+
type=0
25+
shares=10
26+
childnodes=NONE
27+

cmd/sharetree/go.mod

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module github.com/hpc-gridware/go-clusterscheduler/cmd/sharetree
2+
3+
go 1.23.6
4+
5+
replace github.com/hpc-gridware/go-clusterscheduler/cmd/sharetree/pkg/sharetree => ./pkg/sharetree
6+
7+
require (
8+
github.com/onsi/ginkgo/v2 v2.22.2
9+
github.com/onsi/gomega v1.36.2
10+
)
11+
12+
require (
13+
github.com/go-logr/logr v1.4.2 // indirect
14+
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
15+
github.com/google/go-cmp v0.6.0 // indirect
16+
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
17+
golang.org/x/net v0.33.0 // indirect
18+
golang.org/x/sys v0.28.0 // indirect
19+
golang.org/x/text v0.21.0 // indirect
20+
golang.org/x/tools v0.28.0 // indirect
21+
gopkg.in/yaml.v3 v3.0.1 // indirect
22+
)

cmd/sharetree/go.sum

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
4+
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
5+
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
6+
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
7+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
8+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
9+
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
10+
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
11+
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
12+
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
13+
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
14+
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
15+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
16+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
17+
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
18+
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
19+
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
20+
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
21+
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
22+
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
23+
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
24+
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
25+
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
26+
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
27+
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
28+
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
29+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
30+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
31+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
32+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

cmd/sharetree/main.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*___INFO__MARK_BEGIN__*/
2+
/*************************************************************************
3+
* Copyright 2025 HPC-Gridware GmbH
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
************************************************************************/
18+
/*___INFO__MARK_END__*/
19+
20+
package main
21+
22+
import (
23+
"log"
24+
"net/http"
25+
26+
"github.com/hpc-gridware/go-clusterscheduler/cmd/sharetree/pkg/api"
27+
"github.com/hpc-gridware/go-clusterscheduler/cmd/sharetree/pkg/app"
28+
)
29+
30+
// main function starts the server.
31+
func main() {
32+
// Initialize app
33+
appInstance, err := app.NewApp()
34+
if err != nil {
35+
log.Fatalf("Failed to initialize app: %v", err)
36+
}
37+
38+
// Setup API handlers
39+
handler := api.NewHandler(appInstance)
40+
handler.RegisterHandlers()
41+
42+
// Serve static files and index page
43+
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
44+
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
45+
http.ServeFile(w, r, "templates/index.html")
46+
})
47+
48+
// Start server
49+
log.Println("Starting server on http://localhost:8080")
50+
log.Fatal(http.ListenAndServe(":8080", nil))
51+
}

0 commit comments

Comments
 (0)