control: Move serves into a separate components
This commit is contained in:
parent
6f409be8b2
commit
845e927117
12 changed files with 210 additions and 127 deletions
|
|
@ -39,7 +39,7 @@ func (upc updateprefixconfig) Run(context wisski_distillery.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
ddis := dis.Control()
|
ddis := dis.Control()
|
||||||
target := ddis.ResolverConfigPath()
|
target := dis.Resolver().ConfigPath()
|
||||||
|
|
||||||
// print the configuration
|
// print the configuration
|
||||||
config, err := dis.Core.Environment.Create(target, environment.DefaultFilePerm)
|
config, err := dis.Core.Environment.Create(target, environment.DefaultFilePerm)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component/instances"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/core"
|
"github.com/FAU-CDI/wisski-distillery/internal/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
||||||
)
|
)
|
||||||
|
|
@ -14,9 +13,9 @@ import (
|
||||||
type Control struct {
|
type Control struct {
|
||||||
component.ComponentBase
|
component.ComponentBase
|
||||||
|
|
||||||
Instances *instances.Instances
|
Servables []component.Servable
|
||||||
|
|
||||||
ResolverFile string
|
ResolverFile string // TODO: this shouldn't be needed!
|
||||||
}
|
}
|
||||||
|
|
||||||
func (control Control) Name() string {
|
func (control Control) Name() string {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component/instances"
|
"github.com/FAU-CDI/wisski-distillery/internal/component/instances"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
|
|
@ -16,7 +17,17 @@ import (
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (control *Control) info(io stream.IOStream) (http.Handler, error) {
|
type Info struct {
|
||||||
|
component.ComponentBase
|
||||||
|
|
||||||
|
Instances *instances.Instances
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Info) Name() string { return "control-info" }
|
||||||
|
|
||||||
|
func (*Info) Routes() []string { return []string{"/dis/"} }
|
||||||
|
|
||||||
|
func (info *Info) Handler(route string, io stream.IOStream) (http.Handler, error) {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
|
|
||||||
// handle everything under /dis/!
|
// handle everything under /dis/!
|
||||||
|
|
@ -29,7 +40,7 @@ func (control *Control) info(io stream.IOStream) (http.Handler, error) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// static stuff
|
// static stuff
|
||||||
static, err := control.disStatic()
|
static, err := info.disStatic()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -37,22 +48,22 @@ func (control *Control) info(io stream.IOStream) (http.Handler, error) {
|
||||||
|
|
||||||
// render everything
|
// render everything
|
||||||
mux.Handle("/dis/index", httpx.HTMLHandler[disIndex]{
|
mux.Handle("/dis/index", httpx.HTMLHandler[disIndex]{
|
||||||
Handler: control.disIndex,
|
Handler: info.disIndex,
|
||||||
Template: indexTemplate,
|
Template: indexTemplate,
|
||||||
})
|
})
|
||||||
|
|
||||||
mux.Handle("/dis/instance/", httpx.HTMLHandler[disInstance]{
|
mux.Handle("/dis/instance/", httpx.HTMLHandler[disInstance]{
|
||||||
Handler: control.disInstance,
|
Handler: info.disInstance,
|
||||||
Template: instanceTemplate,
|
Template: instanceTemplate,
|
||||||
})
|
})
|
||||||
|
|
||||||
// api -- for future usage
|
// api -- for future usage
|
||||||
mux.Handle("/dis/api/v1/instance/get/", httpx.JSON(control.getinstance))
|
mux.Handle("/dis/api/v1/instance/get/", httpx.JSON(info.getinstance))
|
||||||
mux.Handle("/dis/api/v1/instance/all", httpx.JSON(control.allinstances))
|
mux.Handle("/dis/api/v1/instance/all", httpx.JSON(info.allinstances))
|
||||||
|
|
||||||
// ensure that everyone is logged in!
|
// ensure that everyone is logged in!
|
||||||
return httpx.BasicAuth(mux, "WissKI Distillery Admin", func(user, pass string) bool {
|
return httpx.BasicAuth(mux, "WissKI Distillery Admin", func(user, pass string) bool {
|
||||||
return user == control.Config.DisAdminUser && pass == control.Config.DisAdminPassword
|
return user == info.Config.DisAdminUser && pass == info.Config.DisAdminPassword
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,12 +82,12 @@ type disIndex struct {
|
||||||
Backups []models.Snapshot
|
Backups []models.Snapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dis *Control) disIndex(r *http.Request) (idx disIndex, err error) {
|
func (info *Info) disIndex(r *http.Request) (idx disIndex, err error) {
|
||||||
var group errgroup.Group
|
var group errgroup.Group
|
||||||
|
|
||||||
group.Go(func() error {
|
group.Go(func() error {
|
||||||
// load instances
|
// load instances
|
||||||
idx.Instances, err = dis.allinstances(r)
|
idx.Instances, err = info.allinstances(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -96,12 +107,12 @@ func (dis *Control) disIndex(r *http.Request) (idx disIndex, err error) {
|
||||||
|
|
||||||
// get the log entries
|
// get the log entries
|
||||||
group.Go(func() (err error) {
|
group.Go(func() (err error) {
|
||||||
idx.Backups, err = dis.Instances.SnapshotLogFor("")
|
idx.Backups, err = info.Instances.SnapshotLogFor("")
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
|
|
||||||
// get the static properties
|
// get the static properties
|
||||||
idx.Config = dis.Config
|
idx.Config = info.Config
|
||||||
|
|
||||||
// current time
|
// current time
|
||||||
idx.Time = time.Now().UTC()
|
idx.Time = time.Now().UTC()
|
||||||
|
|
@ -120,13 +131,13 @@ type disInstance struct {
|
||||||
Info instances.WissKIInfo
|
Info instances.WissKIInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dis *Control) disInstance(r *http.Request) (is disInstance, err error) {
|
func (info *Info) disInstance(r *http.Request) (is disInstance, err error) {
|
||||||
// find the slug as the last component of path!
|
// find the slug as the last component of path!
|
||||||
slug := strings.TrimSuffix(r.URL.Path, "/")
|
slug := strings.TrimSuffix(r.URL.Path, "/")
|
||||||
slug = slug[strings.LastIndex(slug, "/")+1:]
|
slug = slug[strings.LastIndex(slug, "/")+1:]
|
||||||
|
|
||||||
// find the instance itself!
|
// find the instance itself!
|
||||||
instance, err := dis.Instances.WissKI(slug)
|
instance, err := info.Instances.WissKI(slug)
|
||||||
if err == instances.ErrWissKINotFound {
|
if err == instances.ErrWissKINotFound {
|
||||||
return is, httpx.ErrNotFound
|
return is, httpx.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
@ -150,7 +161,7 @@ func (dis *Control) disInstance(r *http.Request) (is disInstance, err error) {
|
||||||
//go:embed html/static
|
//go:embed html/static
|
||||||
var htmlStaticFS embed.FS
|
var htmlStaticFS embed.FS
|
||||||
|
|
||||||
func (*Control) disStatic() (http.Handler, error) {
|
func (*Info) disStatic() (http.Handler, error) {
|
||||||
fs, err := fs.Sub(htmlStaticFS, "html/static")
|
fs, err := fs.Sub(htmlStaticFS, "html/static")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -167,29 +178,29 @@ var indexTemplate = template.Must(template.New("index.html").Parse(indexTemplate
|
||||||
var instanceTemplateString string
|
var instanceTemplateString string
|
||||||
var instanceTemplate = template.Must(template.New("instance.html").Parse(instanceTemplateString))
|
var instanceTemplate = template.Must(template.New("instance.html").Parse(instanceTemplateString))
|
||||||
|
|
||||||
func (dis *Control) getinstance(r *http.Request) (info instances.WissKIInfo, err error) {
|
func (info *Info) getinstance(r *http.Request) (iinfo instances.WissKIInfo, err error) {
|
||||||
// find the slug as the last component of path!
|
// find the slug as the last component of path!
|
||||||
slug := strings.TrimSuffix(r.URL.Path, "/")
|
slug := strings.TrimSuffix(r.URL.Path, "/")
|
||||||
slug = slug[strings.LastIndex(slug, "/")+1:]
|
slug = slug[strings.LastIndex(slug, "/")+1:]
|
||||||
|
|
||||||
// load the wisski instance!
|
// load the wisski instance!
|
||||||
wisski, err := dis.Instances.WissKI(strings.TrimSuffix(slug, "/"))
|
wisski, err := info.Instances.WissKI(strings.TrimSuffix(slug, "/"))
|
||||||
if err == instances.ErrWissKINotFound {
|
if err == instances.ErrWissKINotFound {
|
||||||
return info, httpx.ErrNotFound
|
return iinfo, httpx.ErrNotFound
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return info, err
|
return iinfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// get info about it!
|
// get info about it!
|
||||||
return wisski.Info(false)
|
return wisski.Info(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dis *Control) allinstances(*http.Request) (infos []instances.WissKIInfo, err error) {
|
func (info *Info) allinstances(*http.Request) (infos []instances.WissKIInfo, err error) {
|
||||||
var errgroup errgroup.Group
|
var errgroup errgroup.Group
|
||||||
|
|
||||||
// list all the instances
|
// list all the instances
|
||||||
all, err := dis.Instances.All()
|
all, err := info.Instances.All()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -6,14 +6,30 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/internal/component/instances"
|
||||||
"github.com/tkw1536/goprogram/stream"
|
"github.com/tkw1536/goprogram/stream"
|
||||||
)
|
)
|
||||||
|
|
||||||
// self returns the handler for the self overrides
|
// SelfHandler implements serving the '/' route
|
||||||
func (control Control) self(io stream.IOStream) (redirect Redirect, err error) {
|
type SelfHandler struct {
|
||||||
|
component.ComponentBase
|
||||||
|
|
||||||
|
Instances *instances.Instances
|
||||||
|
}
|
||||||
|
|
||||||
|
func (SelfHandler) Name() string { return "control-self" }
|
||||||
|
|
||||||
|
func (*SelfHandler) Routes() []string { return []string{"/"} }
|
||||||
|
|
||||||
|
func (sh *SelfHandler) Handler(route string, io stream.IOStream) (http.Handler, error) {
|
||||||
|
// create a redirect
|
||||||
|
var redirect Redirect
|
||||||
|
var err error
|
||||||
|
|
||||||
// open the overrides file
|
// open the overrides file
|
||||||
overrides, err := control.Environment.Open(control.Config.SelfOverridesFile)
|
overrides, err := sh.Environment.Open(sh.Config.SelfOverridesFile)
|
||||||
io.Printf("loading overrides from %q\n", control.Config.SelfOverridesFile)
|
io.Printf("loading overrides from %q\n", sh.Config.SelfOverridesFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return redirect, err
|
return redirect, err
|
||||||
}
|
}
|
||||||
|
|
@ -21,18 +37,18 @@ func (control Control) self(io stream.IOStream) (redirect Redirect, err error) {
|
||||||
|
|
||||||
// decode the overrides file
|
// decode the overrides file
|
||||||
if err := json.NewDecoder(overrides).Decode(&redirect.Overrides); err != nil {
|
if err := json.NewDecoder(overrides).Decode(&redirect.Overrides); err != nil {
|
||||||
return redirect, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if redirect.Overrides == nil {
|
if redirect.Overrides == nil {
|
||||||
redirect.Overrides = make(map[string]string)
|
redirect.Overrides = make(map[string]string)
|
||||||
}
|
}
|
||||||
redirect.Overrides[""] = control.Config.SelfRedirect.String()
|
redirect.Overrides[""] = sh.Config.SelfRedirect.String()
|
||||||
|
|
||||||
// create a redirect server
|
// create a redirect server
|
||||||
redirect.Fallback, err = control.selfFallback()
|
redirect.Fallback, err = sh.selfFallback()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return redirect, err
|
return nil, err
|
||||||
}
|
}
|
||||||
redirect.Absolute = false
|
redirect.Absolute = false
|
||||||
redirect.Permanent = false
|
redirect.Permanent = false
|
||||||
|
|
@ -41,22 +57,22 @@ func (control Control) self(io stream.IOStream) (redirect Redirect, err error) {
|
||||||
return redirect, nil
|
return redirect, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (control *Control) selfFallback() (http.Handler, error) {
|
func (sh *SelfHandler) selfFallback() (http.Handler, error) {
|
||||||
return http.HandlerFunc(control.serveFallback), nil
|
return http.HandlerFunc(sh.serveFallback), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var notFoundText = []byte("not found")
|
var notFoundText = []byte("not found")
|
||||||
|
|
||||||
func (control *Control) serveFallback(w http.ResponseWriter, r *http.Request) {
|
func (sh *SelfHandler) serveFallback(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
slug := control.Config.SlugFromHost(r.Host)
|
slug := sh.Config.SlugFromHost(r.Host)
|
||||||
if slug == "" {
|
if slug == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
w.Write(notFoundText)
|
w.Write(notFoundText)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ok, _ := control.Instances.Has(slug); !ok {
|
if ok, _ := sh.Instances.Has(slug); !ok {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
fmt.Fprintf(w, "WissKI %q not found\n", slug)
|
fmt.Fprintf(w, "WissKI %q not found\n", slug)
|
||||||
return
|
return
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
package control
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
|
|
||||||
"github.com/FAU-CDI/wdresolve"
|
|
||||||
"github.com/FAU-CDI/wdresolve/resolvers"
|
|
||||||
"github.com/tkw1536/goprogram/stream"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (control Control) ResolverConfigPath() string {
|
|
||||||
return filepath.Join(control.Path(), control.ResolverFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (control Control) resolver(io stream.IOStream) (p wdresolve.ResolveHandler, err error) {
|
|
||||||
p.TrustXForwardedProto = true
|
|
||||||
|
|
||||||
fallback := &resolvers.Regexp{
|
|
||||||
Data: map[string]string{},
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle the default domain name!
|
|
||||||
domainName := control.Config.DefaultDomain
|
|
||||||
if domainName != "" {
|
|
||||||
fallback.Data[fmt.Sprintf("^https?://(.*)\\.%s", regexp.QuoteMeta(domainName))] = fmt.Sprintf("https://$1.%s", domainName)
|
|
||||||
io.Printf("registering default domain %s\n", domainName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle the extra domains!
|
|
||||||
for _, domain := range control.Config.SelfExtraDomains {
|
|
||||||
fallback.Data[fmt.Sprintf("^https?://(.*)\\.%s", regexp.QuoteMeta(domain))] = fmt.Sprintf("https://$1.%s", domainName)
|
|
||||||
io.Printf("registering legacy domain %s\n", domain)
|
|
||||||
}
|
|
||||||
|
|
||||||
// open the prefix file
|
|
||||||
prefixFile := control.ResolverConfigPath()
|
|
||||||
fs, err := control.Environment.Open(prefixFile)
|
|
||||||
io.Println("loading prefixes from ", prefixFile)
|
|
||||||
if err != nil {
|
|
||||||
return p, err
|
|
||||||
}
|
|
||||||
defer fs.Close()
|
|
||||||
|
|
||||||
// read the prefixes
|
|
||||||
// TODO: Do we want to load these without a file?
|
|
||||||
prefixes, err := resolvers.ReadPrefixes(fs)
|
|
||||||
if err != nil {
|
|
||||||
return p, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// and use that as the resolver!
|
|
||||||
p.Resolver = resolvers.InOrder{
|
|
||||||
prefixes,
|
|
||||||
fallback,
|
|
||||||
}
|
|
||||||
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
|
@ -7,33 +7,21 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server returns an http.Mux that implements the main server instance
|
// Server returns an http.Mux that implements the main server instance
|
||||||
func (control Control) Server(io stream.IOStream) (http.Handler, error) {
|
// Logging messages are directed to io.
|
||||||
// self server
|
func (control *Control) Server(io stream.IOStream) (*http.ServeMux, error) {
|
||||||
self, err := control.self(io)
|
// create a new mux
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resolver, err := control.resolver(io)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
info, err := control.info(io)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// resolver
|
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.Handle("/", self)
|
|
||||||
|
|
||||||
mux.Handle("/go/", resolver)
|
|
||||||
mux.Handle("/wisski/get/", resolver)
|
|
||||||
|
|
||||||
// TODO: Fix me!
|
|
||||||
mux.Handle("/dis/", info)
|
|
||||||
|
|
||||||
|
// add all the servable routes!
|
||||||
|
for _, s := range control.Servables {
|
||||||
|
for _, route := range s.Routes() {
|
||||||
|
io.Printf("mounting %s\n", route)
|
||||||
|
handler, err := s.Handler(route, io)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mux.Handle(route, handler)
|
||||||
|
}
|
||||||
|
}
|
||||||
return mux, nil
|
return mux, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
84
internal/component/resolver/resolver.go
Normal file
84
internal/component/resolver/resolver.go
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
package resolver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"net/http"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/FAU-CDI/wdresolve"
|
||||||
|
"github.com/FAU-CDI/wdresolve/resolvers"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/internal/component/control"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/pkg/lazy"
|
||||||
|
"github.com/tkw1536/goprogram/stream"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Resolver struct {
|
||||||
|
component.ComponentBase
|
||||||
|
|
||||||
|
Control *control.Control
|
||||||
|
ResolverFile string
|
||||||
|
|
||||||
|
handler lazy.Lazy[wdresolve.ResolveHandler]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Resolver) Name() string { return "resolver" }
|
||||||
|
|
||||||
|
func (resolver *Resolver) Routes() []string { return []string{"/go/", "/wisski/get/"} }
|
||||||
|
|
||||||
|
func (resolver *Resolver) Handler(route string, io stream.IOStream) (http.Handler, error) {
|
||||||
|
var err error
|
||||||
|
return resolver.handler.Get(func() (p wdresolve.ResolveHandler) {
|
||||||
|
p.TrustXForwardedProto = true
|
||||||
|
|
||||||
|
fallback := &resolvers.Regexp{
|
||||||
|
Data: map[string]string{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle the default domain name!
|
||||||
|
domainName := resolver.Config.DefaultDomain
|
||||||
|
if domainName != "" {
|
||||||
|
fallback.Data[fmt.Sprintf("^https?://(.*)\\.%s", regexp.QuoteMeta(domainName))] = fmt.Sprintf("https://$1.%s", domainName)
|
||||||
|
io.Printf("registering default domain %s\n", domainName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle the extra domains!
|
||||||
|
for _, domain := range resolver.Config.SelfExtraDomains {
|
||||||
|
fallback.Data[fmt.Sprintf("^https?://(.*)\\.%s", regexp.QuoteMeta(domain))] = fmt.Sprintf("https://$1.%s", domainName)
|
||||||
|
io.Printf("registering legacy domain %s\n", domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
configPath := resolver.ConfigPath()
|
||||||
|
{
|
||||||
|
// load the prefix path!
|
||||||
|
var fs fs.File
|
||||||
|
fs, err = resolver.Environment.Open(configPath)
|
||||||
|
io.Println("loading prefixes from ", configPath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer fs.Close()
|
||||||
|
|
||||||
|
// read the file
|
||||||
|
var prefixes resolvers.Prefix
|
||||||
|
prefixes, err = resolvers.ReadPrefixes(fs)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// and use that as the resolver!
|
||||||
|
p.Resolver = resolvers.InOrder{
|
||||||
|
prefixes,
|
||||||
|
fallback,
|
||||||
|
}
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (resolver *Resolver) ConfigPath() string {
|
||||||
|
return filepath.Join(resolver.Control.Path(), resolver.ResolverFile)
|
||||||
|
}
|
||||||
18
internal/component/server.go
Normal file
18
internal/component/server.go
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
package component
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/tkw1536/goprogram/stream"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Servable implements a component with a Serve method
|
||||||
|
type Servable interface {
|
||||||
|
Component
|
||||||
|
|
||||||
|
// Routes returns the routes served by this servable
|
||||||
|
Routes() []string
|
||||||
|
|
||||||
|
// Handler returns the handler for the requested route
|
||||||
|
Handler(route string, io stream.IOStream) (http.Handler, error)
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Package config provides the distillery configuration
|
// Package config contains distillery configuration
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// This file contains domain related derived configuration values.
|
// This file contains domain related derived configuration values.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component/control"
|
"github.com/FAU-CDI/wisski-distillery/internal/component/control"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component/instances"
|
"github.com/FAU-CDI/wisski-distillery/internal/component/instances"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/internal/component/resolver"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component/snapshots"
|
"github.com/FAU-CDI/wisski-distillery/internal/component/snapshots"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component/sql"
|
"github.com/FAU-CDI/wisski-distillery/internal/component/sql"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component/ssh"
|
"github.com/FAU-CDI/wisski-distillery/internal/component/ssh"
|
||||||
|
|
@ -49,7 +50,7 @@ func (dis *Distillery) cWeb(thread int32) *web.Web {
|
||||||
func (dis *Distillery) cControl(thread int32) *control.Control {
|
func (dis *Distillery) cControl(thread int32) *control.Control {
|
||||||
return component.InitComponent(&dis.pool, thread, dis.Core, func(control *control.Control, thread int32) {
|
return component.InitComponent(&dis.pool, thread, dis.Core, func(control *control.Control, thread int32) {
|
||||||
control.ResolverFile = core.PrefixConfig
|
control.ResolverFile = core.PrefixConfig
|
||||||
control.Instances = dis.cInstances(thread)
|
control.Servables = dis.cServables(thread)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,6 +90,13 @@ func (dis *Distillery) cSnapshotManager(thread int32) *snapshots.Manager {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dis *Distillery) cResolver(thread int32) *resolver.Resolver {
|
||||||
|
return component.InitComponent(&dis.pool, thread, dis.Core, func(resolver *resolver.Resolver, thread int32) {
|
||||||
|
resolver.Control = dis.cControl(thread)
|
||||||
|
resolver.ResolverFile = core.PrefixConfig
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// ALL COMPONENTS
|
// ALL COMPONENTS
|
||||||
//
|
//
|
||||||
|
|
@ -96,7 +104,6 @@ func (dis *Distillery) cSnapshotManager(thread int32) *snapshots.Manager {
|
||||||
func (dis *Distillery) cComponents(thread int32) []component.Component {
|
func (dis *Distillery) cComponents(thread int32) []component.Component {
|
||||||
return []component.Component{
|
return []component.Component{
|
||||||
dis.cWeb(thread),
|
dis.cWeb(thread),
|
||||||
dis.cControl(thread),
|
|
||||||
dis.cSSH(thread),
|
dis.cSSH(thread),
|
||||||
dis.cTriplestore(thread),
|
dis.cTriplestore(thread),
|
||||||
dis.cSQL(thread),
|
dis.cSQL(thread),
|
||||||
|
|
@ -110,6 +117,16 @@ func (dis *Distillery) cComponents(thread int32) []component.Component {
|
||||||
c(dis, thread, func(pbs *snapshots.Pathbuilders, thread int32) {
|
c(dis, thread, func(pbs *snapshots.Pathbuilders, thread int32) {
|
||||||
pbs.Instances = dis.cInstances(thread)
|
pbs.Instances = dis.cInstances(thread)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
// Control server
|
||||||
|
dis.cControl(thread),
|
||||||
|
c(dis, thread, func(sh *control.SelfHandler, thread int32) {
|
||||||
|
sh.Instances = dis.cInstances(thread)
|
||||||
|
}),
|
||||||
|
dis.cResolver(thread),
|
||||||
|
c(dis, thread, func(info *control.Info, thread int32) {
|
||||||
|
info.Instances = dis.cInstances(thread)
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,6 +154,10 @@ func (dis *Distillery) cSnapshotable(thread int32) []component.Snapshotable {
|
||||||
return getComponentSubtype[component.Snapshotable](dis, thread)
|
return getComponentSubtype[component.Snapshotable](dis, thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dis *Distillery) cServables(thread int32) []component.Servable {
|
||||||
|
return getComponentSubtype[component.Servable](dis, thread)
|
||||||
|
}
|
||||||
|
|
||||||
func getComponentSubtype[C component.Component](dis *Distillery, thread int32) (components []C) {
|
func getComponentSubtype[C component.Component](dis *Distillery, thread int32) (components []C) {
|
||||||
all := dis.cComponents(thread)
|
all := dis.cComponents(thread)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component/control"
|
"github.com/FAU-CDI/wisski-distillery/internal/component/control"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component/instances"
|
"github.com/FAU-CDI/wisski-distillery/internal/component/instances"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/internal/component/resolver"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component/snapshots"
|
"github.com/FAU-CDI/wisski-distillery/internal/component/snapshots"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component/sql"
|
"github.com/FAU-CDI/wisski-distillery/internal/component/sql"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/component/ssh"
|
"github.com/FAU-CDI/wisski-distillery/internal/component/ssh"
|
||||||
|
|
@ -49,6 +50,9 @@ func (dis *Distillery) Context() context.Context {
|
||||||
func (dis *Distillery) Control() *control.Control {
|
func (dis *Distillery) Control() *control.Control {
|
||||||
return dis.cControl(dis.thread())
|
return dis.cControl(dis.thread())
|
||||||
}
|
}
|
||||||
|
func (dis *Distillery) Resolver() *resolver.Resolver {
|
||||||
|
return dis.cResolver(dis.thread())
|
||||||
|
}
|
||||||
func (dis *Distillery) SSH() *ssh.SSH {
|
func (dis *Distillery) SSH() *ssh.SSH {
|
||||||
return dis.cSSH(dis.thread())
|
return dis.cSSH(dis.thread())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue