mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-29 05:11:04 +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",
|
Usage: "enable quic",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
EnvVar: "DRONE_WWW,WOODPECKER_WWW",
|
EnvVar: "WOODPECKER_WWW_PROXY",
|
||||||
Name: "www",
|
Name: "www-proxy",
|
||||||
Usage: "serve the website from disk",
|
Usage: "serve the website by using a proxy (used for development)",
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
cli.StringSliceFlag{
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httputil"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -90,13 +91,30 @@ func loop(c *cli.Context) error {
|
||||||
store_ := setupStore(c)
|
store_ := setupStore(c)
|
||||||
setupEvilGlobals(c, store_, remote_)
|
setupEvilGlobals(c, store_, remote_)
|
||||||
|
|
||||||
// we are switching from gin to httpservermux|treemux,
|
proxyWebUI := c.String("www-proxy")
|
||||||
// so if this code looks strange, that is why.
|
|
||||||
tree := setupTree(c)
|
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
|
// setup the server and start the listener
|
||||||
handler := router.Load(
|
handler := router.Load(
|
||||||
tree,
|
webUIServe,
|
||||||
ginrus.Ginrus(logrus.StandardLogger(), time.RFC3339, true),
|
ginrus.Ginrus(logrus.StandardLogger(), time.RFC3339, true),
|
||||||
middleware.Version,
|
middleware.Version,
|
||||||
middleware.Config(c),
|
middleware.Config(c),
|
||||||
|
|
|
@ -209,7 +209,6 @@ func setupCoding(c *cli.Context) (remote.Remote, error) {
|
||||||
func setupTree(c *cli.Context) *httptreemux.ContextMux {
|
func setupTree(c *cli.Context) *httptreemux.ContextMux {
|
||||||
tree := httptreemux.NewContextMux()
|
tree := httptreemux.NewContextMux()
|
||||||
web.New(
|
web.New(
|
||||||
web.WithDir(c.String("www")),
|
|
||||||
web.WithSync(time.Hour*72),
|
web.WithSync(time.Hour*72),
|
||||||
web.WithDocs(c.String("docs")),
|
web.WithDocs(c.String("docs")),
|
||||||
).Register(tree)
|
).Register(tree)
|
||||||
|
|
|
@ -17,7 +17,6 @@ package router
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/dimfeld/httptreemux"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"github.com/woodpecker-ci/woodpecker/server/api"
|
"github.com/woodpecker-ci/woodpecker/server/api"
|
||||||
|
@ -30,7 +29,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Load loads the router
|
// 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 := gin.New()
|
||||||
e.Use(gin.Recovery())
|
e.Use(gin.Recovery())
|
||||||
|
@ -49,7 +48,7 @@ func Load(mux *httptreemux.ContextMux, middleware ...gin.HandlerFunc) http.Handl
|
||||||
session.User(c),
|
session.User(c),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
mux.ServeHTTP(c.Writer, req)
|
serveHTTP(c.Writer, req)
|
||||||
})
|
})
|
||||||
|
|
||||||
e.GET("/logout", api.GetLogout)
|
e.GET("/logout", api.GetLogout)
|
||||||
|
|
|
@ -19,7 +19,6 @@ import "time"
|
||||||
// Options defines website handler options.
|
// Options defines website handler options.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
sync time.Duration
|
sync time.Duration
|
||||||
path string
|
|
||||||
docs 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
|
// WithDocs configures the website handler with the documentation
|
||||||
// website address, which should be included in the user interface.
|
// website address, which should be included in the user interface.
|
||||||
func WithDocs(s string) Option {
|
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) {
|
func TestWithDocs(t *testing.T) {
|
||||||
opts := new(Options)
|
opts := new(Options)
|
||||||
WithDocs("http://docs.drone.io")(opts)
|
WithDocs("http://docs.drone.io")(opts)
|
||||||
|
|
|
@ -19,9 +19,7 @@ import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/woodpecker-ci/woodpecker/model"
|
"github.com/woodpecker-ci/woodpecker/model"
|
||||||
|
@ -45,10 +43,6 @@ func New(opt ...Option) Endpoint {
|
||||||
f(opts)
|
f(opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.path != "" {
|
|
||||||
return fromPath(opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &website{
|
return &website{
|
||||||
fs: dist.New(),
|
fs: dist.New(),
|
||||||
opts: opts,
|
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 {
|
type website struct {
|
||||||
opts *Options
|
opts *Options
|
||||||
fs http.FileSystem
|
fs http.FileSystem
|
||||||
|
|
Loading…
Reference in a new issue