Esempio n. 1
0
func main() {
	flag.Parse()

	if *outputVersion {
		fmt.Println(VERSION)
		return
	}

	var err error
	config, err = readConfiguration(*configurationFilePath)
	if err != nil {
		log.Fatal("could not read configuration", err)
	}

	templates, err = parseTemplates(*templatesPath, templatesFiles)
	if err != nil {
		log.Fatal("Parsing templates failed", err)
	}

	dbPath := fmt.Sprintf("%s?cache=shared&_busy_timeout=%s",
		*databasePath, dbBusyTimeout)
	db, err = sql.Open("sqlite3", dbPath)
	if err != nil {
		log.Fatal("could not open sqlite3 database file", err)
	}
	defer db.Close()

	migrated, err := isMigrated(db)
	if err != nil {
		log.Fatal("could not check if database is migrated. Error: ", err)
	}
	if !migrated {
		log.Fatal("please migrate the database to the newest version")
	}

	// If there are deployments in state 'new'/'active' when booting up
	// Applikatoni probably crashed with a deployment running. Set these to
	// 'failed' so we can start other deployments.
	err = failUnfinishedDeployments(db)
	if err != nil {
		log.Fatal("setting unfinished deployments to 'failed' failed", err)
	}

	oauthCfg = &oauth2.Config{
		ClientID:     config.GitHubClientId,
		ClientSecret: config.GitHubClientSecret,
		Scopes:       []string{"user", "repo"},
		Endpoint:     github.Endpoint,
	}

	// Setup the killRegistry to connect deployment managers to the kill button
	killRegistry = NewKillRegistry()

	// Run the daily digest sending in the background
	digestSender := config.DailyDigestSender()
	if digestSender != nil {
		go SendDailyDigests(db, digestSender)
	}

	// Setup session store
	sessionStore = sessions.NewCookieStore([]byte(config.SessionSecret))

	// Initialize global LogRouter
	logRouter = deploy.NewLogRouter()
	defer logRouter.Stop()
	logRouter.Start()

	// Setup a basic listener that prints the logs of all deployments
	logRouter.SubscribeAll(deploy.ConsoleLogger)
	// Setup the listener that persists all log entries
	logRouter.SubscribeAll(newLogEntrySaver(db))

	// Initialize global DeploymentEventHub
	eventHub = NewDeploymentEventHub(db)
	// Subscribe the Bugsnag notifier
	bugsnagStates := []models.DeploymentState{models.DEPLOYMENT_SUCCESSFUL}
	eventHub.Subscribe(bugsnagStates, NotifyBugsnag)
	// Subscribe the NewRelic notifier
	newRelicStates := []models.DeploymentState{models.DEPLOYMENT_SUCCESSFUL}
	eventHub.Subscribe(newRelicStates, NotifyNewRelic)
	// Subscribe the Flowdock notifier
	flowdockStates := []models.DeploymentState{
		models.DEPLOYMENT_SUCCESSFUL,
		models.DEPLOYMENT_FAILED,
	}
	eventHub.Subscribe(flowdockStates, NotifyFlowdock)
	// Subscribe the Slack notifier
	slackStates := []models.DeploymentState{
		models.DEPLOYMENT_SUCCESSFUL,
		models.DEPLOYMENT_FAILED,
	}
	eventHub.Subscribe(slackStates, NotifySlack)
	// Subscribe the GitHub notifier to use the Deployments API
	githubNotifier := NewGitHubNotifier()
	githubStates := []models.DeploymentState{
		models.DEPLOYMENT_NEW,
		models.DEPLOYMENT_ACTIVE,
		models.DEPLOYMENT_SUCCESSFUL,
		models.DEPLOYMENT_FAILED,
	}
	eventHub.Subscribe(githubStates, githubNotifier.Notify)

	// Subscribe the webhooks
	webhookStates := []models.DeploymentState{
		models.DEPLOYMENT_NEW,
		models.DEPLOYMENT_ACTIVE,
		models.DEPLOYMENT_SUCCESSFUL,
		models.DEPLOYMENT_FAILED,
	}
	eventHub.Subscribe(webhookStates, NotifyWebhooks)

	// Setup the router and the routes
	r := mux.NewRouter()

	// Assets
	fsServer := http.FileServer(http.Dir("assets/"))
	assetsServer := http.StripPrefix("/assets/", fsServer)

	r.PathPrefix("/assets/").Handler(assetsServer)
	r.Handle("/favicon.ico", fsServer)

	// OAuth & Login
	r.HandleFunc("/oauth2/authorize", oauth2authorizeHandler)
	r.HandleFunc("/oauth2/callback", oauth2callbackHandler)
	r.HandleFunc("/oauth2/logout", oauth2logoutHandler)

	// Application
	r.HandleFunc("/{application}/deployments", requireAuthorizedUser(createDeploymentHandler)).Methods("POST")
	r.HandleFunc("/{application}/deployments", requireAuthorizedUser(listDeploymentsHandler)).Methods("GET")
	r.HandleFunc("/{application}/deployments/{deploymentId}", requireAuthorizedUser(deploymentHandler)).Methods("GET")
	r.HandleFunc("/{application}/deployments/{deploymentId}/log", requireAuthorizedUser(deploymentWsHandler)).Methods("GET")
	r.HandleFunc("/{application}/deployments/{deploymentId}/kill", requireAuthorizedUser(killDeploymentHandler)).Methods("POST")
	r.HandleFunc("/{application}/pulls", requireAuthorizedUser(pullRequestsHandler)).Methods("GET")
	r.HandleFunc("/{application}/branches", requireAuthorizedUser(branchesHandler)).Methods("GET")
	r.HandleFunc("/{application}/diff", requireAuthorizedUser(diffHandler)).Methods("GET")
	r.HandleFunc("/{application}/toni", requireAuthorizedUser(toniConfigurationHandler))
	r.HandleFunc("/{application}", requireAuthorizedUser(applicationHandler))

	// GET /
	r.HandleFunc("/", authenticate(homeHandler))

	if *env == "development" && terminal.IsTerminal(syscall.Stdin) {
		fmt.Println(BANNER)
	}

	log.Printf("Applikatoni is fully booted. Listening on localhost%s ...\n", *port)
	err = http.ListenAndServe(*port, handlers.LoggingHandler(os.Stdout, r))
	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}
