Example #1
0
// 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)
		}
	}
}
Example #2
0
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.")
}