Add: Installer

master
Siroco 1 year ago
parent ed48c85034
commit d07d1883ca
Signed by: siroco
GPG Key ID: 1324098302A514B0
  1. 2
      installer/REAME.md
  2. 10
      installer/css/style.css
  3. 146
      installer/main.go
  4. BIN
      installer/templates/._base.html.swp
  5. 15
      installer/templates/_base.html
  6. 53
      installer/templates/install.html

@ -0,0 +1,2 @@
https://gowebexamples.com/forms/
https://astaxie.gitbooks.io/build-web-application-with-golang/content/en/04.1.html

@ -0,0 +1,10 @@
* { font-family:Arial;}
body { background:#000; color:#fff; margin:0 10vw;}
h1,h2,h3 {padding:12px 10px;color:#0f0;}
strong {color:#0f0;}
p { padding:12px 10px;}
p.error {background:#f00;}
input { border:0; background-color:transparent;color:#fff;border-bottom:1px solid #fff; margin-bottom:24px; padding:12px 10px; width:100%;}
input[type=submit] { border:0;font-size:1.2em; cursor:pointer; background:#fff;color:#000;transition:0.1s;}
input[type=submit]:hover { background:#0f0;}
footer { font-size:0.8em; padding:12px 10px; opacity:0.8;}

@ -0,0 +1,146 @@
package main
import (
"html/template"
"net/http"
"fmt"
"encoding/json"
"io/ioutil"
"regexp"
"strings"
"os"
"time"
)
type InstallerConfig struct {
Title string `json:"title"`
BaseUrl string `json:"baseurl"`
Server ServerConfig `json:"server"`
UploadPath string `json:"upload_path"`
LogLevel string `json:"log_level"`
LogPath string `json:"log_path"`
DB DBConfig `json:"db"`
AdminEmail string `json:"admin_email"`
}
type ServerConfig struct {
Host string `json:"host"`
Port int `json:"port"`
}
type DBConfig struct {
Dialec string `json:"dialect"`
Storage string `json:"storage"`
Logging bool `json:"logging"`
}
type Message struct {
Success bool
Title string
BaseUrl string
Email string
Errors map[string]string
}
var rxEmail = regexp.MustCompile(".+@.+\\..+")
var rxUrl = regexp.MustCompile(`^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)`)
var CONFIG_PATH = "/data/config.json"
var DB_PATH = "/data/db.sqlite"
var UPLOADS_PATH = "/data/uploads"
var LOGS_PATH = "/data/logs"
func main() {
fmt.Println("Gancio Installer")
tmpl := template.Must(template.ParseFiles("templates/_base.html","templates/install.html"))
http.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("./css"))))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
msg := Message{}
if r.Method != http.MethodPost {
// TODO: GET INSTANCE URL FROM DOCKER GANCIO
msg.BaseUrl = "https://intancia.convoca.la"
msg.Success = false
tmpl.ExecuteTemplate(w,"base",msg)
return
}
// Validation
msg.Errors = make(map[string]string)
msg.Email = r.FormValue("adminemail")
msg.Title = r.FormValue("title")
msg.BaseUrl = r.FormValue("url")
msg.Success = false
// Email
match := rxEmail.Match([]byte(msg.Email))
if match == false {
msg.Errors["Email"] = "Introduce una dirección de correo correcta"
tmpl.ExecuteTemplate(w,"base",msg)
return
}
// Url
match = rxUrl.Match([]byte(msg.BaseUrl))
if match == false {
msg.Errors["BaseUrl"] = "Introduce una URL correcta"
tmpl.ExecuteTemplate(w,"base",msg)
return
}
// Title
if strings.TrimSpace(msg.Title) == "" {
msg.Errors["Title"] = "Introduce un nombre para tu instancia"
tmpl.ExecuteTemplate(w,"base",msg)
return
}
// Gancio Config
serverConfig := ServerConfig{
Host: "0.0.0.0",
Port: 13120,
}
dbConfig := DBConfig{
Dialec: "sqlite",
Storage: DB_PATH,
Logging: false,
}
gancioConfig := InstallerConfig{
Title: r.FormValue("title"),
BaseUrl: r.FormValue("url"),
Server: serverConfig,
UploadPath: UPLOADS_PATH,
LogLevel: "debug",
LogPath: LOGS_PATH,
DB: dbConfig,
AdminEmail: msg.Email,
}
// Write file
file, err := json.MarshalIndent(gancioConfig, "", " ")
err = ioutil.WriteFile(CONFIG_PATH, file, 0644)
if err!=nil {
msg.Errors["WriteConfig"] = "Fallo al escribir el fichero de configuracion"
tmpl.ExecuteTemplate(w,"base",msg)
return
}
// Success
msg.Success = true
tmpl.ExecuteTemplate(w,"base",msg)
//Bye
go func() {
time.Sleep(10 * time.Second)
os.Exit(3)
}()
})
fmt.Println("Runing server http://localhost:8080")
http.ListenAndServe(":8080", nil)
}

@ -0,0 +1,15 @@
{{define "base"}}
<!DOCTYPE html>
<html lang="es">
<head>
<link href="/css/style.css" rel="stylesheet">
</head>
<body>
<h1>Herramienta de configuración de Gancio</h1>
{{template "content" .}}
<footer>
Sindominio 2021 - https://sindominio.net
</footer>
</body>
</html>
{{end}}

@ -0,0 +1,53 @@
{{define "content"}}
<!-- forms.html -->
{{with .Errors.Email}}
<p class="error">{{.}}</p>
{{end}}
{{with .Errors.Title}}
<p class="error">{{.}}</p>
{{end}}
{{with .Errors.BaseUrl}}
<p class="error">{{.}}</p>
{{end}}
{{with .Errors.WriteConfig}}
<p class="error">{{.}}</p>
{{end}}
{{if .Success}}
<h2>Instalación completada</h2>
<p>¡Felicidades! Tu instancia <strong>{{.Title}}</strong> ha sido configurada correctamente.</p>
<p>Un correo electrónico ha sido enviado a <strong>{{.Email}}</strong> con los pasos para recuperar la contraseña de administración.</p>
<p>En breve podrás acceder a <strong>{{.BaseUrl}}</strong> para publicar los eventos.</p>
<p>Disfruta de un café y vuelve en <span id="timeout">.</span> segundos</p>
<script>
let timeout = 30;
document.getElementById("timeout").innerHTML = timeout;
function countdown(n) {
document.getElementById("timeout").innerHTML = n;
if (n > 0) {
n = n-1;
setTimeout(()=>{countdown(n)}, 1000);
} else {
window.location.reload();
}
}
let idt = setTimeout(()=>{countdown(timeout)},1000);
</script>
{{else}}
<form method="POST">
<label>Correo electrónico de administración:</label><br />
<input type="email" name="adminemail" placeholder="gancio@sindominio.net" value="{{.Email}}"><br />
<label>Nombre de la instáncia:</label><br />
<input type="text" name="title" placeholder="Gancio Instance" value="{{.Title}}"><br />
<label>Dirección:</label><br />
<input readonly="true" id="url" type="url" name="url" placeholder="https://gancio.convoca.la" value="{{.BaseUrl}}"><br />
<input type="submit" value="Finalizar instalación">
</form>
<script>
document.getElementById("url").value = window.location.href;
</script>
{{end}}
{{end}}
Loading…
Cancel
Save