Esempio n. 2
0
func main() {
	flag.Parse()

	if *outputVersion {
		fmt.Println(VERSION)
		return
	}

	var err error
	config, err = readConfiguration(*configurationFilePath)
	if err != nil {
		log.Fatal("could not read configuration", err)
	}

	templates, err = parseTemplates(*templatesPath, templatesFiles)
	if err != nil {
		log.Fatal("Parsing templates failed", err)
	}

	db, err = sql.Open("sqlite3", *databasePath)
	if err != nil {
		log.Fatal("could not open sqlite3 database file", err)
	}
	defer db.Close()

	// If there are deployments in state 'new'/'active' when booting up
	// Applikatoni probably crashed with a deployment running. Set these to
	// 'failed' so we can start other deployments.
	err = failUnfinishedDeployments(db)
	if err != nil {
		log.Fatal("setting unfinished deployments to 'failed' failed", err)
	}

	oauthCfg = &oauth2.Config{
		ClientID:     config.GitHubClientId,
		ClientSecret: config.GitHubClientSecret,
		Scopes:       []string{"user", "repo"},
		Endpoint:     github.Endpoint,
	}

	// Setup the killRegistry to connect deployment managers to the kill button
	killRegistry = NewKillRegistry()

	// Run the daily digest sending in the background
	go SendDailyDigests(db)

	// Setup session store
	sessionStore = sessions.NewCookieStore([]byte(config.SessionSecret))

	// Initialize global LogRouter
	logRouter = deploy.NewLogRouter()
	defer logRouter.Stop()
	logRouter.Start()

	// Setup a basic listener that prints the logs of all deployments
	logRouter.SubscribeAll(deploy.ConsoleLogger)
	// Setup the listener that persists all log entries
	logRouter.SubscribeAll(newLogEntrySaver(db))
	// Setup the bugsnag deployment tracking
	logRouter.SubscribeAll(newBugsnagNotifier(db))
	// Setup the flowdock deployment notifcation
	logRouter.SubscribeAll(newFlowdockNotifier(db))
	// Setup the new relic deployment notifcation
	logRouter.SubscribeAll(newNewRelicNotifier(db))

	// Setup the router and the routes
	r := mux.NewRouter()

	// Assets
	fsServer := http.FileServer(http.Dir("assets/"))
	assetsServer := http.StripPrefix("/assets/", fsServer)

	r.PathPrefix("/assets/").Handler(assetsServer)
	r.Handle("/favicon.ico", fsServer)

	// OAuth & Login
	r.HandleFunc("/oauth2/authorize", oauth2authorizeHandler)
	r.HandleFunc("/oauth2/callback", oauth2callbackHandler)
	r.HandleFunc("/oauth2/logout", oauth2logoutHandler)

	// Application
	r.HandleFunc("/{application}/deployments", requireAuthorizedUser(createDeploymentHandler)).Methods("POST")
	r.HandleFunc("/{application}/deployments", requireAuthorizedUser(listDeploymentsHandler)).Methods("GET")
	r.HandleFunc("/{application}/deployments/{deploymentId}", requireAuthorizedUser(deploymentHandler)).Methods("GET")
	r.HandleFunc("/{application}/deployments/{deploymentId}/log", requireAuthorizedUser(deploymentWsHandler)).Methods("GET")
	r.HandleFunc("/{application}/deployments/{deploymentId}/kill", requireAuthorizedUser(killDeploymentHandler)).Methods("POST")
	r.HandleFunc("/{application}/pulls", requireAuthorizedUser(pullRequestsHandler)).Methods("GET")
	r.HandleFunc("/{application}/branches", requireAuthorizedUser(branchesHandler)).Methods("GET")
	r.HandleFunc("/{application}/toni", requireAuthorizedUser(toniConfigurationHandler))
	r.HandleFunc("/{application}", requireAuthorizedUser(applicationHandler))

	// GET /
	r.HandleFunc("/", authenticate(homeHandler))

	log.Printf("Listening on localhost%s\n", *port)
	err = http.ListenAndServe(*port, handlers.LoggingHandler(os.Stdout, r))
	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}