Files
releases/plugins/bundle/status.go
T
Stephan Renatus 1a4227b7dc nightly checks: fix races, bump logrus version (#3439)
* runtime_test: avoid race condition

This had been flagged by our nightly race deteector run. Now, we'll
wait for the server to have stopped before checking its log output.

* plugins: avoid races, bump github.com/sirupsen/logrus

To fix that other one, I've first tried updating logrus (there was a
mention of fixed races in the changelog), but to no avail. Setting up
the hook before any plugin would log from that test resolved the issue.

No harm in updating logrus, though, let's keep that: 1.6.0 -> 1.8.1

* plugins/bundle: fix race

Golang for-range loops need special care when using a reference to the
second variable (v in `for k, v := range m`). We had been copying the
value of m[k], which is a pointer to Status, we had not been -- as was
intended -- copying the values of the struct that the pointer had been
pointing to.

Tests needed to be adapted for this, the s4 update will NOT contain
any bundle-activation-related metrics, as no bundle was activated, and
its status is a fresh copy.

* workflow: add race detector to PR checks

When run from nightly, we use ubuntu-latest; whereas the other checks
in the pull-request workflow use ubuntu-18.04.

I don't think it matters at all for the race detector, since that one
runs only from another docker container, using the golang image.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-05-12 11:06:40 +02:00

79 lines
2.2 KiB
Go

// Copyright 2018 The OPA Authors. All rights reserved.
// Use of this source code is governed by an Apache2
// license that can be found in the LICENSE file.
package bundle
import (
"time"
"github.com/pkg/errors"
"github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/metrics"
"github.com/open-policy-agent/opa/server/types"
)
const (
errCode = "bundle_error"
)
// Status represents the status of processing a bundle.
type Status struct {
Name string `json:"name"`
ActiveRevision string `json:"active_revision,omitempty"`
LastSuccessfulActivation time.Time `json:"last_successful_activation,omitempty"`
LastSuccessfulDownload time.Time `json:"last_successful_download,omitempty"`
LastSuccessfulRequest time.Time `json:"last_successful_request,omitempty"`
LastRequest time.Time `json:"last_request,omitempty"`
Code string `json:"code,omitempty"`
Message string `json:"message,omitempty"`
Errors []error `json:"errors,omitempty"`
Metrics metrics.Metrics `json:"metrics,omitempty"`
}
// SetActivateSuccess updates the status object to reflect a successful
// activation.
func (s *Status) SetActivateSuccess(revision string) {
s.LastSuccessfulActivation = time.Now().UTC()
s.ActiveRevision = revision
}
// SetDownloadSuccess updates the status object to reflect a successful
// download.
func (s *Status) SetDownloadSuccess() {
s.LastSuccessfulDownload = time.Now().UTC()
}
// SetRequest updates the status object to reflect a download attempt.
func (s *Status) SetRequest() {
s.LastRequest = time.Now().UTC()
}
// SetError updates the status object to reflect a failure to download or
// activate. If err is nil, the error status is cleared.
func (s *Status) SetError(err error) {
if err == nil {
s.Code = ""
s.Message = ""
s.Errors = nil
return
}
cause := errors.Cause(err)
if astErr, ok := cause.(ast.Errors); ok {
s.Code = errCode
s.Message = types.MsgCompileModuleError
s.Errors = make([]error, len(astErr))
for i := range astErr {
s.Errors[i] = astErr[i]
}
} else {
s.Code = errCode
s.Message = err.Error()
s.Errors = nil
}
}