Tidy up user experience and log messages during first install. Simplify generated passwords.

This commit is contained in:
Nathan Wallace
2021-01-20 23:01:46 -05:00
parent bf95d1ad77
commit 2a596d9515
8 changed files with 69 additions and 74 deletions

View File

@@ -39,7 +39,7 @@ func refreshConnections(client *Client) error {
numUpdates := len(updates.Update)
if numUpdates > 0 {
s := utils.ShowSpinner("Refreshing connections")
s := utils.ShowSpinner("Refreshing connections...")
defer utils.StopSpinner(s)
connectionQueries = getSchemaQueries(updates.Update)

View File

@@ -36,64 +36,88 @@ func EnsureDBInstalled() {
}
log.Println("[TRACE] calling killPreviousInstanceIfAny")
killPreviousSpinner := utils.ShowSpinner(fmt.Sprintf("Cleanup any Steampipe processes..."))
killPreviousInstanceIfAny()
log.Println("[TRACE] calling removeRunningInstanceInfo")
err := removeRunningInstanceInfo()
utils.StopSpinner(killPreviousSpinner)
if err != nil && !os.IsNotExist(err) {
utils.FailOnErrorWithMessage(err, "Installation failed")
utils.FailOnErrorWithMessage(err, "x Cleanup any Steampipe processes... FAILED!")
}
log.Println("[TRACE] removing previous installation")
dbCleanupSpinner := utils.ShowSpinner(fmt.Sprintf("Prepare database install location..."))
err = os.RemoveAll(getDatabaseLocation())
if err != nil {
utils.FailOnErrorWithMessage(err, "Installation failed")
utils.StopSpinner(dbCleanupSpinner)
utils.FailOnErrorWithMessage(err, "x Prepare database install location... FAILED!")
}
err = os.RemoveAll(getDataLocation())
if err != nil {
utils.FailOnErrorWithMessage(err, "Installation failed")
utils.StopSpinner(dbCleanupSpinner)
utils.FailOnErrorWithMessage(err, "x Prepare database install location... FAILED!")
}
utils.StopSpinner(dbCleanupSpinner)
fmt.Printf("\nInstalling dbClient from image: %s\n", constants.DefaultEmbeddedPostgresImage)
dbInstallSpinner := utils.ShowSpinner(fmt.Sprintf("Download & install embedded PostgreSQL database..."))
dbImageDigest, err := ociinstaller.InstallDB(constants.DefaultEmbeddedPostgresImage, getDatabaseLocation())
utils.FailOnErrorWithMessage(err, "dbClient Installation failed")
fmt.Printf("\nInstalling hub extension from image: %s\n", constants.DefaultFdwImage)
fdwDigest, err := ociinstaller.InstallFdw(constants.DefaultFdwImage, getDatabaseLocation())
utils.FailOnErrorWithMessage(err, "Hub extension installation failed")
fmt.Println("Initializing SQL Support...")
err = initDatabase()
utils.StopSpinner(dbInstallSpinner)
if err != nil {
fmt.Printf("%v\n", err)
utils.FailOnErrorWithMessage(err, "x Download & install embedded PostgreSQL database... FAILED!")
}
utils.FailOnError(err)
fmt.Println("Initializing steampipe Database...")
steampipePassword := generatePassword(64, 8, 8, 8)
rootPassword := generatePassword(64, 8, 8, 8)
fdwInstallSpinner := utils.ShowSpinner(fmt.Sprintf("Download & install Steampipe PostgreSQL FDW..."))
fdwDigest, err := ociinstaller.InstallFdw(constants.DefaultFdwImage, getDatabaseLocation())
utils.StopSpinner(fdwInstallSpinner)
if err != nil {
utils.FailOnErrorWithMessage(err, "x Download & install Steampipe Postgres FDW... FAILED!")
}
dbInitSpinner := utils.ShowSpinner(fmt.Sprintf("Initializing database..."))
err = initDatabase()
utils.StopSpinner(dbInitSpinner)
if err != nil {
utils.FailOnErrorWithMessage(err, "x Initializing database... FAILED!")
}
pwSpinner := utils.ShowSpinner(fmt.Sprintf("Generating database passwords..."))
// Try for passwords of the form dbC-3Ji-d04d
steampipePassword := generatePassword()
rootPassword := generatePassword()
// write the passwords that were generated
err = writePasswordFile(steampipePassword, rootPassword)
utils.FailOnErrorWithMessage(err, "failed")
utils.StopSpinner(pwSpinner)
if err != nil {
utils.FailOnErrorWithMessage(err, "x Generating database passwords... FAILED!")
}
startServiceSpinner := utils.ShowSpinner(fmt.Sprintf("Configuring database..."))
StartService(InvokerInstaller)
defer func() {
// force stop
StopDB(true)
}()
err = installSteampipeDatabase(steampipePassword, rootPassword)
utils.FailOnErrorWithMessage(err, "failed")
utils.StopSpinner(startServiceSpinner)
if err != nil {
utils.FailOnErrorWithMessage(err, "x Configuring database... FAILED!")
}
fmt.Println("Installing SteampipeHub...")
installSteampipeSpinner := utils.ShowSpinner(fmt.Sprintf("Configuring Steampipe..."))
err = installSteampipeHub()
utils.FailOnErrorWithMessage(err, "failed")
utils.StopSpinner(installSteampipeSpinner)
if err != nil {
utils.FailOnErrorWithMessage(err, "x Configuring Steampipe... FAILED!")
}
// write a signature after everything gets done!
// so that we can check for this later on
writeSignaturesSpinner := utils.ShowSpinner(fmt.Sprintf("Updating install records..."))
err = writeDownloadedBinarySignature(dbImageDigest, fdwDigest)
utils.FailOnErrorWithMessage(err, "failed")
utils.StopSpinner(writeSignaturesSpinner)
if err != nil {
utils.FailOnErrorWithMessage(err, "x Updating install records... FAILED!")
}
}
func installSteampipeDatabase(withSteampipePassword string, withRootPassword string) error {
@@ -221,7 +245,7 @@ func StartService(invoker Invoker) {
break
}
if time.Since(startedAt) > constants.SpinnerShowTimeout && !spinnerShown {
s := utils.ShowSpinner("Waiting for service startup")
s := utils.ShowSpinner("Waiting for database to start...")
spinnerShown = true
defer utils.StopSpinner(s)
}
@@ -233,7 +257,7 @@ func StartService(invoker Invoker) {
select {
case <-timeoutAfter:
utils.ShowError(fmt.Errorf("could not start service"))
utils.ShowError(fmt.Errorf("x Waiting for database to start... FAILED!"))
return
case <-startedChannel:
// do nothing

View File

@@ -4,8 +4,8 @@ import (
"encoding/json"
"io/ioutil"
"log"
"math/rand"
"strings"
"github.com/google/uuid"
)
// Passwords :: structure for working with DB passwords
@@ -40,43 +40,15 @@ func getPasswords() (*Passwords, error) {
return passwords, nil
}
func generatePassword(passwordLength, minSpecialChar, minNum, minUpperCase int) string {
const (
lowerCharSet = "abcdedfghijklmnopqrst"
upperCharSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
specialCharSet = "#$*"
numberSet = "0123456789"
allCharSet = lowerCharSet + upperCharSet + specialCharSet + numberSet
)
var password strings.Builder
// set special character
for i := 0; i < minSpecialChar; i++ {
random := rand.Intn(len(specialCharSet))
password.WriteString(string(specialCharSet[random]))
func generatePassword() string {
// Create a simple, random password of the form f9fe-442f-90fb
// Simple to read / write, and has a strength rating of 4 per https://lowe.github.io/tryzxcvbn/
// Yes, this UUIDv4 does always include a 4, but good enough for our needs.
u, err := uuid.NewRandom()
if err != nil {
// Should never happen?
panic(err)
}
// set numeric
for i := 0; i < minNum; i++ {
random := rand.Intn(len(numberSet))
password.WriteString(string(numberSet[random]))
}
// set uppercase
for i := 0; i < minUpperCase; i++ {
random := rand.Intn(len(upperCharSet))
password.WriteString(string(upperCharSet[random]))
}
remainingLength := passwordLength - minSpecialChar - minNum - minUpperCase
for i := 0; i < remainingLength; i++ {
random := rand.Intn(len(allCharSet))
password.WriteString(string(allCharSet[random]))
}
inRune := []rune(password.String())
rand.Shuffle(len(inRune), func(i, j int) {
inRune[i], inRune[j] = inRune[j], inRune[i]
})
return string(inRune)
s := u.String()
return s[9:23]
}

View File

@@ -96,7 +96,7 @@ func StopDB(force bool) (StopStatus, error) {
break
}
if time.Since(signalSentAt) > constants.SpinnerShowTimeout && !spinnerShown {
s := utils.ShowSpinner("Shutting down service")
s := utils.ShowSpinner("Shutting down...")
defer utils.StopSpinner(s)
spinnerShown = true
}

4
go.mod
View File

@@ -14,7 +14,7 @@ require (
github.com/fatih/color v1.7.0
github.com/gertd/go-pluralize v0.1.7
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/google/uuid v1.1.2
github.com/google/uuid v1.1.5
github.com/hashicorp/go-hclog v0.14.1
github.com/hashicorp/go-plugin v1.3.0
github.com/hashicorp/go-version v1.2.1
@@ -39,7 +39,7 @@ require (
github.com/turbot/go-kit v0.0.0-20210119154454-db924443f736
github.com/turbot/steampipe-plugin-sdk v0.0.0-20210119154656-52569ae6f10d
github.com/ulikunitz/xz v0.5.8
github.com/zclconf/go-cty v1.7.0
github.com/zclconf/go-cty v1.7.0 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gotest.tools/v3 v3.0.3 // indirect
)

2
go.sum
View File

@@ -188,6 +188,8 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.5 h1:kxhtnfFVi+rYdOALN0B3k9UT86zVJKfBimRaciULW4I=
github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=

View File

@@ -2,7 +2,6 @@ package ociinstaller
import (
"context"
"fmt"
"path/filepath"
"time"
@@ -17,14 +16,12 @@ func InstallDB(imageRef string, dest string) (string, error) {
imageDownloader := NewOciDownloader(context.Background())
// Download the blobs
fmt.Println("Downloading...")
image, err := imageDownloader.Download(imageRef, "db", tempDir.Path)
if err != nil {
return "", err
}
// install the files
fmt.Printf("\nInstalling...")
if err = extractDbFiles(image, tempDir.Path, dest); err != nil {
return "", err
}

View File

@@ -14,7 +14,7 @@ func ShowSpinner(msg string) *spinner.Spinner {
spinner.CharSets[14],
100*time.Millisecond,
spinner.WithWriter(os.Stdout),
spinner.WithSuffix(fmt.Sprintf(" %s", msg)),
spinner.WithSuffix(fmt.Sprintf(" %s", msg)),
)
s.Start()
return s