mirror of
https://github.com/donl/gPanel.git
synced 2026-06-30 06:12:06 -06:00
started development on creating new bundles
This commit is contained in:
parent
dd7bae479d
commit
9cfa4fd8b1
14 changed files with 269 additions and 105 deletions
|
|
@ -4,5 +4,6 @@ The actual log files are ignored by the .gitignore file. They are generated auto
|
|||
|
||||
Current log files:
|
||||
- client_errors.log
|
||||
- account_errors.log
|
||||
- server_errors.log
|
||||
- loadtime.log
|
||||
|
|
|
|||
4
main.go
4
main.go
|
|
@ -13,6 +13,6 @@ func main() {
|
|||
|
||||
log.Printf("To Exit: CTRL+C")
|
||||
|
||||
log.Print("Listening (server) on localhost:2083, serving out of the server/document_root/ directory...")
|
||||
http.ListenAndServe("localhost:2083", context.ClearHandler(mains))
|
||||
log.Print("Listening (server) on localhost:2082, serving out of the server/document_root/ directory...")
|
||||
http.ListenAndServe("localhost:2082", context.ClearHandler(mains))
|
||||
}
|
||||
|
|
|
|||
70
pkg/api/bundle/create.go
Normal file
70
pkg/api/bundle/create.go
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package bundle
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/Ennovar/gPanel/pkg/gpaccount"
|
||||
)
|
||||
|
||||
func Create(res http.ResponseWriter, req *http.Request, bundles map[string]*gpaccount.Controller) bool {
|
||||
if req.Method != "POST" {
|
||||
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||
return false
|
||||
}
|
||||
|
||||
var createBundleRequestData struct {
|
||||
Name string `json:"name"`
|
||||
AccPort int `json:"account_port"`
|
||||
PubPort int `json:"public_port"`
|
||||
}
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&createBundleRequestData)
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
|
||||
check, err := net.Listen("tcp", ":"+strconv.Itoa(createBundleRequestData.AccPort))
|
||||
if err != nil {
|
||||
http.Error(res, "A service is already listening on port "+strconv.Itoa(createBundleRequestData.AccPort), http.StatusInternalServerError)
|
||||
return false
|
||||
}
|
||||
check.Close()
|
||||
|
||||
check, err = net.Listen("tcp", ":"+strconv.Itoa(createBundleRequestData.PubPort))
|
||||
if err != nil {
|
||||
http.Error(res, "A service is already listening on port "+strconv.Itoa(createBundleRequestData.PubPort), http.StatusInternalServerError)
|
||||
return false
|
||||
}
|
||||
check.Close()
|
||||
|
||||
err = nil
|
||||
for k, v := range bundles {
|
||||
if k == createBundleRequestData.Name {
|
||||
err = errors.New("Bundle \"" + k + "\" already exists")
|
||||
break
|
||||
}
|
||||
|
||||
if v.Port == createBundleRequestData.AccPort ||
|
||||
v.Port == createBundleRequestData.PubPort ||
|
||||
v.Public.Port == createBundleRequestData.AccPort ||
|
||||
v.Public.Port == createBundleRequestData.PubPort {
|
||||
err = errors.New("An existing bundle is using the port \"" + strconv.Itoa(v.Port) + "\" already")
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
|
||||
res.WriteHeader(http.StatusOK)
|
||||
res.Write([]byte(createBundleRequestData.Name))
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
@ -27,14 +27,14 @@ var controller Controller
|
|||
var httpserver http.Server
|
||||
|
||||
// New returns a new Controller reference.
|
||||
func New(root string) *Controller {
|
||||
func New(dir string, accPort int, pubPort int) *Controller {
|
||||
serverErrorLogger, _ := file.Open(file.LOG_SERVER_ERRORS, true, true)
|
||||
|
||||
controller = Controller{
|
||||
Directory: root,
|
||||
Directory: dir,
|
||||
DocumentRoot: "account/",
|
||||
Port: 2082,
|
||||
Public: public.New(root + "public/"),
|
||||
Port: accPort,
|
||||
Public: public.New(dir+"public/", pubPort),
|
||||
GracefulShutdownTimeout: 5 * time.Second,
|
||||
Status: 0,
|
||||
ServerLogger: serverErrorLogger,
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Ennovar/gPanel/pkg/api/log"
|
||||
"github.com/Ennovar/gPanel/pkg/api/server"
|
||||
"github.com/Ennovar/gPanel/pkg/api/bundle"
|
||||
"github.com/Ennovar/gPanel/pkg/api/user"
|
||||
)
|
||||
|
||||
|
|
@ -28,20 +27,8 @@ func (con *Controller) apiHandler(res http.ResponseWriter, req *http.Request, cu
|
|||
return true, user.Register(res, req, con.Directory)
|
||||
case "/user/logout":
|
||||
return true, user.Logout(res, req, con.Directory)
|
||||
case "/server/status":
|
||||
return true, server.Status(res, req, con.Bundles[curBundle].Public)
|
||||
case "/server/start":
|
||||
return true, server.Start(res, req, con.Bundles[curBundle].Public)
|
||||
case "/server/shutdown":
|
||||
return true, server.Shutdown(res, req, con.Bundles[curBundle].Public)
|
||||
case "/server/restart":
|
||||
return true, server.Restart(res, req, con.Bundles[curBundle].Public)
|
||||
case "/server/maintenance":
|
||||
return true, server.Maintenance(res, req, con.Bundles[curBundle].Public)
|
||||
case "/log/read":
|
||||
return true, log.Read(res, req)
|
||||
case "/log/delete":
|
||||
return true, log.Delete(res, req)
|
||||
case "/bundle/create":
|
||||
return true, bundle.Create(res, req, con.Bundles)
|
||||
default:
|
||||
return false, false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@ import (
|
|||
type Controller struct {
|
||||
Directory string
|
||||
DocumentRoot string
|
||||
Bundles []gpaccount.Controller
|
||||
Bundles map[string]*gpaccount.Controller
|
||||
}
|
||||
|
||||
func New() *Controller {
|
||||
return &Controller{
|
||||
Directory: "server/",
|
||||
DocumentRoot: "document_root/",
|
||||
Bundles: []gpaccount.Controller{},
|
||||
Bundles: make(map[string]*gpaccount.Controller),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
package public
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
|
@ -21,7 +19,6 @@ type Controller struct {
|
|||
GracefulShutdownTimeout time.Duration
|
||||
Status int
|
||||
ClientLogger *file.Handler
|
||||
ServerLogger *file.Handler
|
||||
LoadTimeLogger *file.Handler
|
||||
}
|
||||
|
||||
|
|
@ -29,18 +26,16 @@ var controller Controller
|
|||
var server http.Server
|
||||
|
||||
// New function returns a new PublicWeb type.
|
||||
func New(root string) *Controller {
|
||||
func New(root string, port int) *Controller {
|
||||
clientLogHandler, _ := file.Open(file.LOG_CLIENT_ERRORS, true, true)
|
||||
serverLogHandler, _ := file.Open(file.LOG_CLIENT_ERRORS, true, true)
|
||||
loadLogHandler, _ := file.Open(file.LOG_LOADTIME, true, true)
|
||||
|
||||
controller = Controller{
|
||||
DocumentRoot: root,
|
||||
Port: 3000,
|
||||
Port: port,
|
||||
GracefulShutdownTimeout: 5 * time.Second,
|
||||
Status: 0,
|
||||
ClientLogger: clientLogHandler,
|
||||
ServerLogger: serverLogHandler,
|
||||
LoadTimeLogger: loadLogHandler,
|
||||
}
|
||||
|
||||
|
|
@ -55,73 +50,6 @@ func New(root string) *Controller {
|
|||
return &controller
|
||||
}
|
||||
|
||||
// Start function starts listening on the public server
|
||||
func (con *Controller) Start() error {
|
||||
if con.Status == 1 {
|
||||
return errors.New("Public server is already on.")
|
||||
}
|
||||
|
||||
con.Status = 1
|
||||
go server.ListenAndServe()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop function stops the server gracefully or forceful, depending on the boolean input
|
||||
func (con *Controller) Stop(graceful bool) error {
|
||||
if graceful {
|
||||
context, cancel := context.WithTimeout(context.Background(), con.GracefulShutdownTimeout)
|
||||
defer cancel()
|
||||
|
||||
err := server.Shutdown(context)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("Graceful shutdown failed attempting forced: %v\n", err)
|
||||
}
|
||||
|
||||
if err := server.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
con.Status = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
// Restart function combines both the start and stop function, using different
|
||||
// status codes, as it is restarting.
|
||||
func (con *Controller) Restart(graceful bool) error {
|
||||
con.Status = 3
|
||||
|
||||
if graceful {
|
||||
context, cancel := context.WithTimeout(context.Background(), con.GracefulShutdownTimeout)
|
||||
defer cancel()
|
||||
|
||||
err := server.Shutdown(context)
|
||||
if err != nil {
|
||||
fmt.Printf("Graceful shutdown failed attempting forced: %v\n", err)
|
||||
|
||||
err = server.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err := server.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
con.Status = 1
|
||||
go server.ListenAndServe()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (con *Controller) Maintenance() {
|
||||
con.Status = 2
|
||||
}
|
||||
|
||||
// ServeHTTP function routes all requests for the public web server. It is used in the main
|
||||
// function inside of the http.ListenAndServe() function for the public host.
|
||||
func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) {
|
||||
|
|
@ -168,7 +96,7 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) {
|
|||
_, err = io.Copy(res, f)
|
||||
|
||||
if err != nil {
|
||||
con.ServerLogger.Write(path + "::" + strconv.Itoa(http.StatusInternalServerError) + "::" + err.Error())
|
||||
fmt.Printf("Server error serving files to client: %v\n", err)
|
||||
routing.HttpThrowStatus(http.StatusInternalServerError, res)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
41
pkg/public/restart.go
Normal file
41
pkg/public/restart.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Package public handles the logic of the public facing website
|
||||
package public
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Restart function combines both the start and stop function, using different
|
||||
// status codes, as it is restarting.
|
||||
func (con *Controller) Restart(graceful bool) error {
|
||||
con.Status = 3
|
||||
|
||||
if graceful {
|
||||
context, cancel := context.WithTimeout(context.Background(), con.GracefulShutdownTimeout)
|
||||
defer cancel()
|
||||
|
||||
err := server.Shutdown(context)
|
||||
if err != nil {
|
||||
fmt.Printf("Graceful shutdown failed attempting forced: %v\n", err)
|
||||
|
||||
err = server.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err := server.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
con.Status = 1
|
||||
go server.ListenAndServe()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (con *Controller) Maintenance() {
|
||||
con.Status = 2
|
||||
}
|
||||
41
pkg/public/toggle.go
Normal file
41
pkg/public/toggle.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Package public handles the logic of the public facing website
|
||||
package public
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Start function starts listening on the public server
|
||||
func (con *Controller) Start() error {
|
||||
if con.Status == 1 {
|
||||
return errors.New("Public server is already on.")
|
||||
}
|
||||
|
||||
con.Status = 1
|
||||
go server.ListenAndServe()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop function stops the server gracefully or forceful, depending on the boolean input
|
||||
func (con *Controller) Stop(graceful bool) error {
|
||||
if graceful {
|
||||
context, cancel := context.WithTimeout(context.Background(), con.GracefulShutdownTimeout)
|
||||
defer cancel()
|
||||
|
||||
err := server.Shutdown(context)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("Graceful shutdown failed attempting forced: %v\n", err)
|
||||
}
|
||||
|
||||
if err := server.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
con.Status = 0
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
newBundleModal = jQuery('.new-bundle-modal');
|
||||
|
||||
jQuery('._js_bundles-create').on('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
newBundleModal.modal('show');
|
||||
});
|
||||
|
||||
jQuery('._js_create-bundle-form').on('submit', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
var formData = {};
|
||||
for(var y = 0, yy = this.length; y < yy; y++) {
|
||||
var input = this[y];
|
||||
if(input.name) {
|
||||
if(input.type == "number") {
|
||||
formData[input.name] = parseInt(input.value);
|
||||
}
|
||||
else {
|
||||
formData[input.name] = input.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open(jQuery(this).attr('method'), jQuery(this).attr('action'), true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
|
||||
xhr.send(JSON.stringify(formData));
|
||||
|
||||
xhr.onloadend = function() {
|
||||
if(xhr.status == 200) {
|
||||
if(xhr.response != undefined && xhr.response.length != 0) {
|
||||
alert("Bundle \"" + xhr.response + "\" successfully created.");
|
||||
}
|
||||
else {
|
||||
alert("Bundle successfully created.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(xhr.response != undefined && xhr.response.length != 0) {
|
||||
alert("Error: " + xhr.response);
|
||||
}
|
||||
else {
|
||||
alert("An error has occurred. Please try again. If problem persists contact server administrator.");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -27,17 +27,54 @@
|
|||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Create New Bundle Modal -->
|
||||
<div class="modal fade new-bundle-modal" tabindex="-1" role="dialog" aria-labelledby="new-bundle-modal" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Create New Bundle</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="_js_create-bundle-form" action="api/bundle/create" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="newBundleName">Bundle Name</label>
|
||||
<input name="name" type="text" class="form-control" id="newBundleName" aria-describedby="newBundleNameHelp" placeholder="Bundle Name">
|
||||
<small id="newBundleNameHelp" class="form-text text-muted">Bundle name must be unqiue in terms of your current bundle collection.</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="newBundleAccountPort">Bundle Account Port</label>
|
||||
<input name="account_port" type="number" class="form-control" id="newBundleAccountPort" aria-describedby="newBundleAccountPortHelp" min="2000" max="4000" value="2083">
|
||||
<small id="newBundleAccountPortHelp" class="form-text text-muted">Bundle account port must be unique in terms of your current bundle collection.</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="newBundlePublicPort">Bundle Public Port</label>
|
||||
<input name="public_port" type="number" class="form-control" id="newBundlePublicPort" aria-describedby="newBundlePublicPortHelp" min="2000" max="4000" value="2084">
|
||||
<small id="newBundlePublicPortHelp" class="form-text text-muted">Bundle public port must be unique in terms of your current bundle collection.</small>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Create Bundle</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Test</h4>
|
||||
<h6 class="card-subtitle mb-4 text-muted">Test</h6>
|
||||
<button class="btn btn-outline-primary">Test</button>
|
||||
</div>
|
||||
<div class="card-footer text-muted text-center">
|
||||
TEST
|
||||
<h4 class="card-title">Bundles</h4>
|
||||
<h6 class="card-subtitle mb-4 text-muted">Create new bundles and update current bundles.</h6>
|
||||
<div class="btn-group" role="group">
|
||||
<button class="btn btn-outline-primary _js_bundles-create">Create New Bundle</button>
|
||||
<button class="btn btn-outline-primary">Manage Current Bundles</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -64,6 +101,8 @@
|
|||
|
||||
<script type="text/javascript" src="assets/js/formHandlers/search.js"></script>
|
||||
<script type="text/javascript" src="assets/js/formHandlers/logout.js"></script>
|
||||
|
||||
<script type="text/javascript" src="assets/js/panelHandlers/bundles/create.js"></script>
|
||||
<!-- KEEP AT BOTTOM OF BODY TAGS -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
9
server/logs/README.md
Normal file
9
server/logs/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# gPanel Logs
|
||||
|
||||
The actual log files are ignored by the .gitignore file. They are generated automatically upon being needed within the software itself.
|
||||
|
||||
Current log files:
|
||||
- client_errors.log
|
||||
- account_errors.log
|
||||
- server_errors.log
|
||||
- loadtime.log
|
||||
Loading…
Add table
Add a link
Reference in a new issue