mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-25 19:31:05 +00:00
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:
parent
da6fa0ec70
commit
bd19f90756
7 changed files with 27 additions and 47 deletions
|
@ -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{
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue