Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/pillar/cmd/downloader/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ func objectMetadata(ctx *downloaderContext, trType zedUpload.SyncTransportType,
return sha256, errors.New("NewRequest failed")
}

// XXX add timer?
req = req.WithCancel(context.Background())
defer req.Cancel()

Expand Down
20 changes: 12 additions & 8 deletions pkg/pillar/cmd/downloader/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,15 @@ func maybeRetryDownload(ctx *downloaderContext,
return
}

// reset Error, to start download again
if status.RetryCount == 0 {
status.OrigError = status.Error
}
// Increment count; we defer clearing error until success
// to avoid confusing the user.
status.RetryCount++
status.ClearError()
errStr := fmt.Sprintf("Retry attempt %d after %s",
status.RetryCount, status.OrigError)
status.SetErrorNow(errStr)
publishDownloaderStatus(ctx, status)

doDownload(ctx, *config, status)
Expand Down Expand Up @@ -409,19 +415,17 @@ func doDownload(ctx *downloaderContext, config types.DownloaderConfig, status *t
if config.RefCount == 0 {
errStr := fmt.Sprintf("RefCount==0; download deferred for %s\n",
config.Name)
status.RetryCount++
status.HandleDownloadFail(errStr)
status.HandleDownloadFail(errStr, 0)
publishDownloaderStatus(ctx, status)
log.Errorf("doDownload(%s): deferred with %s", config.Name, errStr)
return
}

dst, err := utils.LookupDatastoreConfig(ctx.subDatastoreConfig, config.DatastoreID)
if dst == nil {
status.RetryCount++
// XXX can we have a faster retry in this case?
// React when DatastoreConfig changes?
status.HandleDownloadFail(err.Error())
errStr := fmt.Sprintf("Will retry when datastore available: %s",
err.Error())
status.HandleDownloadFail(errStr, 0)
publishDownloaderStatus(ctx, status)
log.Errorf("doDownload(%s): deferred with %v", config.Name, err)
return
Expand Down
30 changes: 22 additions & 8 deletions pkg/pillar/cmd/downloader/resolveconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,15 @@ func maybeRetryResolve(ctx *downloaderContext, status *types.ResolveStatus) {
return
}

// reset Error, to start download again
if status.RetryCount == 0 {
status.OrigError = status.Error
}
// Increment count; we defer clearing error until success
// to avoid confusing the user.
status.RetryCount++
status.ClearError()
errStr := fmt.Sprintf("Retry attempt %d after %s",
status.RetryCount, status.OrigError)
status.SetErrorNow(errStr)
publishResolveStatus(ctx, status)

resolveTagsToHash(ctx, *config)
Expand Down Expand Up @@ -147,8 +153,6 @@ func resolveTagsToHash(ctx *downloaderContext, rc types.ResolveConfig) {
Counter: rc.Counter,
}
}
rs.ClearError()

sha := maybeNameHasSha(rc.Name)
if sha != "" {
rs.ImageSha256 = sha
Expand All @@ -158,7 +162,9 @@ func resolveTagsToHash(ctx *downloaderContext, rc types.ResolveConfig) {

dst, err := utils.LookupDatastoreConfig(ctx.subDatastoreConfig, rc.DatastoreID)
if err != nil {
rs.SetErrorNow(err.Error())
errStr := fmt.Sprintf("Will retry when datastore available: %s",
err.Error())
rs.SetErrorNow(errStr)
publishResolveStatus(ctx, rs)
return
}
Expand All @@ -167,7 +173,8 @@ func resolveTagsToHash(ctx *downloaderContext, rc types.ResolveConfig) {
// construct the datastore context
dsCtx, err := constructDatastoreContext(ctx, rc.Name, false, *dst)
if err != nil {
errStr := fmt.Sprintf("%s, Datastore construction failed, %s", rc.Name, err)
errStr := fmt.Sprintf("Will retry in %v: %s failed: %s",
retryTime, rc.Name, err)
rs.SetErrorNow(errStr)
publishResolveStatus(ctx, rs)
return
Expand All @@ -182,10 +189,12 @@ func resolveTagsToHash(ctx *downloaderContext, rc types.ResolveConfig) {
log.Functionf("Have %d management port addresses for cost %d",
addrCount, downloadMaxPortCost)
if addrCount == 0 {
err := fmt.Errorf("No IP management port addresses for resolve with cost %d",
err := fmt.Errorf("No IP management port addresses with cost <= %d",
downloadMaxPortCost)
log.Error(err.Error())
rs.SetErrorNow(err.Error())
errStr := fmt.Sprintf("Will retry in %v: %s",
retryTime, err)
rs.SetErrorNow(errStr)
publishResolveStatus(ctx, rs)
return
}
Expand Down Expand Up @@ -214,6 +223,8 @@ func resolveTagsToHash(ctx *downloaderContext, rc types.ResolveConfig) {
// and return, but we will get to it later
if errStr != "" {
log.Errorf("Error preparing to download. All errors:%s", errStr)
errStr := fmt.Sprintf("Will retry in %v: %s",
retryTime, errStr)
rs.SetErrorNow(errStr)
publishResolveStatus(ctx, rs)
return
Expand All @@ -239,12 +250,15 @@ func resolveTagsToHash(ctx *downloaderContext, rc types.ResolveConfig) {
errStr = errStr + "\n" + err.Error()
continue
}
rs.ClearError()
rs.ImageSha256 = sha256
publishResolveStatus(ctx, rs)
return

}
log.Errorf("All source IP addresses failed. All errors:%s", errStr)
errStr = fmt.Sprintf("Will retry in %v: %s",
retryTime, errStr)
rs.SetErrorNow(errStr)
publishResolveStatus(ctx, rs)
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/pillar/cmd/downloader/syncop.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ func handleSyncOp(ctx *downloaderContext, key string,
// construct the datastore context
dsCtx, err := constructDatastoreContext(ctx, config.Name, config.NameIsURL, *dst)
if err != nil {
errStr := fmt.Sprintf("%s, Datastore construction failed, %s", config.Name, err)
errStr := fmt.Sprintf("Will retry in %v: %s failed: %s",
retryTime, config.Name, err)
handleSyncOpResponse(ctx, config, status, locFilename, key, errStr)
return
}
Expand Down Expand Up @@ -74,7 +75,7 @@ func handleSyncOp(ctx *downloaderContext, key string,
addrCount := types.CountLocalAddrNoLinkLocalWithCost(ctx.deviceNetworkStatus,
downloadMaxPortCost)
if addrCount == 0 {
err := fmt.Errorf("No IP management port addresses for download with cost %d",
err := fmt.Errorf("No IP management port addresses with cost <= %d",
downloadMaxPortCost)
log.Error(err.Error())
handleSyncOpResponse(ctx, config, status, locFilename,
Expand Down Expand Up @@ -236,8 +237,7 @@ func handleSyncOpResponse(ctx *downloaderContext, config types.DownloaderConfig,
if errStr != "" {
// Delete file, and update the storage
doDelete(ctx, key, locFilename, status)
status.RetryCount++
status.HandleDownloadFail(errStr)
status.HandleDownloadFail(errStr, retryTime)
publishDownloaderStatus(ctx, status)
log.Errorf("handleSyncOpResponse(%s): failed with %s",
status.Name, errStr)
Expand All @@ -250,8 +250,7 @@ func handleSyncOpResponse(ctx *downloaderContext, config types.DownloaderConfig,
// error, so delete the file
doDelete(ctx, key, locFilename, status)
errStr := fmt.Sprintf("%v", err)
status.RetryCount++
status.HandleDownloadFail(errStr)
status.HandleDownloadFail(errStr, retryTime)
publishDownloaderStatus(ctx, status)
log.Errorf("handleSyncOpResponse(%s): failed with %s",
status.Name, errStr)
Expand All @@ -263,6 +262,7 @@ func handleSyncOpResponse(ctx *downloaderContext, config types.DownloaderConfig,
// We do not clear any status.RetryCount, Error, etc. The caller
// should look at State == DOWNLOADED to determine it is done.

status.ClearError()
status.ModTime = time.Now()
status.State = types.DOWNLOADED
status.Progress = 100 // Just in case
Expand Down
36 changes: 33 additions & 3 deletions pkg/pillar/cmd/zedagent/handlemetrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -901,10 +901,13 @@ func PublishAppInfoToZedCloud(ctx *zedagentContext, uuid string,
ReportAppInfo.AppID = uuid
ReportAppInfo.SystemApp = false
ReportAppInfo.State = info.ZSwState_HALTED
var state types.SwState
var objErr bool
if aiStatus != nil {
ReportAppInfo.AppName = aiStatus.DisplayName
ReportAppInfo.State = aiStatus.State.ZSwState()

state = aiStatus.State
objErr = aiStatus.HasError()
if !aiStatus.ErrorTime.IsZero() {
errInfo := encodeErrorInfo(
aiStatus.ErrorAndTimeWithSource.ErrorAndTime())
Expand Down Expand Up @@ -1015,6 +1018,7 @@ func PublishAppInfoToZedCloud(ctx *zedagentContext, uuid string,
log.Fatal("malloc error")
}
size := int64(proto.Size(ReportInfo))
start := time.Now()
err = SendProtobuf(statusUrl, buf, size, iteration)
if err != nil {
log.Errorf("PublishAppInfoToZedCloud failed: %s", err)
Expand All @@ -1028,6 +1032,9 @@ func PublishAppInfoToZedCloud(ctx *zedagentContext, uuid string,
true)
} else {
writeSentAppInfoProtoMessage(data)

log.Functionf("sent app info %s state %s err %t took %v",
uuid, state.String(), objErr, time.Since(start))
}
}

Expand All @@ -1050,10 +1057,13 @@ func PublishContentInfoToZedCloud(ctx *zedagentContext, uuid string,

ReportContentInfo.Uuid = uuid
ReportContentInfo.State = info.ZSwState_HALTED
var state types.SwState
var objErr bool
if ctStatus != nil {
ReportContentInfo.DisplayName = ctStatus.DisplayName
ReportContentInfo.State = ctStatus.State.ZSwState()

state = ctStatus.State
objErr = ctStatus.HasError()
if !ctStatus.ErrorTime.IsZero() {
errInfo := encodeErrorInfo(
ctStatus.ErrorAndTimeWithSource.ErrorAndTime())
Expand Down Expand Up @@ -1089,6 +1099,7 @@ func PublishContentInfoToZedCloud(ctx *zedagentContext, uuid string,
log.Fatal("malloc error")
}
size := int64(proto.Size(ReportInfo))
start := time.Now()
err = SendProtobuf(statusURL, buf, size, iteration)
if err != nil {
log.Errorf("PublishContentInfoToZedCloud failed: %s", err)
Expand All @@ -1100,6 +1111,9 @@ func PublishContentInfoToZedCloud(ctx *zedagentContext, uuid string,
}
zedcloud.SetDeferred(zedcloudCtx, uuid, buf, size, statusURL,
true)
} else {
log.Functionf("sent content info %s state %s err %t took %v",
uuid, state.String(), objErr, time.Since(start))
}
}

Expand All @@ -1122,10 +1136,13 @@ func PublishVolumeToZedCloud(ctx *zedagentContext, uuid string,

ReportVolumeInfo.Uuid = uuid
ReportVolumeInfo.State = info.ZSwState_INITIAL
var state types.SwState
var objErr bool
if volStatus != nil {
ReportVolumeInfo.DisplayName = volStatus.DisplayName
ReportVolumeInfo.State = volStatus.State.ZSwState()

state = volStatus.State
objErr = volStatus.HasError()
if !volStatus.ErrorTime.IsZero() {
errInfo := encodeErrorInfo(
volStatus.ErrorAndTimeWithSource.ErrorAndTime())
Expand Down Expand Up @@ -1168,6 +1185,7 @@ func PublishVolumeToZedCloud(ctx *zedagentContext, uuid string,
log.Fatal("malloc error")
}
size := int64(proto.Size(ReportInfo))
start := time.Now()
err = SendProtobuf(statusURL, buf, size, iteration)
if err != nil {
log.Errorf("PublishVolumeToZedCloud failed: %s", err)
Expand All @@ -1179,7 +1197,11 @@ func PublishVolumeToZedCloud(ctx *zedagentContext, uuid string,
}
zedcloud.SetDeferred(zedcloudCtx, uuid, buf, size, statusURL,
true)
} else {
log.Functionf("sent vol info %s state %s err %t took %v",
uuid, state.String(), objErr, time.Since(start))
}

}

// PublishBlobInfoToZedCloud is called per change, hence needs to try over all management ports
Expand All @@ -1200,8 +1222,12 @@ func PublishBlobInfoToZedCloud(ctx *zedagentContext, blobSha string, blobStatus
ReportBlobInfo := new(info.ZInfoBlob)

ReportBlobInfo.Sha256 = blobSha
var state types.SwState
var objErr bool
if blobStatus != nil {
ReportBlobInfo.State = blobStatus.State.ZSwState()
state = blobStatus.State
objErr = blobStatus.HasError()
ReportBlobInfo.ProgressPercentage = blobStatus.GetDownloadedPercentage()
ReportBlobInfo.Usage = &info.UsageInfo{RefCount: uint32(blobStatus.RefCount)}
ReportBlobInfo.Resources = &info.ContentResources{CurSizeBytes: blobStatus.Size}
Expand All @@ -1227,6 +1253,7 @@ func PublishBlobInfoToZedCloud(ctx *zedagentContext, blobSha string, blobStatus
log.Fatal("malloc error")
}
size := int64(proto.Size(ReportInfo))
start := time.Now()
err = SendProtobuf(statusURL, buf, size, iteration)
if err != nil {
log.Errorf("PublishBlobInfoToZedCloud failed: %s", err)
Expand All @@ -1238,6 +1265,9 @@ func PublishBlobInfoToZedCloud(ctx *zedagentContext, blobSha string, blobStatus
}
zedcloud.SetDeferred(zedcloudCtx, blobSha, buf, size, statusURL,
true)
} else {
log.Functionf("sent blob info %s state %s err %t took %v",
blobSha, state.String(), objErr, time.Since(start))
}
}

Expand Down
4 changes: 4 additions & 0 deletions pkg/pillar/cmd/zedagent/reportinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ func PublishDeviceInfoToZedCloud(ctx *zedagentContext) {
log.Fatal("malloc error")
}
size := int64(proto.Size(ReportInfo))
start := time.Now()
err = SendProtobuf(statusUrl, buf, size, iteration)
if err != nil {
log.Errorf("PublishDeviceInfoToZedCloud failed: %s", err)
Expand All @@ -534,6 +535,9 @@ func PublishDeviceInfoToZedCloud(ctx *zedagentContext) {
statusUrl, true)
} else {
writeSentDeviceInfoProtoMessage(data)

log.Functionf("sent device info %s took %v", deviceUUID,
time.Since(start))
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/pillar/hypervisor/qmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const sockTimeout = 10 * time.Second

func execRawCmd(socket, cmd string) ([]byte, error) {
var retry = 3
logrus.Infof("executing QMP command: %s", cmd)
logrus.Debugf("executing QMP command: %s", cmd)
var err error
var monitor *qmp.SocketMonitor

Expand Down
9 changes: 8 additions & 1 deletion pkg/pillar/types/downloadertypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package types

import (
"fmt"
"time"

"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -113,6 +114,8 @@ type DownloaderStatus struct {
// ErrorAndTime provides SetErrorNow() and ClearError()
ErrorAndTime
RetryCount int
// We save the original error when we do a retry
OrigError string
}

func (status DownloaderStatus) Key() string {
Expand All @@ -134,7 +137,11 @@ func (status *DownloaderStatus) ClearPendingStatus() {
}

// HandleDownloadFail : Do Failure specific tasks
func (status *DownloaderStatus) HandleDownloadFail(errStr string) {
func (status *DownloaderStatus) HandleDownloadFail(errStr string, retryTime time.Duration) {
if retryTime != 0 {
errStr = fmt.Sprintf("Will retry in %v: %s",
retryTime, errStr)
}
status.SetErrorNow(errStr)
status.ClearPendingStatus()
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/pillar/types/resolvertypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ type ResolveStatus struct {
RetryCount int
// ErrorAndTime provides SetErrorNow() and ClearError()
ErrorAndTime
// We save the original error when we do a retry
OrigError string
}

// Key : DatastoreID, name and sequence counter are used
Expand Down
Loading