Skip to content

Commit

Permalink
Merge pull request #1636 from replicatedhq/divolgin/preflight-status
Browse files Browse the repository at this point in the history
Report back some basic preflight progress
  • Loading branch information
divolgin committed Mar 18, 2021
2 parents 7a55703 + e5d0fd8 commit 76c62db
Show file tree
Hide file tree
Showing 12 changed files with 230 additions and 80 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ require (
github.com/pierrec/lz4 v2.2.6+incompatible // indirect
github.com/pkg/errors v0.9.1
github.com/replicatedhq/kurl/kurlkinds v0.0.0-20210227025942-3b373149acb7
github.com/replicatedhq/troubleshoot v0.10.10
github.com/replicatedhq/troubleshoot v0.10.11
github.com/replicatedhq/yaml/v3 v3.0.0-beta5-replicatedhq
github.com/robfig/cron v1.1.0
github.com/robfig/cron/v3 v3.0.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1169,8 +1169,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uY
github.com/replicatedhq/kurl/kurlkinds v0.0.0-20210227025942-3b373149acb7 h1:AeeWDSNVtms4pqKwNS65BoZvjP5l2GvSTzbtUrHeDwI=
github.com/replicatedhq/kurl/kurlkinds v0.0.0-20210227025942-3b373149acb7/go.mod h1:LNkb/bMcnPPv8KLuTAKWkBzWFTo19ncFf+UzxGNwhNM=
github.com/replicatedhq/termui/v3 v3.1.1-0.20200811145416-f40076d26851/go.mod h1:JDxG6+uubnk9/BZ2yUsyAJJwlptjrnmB2MPF5d2Xe/8=
github.com/replicatedhq/troubleshoot v0.10.10 h1:kypCadDvSLBKB23J/ljHsZgW1V4O1xzIFLbin3/erTg=
github.com/replicatedhq/troubleshoot v0.10.10/go.mod h1:szF/UQfsZWjshzJz3XylS1uEpkRDyGcNY2BZHcI+9DU=
github.com/replicatedhq/troubleshoot v0.10.11 h1:6HdQAoxSqSgmjZmB/HZBFdEaYk0Bv66ahw012ach/sk=
github.com/replicatedhq/troubleshoot v0.10.11/go.mod h1:szF/UQfsZWjshzJz3XylS1uEpkRDyGcNY2BZHcI+9DU=
github.com/replicatedhq/yaml/v3 v3.0.0-beta5-replicatedhq h1:PwPggruelq2336c1Ayg5STFqgbn/QB1tWLQwrVlU7ZQ=
github.com/replicatedhq/yaml/v3 v3.0.0-beta5-replicatedhq/go.mod h1:Txa7LopbYCU8aRgmNe0n+y/EPMz50NbCPcVVJBquwag=
github.com/robfig/cron v1.1.0 h1:jk4/Hud3TTdcrJgUOBgsqrZBarcxl6ADIjSC2iniwLY=
Expand Down
2 changes: 1 addition & 1 deletion kotsadm/operator/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/mitchellh/hashstructure v1.1.0
github.com/pact-foundation/pact-go v1.5.1
github.com/pkg/errors v0.9.1
github.com/replicatedhq/troubleshoot v0.10.10
github.com/replicatedhq/troubleshoot v0.10.11
github.com/spf13/cobra v0.0.7
github.com/spf13/viper v1.4.0
gopkg.in/yaml.v2 v2.3.0
Expand Down
59 changes: 55 additions & 4 deletions kotsadm/operator/go.sum

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions migrations/tables/app_downstream_version.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ spec:
type: text
- name: diff_summary_error
type: text
- name: preflight_progress
type: text
- name: preflight_result
type: text
- name: preflight_result_created_at
Expand Down
3 changes: 1 addition & 2 deletions pkg/handlers/mock/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 33 additions & 7 deletions pkg/handlers/preflight.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import (
)

type GetPreflightResultResponse struct {
PreflightResult preflighttypes.PreflightResult `json:"preflightResult"`
PreflightProgress string `json:"preflightProgress,omitempty"`
PreflightResult preflighttypes.PreflightResult `json:"preflightResult"`
}

type GetPreflightCommandRequest struct {
Expand Down Expand Up @@ -52,24 +53,49 @@ func (h *Handler) GetPreflightResult(w http.ResponseWriter, r *http.Request) {
return
}

progress, err := store.GetStore().GetPreflightProgress(foundApp.ID, 0)
if err != nil {
logger.Error(errors.Wrap(err, "failed to get preflight progress"))
w.WriteHeader(http.StatusInternalServerError)
return
}

response := GetPreflightResultResponse{
PreflightResult: *result,
PreflightResult: *result,
PreflightProgress: progress,
}
JSON(w, 200, response)
}

func (h *Handler) GetLatestPreflightResultsForSequenceZero(w http.ResponseWriter, r *http.Request) {
result, err := store.GetStore().GetLatestPreflightResultsForSequenceZero()
appSlug := mux.Vars(r)["appSlug"]

foundApp, err := store.GetStore().GetAppFromSlug(appSlug)
if err != nil {
logger.Error(err)
w.WriteHeader(500)
logger.Error(errors.Wrap(err, "failed to get app from slug"))
w.WriteHeader(http.StatusInternalServerError)
return
}

result, err := store.GetStore().GetPreflightResults(foundApp.ID, 0)
if err != nil {
logger.Error(errors.Wrap(err, "failed to get reflight result"))
w.WriteHeader(http.StatusInternalServerError)
return
}

progress, err := store.GetStore().GetPreflightProgress(foundApp.ID, 0)
if err != nil {
logger.Error(errors.Wrap(err, "failed to get preflight progress"))
w.WriteHeader(http.StatusInternalServerError)
return
}

response := GetPreflightResultResponse{
PreflightResult: *result,
PreflightResult: *result,
PreflightProgress: progress,
}
JSON(w, 200, response)
JSON(w, http.StatusOK, response)
}

func (h *Handler) IgnorePreflightRBACErrors(w http.ResponseWriter, r *http.Request) {
Expand Down
40 changes: 37 additions & 3 deletions pkg/preflight/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package preflight
import (
"encoding/json"
"strings"
"sync"
"time"

"github.com/pkg/errors"
"github.com/replicatedhq/kots/pkg/logger"
Expand All @@ -24,14 +26,42 @@ func execute(appID string, sequence int64, preflightSpec *troubleshootv1beta2.Pr
progressChan := make(chan interface{}, 0) // non-zero buffer will result in missed messages
defer close(progressChan)

completeMx := sync.Mutex{}
isComplete := false
go func() {
for {
msg, ok := <-progressChan
if ok {
logger.Debugf("%v", msg)
} else {
if !ok {
return
}

logger.Debugf("%v", msg)

progress, ok := msg.(preflight.CollectProgress)
if !ok {
continue
}

type CollectProgress struct {
Name string
Status string
}

// TODO: We need a nice title to display
progresBytes, err := json.Marshal(map[string]interface{}{
"name": progress.Name,
"status": progress.Status,
"updatedAt": time.Now().Format(time.RFC3339),
})
if err != nil {
continue
}

completeMx.Lock()
if !isComplete {
_ = store.GetStore().SetPreflightProgress(appID, sequence, string(progresBytes))
}
completeMx.Unlock()
}
}()

Expand Down Expand Up @@ -99,6 +129,10 @@ func execute(appID string, sequence int64, preflightSpec *troubleshootv1beta2.Pr
return uploadPreflightResults, errors.Wrap(err, "failed to marshal results")
}

completeMx.Lock()
defer completeMx.Unlock()

isComplete = true
if err := store.GetStore().SetPreflightResults(appID, sequence, b); err != nil {
return uploadPreflightResults, errors.Wrap(err, "failed to set preflight results")
}
Expand Down
55 changes: 30 additions & 25 deletions pkg/store/kotsstore/preflight_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,51 @@ import (
preflighttypes "github.com/replicatedhq/kots/pkg/preflight/types"
)

func (s KOTSStore) SetPreflightResults(appID string, sequence int64, results []byte) error {
func (s KOTSStore) SetPreflightProgress(appID string, sequence int64, progress string) error {
db := persistence.MustGetPGSession()
query := `update app_downstream_version set preflight_result = $1, preflight_result_created_at = $2,
status = (case when status = 'deployed' then 'deployed' else 'pending' end)
where app_id = $3 and parent_sequence = $4`
query := `update app_downstream_version set preflight_progress = $1 where app_id = $2 and parent_sequence = $3`

_, err := db.Exec(query, results, time.Now(), appID, sequence)
_, err := db.Exec(query, progress, appID, sequence)
if err != nil {
return errors.Wrap(err, "failed to write preflight results")
}

return nil
}

func (s KOTSStore) GetPreflightResults(appID string, sequence int64) (*preflighttypes.PreflightResult, error) {
func (s KOTSStore) GetPreflightProgress(appID string, sequence int64) (string, error) {
db := persistence.MustGetPGSession()
query := `
SELECT
app_downstream_version.preflight_result,
app_downstream_version.preflight_result_created_at,
app.slug as app_slug,
cluster.slug as cluster_slug
SELECT preflight_progress
FROM app_downstream_version
INNER JOIN app ON app_downstream_version.app_id = app.id
INNER JOIN cluster ON app_downstream_version.cluster_id = cluster.id
WHERE
app_downstream_version.app_id = $1 AND
app_downstream_version.sequence = $2`
WHERE app_id = $1 AND sequence = $2`

row := db.QueryRow(query, appID, sequence)
r, err := preflightResultFromRow(row)

var progress sql.NullString
if err := row.Scan(&progress); err != nil {
return "", errors.Wrap(err, "failed to scan")
}

return progress.String, nil
}

func (s KOTSStore) SetPreflightResults(appID string, sequence int64, results []byte) error {
db := persistence.MustGetPGSession()
query := `update app_downstream_version set preflight_result = $1, preflight_result_created_at = $2,
status = (case when status = 'deployed' then 'deployed' else 'pending' end),
preflight_progress = NULL
where app_id = $3 and parent_sequence = $4`

_, err := db.Exec(query, results, time.Now(), appID, sequence)
if err != nil {
return nil, errors.Wrap(err, "failed to get preflight result from row")
return errors.Wrap(err, "failed to write preflight results")
}

return r, nil
return nil
}

func (s KOTSStore) GetLatestPreflightResultsForSequenceZero() (*preflighttypes.PreflightResult, error) {
func (s KOTSStore) GetPreflightResults(appID string, sequence int64) (*preflighttypes.PreflightResult, error) {
db := persistence.MustGetPGSession()
query := `
SELECT
Expand All @@ -56,14 +62,13 @@ func (s KOTSStore) GetLatestPreflightResultsForSequenceZero() (*preflighttypes.P
app.slug as app_slug,
cluster.slug as cluster_slug
FROM app_downstream_version
INNER JOIN (
SELECT id, slug FROM app WHERE current_sequence = 0 ORDER BY created_at DESC LIMIT 1
) AS app ON app_downstream_version.app_id = app.id
INNER JOIN app ON app_downstream_version.app_id = app.id
INNER JOIN cluster ON app_downstream_version.cluster_id = cluster.id
WHERE
app_downstream_version.sequence = 0`
app_downstream_version.app_id = $1 AND
app_downstream_version.sequence = $2`

row := db.QueryRow(query)
row := db.QueryRow(query, appID, sequence)
r, err := preflightResultFromRow(row)
if err != nil {
return nil, errors.Wrap(err, "failed to get preflight result from row")
Expand Down
88 changes: 58 additions & 30 deletions pkg/store/mock/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 76c62db

Please sign in to comment.