Bundle and serve admin (#317)
* WIP with admin bundling * Current state of the admin is bundled * Update admin bundler to work with binary bundling * Log detail about the admin interface. Closes #312 * Move bundle script to the build dir * Update to current version of admin * Commit updated API documentation Co-authored-by: Owncast <owncast@owncast.online>
This commit is contained in:
parent
2517e9944e
commit
1dbd550134
1
.gitignore
vendored
1
.gitignore
vendored
@ -25,6 +25,7 @@ webroot/static/content.md
|
||||
hls/
|
||||
dist/
|
||||
data/
|
||||
admin/
|
||||
transcoder.log
|
||||
chat.db
|
||||
.yp.key
|
||||
|
40
build/admin/bundleAdmin.sh
Executable file
40
build/admin/bundleAdmin.sh
Executable file
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2059
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
INSTALL_TEMP_DIRECTORY="$(mktemp -d)"
|
||||
PROJECT_SOURCE_DIR=$(pwd)
|
||||
cd $INSTALL_TEMP_DIRECTORY
|
||||
|
||||
shutdown () {
|
||||
rm -rf "$PROJECT_SOURCE_DIR/admin"
|
||||
rm -rf "$INSTALL_TEMP_DIRECTORY"
|
||||
}
|
||||
trap shutdown INT TERM ABRT EXIT
|
||||
|
||||
echo "Cloning owncast admin into $INSTALL_TEMP_DIRECTORY..."
|
||||
git clone --depth 1 https://github.com/owncast/owncast-admin 2> /dev/null
|
||||
cd owncast-admin
|
||||
|
||||
echo "Installing npm modules for the owncast admin..."
|
||||
npm --silent install 2> /dev/null
|
||||
|
||||
echo "Building owncast admin..."
|
||||
rm -rf .next
|
||||
(node_modules/.bin/next build && node_modules/.bin/next export) | grep info
|
||||
|
||||
echo "Copying admin to project directory..."
|
||||
ADMIN_BUILD_DIR=$(pwd)
|
||||
cd $PROJECT_SOURCE_DIR
|
||||
mkdir -p admin 2> /dev/null
|
||||
cd admin
|
||||
cp -R ${ADMIN_BUILD_DIR}/out/* .
|
||||
|
||||
echo "Bundling admin into owncast codebase..."
|
||||
~/go/bin/pkger
|
||||
|
||||
shutdown
|
||||
echo "Done."
|
44
controllers/admin/index.go
Normal file
44
controllers/admin/index.go
Normal file
@ -0,0 +1,44 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/markbates/pkger"
|
||||
"github.com/owncast/owncast/router/middleware"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// ServeAdmin will return admin web assets
|
||||
func ServeAdmin(w http.ResponseWriter, r *http.Request) {
|
||||
// Set a cache control max-age header
|
||||
middleware.SetCachingHeaders(w, r)
|
||||
|
||||
path := r.URL.Path
|
||||
if path == "/admin" || path == "/admin/" {
|
||||
path = "/admin/index.html"
|
||||
}
|
||||
|
||||
f, err := pkger.Open(path)
|
||||
if err != nil {
|
||||
log.Warnln(err, path)
|
||||
errorHandler(w, r, http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
log.Warnln(err)
|
||||
return
|
||||
}
|
||||
|
||||
mimeType := mime.TypeByExtension(filepath.Ext(path))
|
||||
w.Header().Set("Content-Type", mimeType)
|
||||
w.Write(b)
|
||||
}
|
||||
|
||||
func errorHandler(w http.ResponseWriter, r *http.Request, status int) {
|
||||
w.WriteHeader(status)
|
||||
}
|
@ -28,7 +28,6 @@ type MetadataPage struct {
|
||||
//IndexHandler handles the default index route
|
||||
func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
||||
middleware.EnableCors(&w)
|
||||
|
||||
isIndexRequest := r.URL.Path == "/" || filepath.Base(r.URL.Path) == "index.html" || filepath.Base(r.URL.Path) == ""
|
||||
|
||||
// For search engine bots and social scrapers return a special
|
||||
|
@ -65,6 +65,10 @@ func Start() error {
|
||||
// start the rtmp server
|
||||
go rtmp.Start(setStreamAsConnected, setBroadcaster)
|
||||
|
||||
port := config.Config.GetPublicWebServerPort()
|
||||
log.Infof("Web server is listening on port %d, RTMP is accepting inbound streams on port 1935.", port)
|
||||
log.Infoln("The web admin interface is available at /admin.")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ func Start(setStreamAsConnected func(), setBroadcaster func(models.Broadcaster))
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
log.Infof("RTMP server is listening for incoming stream on port: %d", port)
|
||||
log.Tracef("RTMP server is listening for incoming stream on port: %d", port)
|
||||
|
||||
for {
|
||||
nc, err := lis.Accept()
|
||||
|
1
go.mod
1
go.mod
@ -8,6 +8,7 @@ require (
|
||||
github.com/aws/aws-sdk-go v1.35.22
|
||||
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||
github.com/grafov/m3u8 v0.11.1
|
||||
github.com/markbates/pkger v0.17.1
|
||||
github.com/mattn/go-sqlite3 v1.14.4
|
||||
github.com/microcosm-cc/bluemonday v1.0.4
|
||||
github.com/mssola/user_agent v0.5.2
|
||||
|
7
go.sum
7
go.sum
@ -13,6 +13,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/gobuffalo/here v0.6.0 h1:hYrd0a6gDmWxBM4TnrGw8mQg24iSVoIkHEk7FodQcBI=
|
||||
github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
|
||||
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
||||
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||
github.com/grafov/m3u8 v0.11.1 h1:igZ7EBIB2IAsPPazKwRKdbhxcoBKO3lO1UY57PZDeNA=
|
||||
@ -21,9 +23,12 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/markbates/pkger v0.17.1 h1:/MKEtWqtc0mZvu9OinB9UzVN9iYCwLWuyUv4Bw+PCno=
|
||||
github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI=
|
||||
github.com/mattn/go-sqlite3 v1.14.4 h1:4rQjbDxdu9fSgI/r3KN72G3c2goxknAqHHgPWWs8UlI=
|
||||
github.com/mattn/go-sqlite3 v1.14.4/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
|
||||
github.com/microcosm-cc/bluemonday v1.0.4 h1:p0L+CTpo/PLFdkoPcJemLXG+fpMD7pYOoDEq1axMbGg=
|
||||
@ -79,9 +84,11 @@ golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
4
main.go
4
main.go
@ -4,6 +4,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/markbates/pkger"
|
||||
"github.com/owncast/owncast/logging"
|
||||
"github.com/sirupsen/logrus"
|
||||
log "github.com/sirupsen/logrus"
|
||||
@ -29,6 +30,8 @@ func main() {
|
||||
configureLogging()
|
||||
|
||||
log.Infoln(getReleaseString())
|
||||
// Enable bundling of admin assets
|
||||
pkger.Include("/admin")
|
||||
|
||||
configFile := flag.String("configFile", "config.yaml", "Config File full path. Defaults to current folder")
|
||||
dbFile := flag.String("database", "", "Path to the database file.")
|
||||
@ -72,7 +75,6 @@ func main() {
|
||||
log.Error("failed to start/run the router")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//getReleaseString gets the version string
|
||||
|
@ -19,6 +19,9 @@ func Start() error {
|
||||
// static files
|
||||
http.HandleFunc("/", controllers.IndexHandler)
|
||||
|
||||
// admin static files
|
||||
http.HandleFunc("/admin/", middleware.RequireAdminAuth(admin.ServeAdmin))
|
||||
|
||||
// status of the system
|
||||
http.HandleFunc("/api/status", controllers.GetStatus)
|
||||
|
||||
@ -76,7 +79,7 @@ func Start() error {
|
||||
|
||||
port := config.Config.GetPublicWebServerPort()
|
||||
|
||||
log.Infof("Web server running on port: %d", port)
|
||||
log.Tracef("Web server running on port: %d", port)
|
||||
|
||||
return http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
PROJECT_SOURCE_DIR=$(pwd)
|
||||
mkdir $TMPDIR/admin 2> /dev/null
|
||||
cd $TMPDIR/admin
|
||||
git clone --depth 1 https://github.com/owncast/owncast-admin 2> /dev/null
|
||||
cd owncast-admin
|
||||
npm --silent install 2> /dev/null
|
||||
(node_modules/.bin/next build && node_modules/.bin/next export) | grep info
|
||||
ADMIN_BUILD_DIR=$(pwd)
|
||||
cd $PROJECT_SOURCE_DIR
|
||||
mkdir webroot/admin 2> /dev/null
|
||||
cd webroot/admin
|
||||
cp -R ${ADMIN_BUILD_DIR}/out/* .
|
||||
rm -rf $TMPDIR/admin
|
Loading…
Reference in New Issue
Block a user