// StartModule sets up the module with the given name. func StartModule(name string, setup func(context *ModuleContext) error) { logger := log.New(os.Stderr, name+" ", log.LstdFlags) // Load configuration flag.Parse() if flag.NArg() != 1 { logger.Fatal("Expecting configuration path.") } cfgPath := util.GetConfigPath(flag.Arg(0)) settings, err := util.LoadMonstiSettings(cfgPath) if err != nil { logger.Fatal("Could not load settings: ", err) } gettext.DefaultLocales.Domain = "monsti-" + name gettext.DefaultLocales.LocaleDir = settings.Directories.Locale renderer := mtemplate.Renderer{ Root: settings.GetTemplatesPath()} monstiPath := settings.GetServicePath(service.MonstiService.String()) sessions := service.NewSessionPool(1, monstiPath) session, err := sessions.New() if err != nil { logger.Fatalf("Could not get session: %v", err) } defer sessions.Free(session) if err := setup(&ModuleContext{ settings, sessions, session, logger, &renderer, }); err != nil { logger.Fatalf("Could not setup module: %v", err) } if err := session.Monsti().ModuleInitDone("example-module"); err != nil { logger.Fatalf("Could not finish initialization: %v", err) } for { if err := session.Monsti().WaitSignal(); err != nil { logger.Printf("Could not wait for signal: %v", err) } } }
func main() { useSyslog := flag.Bool("syslog", false, "use syslog") flag.Parse() var logger *log.Logger if *useSyslog { var err error logger, err = syslog.NewLogger(syslog.LOG_INFO|syslog.LOG_DAEMON, 0) if err != nil { fmt.Fprintf(os.Stderr, "Could not setup syslog logger: %v\n", err) os.Exit(1) } } else { logger = log.New(os.Stderr, "monsti ", log.LstdFlags) } // Load configuration if flag.NArg() != 1 { logger.Fatalf("Usage: %v <config_directory>\n", filepath.Base(os.Args[0])) } cfgPath := util.GetConfigPath(flag.Arg(0)) var settings settings if err := util.LoadModuleSettings("daemon", cfgPath, &settings); err != nil { logger.Fatal("Could not load settings: ", err) } if err := (&settings).Monsti.LoadSiteSettings(); err != nil { logger.Fatal("Could not load site settings: ", err) } gettext.DefaultLocales.Domain = "monsti-daemon" gettext.DefaultLocales.LocaleDir = settings.Monsti.Directories.Locale var waitGroup sync.WaitGroup // Start service handler logger.Println("Setting up service") monstiPath := settings.Monsti.GetServicePath(service.MonstiService.String()) monsti := new(MonstiService) monsti.Settings = &settings monsti.Logger = logger provider := service.NewProvider("Monsti", monsti) provider.Logger = logger if err := provider.Listen(monstiPath); err != nil { logger.Fatalf("service: Could not start service: %v", err) } waitGroup.Add(1) go func() { defer waitGroup.Done() if err := provider.Accept(); err != nil { logger.Fatalf("Could not accept at service: %v", err) } }() // Start modules for _, module := range settings.Modules { logger.Println("Starting module", module) executable := "monsti-" + module cmd := exec.Command(executable, cfgPath) cmd.Stderr = moduleLog{module, logger} go func() { if err := cmd.Run(); err != nil { logger.Fatalf("Module %q failed: %v", module, err) } }() } sessions := service.NewSessionPool(1, monstiPath) renderer := template.Renderer{Root: settings.Monsti.GetTemplatesPath()} // Init core functionality session, err := sessions.New() if err != nil { logger.Fatalf("Could not get session: %v", err) } if err := initNodeTypes(&settings, session, logger); err != nil { logger.Fatalf("Could not init node types: %v", err) } if err := initBlog(&settings, session, logger, &renderer); err != nil { logger.Fatalf("Could not init blog: %v", err) } // Wait for signals go func() { for { if err := session.Monsti().WaitSignal(); err != nil { logger.Fatalf("Could not wait for signal: %v", err) } } }() // Setup up httpd handler := nodeHandler{ Renderer: renderer, Settings: &settings, Log: logger, Sessions: sessions, } monsti.Handler = &handler http.Handle("/static/", http.FileServer(http.Dir( filepath.Dir(settings.Monsti.GetStaticsPath())))) handler.Hosts = make(map[string]string) for site_title, site := range settings.Monsti.Sites { for _, host := range site.Hosts { handler.Hosts[host] = site_title http.Handle(host+"/site-static/", http.FileServer(http.Dir( filepath.Dir(settings.Monsti.GetSiteStaticsPath(site_title))))) } } http.Handle("/", &handler) waitGroup.Add(1) go func() { if err := http.ListenAndServe(settings.Listen, nil); err != nil { logger.Fatal("HTTP Listener failed: ", err) } waitGroup.Done() }() logger.Printf("Monsti is up and running, listening on %q", settings.Listen) waitGroup.Wait() logger.Println("Monsti is shutting down.") }