Replace www-path with www-proxy option for development (#248)

By adding a new ENV variable called `WOODPECKER_WWW_PROXY` it is possible to serve a webinterface via a proxy configured by the `WOODPECKER_WWW_PROXY` value for development instead of serving the interface from the bundled code or from some folder location as the old `WOODPECKER_WWW` option allowed. Using a proxy allows developing the UI with hot-reloading.
This commit is contained in:
Anbraten 2021-09-27 00:22:23 +02:00 committed by GitHub
parent da6fa0ec70
commit bd19f90756
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 27 additions and 47 deletions

View file

@ -64,9 +64,9 @@ var flags = []cli.Flag{
Usage: "enable quic",
},
cli.StringFlag{
EnvVar: "DRONE_WWW,WOODPECKER_WWW",
Name: "www",
Usage: "serve the website from disk",
EnvVar: "WOODPECKER_WWW_PROXY",
Name: "www-proxy",
Usage: "serve the website by using a proxy (used for development)",
Hidden: true,
},
cli.StringSliceFlag{

View file

@ -20,6 +20,7 @@ import (
"errors"
"net"
"net/http"
"net/http/httputil"
"net/url"
"os"
"path/filepath"
@ -90,13 +91,30 @@ func loop(c *cli.Context) error {
store_ := setupStore(c)
setupEvilGlobals(c, store_, remote_)
// we are switching from gin to httpservermux|treemux,
// so if this code looks strange, that is why.
tree := setupTree(c)
proxyWebUI := c.String("www-proxy")
var webUIServe func(w http.ResponseWriter, r *http.Request)
if proxyWebUI == "" {
// we are switching from gin to httpservermux|treemux,
webUIServe = setupTree(c).ServeHTTP
} else {
origin, _ := url.Parse(proxyWebUI)
director := func(req *http.Request) {
req.Header.Add("X-Forwarded-Host", req.Host)
req.Header.Add("X-Origin-Host", origin.Host)
req.URL.Scheme = origin.Scheme
req.URL.Host = origin.Host
}
proxy := &httputil.ReverseProxy{Director: director}
webUIServe = proxy.ServeHTTP
}
// setup the server and start the listener
handler := router.Load(
tree,
webUIServe,
ginrus.Ginrus(logrus.StandardLogger(), time.RFC3339, true),
middleware.Version,
middleware.Config(c),

View file

@ -209,7 +209,6 @@ func setupCoding(c *cli.Context) (remote.Remote, error) {
func setupTree(c *cli.Context) *httptreemux.ContextMux {
tree := httptreemux.NewContextMux()
web.New(
web.WithDir(c.String("www")),
web.WithSync(time.Hour*72),
web.WithDocs(c.String("docs")),
).Register(tree)

View file

@ -17,7 +17,6 @@ package router
import (
"net/http"
"github.com/dimfeld/httptreemux"
"github.com/gin-gonic/gin"
"github.com/woodpecker-ci/woodpecker/server/api"
@ -30,7 +29,7 @@ import (
)
// Load loads the router
func Load(mux *httptreemux.ContextMux, middleware ...gin.HandlerFunc) http.Handler {
func Load(serveHTTP func(w http.ResponseWriter, r *http.Request), middleware ...gin.HandlerFunc) http.Handler {
e := gin.New()
e.Use(gin.Recovery())
@ -49,7 +48,7 @@ func Load(mux *httptreemux.ContextMux, middleware ...gin.HandlerFunc) http.Handl
session.User(c),
),
)
mux.ServeHTTP(c.Writer, req)
serveHTTP(c.Writer, req)
})
e.GET("/logout", api.GetLogout)

View file

@ -19,7 +19,6 @@ import "time"
// Options defines website handler options.
type Options struct {
sync time.Duration
path string
docs string
}
@ -34,14 +33,6 @@ func WithSync(d time.Duration) Option {
}
}
// WithDir configures the website handler with the directory value
// used to serve the website from the local filesystem.
func WithDir(s string) Option {
return func(o *Options) {
o.path = s
}
}
// WithDocs configures the website handler with the documentation
// website address, which should be included in the user interface.
func WithDocs(s string) Option {

View file

@ -27,14 +27,6 @@ func TestWithSync(t *testing.T) {
}
}
func TestWithDir(t *testing.T) {
opts := new(Options)
WithDir("/tmp/www")(opts)
if got, want := opts.path, "/tmp/www"; got != want {
t.Errorf("Want www directory %q, got %q", want, got)
}
}
func TestWithDocs(t *testing.T) {
opts := new(Options)
WithDocs("http://docs.drone.io")(opts)

View file

@ -19,9 +19,7 @@ import (
"crypto/md5"
"fmt"
"html/template"
"io/ioutil"
"net/http"
"path/filepath"
"time"
"github.com/woodpecker-ci/woodpecker/model"
@ -45,10 +43,6 @@ func New(opt ...Option) Endpoint {
f(opts)
}
if opts.path != "" {
return fromPath(opts)
}
return &website{
fs: dist.New(),
opts: opts,
@ -58,19 +52,6 @@ func New(opt ...Option) Endpoint {
}
}
func fromPath(opts *Options) *website {
f := filepath.Join(opts.path, "index.html")
b, err := ioutil.ReadFile(f)
if err != nil {
panic(err)
}
return &website{
fs: http.Dir(opts.path),
tmpl: mustCreateTemplate(string(b)),
opts: opts,
}
}
type website struct {
opts *Options
fs http.FileSystem