From a2f50c3dc4d01da22ea725882ee389da8d6f8e03 Mon Sep 17 00:00:00 2001 From: Arjan H Date: Sat, 11 Apr 2020 19:02:37 +0200 Subject: [PATCH 1/5] Reduce the purgeInterval --- gui/apply-boulder | 1 + 1 file changed, 1 insertion(+) diff --git a/gui/apply-boulder b/gui/apply-boulder index 096b460..8b92431 100755 --- a/gui/apply-boulder +++ b/gui/apply-boulder @@ -44,6 +44,7 @@ sed -i -e "s/\"server\": \".*\"/\"server\": \"$PKI_EMAIL_SERVER\"/" config/expir sed -i -e "s/\"port\": \".*\"/\"port\": \"$PKI_EMAIL_PORT\"/" config/expiration-mailer.json sed -i -e "s/\"username\": \".*\"/\"username\": \"$PKI_EMAIL_USER\"/" config/expiration-mailer.json sed -i -e "s/\"from\": \".*\"/\"from\": \"$PKI_EMAIL_FROM\"/" config/expiration-mailer.json +sed -i -e "s/\"purgeInterval\": \".*\"/\"purgeInterval\": \"1s\"/" config/akamai-purger.json if [ "$PKI_EMAIL_PASS" != "" ]; then sed -i -e "s/.*/$PKI_EMAIL_PASS/" secrets/smtp_password From 5d2355984943461e18db13b4b66e27b00817a4be Mon Sep 17 00:00:00 2001 From: Arjan H Date: Sun, 12 Apr 2020 17:42:51 +0200 Subject: [PATCH 2/5] Check for new versions and upgrade from webgui. closes #1 --- commander | 8 +- gui/main.go | 102 ++++++++++++++++++++++--- gui/setup.sh | 1 + gui/templates/views/dashboard.tmpl | 8 +- gui/templates/views/manage.tmpl | 115 +++++++++++++++++++++++------ www/css/labca.css | 25 +++++++ www/js/bootstrap-dialog.min.js | 1 + 7 files changed, 219 insertions(+), 41 deletions(-) create mode 100644 www/js/bootstrap-dialog.min.js diff --git a/commander b/commander index 414c252..2a7c11f 100755 --- a/commander +++ b/commander @@ -199,6 +199,9 @@ case $txt in "server-shutdown") halt ;; +"version-update") + /home/labca/labca/install &>>$LOGFILE + ;; *) echo "Unknown command '$txt'. ERROR!" exit 1 @@ -206,8 +209,3 @@ case $txt in esac echo "ok" - - -# TODO: -# upgrade the labca stuff - diff --git a/gui/main.go b/gui/main.go index c5be64f..1b3dd10 100644 --- a/gui/main.go +++ b/gui/main.go @@ -3,6 +3,7 @@ package main import ( "bufio" "bytes" + "context" "crypto/aes" "crypto/cipher" "crypto/rand" @@ -11,7 +12,9 @@ import ( "errors" "fmt" "github.com/biz/templates" + "github.com/dustin/go-humanize" _ "github.com/go-sql-driver/mysql" + "github.com/google/go-github/github" "github.com/gorilla/mux" "github.com/gorilla/securecookie" "github.com/gorilla/sessions" @@ -39,20 +42,23 @@ import ( ) const ( - writeWait = 10 * time.Second - pongWait = 60 * time.Second - pingPeriod = (pongWait * 9) / 10 + writeWait = 10 * time.Second + pongWait = 60 * time.Second + pingPeriod = (pongWait * 9) / 10 + updateInterval = 24 * time.Hour ) var ( - appSession *sessions.Session - restartSecret string - sessionStore *sessions.CookieStore - tmpls *templates.Templates - version string - dbConn string - dbType string - isDev bool + appSession *sessions.Session + restartSecret string + sessionStore *sessions.CookieStore + tmpls *templates.Templates + version string + dbConn string + dbType string + isDev bool + updateAvailable bool + updateChecked time.Time upgrader = websocket.Upgrader{ ReadBufferSize: 1024, @@ -232,6 +238,43 @@ func errorHandler(w http.ResponseWriter, r *http.Request, err error, status int) } } +func checkUpdates(forced bool) ([]string, []string) { + var versions []string + var descriptions []string + + if forced || updateChecked.Add(updateInterval).Before(time.Now()) { + latest := "" + newer := true + + client := github.NewClient(nil) + + if releases, _, err := client.Repositories.ListReleases(context.Background(), "hakwerk", "labca", nil); err == nil { + for i := 0; i < len(releases); i++ { + release := releases[i] + if !*release.Draft { + if !*release.Prerelease || isDev { + if latest == "" { + latest = *release.Name + } + if *release.Name == version { + newer = false + } + if newer { + versions = append(versions, *release.Name) + descriptions = append(descriptions, *release.Body) + } + } + } + } + + updateChecked = time.Now() + updateAvailable = (len(releases) > 0) && (latest != version) + } + } + + return versions, descriptions +} + func rootHandler(w http.ResponseWriter, r *http.Request) { if !viper.GetBool("config.complete") { http.Redirect(w, r, r.Header.Get("X-Request-Base")+"/setup", http.StatusFound) @@ -240,6 +283,10 @@ func rootHandler(w http.ResponseWriter, r *http.Request) { dashboardData, err := CollectDashboardData(w, r) if err == nil { + checkUpdates(false) + dashboardData["UpdateAvailable"] = updateAvailable + dashboardData["UpdateChecked"] = humanize.RelTime(updateChecked, time.Now(), "", "") + render(w, r, "dashboard", dashboardData) } } @@ -798,6 +845,24 @@ func (res *Result) ManageComponents(w http.ResponseWriter, r *http.Request, acti } } +func _checkUpdatesHandler(w http.ResponseWriter, r *http.Request) { + res := struct { + Success bool + UpdateAvailable bool + UpdateChecked string + Versions []string + Descriptions []string + Errors map[string]string + }{Success: true, Errors: make(map[string]string)} + + res.Versions, res.Descriptions = checkUpdates(true) + res.UpdateAvailable = updateAvailable + res.UpdateChecked = humanize.RelTime(updateChecked, time.Now(), "", "") + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(res) +} + func _managePostDispatch(w http.ResponseWriter, r *http.Request, action string) bool { if action == "backup-restore" || action == "backup-delete" || action == "backup-now" { _backupHandler(w, r) @@ -829,6 +894,11 @@ func _managePostDispatch(w http.ResponseWriter, r *http.Request, action string) return true } + if action == "version-check" { + _checkUpdatesHandler(w, r) + return true + } + return false } @@ -858,6 +928,8 @@ func _managePost(w http.ResponseWriter, r *http.Request) { "update-config", "update-email", "send-email", + "version-check", + "version-update", } { if a == action { actionKnown = true @@ -878,7 +950,7 @@ func _managePost(w http.ResponseWriter, r *http.Request) { res.Message = "Command failed - see LabCA log for any details" } - if action != "server-restart" && action != "server-shutdown" { + if action != "server-restart" && action != "server-shutdown" && action != "version-update" { res.ManageComponents(w, r, action) } @@ -890,6 +962,10 @@ func _manageGet(w http.ResponseWriter, r *http.Request) { manageData := make(map[string]interface{}) manageData["RequestBase"] = r.Header.Get("X-Request-Base") + checkUpdates(false) + manageData["UpdateAvailable"] = updateAvailable + manageData["UpdateChecked"] = humanize.RelTime(updateChecked, time.Now(), "", "") + components := _parseComponents(getLog(w, r, "components")) for i := 0; i < len(components); i++ { if components[i].Name == "NGINX Webserver" { @@ -2292,6 +2368,8 @@ func init() { dbType = viper.GetString("db.type") version = viper.GetString("version") + + updateAvailable = false } func main() { diff --git a/gui/setup.sh b/gui/setup.sh index 71e299f..b63b928 100755 --- a/gui/setup.sh +++ b/gui/setup.sh @@ -9,6 +9,7 @@ if [ ! -e bin/labca ]; then go get github.com/biz/templates go get github.com/go-sql-driver/mysql go get github.com/dustin/go-humanize + go get github.com/google/go-github/github go get github.com/gorilla/mux go get github.com/gorilla/securecookie go get github.com/gorilla/sessions diff --git a/gui/templates/views/dashboard.tmpl b/gui/templates/views/dashboard.tmpl index 5f9bc35..274dc36 100644 --- a/gui/templates/views/dashboard.tmpl +++ b/gui/templates/views/dashboard.tmpl @@ -127,7 +127,13 @@
- System Overview + System Overview + {{ if .UpdateAvailable }} + + update available! + + {{ end }} +
diff --git a/gui/templates/views/manage.tmpl b/gui/templates/views/manage.tmpl index afb8478..2296947 100644 --- a/gui/templates/views/manage.tmpl +++ b/gui/templates/views/manage.tmpl @@ -43,6 +43,16 @@ {{ range $btn := $item.Buttons }} {{ end }} + {{ if eq $item.Name "LabCA Application" }} +
+ +
+ + +
+ Last checked: {{ $.UpdateChecked }} +
+ {{ end }} {{ end }} @@ -262,7 +272,7 @@ -