Semaphore/cli/main.go

180 lines
4.4 KiB
Go
Raw Normal View History

2016-01-05 00:32:53 +01:00
package main
import (
"bufio"
2016-04-18 02:58:29 +02:00
"encoding/json"
2016-01-05 00:32:53 +01:00
"fmt"
2016-04-18 02:58:29 +02:00
"io/ioutil"
2017-02-23 00:21:49 +01:00
"net/http"
2016-04-18 02:58:29 +02:00
"os"
2016-04-24 20:11:43 +02:00
"path"
2016-04-18 02:58:29 +02:00
"strings"
"time"
2016-04-18 02:58:29 +02:00
2016-05-24 11:55:48 +02:00
"github.com/ansible-semaphore/semaphore/api"
"github.com/ansible-semaphore/semaphore/api/sockets"
"github.com/ansible-semaphore/semaphore/api/tasks"
2017-02-23 06:12:16 +01:00
"github.com/ansible-semaphore/semaphore/db"
2016-03-16 22:49:43 +01:00
"github.com/ansible-semaphore/semaphore/util"
2017-02-23 00:21:49 +01:00
"github.com/gorilla/handlers"
2016-04-30 09:52:33 +02:00
"golang.org/x/crypto/bcrypt"
2016-01-05 00:32:53 +01:00
)
func main() {
util.ConfigInit()
2016-04-18 02:58:29 +02:00
if util.InteractiveSetup {
os.Exit(doSetup())
}
2016-04-26 20:18:28 +02:00
if util.Upgrade {
2016-05-24 11:55:48 +02:00
if err := util.DoUpgrade(util.Version); err != nil {
2016-04-26 20:18:28 +02:00
panic(err)
}
os.Exit(0)
}
2016-01-05 00:32:53 +01:00
fmt.Printf("Semaphore %v\n", util.Version)
fmt.Printf("Port %v\n", util.Config.Port)
2016-04-18 02:58:29 +02:00
fmt.Printf("MySQL %v@%v %v\n", util.Config.MySQL.Username, util.Config.MySQL.Hostname, util.Config.MySQL.DbName)
fmt.Printf("Tmp Path (projects home) %v\n", util.Config.TmpPath)
2016-01-05 00:32:53 +01:00
2017-02-23 06:12:16 +01:00
if err := db.Connect(); err != nil {
fmt.Println("\n Have you run semaphore -setup?")
2016-04-18 02:58:29 +02:00
panic(err)
}
2017-02-23 06:12:16 +01:00
db.SetupDBLink()
defer db.Mysql.Db.Close()
2016-01-05 00:32:53 +01:00
2017-05-20 15:21:13 +02:00
if err := db.MigrateAll(); err != nil {
panic(err)
}
// legacy
2016-01-05 00:32:53 +01:00
if util.Migration {
2017-05-20 15:21:13 +02:00
fmt.Println("\n DB migrations run on startup automatically")
2016-01-05 00:32:53 +01:00
return
}
2016-04-02 14:40:07 +02:00
go sockets.StartWS()
go checkUpdates()
2016-04-04 15:44:34 +02:00
go tasks.StartRunner()
2016-01-05 00:32:53 +01:00
2017-02-23 00:21:49 +01:00
var router http.Handler = api.Route()
router = handlers.ProxyHeaders(router)
http.Handle("/", router)
http.ListenAndServe(util.Config.Port, nil)
2016-01-05 00:32:53 +01:00
}
2016-04-18 02:58:29 +02:00
func doSetup() int {
fmt.Print(`
2016-04-30 09:52:33 +02:00
Hello! You will now be guided through a setup to:
2016-04-18 02:58:29 +02:00
2016-04-30 09:52:33 +02:00
1. Set up configuration for a MySQL/MariaDB database
2. Set up a path for your playbooks (auto-created)
3. Run database Migrations
2017-05-28 15:11:41 +02:00
4. Set up initial semaphore user & password
2016-04-18 02:58:29 +02:00
`)
var b []byte
setup := util.NewConfig()
for {
setup.Scan()
setup.GenerateCookieSecrets()
2016-04-18 02:58:29 +02:00
var err error
2016-04-30 09:52:33 +02:00
b, err = json.MarshalIndent(&setup, " ", "\t")
2016-04-18 02:58:29 +02:00
if err != nil {
panic(err)
}
2016-04-30 09:52:33 +02:00
fmt.Printf("\n Generated configuration:\n %v\n\n", string(b))
fmt.Print(" > Is this correct? (yes/no): ")
2016-04-18 02:58:29 +02:00
var answer string
fmt.Scanln(&answer)
2016-04-30 09:52:33 +02:00
if answer == "yes" || answer == "y" {
break
2016-04-18 02:58:29 +02:00
}
2016-04-30 09:52:33 +02:00
fmt.Println()
setup = util.NewConfig()
2016-04-18 02:58:29 +02:00
}
2016-04-30 09:52:33 +02:00
fmt.Printf(" Running: mkdir -p %v..\n", setup.TmpPath)
2016-04-24 20:11:43 +02:00
os.MkdirAll(setup.TmpPath, 0755)
configPath := path.Join(setup.TmpPath, "/semaphore_config.json")
fmt.Printf(" Configuration written to %v..\n", configPath)
2016-04-24 20:11:43 +02:00
if err := ioutil.WriteFile(configPath, b, 0644); err != nil {
2016-04-18 02:58:29 +02:00
panic(err)
}
2017-02-23 06:12:16 +01:00
fmt.Println(" Pinging db..")
2016-04-18 02:58:29 +02:00
util.Config = setup
2017-02-23 06:12:16 +01:00
if err := db.Connect(); err != nil {
2016-04-30 09:52:33 +02:00
fmt.Printf("\n Cannot connect to database!\n %v\n", err.Error())
os.Exit(1)
2016-04-18 02:58:29 +02:00
}
2016-04-30 09:52:33 +02:00
fmt.Println("\n Running DB Migrations..")
2017-02-23 06:12:16 +01:00
if err := db.MigrateAll(); err != nil {
2016-04-30 09:52:33 +02:00
fmt.Printf("\n Database migrations failed!\n %v\n", err.Error())
os.Exit(1)
2016-04-18 02:58:29 +02:00
}
stdin := bufio.NewReader(os.Stdin)
2016-04-18 02:58:29 +02:00
2017-02-23 06:12:16 +01:00
var user db.User
user.Username = readNewline("\n\n > Username: ", stdin)
2016-04-18 02:58:29 +02:00
user.Username = strings.ToLower(user.Username)
user.Email = readNewline(" > Email: ", stdin)
2016-04-18 02:58:29 +02:00
user.Email = strings.ToLower(user.Email)
2017-02-23 06:12:16 +01:00
var existingUser db.User
db.Mysql.SelectOne(&existingUser, "select * from user where email=? or username=?", user.Email, user.Username)
if existingUser.ID > 0 {
// user already exists
fmt.Printf("\n Welcome back, %v! (a user with this username/email is already set up..)\n\n", existingUser.Name)
} else {
user.Name = readNewline(" > Your name: ", stdin)
user.Password = readNewline(" > Password: ", stdin)
pwdHash, _ := bcrypt.GenerateFromPassword([]byte(user.Password), 11)
2017-07-26 08:37:16 +02:00
if _, err := db.Mysql.Exec("insert into user set name=?, username=?, email=?, password=?, admin=1, created=UTC_TIMESTAMP()", user.Name, user.Username, user.Email, pwdHash); err != nil {
fmt.Printf(" Inserting user failed. If you already have a user, you can disregard this error.\n %v\n", err.Error())
os.Exit(1)
}
fmt.Printf("\n You are all setup %v!\n", user.Name)
2016-04-18 02:58:29 +02:00
}
2016-04-30 09:52:33 +02:00
fmt.Printf(" Re-launch this program pointing to the configuration file\n\n./semaphore -config %v\n\n", configPath)
fmt.Printf(" To run as daemon:\n\nnohup ./semaphore -config %v &\n\n", configPath)
fmt.Printf(" You can login with %v or %v.\n", user.Email, user.Username)
2016-04-18 02:58:29 +02:00
return 0
}
func readNewline(pre string, stdin *bufio.Reader) string {
fmt.Print(pre)
str, _ := stdin.ReadString('\n')
2016-12-21 19:35:31 +01:00
str = strings.Replace(strings.Replace(str, "\n", "", -1), "\r", "", -1)
return str
}
func checkUpdates() {
2016-05-24 11:55:48 +02:00
util.CheckUpdate(util.Version)
t := time.NewTicker(time.Hour * 24)
for range t.C {
2016-05-24 11:55:48 +02:00
util.CheckUpdate(util.Version)
}
}