diff --git a/cmd/main.go b/cmd/main.go index 568965a3..02eccd63 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -7,9 +7,10 @@ import ( "github.com/gorilla/mux" "github.com/mickael-kerjean/filestash" - . "github.com/mickael-kerjean/filestash/server" + "github.com/mickael-kerjean/filestash/server" . "github.com/mickael-kerjean/filestash/server/common" - . "github.com/mickael-kerjean/filestash/server/ctrl" + "github.com/mickael-kerjean/filestash/server/ctrl" + "github.com/mickael-kerjean/filestash/server/model" _ "github.com/mickael-kerjean/filestash/server/plugin" ) @@ -18,7 +19,7 @@ func main() { router *mux.Router = mux.NewRouter() app = App{} ) - Build(router, app) + server.Build(router, app) Run(router, app) } @@ -27,21 +28,20 @@ func Run(routes *mux.Router, app App) { // support many more protocols in the future: HTTPS, HTTP2, TOR or whatever that sounds // fancy I don't know much when this got written: IPFS, solid, ... Log.Info("Filestash %s starting", APP_VERSION) + check(InitLogger(), "Logger init failed. err=%s") + check(InitConfig(), "Config init failed. err=%s") + check(model.PluginDiscovery(), "Plugin Discovery failed. err=%s") + ctrl.InitPluginList(embed.EmbedPluginList, model.PLUGINS) if len(Hooks.Get.Starter()) == 0 { - Log.Warning("No starter plugin available") - os.Exit(1) - return + check(ErrNotFound, "Missing starter plugin. err=%s") } - InitLogger() - InitConfig() - InitPluginList(embed.EmbedPluginList) for _, obj := range Hooks.Get.HttpEndpoint() { obj(routes, &app) } for _, fn := range Hooks.Get.Onload() { fn() } - CatchAll(routes, app) + server.CatchAll(routes, app) var wg sync.WaitGroup for _, obj := range Hooks.Get.Starter() { wg.Add(1) @@ -52,3 +52,11 @@ func Run(routes *mux.Router, app App) { } wg.Wait() } + +func check(err error, msg string) { + if err == nil { + return + } + Log.Error(msg, err.Error()) + os.Exit(1) +} diff --git a/server/common/config.go b/server/common/config.go index b99ed05f..116a84d3 100644 --- a/server/common/config.go +++ b/server/common/config.go @@ -50,10 +50,13 @@ type FormElement struct { Required bool `json:"required"` } -func InitConfig() { +func InitConfig() error { Config = NewConfiguration() - Config.Load() + if err := Config.Load(); err != nil { + return err + } Config.Initialise() + return nil } func NewConfiguration() Configuration { @@ -218,11 +221,11 @@ func (this *Form) Iterator() []FormIterator { return slice } -func (this *Configuration) Load() { +func (this *Configuration) Load() error { cFile, err := LoadConfig() if err != nil { Log.Error("config::load %s", err) - return + return err } // Extract enabled backends @@ -251,7 +254,7 @@ func (this *Configuration) Load() { this.onChange[i].Listener <- nil } }() - return + return nil } type JSONIterator struct { diff --git a/server/common/log.go b/server/common/log.go index 32d54b9f..32230139 100644 --- a/server/common/log.go +++ b/server/common/log.go @@ -13,14 +13,14 @@ var ( logfile *os.File ) -func InitLogger() { - var err error - logfile, err = os.OpenFile(GetAbsolutePath(LOG_PATH, "access.log"), os.O_APPEND|os.O_WRONLY|os.O_CREATE, os.ModePerm) +func InitLogger() error { + logfile, err := os.OpenFile(GetAbsolutePath(LOG_PATH, "access.log"), os.O_APPEND|os.O_WRONLY|os.O_CREATE, os.ModePerm) if err != nil { slog.Printf("ERROR log file: %+v", err) - return + return err } logfile.WriteString("") + return nil } type log struct { diff --git a/server/ctrl/about.go b/server/ctrl/about.go new file mode 100644 index 00000000..d5321087 --- /dev/null +++ b/server/ctrl/about.go @@ -0,0 +1,124 @@ +package ctrl + +import ( + "fmt" + "html" + "net/http" + "os" + "path/filepath" + "regexp" + "strings" + "text/template" + + . "github.com/mickael-kerjean/filestash/server/common" + "github.com/mickael-kerjean/filestash/server/model" +) + +var listOfPlugins = struct { + oss []string + enterprise []string + custom []string + apps []string +}{} + +func InitPluginList(code []byte, plgs map[string]model.PluginImpl) { + listOfPackages := regexp.MustCompile(`\t_?\s*\"(github.com/[^\"]+)`).FindAllStringSubmatch(string(code), -1) + for _, packageNameMatch := range listOfPackages { + if len(packageNameMatch) != 2 { + Log.Error("ctrl::static error=assertion_failed msg=invalid_match_size arg=%d", len(packageNameMatch)) + } + packageName := packageNameMatch[1] + packageShortName := filepath.Base(packageName) + + if strings.HasPrefix(packageName, "github.com/mickael-kerjean/filestash/server/plugin/") { + listOfPlugins.oss = append(listOfPlugins.oss, packageShortName) + } else if strings.HasPrefix(packageName, "github.com/mickael-kerjean/filestash/filestash-enterprise/plugins/") { + listOfPlugins.enterprise = append(listOfPlugins.enterprise, packageShortName) + } else if strings.HasPrefix(packageName, "github.com/mickael-kerjean/filestash/filestash-enterprise/customers/") { + listOfPlugins.custom = append(listOfPlugins.custom, packageShortName) + } else { + listOfPlugins.custom = append(listOfPlugins.custom, packageShortName) + } + } + for name, _ := range plgs { + listOfPlugins.apps = append(listOfPlugins.apps, name) + } +} + +func AboutHandler(ctx *App, res http.ResponseWriter, req *http.Request) { + t, _ := template. + New("about"). + Funcs(map[string]interface{}{ + "renderPlugin": func(lstr string, commit string) string { + if len(lstr) == 0 { + return "N/A" + } else if commit == "" { + return html.EscapeString(lstr) + } + list := strings.Split(lstr, " ") + for i, _ := range list { + list[i] = `` + html.EscapeString(list[i]) + `` + } + return strings.Join(list, " ") + }, + }). + Parse(Page(` +

{{ .Version }}

+ + + + + + + + + +
Commit hash {{ .CommitHash }}
Binary hash {{ index .Checksum 0}}
Config hash {{ index .Checksum 1}}
License {{ .License }}
Plugins + STANDARD[{{ renderPlugin (index .Plugins 0) .CommitHash }}] +
+ APPS[{{ renderPlugin (index .Plugins 3) "" }}] +
+ ENTERPRISE[{{ renderPlugin (index .Plugins 1) "" }}] +
+ CUSTOM[{{ renderPlugin (index .Plugins 2) "" }}] +
+ + + `)) + hashFileContent := func(path string, n int) string { + f, err := os.OpenFile(path, os.O_RDONLY, os.ModePerm) + if err != nil { + return "" + } + defer f.Close() + return HashStream(f, n) + } + t.Execute(res, struct { + Version string + CommitHash string + Checksum []string + License string + Plugins []string + }{ + Version: fmt.Sprintf("Filestash %s.%s", APP_VERSION, BUILD_DATE), + CommitHash: BUILD_REF, + Checksum: []string{ + hashFileContent(GetAbsolutePath("filestash"), 0), + hashFileContent(GetAbsolutePath(CONFIG_PATH, "config.json"), 0), + }, + License: strings.ToUpper(LICENSE), + Plugins: []string{ + strings.Join(listOfPlugins.oss, " "), + strings.Join(listOfPlugins.enterprise, " "), + strings.Join(listOfPlugins.custom, " "), + strings.Join(listOfPlugins.apps, " "), + }, + }) +} diff --git a/server/ctrl/plugin.go b/server/ctrl/plugin.go index 33b7b0fb..c34dd0c8 100644 --- a/server/ctrl/plugin.go +++ b/server/ctrl/plugin.go @@ -13,15 +13,6 @@ import ( "github.com/gorilla/mux" ) -func init() { - Hooks.Register.Onload(func() { - if err := model.PluginDiscovery(); err != nil { - Log.Error("Plugin Discovery failed. err=%s", err.Error()) - os.Exit(1) - } - }) -} - func PluginExportHandler(ctx *App, res http.ResponseWriter, req *http.Request) { plgExports := map[string][]string{} for name, plg := range model.PLUGINS { diff --git a/server/ctrl/static.go b/server/ctrl/static.go index ec942eda..3b6bb2bf 100644 --- a/server/ctrl/static.go +++ b/server/ctrl/static.go @@ -11,7 +11,6 @@ import ( "net/http" "os" "path/filepath" - "regexp" "strings" "text/template" @@ -105,87 +104,6 @@ func NotFoundHandler(ctx *App, res http.ResponseWriter, req *http.Request) { SendErrorResult(res, ErrNotFound) } -var listOfPlugins map[string][]string = map[string][]string{ - "oss": []string{}, - "enterprise": []string{}, - "custom": []string{}, -} - -func AboutHandler(ctx *App, res http.ResponseWriter, req *http.Request) { - t, _ := template. - New("about"). - Funcs(map[string]interface{}{ - "renderPlugin": func(lstr string, commit string) string { - if len(lstr) == 0 { - return "N/A" - } else if commit == "" { - return lstr - } - list := strings.Split(lstr, " ") - for i, _ := range list { - list[i] = `` + list[i] + `` - } - return strings.Join(list, " ") - }, - }). - Parse(Page(` -

{{ .Version }}

- - - - - - - - - -
Commit hash {{ .CommitHash }}
Binary hash {{ index .Checksum 0}}
Config hash {{ index .Checksum 1}}
License {{ .License }}
Plugins - STANDARD[{{ renderPlugin (index .Plugins 0) .CommitHash }}] -
- ENTERPRISE[{{ renderPlugin (index .Plugins 1) "" }}] -
- CUSTOM[{{ renderPlugin (index .Plugins 2) "" }}] -
- - - `)) - hashFileContent := func(path string, n int) string { - f, err := os.OpenFile(path, os.O_RDONLY, os.ModePerm) - if err != nil { - return "" - } - defer f.Close() - return HashStream(f, n) - } - t.Execute(res, struct { - Version string - CommitHash string - Checksum []string - License string - Plugins []string - }{ - Version: fmt.Sprintf("Filestash %s.%s", APP_VERSION, BUILD_DATE), - CommitHash: BUILD_REF, - Checksum: []string{ - hashFileContent(GetAbsolutePath("filestash"), 0), - hashFileContent(GetAbsolutePath(CONFIG_PATH, "config.json"), 0), - }, - License: strings.ToUpper(LICENSE), - Plugins: []string{ - strings.Join(listOfPlugins["oss"], " "), - strings.Join(listOfPlugins["enterprise"], " "), - strings.Join(listOfPlugins["custom"], " "), - }, - }) -} - func ManifestHandler(ctx *App, res http.ResponseWriter, req *http.Request) { res.WriteHeader(http.StatusOK) res.Write([]byte(fmt.Sprintf(`{ @@ -234,7 +152,6 @@ func ServeFile(chroot string) func(*App, http.ResponseWriter, *http.Request) { ) head := res.Header() - // case: patch must be apply because of a "StaticPatch" plugin if f := applyPatch(filePath); f != nil { head.Set("Content-Type", GetMimeType(filepath.Ext(filePath))) head.Set("Cache-Control", "no-cache") @@ -405,27 +322,6 @@ func applyPatch(filePath string) (file *bytes.Buffer) { return nil } -func InitPluginList(code []byte) { - listOfPackages := regexp.MustCompile(`\t_?\s*\"(github.com/[^\"]+)`).FindAllStringSubmatch(string(code), -1) - for _, packageNameMatch := range listOfPackages { - if len(packageNameMatch) != 2 { - Log.Error("ctrl::static error=assertion_failed msg=invalid_match_size arg=%d", len(packageNameMatch)) - } - packageName := packageNameMatch[1] - packageShortName := filepath.Base(packageName) - - if strings.HasPrefix(packageName, "github.com/mickael-kerjean/filestash/server/plugin/") { - listOfPlugins["oss"] = append(listOfPlugins["oss"], packageShortName) - } else if strings.HasPrefix(packageName, "github.com/mickael-kerjean/filestash/filestash-enterprise/plugins/") { - listOfPlugins["enterprise"] = append(listOfPlugins["enterprise"], packageShortName) - } else if strings.HasPrefix(packageName, "github.com/mickael-kerjean/filestash/filestash-enterprise/customers/") { - listOfPlugins["custom"] = append(listOfPlugins["custom"], packageShortName) - } else { - listOfPlugins["custom"] = append(listOfPlugins["custom"], packageShortName) - } - } -} - func preload() string { out, _ := json.Marshal([][]string{ { diff --git a/server/routes.go b/server/routes.go index 55265510..fa4f88b6 100644 --- a/server/routes.go +++ b/server/routes.go @@ -1,4 +1,4 @@ -package routes +package server import ( "fmt"