diff --git a/apiserver/controllers/controllers.go b/apiserver/controllers/controllers.go index 0c610c38..66aa6db9 100644 --- a/apiserver/controllers/controllers.go +++ b/apiserver/controllers/controllers.go @@ -17,6 +17,8 @@ package controllers import ( "context" "encoding/json" + "errors" + "fmt" "io" "log/slog" "net/http" @@ -25,7 +27,6 @@ import ( "github.com/gorilla/mux" "github.com/gorilla/websocket" - "github.com/pkg/errors" gErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm-provider-common/util" @@ -43,7 +44,7 @@ import ( func NewAPIController(r *runner.Runner, authenticator *auth.Authenticator, hub *wsWriter.Hub, apiCfg config.APIServer) (*APIController, error) { controllerInfo, err := r.GetControllerInfo(auth.GetAdminContext(context.Background())) if err != nil { - return nil, errors.Wrap(err, "failed to get controller info") + return nil, fmt.Errorf("failed to get controller info: %w", err) } var checkOrigin func(r *http.Request) bool if len(apiCfg.CORSOrigins) > 0 { @@ -91,24 +92,22 @@ type APIController struct { func handleError(ctx context.Context, w http.ResponseWriter, err error) { w.Header().Set("Content-Type", "application/json") - origErr := errors.Cause(err) apiErr := params.APIErrorResponse{ - Details: origErr.Error(), + Details: err.Error(), } - - switch origErr.(type) { - case *gErrors.NotFoundError: + switch { + case errors.Is(err, gErrors.ErrNotFound): w.WriteHeader(http.StatusNotFound) apiErr.Error = "Not Found" - case *gErrors.UnauthorizedError: + case errors.Is(err, gErrors.ErrUnauthorized): w.WriteHeader(http.StatusUnauthorized) apiErr.Error = "Not Authorized" // Don't include details on 401 errors. apiErr.Details = "" - case *gErrors.BadRequestError: + case errors.Is(err, gErrors.ErrBadRequest): w.WriteHeader(http.StatusBadRequest) apiErr.Error = "Bad Request" - case *gErrors.DuplicateUserError, *gErrors.ConflictError: + case errors.Is(err, gErrors.ErrDuplicateEntity), errors.Is(err, &gErrors.ConflictError{}): w.WriteHeader(http.StatusConflict) apiErr.Error = "Conflict" default: diff --git a/auth/auth.go b/auth/auth.go index 7dfabcf0..c5fa1ebd 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -16,11 +16,12 @@ package auth import ( "context" + "errors" + "fmt" "time" jwt "github.com/golang-jwt/jwt/v5" "github.com/nbutton23/zxcvbn-go" - "github.com/pkg/errors" "golang.org/x/crypto/bcrypt" runnerErrors "github.com/cloudbase/garm-provider-common/errors" @@ -49,7 +50,7 @@ func (a *Authenticator) IsInitialized() bool { func (a *Authenticator) GetJWTToken(ctx context.Context) (string, error) { tokenID, err := util.GetRandomString(16) if err != nil { - return "", errors.Wrap(err, "generating random string") + return "", fmt.Errorf("error generating random string: %w", err) } expireToken := time.Now().Add(a.cfg.TimeToLive.Duration()) expires := &jwt.NumericDate{ @@ -72,7 +73,7 @@ func (a *Authenticator) GetJWTToken(ctx context.Context) (string, error) { token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenString, err := token.SignedString([]byte(a.cfg.Secret)) if err != nil { - return "", errors.Wrap(err, "fetching token string") + return "", fmt.Errorf("error fetching token string: %w", err) } return tokenString, nil @@ -87,7 +88,7 @@ func (a *Authenticator) GetJWTMetricsToken(ctx context.Context) (string, error) tokenID, err := util.GetRandomString(16) if err != nil { - return "", errors.Wrap(err, "generating random string") + return "", fmt.Errorf("error generating random string: %w", err) } // nolint:golangci-lint,godox // TODO: currently this is the same TTL as the normal Token @@ -111,7 +112,7 @@ func (a *Authenticator) GetJWTMetricsToken(ctx context.Context) (string, error) token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenString, err := token.SignedString([]byte(a.cfg.Secret)) if err != nil { - return "", errors.Wrap(err, "fetching token string") + return "", fmt.Errorf("error fetching token string: %w", err) } return tokenString, nil @@ -121,7 +122,7 @@ func (a *Authenticator) InitController(ctx context.Context, param params.NewUser _, err := a.store.ControllerInfo() if err != nil { if !errors.Is(err, runnerErrors.ErrNotFound) { - return params.User{}, errors.Wrap(err, "initializing controller") + return params.User{}, fmt.Errorf("error initializing controller: %w", err) } } if a.store.HasAdminUser(ctx) { @@ -151,7 +152,7 @@ func (a *Authenticator) InitController(ctx context.Context, param params.NewUser hashed, err := util.PaswsordToBcrypt(param.Password) if err != nil { - return params.User{}, errors.Wrap(err, "creating user") + return params.User{}, fmt.Errorf("error creating user: %w", err) } param.Password = hashed @@ -169,7 +170,7 @@ func (a *Authenticator) AuthenticateUser(ctx context.Context, info params.Passwo if errors.Is(err, runnerErrors.ErrNotFound) { return ctx, runnerErrors.ErrUnauthorized } - return ctx, errors.Wrap(err, "authenticating") + return ctx, fmt.Errorf("error authenticating: %w", err) } if !user.Enabled { diff --git a/auth/instance_middleware.go b/auth/instance_middleware.go index bcae0b0a..dc31327e 100644 --- a/auth/instance_middleware.go +++ b/auth/instance_middleware.go @@ -24,7 +24,6 @@ import ( "time" jwt "github.com/golang-jwt/jwt/v5" - "github.com/pkg/errors" runnerErrors "github.com/cloudbase/garm-provider-common/errors" commonParams "github.com/cloudbase/garm-provider-common/params" @@ -91,7 +90,7 @@ func (i *instanceToken) NewInstanceJWTToken(instance params.Instance, entity par token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenString, err := token.SignedString([]byte(i.jwtSecret)) if err != nil { - return "", errors.Wrap(err, "signing token") + return "", fmt.Errorf("error signing token: %w", err) } return tokenString, nil diff --git a/cmd/garm-cli/cmd/init.go b/cmd/garm-cli/cmd/init.go index 6c6a6072..c544699e 100644 --- a/cmd/garm-cli/cmd/init.go +++ b/cmd/garm-cli/cmd/init.go @@ -21,7 +21,6 @@ import ( openapiRuntimeClient "github.com/go-openapi/runtime/client" "github.com/jedib0t/go-pretty/v6/table" - "github.com/pkg/errors" "github.com/spf13/cobra" apiClientController "github.com/cloudbase/garm/client/controller" @@ -80,7 +79,7 @@ garm-cli init --name=dev --url=https://runner.example.com --username=admin --pas response, err := apiCli.FirstRun.FirstRun(newUserReq, authToken) if err != nil { - return errors.Wrap(err, "initializing manager") + return fmt.Errorf("error initializing manager: %w", err) } newLoginParamsReq := apiClientLogin.NewLoginParams() @@ -91,7 +90,7 @@ garm-cli init --name=dev --url=https://runner.example.com --username=admin --pas token, err := apiCli.Login.Login(newLoginParamsReq, authToken) if err != nil { - return errors.Wrap(err, "authenticating") + return fmt.Errorf("error authenticating: %w", err) } cfg.Managers = append(cfg.Managers, config.Manager{ @@ -104,7 +103,7 @@ garm-cli init --name=dev --url=https://runner.example.com --username=admin --pas cfg.ActiveManager = loginProfileName if err := cfg.SaveConfig(); err != nil { - return errors.Wrap(err, "saving config") + return fmt.Errorf("error saving config: %w", err) } updateUrlsReq := apiClientController.NewUpdateControllerParams() diff --git a/cmd/garm-cli/cmd/pool.go b/cmd/garm-cli/cmd/pool.go index 445801a6..5b8cadf3 100644 --- a/cmd/garm-cli/cmd/pool.go +++ b/cmd/garm-cli/cmd/pool.go @@ -21,7 +21,6 @@ import ( "strings" "github.com/jedib0t/go-pretty/v6/table" - "github.com/pkg/errors" "github.com/spf13/cobra" commonParams "github.com/cloudbase/garm-provider-common/params" @@ -471,7 +470,7 @@ func init() { func extraSpecsFromFile(specsFile string) (json.RawMessage, error) { data, err := os.ReadFile(specsFile) if err != nil { - return nil, errors.Wrap(err, "opening specs file") + return nil, fmt.Errorf("error opening specs file: %w", err) } return asRawMessage(data) } @@ -481,14 +480,14 @@ func asRawMessage(data []byte) (json.RawMessage, error) { // have a valid json. var unmarshaled interface{} if err := json.Unmarshal(data, &unmarshaled); err != nil { - return nil, errors.Wrap(err, "decoding extra specs") + return nil, fmt.Errorf("error decoding extra specs: %w", err) } var asRawJSON json.RawMessage var err error asRawJSON, err = json.Marshal(unmarshaled) if err != nil { - return nil, errors.Wrap(err, "marshaling json") + return nil, fmt.Errorf("error marshaling json: %w", err) } return asRawJSON, nil } diff --git a/cmd/garm-cli/config/config.go b/cmd/garm-cli/config/config.go index 6f6b197c..cf1cf1d2 100644 --- a/cmd/garm-cli/config/config.go +++ b/cmd/garm-cli/config/config.go @@ -15,13 +15,13 @@ package config import ( + "errors" "fmt" "os" "path/filepath" "sync" "github.com/BurntSushi/toml" - "github.com/pkg/errors" runnerErrors "github.com/cloudbase/garm-provider-common/errors" ) @@ -34,11 +34,11 @@ const ( func getConfigFilePath() (string, error) { configDir, err := getHomeDir() if err != nil { - return "", errors.Wrap(err, "fetching home folder") + return "", fmt.Errorf("error fetching home folder: %w", err) } if err := ensureHomeDir(configDir); err != nil { - return "", errors.Wrap(err, "ensuring config dir") + return "", fmt.Errorf("error ensuring config dir: %w", err) } cfgFile := filepath.Join(configDir, DefaultConfigFileName) @@ -48,7 +48,7 @@ func getConfigFilePath() (string, error) { func LoadConfig() (*Config, error) { cfgFile, err := getConfigFilePath() if err != nil { - return nil, errors.Wrap(err, "fetching config") + return nil, fmt.Errorf("error fetching config: %w", err) } if _, err := os.Stat(cfgFile); err != nil { @@ -56,12 +56,12 @@ func LoadConfig() (*Config, error) { // return empty config return &Config{}, nil } - return nil, errors.Wrap(err, "accessing config file") + return nil, fmt.Errorf("error accessing config file: %w", err) } var config Config if _, err := toml.DecodeFile(cfgFile, &config); err != nil { - return nil, errors.Wrap(err, "decoding toml") + return nil, fmt.Errorf("error decoding toml: %w", err) } return &config, nil @@ -157,17 +157,17 @@ func (c *Config) SaveConfig() error { cfgFile, err := getConfigFilePath() if err != nil { if !errors.Is(err, os.ErrNotExist) { - return errors.Wrap(err, "getting config") + return fmt.Errorf("error getting config: %w", err) } } cfgHandle, err := os.Create(cfgFile) if err != nil { - return errors.Wrap(err, "getting file handle") + return fmt.Errorf("error getting file handle: %w", err) } encoder := toml.NewEncoder(cfgHandle) if err := encoder.Encode(c); err != nil { - return errors.Wrap(err, "saving config") + return fmt.Errorf("error saving config: %w", err) } return nil diff --git a/cmd/garm-cli/config/home.go b/cmd/garm-cli/config/home.go index b6043289..11821e9c 100644 --- a/cmd/garm-cli/config/home.go +++ b/cmd/garm-cli/config/home.go @@ -15,19 +15,19 @@ package config import ( + "errors" + "fmt" "os" - - "github.com/pkg/errors" ) func ensureHomeDir(folder string) error { if _, err := os.Stat(folder); err != nil { if !errors.Is(err, os.ErrNotExist) { - return errors.Wrap(err, "checking home dir") + return fmt.Errorf("error checking home dir: %w", err) } if err := os.MkdirAll(folder, 0o710); err != nil { - return errors.Wrapf(err, "creating %s", folder) + return fmt.Errorf("error creating %s: %w", folder, err) } } diff --git a/cmd/garm-cli/config/home_nix.go b/cmd/garm-cli/config/home_nix.go index e9ffa521..323f29d7 100644 --- a/cmd/garm-cli/config/home_nix.go +++ b/cmd/garm-cli/config/home_nix.go @@ -17,16 +17,15 @@ package config import ( + "fmt" "os" "path/filepath" - - "github.com/pkg/errors" ) func getHomeDir() (string, error) { home, err := os.UserHomeDir() if err != nil { - return "", errors.Wrap(err, "fetching home dir") + return "", fmt.Errorf("error fetching home dir: %w", err) } return filepath.Join(home, ".local", "share", DefaultAppFolder), nil diff --git a/cmd/garm/main.go b/cmd/garm/main.go index 226a9e2a..bfc23d50 100644 --- a/cmd/garm/main.go +++ b/cmd/garm/main.go @@ -31,7 +31,6 @@ import ( "github.com/gorilla/handlers" "github.com/gorilla/mux" - "github.com/pkg/errors" lumberjack "gopkg.in/natefinch/lumberjack.v2" "github.com/cloudbase/garm-provider-common/util" @@ -73,7 +72,7 @@ func maybeInitController(db common.Store) (params.ControllerInfo, error) { info, err := db.InitController() if err != nil { - return params.ControllerInfo{}, errors.Wrap(err, "initializing controller") + return params.ControllerInfo{}, fmt.Errorf("error initializing controller: %w", err) } return info, nil @@ -152,7 +151,7 @@ func setupLogging(ctx context.Context, logCfg config.Logging, hub *websocket.Hub func maybeUpdateURLsFromConfig(cfg config.Config, store common.Store) error { info, err := store.ControllerInfo() if err != nil { - return errors.Wrap(err, "fetching controller info") + return fmt.Errorf("error fetching controller info: %w", err) } var updateParams params.UpdateControllerParams @@ -176,7 +175,7 @@ func maybeUpdateURLsFromConfig(cfg config.Config, store common.Store) error { _, err = store.UpdateController(updateParams) if err != nil { - return errors.Wrap(err, "updating controller info") + return fmt.Errorf("error updating controller info: %w", err) } return nil } diff --git a/config/config.go b/config/config.go index cdbec393..31a16ae2 100644 --- a/config/config.go +++ b/config/config.go @@ -31,7 +31,6 @@ import ( "github.com/BurntSushi/toml" "github.com/bradleyfalzon/ghinstallation/v2" zxcvbn "github.com/nbutton23/zxcvbn-go" - "github.com/pkg/errors" "golang.org/x/oauth2" "github.com/cloudbase/garm/params" @@ -84,10 +83,10 @@ const ( func NewConfig(cfgFile string) (*Config, error) { var config Config if _, err := toml.DecodeFile(cfgFile, &config); err != nil { - return nil, errors.Wrap(err, "decoding toml") + return nil, fmt.Errorf("error decoding toml: %w", err) } if err := config.Validate(); err != nil { - return nil, errors.Wrap(err, "validating config") + return nil, fmt.Errorf("error validating config: %w", err) } return &config, nil } @@ -496,19 +495,19 @@ type Database struct { // GormParams returns the database type and connection URI func (d *Database) GormParams() (dbType DBBackendType, uri string, err error) { if err := d.Validate(); err != nil { - return "", "", errors.Wrap(err, "validating database config") + return "", "", fmt.Errorf("error validating database config: %w", err) } dbType = d.DbBackend switch dbType { case MySQLBackend: uri, err = d.MySQL.ConnectionString() if err != nil { - return "", "", errors.Wrap(err, "fetching mysql connection string") + return "", "", fmt.Errorf("error fetching mysql connection string: %w", err) } case SQLiteBackend: uri, err = d.SQLite.ConnectionString() if err != nil { - return "", "", errors.Wrap(err, "fetching sqlite3 connection string") + return "", "", fmt.Errorf("error fetching sqlite3 connection string: %w", err) } default: return "", "", fmt.Errorf("invalid database backend: %s", dbType) diff --git a/config/config_test.go b/config/config_test.go index 52c2928e..bbf9e299 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -517,7 +517,6 @@ func TestJWTAuthConfig(t *testing.T) { func TestTimeToLiveDuration(t *testing.T) { cfg := JWTAuth{ - Secret: EncryptionPassphrase, TimeToLive: "48h", } diff --git a/database/sql/controller.go b/database/sql/controller.go index fb360e00..5bf60763 100644 --- a/database/sql/controller.go +++ b/database/sql/controller.go @@ -15,10 +15,11 @@ package sql import ( + "errors" + "fmt" "net/url" "github.com/google/uuid" - "github.com/pkg/errors" "gorm.io/gorm" runnerErrors "github.com/cloudbase/garm-provider-common/errors" @@ -30,7 +31,7 @@ import ( func dbControllerToCommonController(dbInfo ControllerInfo) (params.ControllerInfo, error) { url, err := url.JoinPath(dbInfo.WebhookBaseURL, dbInfo.ControllerID.String()) if err != nil { - return params.ControllerInfo{}, errors.Wrap(err, "joining webhook URL") + return params.ControllerInfo{}, fmt.Errorf("error joining webhook URL: %w", err) } return params.ControllerInfo{ @@ -49,14 +50,14 @@ func (s *sqlDatabase) ControllerInfo() (params.ControllerInfo, error) { q := s.conn.Model(&ControllerInfo{}).First(&info) if q.Error != nil { if errors.Is(q.Error, gorm.ErrRecordNotFound) { - return params.ControllerInfo{}, errors.Wrap(runnerErrors.ErrNotFound, "fetching controller info") + return params.ControllerInfo{}, fmt.Errorf("error fetching controller info: %w", runnerErrors.ErrNotFound) } - return params.ControllerInfo{}, errors.Wrap(q.Error, "fetching controller info") + return params.ControllerInfo{}, fmt.Errorf("error fetching controller info: %w", q.Error) } paramInfo, err := dbControllerToCommonController(info) if err != nil { - return params.ControllerInfo{}, errors.Wrap(err, "converting controller info") + return params.ControllerInfo{}, fmt.Errorf("error converting controller info: %w", err) } return paramInfo, nil @@ -69,7 +70,7 @@ func (s *sqlDatabase) InitController() (params.ControllerInfo, error) { newID, err := uuid.NewRandom() if err != nil { - return params.ControllerInfo{}, errors.Wrap(err, "generating UUID") + return params.ControllerInfo{}, fmt.Errorf("error generating UUID: %w", err) } newInfo := ControllerInfo{ @@ -79,7 +80,7 @@ func (s *sqlDatabase) InitController() (params.ControllerInfo, error) { q := s.conn.Save(&newInfo) if q.Error != nil { - return params.ControllerInfo{}, errors.Wrap(q.Error, "saving controller info") + return params.ControllerInfo{}, fmt.Errorf("error saving controller info: %w", q.Error) } return params.ControllerInfo{ @@ -98,13 +99,13 @@ func (s *sqlDatabase) UpdateController(info params.UpdateControllerParams) (para q := tx.Model(&ControllerInfo{}).First(&dbInfo) if q.Error != nil { if errors.Is(q.Error, gorm.ErrRecordNotFound) { - return errors.Wrap(runnerErrors.ErrNotFound, "fetching controller info") + return fmt.Errorf("error fetching controller info: %w", runnerErrors.ErrNotFound) } - return errors.Wrap(q.Error, "fetching controller info") + return fmt.Errorf("error fetching controller info: %w", q.Error) } if err := info.Validate(); err != nil { - return errors.Wrap(err, "validating controller info") + return fmt.Errorf("error validating controller info: %w", err) } if info.MetadataURL != nil { @@ -125,17 +126,17 @@ func (s *sqlDatabase) UpdateController(info params.UpdateControllerParams) (para q = tx.Save(&dbInfo) if q.Error != nil { - return errors.Wrap(q.Error, "saving controller info") + return fmt.Errorf("error saving controller info: %w", q.Error) } return nil }) if err != nil { - return params.ControllerInfo{}, errors.Wrap(err, "updating controller info") + return params.ControllerInfo{}, fmt.Errorf("error updating controller info: %w", err) } paramInfo, err = dbControllerToCommonController(dbInfo) if err != nil { - return params.ControllerInfo{}, errors.Wrap(err, "converting controller info") + return params.ControllerInfo{}, fmt.Errorf("error converting controller info: %w", err) } return paramInfo, nil } diff --git a/database/sql/enterprise.go b/database/sql/enterprise.go index fc273165..d201cd21 100644 --- a/database/sql/enterprise.go +++ b/database/sql/enterprise.go @@ -16,10 +16,11 @@ package sql import ( "context" + "errors" + "fmt" "log/slog" "github.com/google/uuid" - "github.com/pkg/errors" "gorm.io/gorm" runnerErrors "github.com/cloudbase/garm-provider-common/errors" @@ -33,12 +34,12 @@ func (s *sqlDatabase) CreateEnterprise(ctx context.Context, name string, credent return params.Enterprise{}, errors.New("creating enterprise: missing secret") } if credentials.ForgeType != params.GithubEndpointType { - return params.Enterprise{}, errors.Wrap(runnerErrors.ErrBadRequest, "enterprises are not supported on this forge type") + return params.Enterprise{}, fmt.Errorf("enterprises are not supported on this forge type: %w", runnerErrors.ErrBadRequest) } secret, err := util.Seal([]byte(webhookSecret), []byte(s.cfg.Passphrase)) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "encoding secret") + return params.Enterprise{}, fmt.Errorf("error encoding secret: %w", err) } defer func() { @@ -57,22 +58,22 @@ func (s *sqlDatabase) CreateEnterprise(ctx context.Context, name string, credent q := tx.Create(&newEnterprise) if q.Error != nil { - return errors.Wrap(q.Error, "creating enterprise") + return fmt.Errorf("error creating enterprise: %w", q.Error) } newEnterprise, err = s.getEnterpriseByID(ctx, tx, newEnterprise.ID.String(), "Pools", "Credentials", "Endpoint", "Credentials.Endpoint") if err != nil { - return errors.Wrap(err, "creating enterprise") + return fmt.Errorf("error creating enterprise: %w", err) } return nil }) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "creating enterprise") + return params.Enterprise{}, fmt.Errorf("error creating enterprise: %w", err) } ret, err := s.GetEnterpriseByID(ctx, newEnterprise.ID.String()) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "creating enterprise") + return params.Enterprise{}, fmt.Errorf("error creating enterprise: %w", err) } return ret, nil @@ -81,12 +82,12 @@ func (s *sqlDatabase) CreateEnterprise(ctx context.Context, name string, credent func (s *sqlDatabase) GetEnterprise(ctx context.Context, name, endpointName string) (params.Enterprise, error) { enterprise, err := s.getEnterprise(ctx, name, endpointName) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "fetching enterprise") + return params.Enterprise{}, fmt.Errorf("error fetching enterprise: %w", err) } param, err := s.sqlToCommonEnterprise(enterprise, true) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "fetching enterprise") + return params.Enterprise{}, fmt.Errorf("error fetching enterprise: %w", err) } return param, nil } @@ -101,12 +102,12 @@ func (s *sqlDatabase) GetEnterpriseByID(ctx context.Context, enterpriseID string } enterprise, err := s.getEnterpriseByID(ctx, s.conn, enterpriseID, preloadList...) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "fetching enterprise") + return params.Enterprise{}, fmt.Errorf("error fetching enterprise: %w", err) } param, err := s.sqlToCommonEnterprise(enterprise, true) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "fetching enterprise") + return params.Enterprise{}, fmt.Errorf("error fetching enterprise: %w", err) } return param, nil } @@ -125,7 +126,7 @@ func (s *sqlDatabase) ListEnterprises(_ context.Context, filter params.Enterpris } q = q.Find(&enterprises) if q.Error != nil { - return []params.Enterprise{}, errors.Wrap(q.Error, "fetching enterprises") + return []params.Enterprise{}, fmt.Errorf("error fetching enterprises: %w", q.Error) } ret := make([]params.Enterprise, len(enterprises)) @@ -133,7 +134,7 @@ func (s *sqlDatabase) ListEnterprises(_ context.Context, filter params.Enterpris var err error ret[idx], err = s.sqlToCommonEnterprise(val, true) if err != nil { - return nil, errors.Wrap(err, "fetching enterprises") + return nil, fmt.Errorf("error fetching enterprises: %w", err) } } @@ -143,7 +144,7 @@ func (s *sqlDatabase) ListEnterprises(_ context.Context, filter params.Enterpris func (s *sqlDatabase) DeleteEnterprise(ctx context.Context, enterpriseID string) error { enterprise, err := s.getEnterpriseByID(ctx, s.conn, enterpriseID, "Endpoint", "Credentials", "Credentials.Endpoint") if err != nil { - return errors.Wrap(err, "fetching enterprise") + return fmt.Errorf("error fetching enterprise: %w", err) } defer func(ent Enterprise) { @@ -159,7 +160,7 @@ func (s *sqlDatabase) DeleteEnterprise(ctx context.Context, enterpriseID string) q := s.conn.Unscoped().Delete(&enterprise) if q.Error != nil && !errors.Is(q.Error, gorm.ErrRecordNotFound) { - return errors.Wrap(q.Error, "deleting enterprise") + return fmt.Errorf("error deleting enterprise: %w", q.Error) } return nil @@ -177,31 +178,31 @@ func (s *sqlDatabase) UpdateEnterprise(ctx context.Context, enterpriseID string, var err error enterprise, err = s.getEnterpriseByID(ctx, tx, enterpriseID) if err != nil { - return errors.Wrap(err, "fetching enterprise") + return fmt.Errorf("error fetching enterprise: %w", err) } if enterprise.EndpointName == nil { - return errors.Wrap(runnerErrors.ErrUnprocessable, "enterprise has no endpoint") + return fmt.Errorf("error enterprise has no endpoint: %w", runnerErrors.ErrUnprocessable) } if param.CredentialsName != "" { creds, err = s.getGithubCredentialsByName(ctx, tx, param.CredentialsName, false) if err != nil { - return errors.Wrap(err, "fetching credentials") + return fmt.Errorf("error fetching credentials: %w", err) } if creds.EndpointName == nil { - return errors.Wrap(runnerErrors.ErrUnprocessable, "credentials have no endpoint") + return fmt.Errorf("error credentials have no endpoint: %w", runnerErrors.ErrUnprocessable) } if *creds.EndpointName != *enterprise.EndpointName { - return errors.Wrap(runnerErrors.ErrBadRequest, "endpoint mismatch") + return fmt.Errorf("error endpoint mismatch: %w", runnerErrors.ErrBadRequest) } enterprise.CredentialsID = &creds.ID } if param.WebhookSecret != "" { secret, err := util.Seal([]byte(param.WebhookSecret), []byte(s.cfg.Passphrase)) if err != nil { - return errors.Wrap(err, "encoding secret") + return fmt.Errorf("error encoding secret: %w", err) } enterprise.WebhookSecret = secret } @@ -212,22 +213,22 @@ func (s *sqlDatabase) UpdateEnterprise(ctx context.Context, enterpriseID string, q := tx.Save(&enterprise) if q.Error != nil { - return errors.Wrap(q.Error, "saving enterprise") + return fmt.Errorf("error saving enterprise: %w", q.Error) } return nil }) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "updating enterprise") + return params.Enterprise{}, fmt.Errorf("error updating enterprise: %w", err) } enterprise, err = s.getEnterpriseByID(ctx, s.conn, enterpriseID, "Endpoint", "Credentials", "Credentials.Endpoint") if err != nil { - return params.Enterprise{}, errors.Wrap(err, "updating enterprise") + return params.Enterprise{}, fmt.Errorf("error updating enterprise: %w", err) } newParams, err = s.sqlToCommonEnterprise(enterprise, true) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "updating enterprise") + return params.Enterprise{}, fmt.Errorf("error updating enterprise: %w", err) } return newParams, nil } @@ -244,7 +245,7 @@ func (s *sqlDatabase) getEnterprise(_ context.Context, name, endpointName string if errors.Is(q.Error, gorm.ErrRecordNotFound) { return Enterprise{}, runnerErrors.ErrNotFound } - return Enterprise{}, errors.Wrap(q.Error, "fetching enterprise from database") + return Enterprise{}, fmt.Errorf("error fetching enterprise from database: %w", q.Error) } return enterprise, nil } @@ -252,7 +253,7 @@ func (s *sqlDatabase) getEnterprise(_ context.Context, name, endpointName string func (s *sqlDatabase) getEnterpriseByID(_ context.Context, tx *gorm.DB, id string, preload ...string) (Enterprise, error) { u, err := uuid.Parse(id) if err != nil { - return Enterprise{}, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return Enterprise{}, fmt.Errorf("error parsing id: %w", runnerErrors.ErrBadRequest) } var enterprise Enterprise @@ -268,7 +269,7 @@ func (s *sqlDatabase) getEnterpriseByID(_ context.Context, tx *gorm.DB, id strin if errors.Is(q.Error, gorm.ErrRecordNotFound) { return Enterprise{}, runnerErrors.ErrNotFound } - return Enterprise{}, errors.Wrap(q.Error, "fetching enterprise from database") + return Enterprise{}, fmt.Errorf("error fetching enterprise from database: %w", q.Error) } return enterprise, nil } diff --git a/database/sql/enterprise_test.go b/database/sql/enterprise_test.go index 056bb7fa..224c04aa 100644 --- a/database/sql/enterprise_test.go +++ b/database/sql/enterprise_test.go @@ -218,7 +218,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterpriseInvalidDBPassphrase() { params.PoolBalancerTypeRoundRobin) s.Require().NotNil(err) - s.Require().Equal("encoding secret: invalid passphrase length (expected length 32 characters)", err.Error()) + s.Require().Equal("error encoding secret: invalid passphrase length (expected length 32 characters)", err.Error()) } func (s *EnterpriseTestSuite) TestCreateEnterpriseDBCreateErr() { @@ -236,7 +236,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterpriseDBCreateErr() { params.PoolBalancerTypeRoundRobin) s.Require().NotNil(err) - s.Require().Equal("creating enterprise: creating enterprise: creating enterprise mock error", err.Error()) + s.Require().Equal("error creating enterprise: error creating enterprise: creating enterprise mock error", err.Error()) s.assertSQLMockExpectations() } @@ -259,7 +259,7 @@ func (s *EnterpriseTestSuite) TestGetEnterpriseNotFound() { _, err := s.Store.GetEnterprise(s.adminCtx, "dummy-name", "github.com") s.Require().NotNil(err) - s.Require().Equal("fetching enterprise: not found", err.Error()) + s.Require().Equal("error fetching enterprise: not found", err.Error()) } func (s *EnterpriseTestSuite) TestGetEnterpriseDBDecryptingErr() { @@ -271,7 +271,7 @@ func (s *EnterpriseTestSuite) TestGetEnterpriseDBDecryptingErr() { _, err := s.StoreSQLMocked.GetEnterprise(s.adminCtx, s.Fixtures.Enterprises[0].Name, s.Fixtures.Enterprises[0].Endpoint.Name) s.Require().NotNil(err) - s.Require().Equal("fetching enterprise: missing secret", err.Error()) + s.Require().Equal("error fetching enterprise: missing secret", err.Error()) s.assertSQLMockExpectations() } @@ -341,7 +341,7 @@ func (s *EnterpriseTestSuite) TestListEnterprisesDBFetchErr() { s.assertSQLMockExpectations() s.Require().NotNil(err) - s.Require().Equal("fetching enterprises: fetching user from database mock error", err.Error()) + s.Require().Equal("error fetching enterprises: fetching user from database mock error", err.Error()) } func (s *EnterpriseTestSuite) TestDeleteEnterprise() { @@ -350,14 +350,14 @@ func (s *EnterpriseTestSuite) TestDeleteEnterprise() { s.Require().Nil(err) _, err = s.Store.GetEnterpriseByID(s.adminCtx, s.Fixtures.Enterprises[0].ID) s.Require().NotNil(err) - s.Require().Equal("fetching enterprise: not found", err.Error()) + s.Require().Equal("error fetching enterprise: not found", err.Error()) } func (s *EnterpriseTestSuite) TestDeleteEnterpriseInvalidEnterpriseID() { err := s.Store.DeleteEnterprise(s.adminCtx, "dummy-enterprise-id") s.Require().NotNil(err) - s.Require().Equal("fetching enterprise: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching enterprise: error parsing id: invalid request", err.Error()) } func (s *EnterpriseTestSuite) TestDeleteEnterpriseDBDeleteErr() { @@ -375,7 +375,7 @@ func (s *EnterpriseTestSuite) TestDeleteEnterpriseDBDeleteErr() { err := s.StoreSQLMocked.DeleteEnterprise(s.adminCtx, s.Fixtures.Enterprises[0].ID) s.Require().NotNil(err) - s.Require().Equal("deleting enterprise: mocked delete enterprise error", err.Error()) + s.Require().Equal("error deleting enterprise: mocked delete enterprise error", err.Error()) s.assertSQLMockExpectations() } @@ -391,7 +391,7 @@ func (s *EnterpriseTestSuite) TestUpdateEnterpriseInvalidEnterpriseID() { _, err := s.Store.UpdateEnterprise(s.adminCtx, "dummy-enterprise-id", s.Fixtures.UpdateRepoParams) s.Require().NotNil(err) - s.Require().Equal("updating enterprise: fetching enterprise: parsing id: invalid request", err.Error()) + s.Require().Equal("error updating enterprise: error fetching enterprise: error parsing id: invalid request", err.Error()) } func (s *EnterpriseTestSuite) TestUpdateEnterpriseDBEncryptErr() { @@ -416,7 +416,7 @@ func (s *EnterpriseTestSuite) TestUpdateEnterpriseDBEncryptErr() { _, err := s.StoreSQLMocked.UpdateEnterprise(s.adminCtx, s.Fixtures.Enterprises[0].ID, s.Fixtures.UpdateRepoParams) s.Require().NotNil(err) - s.Require().Equal("updating enterprise: encoding secret: invalid passphrase length (expected length 32 characters)", err.Error()) + s.Require().Equal("error updating enterprise: error encoding secret: invalid passphrase length (expected length 32 characters)", err.Error()) s.assertSQLMockExpectations() } @@ -444,7 +444,7 @@ func (s *EnterpriseTestSuite) TestUpdateEnterpriseDBSaveErr() { _, err := s.StoreSQLMocked.UpdateEnterprise(s.adminCtx, s.Fixtures.Enterprises[0].ID, s.Fixtures.UpdateRepoParams) s.Require().NotNil(err) - s.Require().Equal("updating enterprise: saving enterprise: saving enterprise mock error", err.Error()) + s.Require().Equal("error updating enterprise: error saving enterprise: saving enterprise mock error", err.Error()) s.assertSQLMockExpectations() } @@ -472,7 +472,7 @@ func (s *EnterpriseTestSuite) TestUpdateEnterpriseDBDecryptingErr() { _, err := s.StoreSQLMocked.UpdateEnterprise(s.adminCtx, s.Fixtures.Enterprises[0].ID, s.Fixtures.UpdateRepoParams) s.Require().NotNil(err) - s.Require().Equal("updating enterprise: encoding secret: invalid passphrase length (expected length 32 characters)", err.Error()) + s.Require().Equal("error updating enterprise: error encoding secret: invalid passphrase length (expected length 32 characters)", err.Error()) s.assertSQLMockExpectations() } @@ -487,7 +487,7 @@ func (s *EnterpriseTestSuite) TestGetEnterpriseByIDInvalidEnterpriseID() { _, err := s.Store.GetEnterpriseByID(s.adminCtx, "dummy-enterprise-id") s.Require().NotNil(err) - s.Require().Equal("fetching enterprise: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching enterprise: error parsing id: invalid request", err.Error()) } func (s *EnterpriseTestSuite) TestGetEnterpriseByIDDBDecryptingErr() { @@ -508,7 +508,7 @@ func (s *EnterpriseTestSuite) TestGetEnterpriseByIDDBDecryptingErr() { s.assertSQLMockExpectations() s.Require().NotNil(err) - s.Require().Equal("fetching enterprise: missing secret", err.Error()) + s.Require().Equal("error fetching enterprise: missing secret", err.Error()) } func (s *EnterpriseTestSuite) TestCreateEnterprisePool() { @@ -547,7 +547,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterprisePoolInvalidEnterpriseID() { _, err := s.Store.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("parsing id: invalid request", err.Error()) + s.Require().Equal("error parsing id: invalid request", err.Error()) } func (s *EnterpriseTestSuite) TestCreateEnterprisePoolDBFetchTagErr() { @@ -565,7 +565,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterprisePoolDBFetchTagErr() { _, err = s.StoreSQLMocked.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("creating tag: fetching tag from database: mocked fetching tag error", err.Error()) + s.Require().Equal("error creating tag: error fetching tag from database: mocked fetching tag error", err.Error()) s.assertSQLMockExpectations() } @@ -592,7 +592,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterprisePoolDBAddingPoolErr() { _, err = s.StoreSQLMocked.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("creating pool: mocked adding pool error", err.Error()) + s.Require().Equal("error creating pool: mocked adding pool error", err.Error()) s.assertSQLMockExpectations() } @@ -623,7 +623,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterprisePoolDBSaveTagErr() { _, err = s.StoreSQLMocked.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("associating tags: mocked saving tag error", err.Error()) + s.Require().Equal("error associating tags: mocked saving tag error", err.Error()) s.assertSQLMockExpectations() } @@ -663,7 +663,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterprisePoolDBFetchPoolErr() { _, err = s.StoreSQLMocked.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("fetching pool: not found", err.Error()) + s.Require().Equal("error fetching pool: not found", err.Error()) s.assertSQLMockExpectations() } @@ -694,7 +694,7 @@ func (s *EnterpriseTestSuite) TestListEnterprisePoolsInvalidEnterpriseID() { _, err := s.Store.ListEntityPools(s.adminCtx, entity) s.Require().NotNil(err) - s.Require().Equal("fetching pools: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching pools: error parsing id: invalid request", err.Error()) } func (s *EnterpriseTestSuite) TestGetEnterprisePool() { @@ -719,7 +719,7 @@ func (s *EnterpriseTestSuite) TestGetEnterprisePoolInvalidEnterpriseID() { _, err := s.Store.GetEntityPool(s.adminCtx, entity, "dummy-pool-id") s.Require().NotNil(err) - s.Require().Equal("fetching pool: parsing id: invalid request", err.Error()) + s.Require().Equal("fetching pool: error parsing id: invalid request", err.Error()) } func (s *EnterpriseTestSuite) TestDeleteEnterprisePool() { @@ -734,7 +734,7 @@ func (s *EnterpriseTestSuite) TestDeleteEnterprisePool() { s.Require().Nil(err) _, err = s.Store.GetEntityPool(s.adminCtx, entity, pool.ID) - s.Require().Equal("fetching pool: finding pool: not found", err.Error()) + s.Require().Equal("fetching pool: error finding pool: not found", err.Error()) } func (s *EnterpriseTestSuite) TestDeleteEnterprisePoolInvalidEnterpriseID() { @@ -745,7 +745,7 @@ func (s *EnterpriseTestSuite) TestDeleteEnterprisePoolInvalidEnterpriseID() { err := s.Store.DeleteEntityPool(s.adminCtx, entity, "dummy-pool-id") s.Require().NotNil(err) - s.Require().Equal("parsing id: invalid request", err.Error()) + s.Require().Equal("error parsing id: invalid request", err.Error()) } func (s *EnterpriseTestSuite) TestDeleteEnterprisePoolDBDeleteErr() { @@ -765,7 +765,7 @@ func (s *EnterpriseTestSuite) TestDeleteEnterprisePoolDBDeleteErr() { err = s.StoreSQLMocked.DeleteEntityPool(s.adminCtx, entity, pool.ID) s.Require().NotNil(err) - s.Require().Equal("removing pool: mocked deleting pool error", err.Error()) + s.Require().Equal("error removing pool: mocked deleting pool error", err.Error()) s.assertSQLMockExpectations() } @@ -800,7 +800,7 @@ func (s *EnterpriseTestSuite) TestListEnterpriseInstancesInvalidEnterpriseID() { _, err := s.Store.ListEntityInstances(s.adminCtx, entity) s.Require().NotNil(err) - s.Require().Equal("fetching entity: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching entity: error parsing id: invalid request", err.Error()) } func (s *EnterpriseTestSuite) TestUpdateEnterprisePool() { @@ -828,7 +828,7 @@ func (s *EnterpriseTestSuite) TestUpdateEnterprisePoolInvalidEnterpriseID() { _, err := s.Store.UpdateEntityPool(s.adminCtx, entity, "dummy-pool-id", s.Fixtures.UpdatePoolParams) s.Require().NotNil(err) - s.Require().Equal("fetching pool: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching pool: error parsing id: invalid request", err.Error()) } func (s *EnterpriseTestSuite) TestAddRepoEntityEvent() { diff --git a/database/sql/gitea.go b/database/sql/gitea.go index 45dc30e5..a9edde09 100644 --- a/database/sql/gitea.go +++ b/database/sql/gitea.go @@ -16,9 +16,10 @@ package sql import ( "context" + "errors" + "fmt" "log/slog" - "github.com/pkg/errors" "gorm.io/gorm" runnerErrors "github.com/cloudbase/garm-provider-common/errors" @@ -36,7 +37,7 @@ func (s *sqlDatabase) CreateGiteaEndpoint(_ context.Context, param params.Create var endpoint GithubEndpoint err = s.conn.Transaction(func(tx *gorm.DB) error { if err := tx.Where("name = ?", param.Name).First(&endpoint).Error; err == nil { - return errors.Wrap(runnerErrors.ErrDuplicateEntity, "gitea endpoint already exists") + return fmt.Errorf("gitea endpoint already exists: %w", runnerErrors.ErrDuplicateEntity) } endpoint = GithubEndpoint{ Name: param.Name, @@ -48,16 +49,16 @@ func (s *sqlDatabase) CreateGiteaEndpoint(_ context.Context, param params.Create } if err := tx.Create(&endpoint).Error; err != nil { - return errors.Wrap(err, "creating gitea endpoint") + return fmt.Errorf("error creating gitea endpoint: %w", err) } return nil }) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "creating gitea endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("error creating gitea endpoint: %w", err) } ghEndpoint, err = s.sqlToCommonGithubEndpoint(endpoint) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "converting gitea endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("error converting gitea endpoint: %w", err) } return ghEndpoint, nil } @@ -66,14 +67,14 @@ func (s *sqlDatabase) ListGiteaEndpoints(_ context.Context) ([]params.ForgeEndpo var endpoints []GithubEndpoint err := s.conn.Where("endpoint_type = ?", params.GiteaEndpointType).Find(&endpoints).Error if err != nil { - return nil, errors.Wrap(err, "fetching gitea endpoints") + return nil, fmt.Errorf("error fetching gitea endpoints: %w", err) } var ret []params.ForgeEndpoint for _, ep := range endpoints { commonEp, err := s.sqlToCommonGithubEndpoint(ep) if err != nil { - return nil, errors.Wrap(err, "converting gitea endpoint") + return nil, fmt.Errorf("error converting gitea endpoint: %w", err) } ret = append(ret, commonEp) } @@ -90,19 +91,19 @@ func (s *sqlDatabase) UpdateGiteaEndpoint(_ context.Context, name string, param err = s.conn.Transaction(func(tx *gorm.DB) error { if err := tx.Where("name = ? and endpoint_type = ?", name, params.GiteaEndpointType).First(&endpoint).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(runnerErrors.ErrNotFound, "gitea endpoint not found") + return runnerErrors.NewNotFoundError("gitea endpoint %q not found", name) } - return errors.Wrap(err, "fetching gitea endpoint") + return fmt.Errorf("error fetching gitea endpoint: %w", err) } var credsCount int64 if err := tx.Model(&GiteaCredentials{}).Where("endpoint_name = ?", endpoint.Name).Count(&credsCount).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(err, "fetching gitea credentials") + return fmt.Errorf("error fetching gitea credentials: %w", err) } } if credsCount > 0 && (param.APIBaseURL != nil || param.BaseURL != nil) { - return errors.Wrap(runnerErrors.ErrBadRequest, "cannot update endpoint URLs with existing credentials") + return runnerErrors.NewBadRequestError("cannot update endpoint URLs with existing credentials") } if param.APIBaseURL != nil { @@ -122,17 +123,17 @@ func (s *sqlDatabase) UpdateGiteaEndpoint(_ context.Context, name string, param } if err := tx.Save(&endpoint).Error; err != nil { - return errors.Wrap(err, "updating gitea endpoint") + return fmt.Errorf("error updating gitea endpoint: %w", err) } return nil }) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "updating gitea endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("error updating gitea endpoint: %w", err) } ghEndpoint, err = s.sqlToCommonGithubEndpoint(endpoint) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "converting gitea endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("error converting gitea endpoint: %w", err) } return ghEndpoint, nil } @@ -142,9 +143,9 @@ func (s *sqlDatabase) GetGiteaEndpoint(_ context.Context, name string) (params.F err := s.conn.Where("name = ? and endpoint_type = ?", name, params.GiteaEndpointType).First(&endpoint).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return params.ForgeEndpoint{}, errors.Wrap(runnerErrors.ErrNotFound, "gitea endpoint not found") + return params.ForgeEndpoint{}, runnerErrors.NewNotFoundError("gitea endpoint %q not found", name) } - return params.ForgeEndpoint{}, errors.Wrap(err, "fetching gitea endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("error fetching gitea endpoint: %w", err) } return s.sqlToCommonGithubEndpoint(endpoint) @@ -162,41 +163,41 @@ func (s *sqlDatabase) DeleteGiteaEndpoint(_ context.Context, name string) (err e if errors.Is(err, gorm.ErrRecordNotFound) { return nil } - return errors.Wrap(err, "fetching gitea endpoint") + return fmt.Errorf("error fetching gitea endpoint: %w", err) } var credsCount int64 if err := tx.Model(&GiteaCredentials{}).Where("endpoint_name = ?", endpoint.Name).Count(&credsCount).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(err, "fetching gitea credentials") + return fmt.Errorf("error fetching gitea credentials: %w", err) } } var repoCnt int64 if err := tx.Model(&Repository{}).Where("endpoint_name = ?", endpoint.Name).Count(&repoCnt).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(err, "fetching gitea repositories") + return fmt.Errorf("error fetching gitea repositories: %w", err) } } var orgCnt int64 if err := tx.Model(&Organization{}).Where("endpoint_name = ?", endpoint.Name).Count(&orgCnt).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(err, "fetching gitea organizations") + return fmt.Errorf("error fetching gitea organizations: %w", err) } } if credsCount > 0 || repoCnt > 0 || orgCnt > 0 { - return errors.Wrap(runnerErrors.ErrBadRequest, "cannot delete endpoint with associated entities") + return runnerErrors.NewBadRequestError("cannot delete endpoint with associated entities") } if err := tx.Unscoped().Delete(&endpoint).Error; err != nil { - return errors.Wrap(err, "deleting gitea endpoint") + return fmt.Errorf("error deleting gitea endpoint: %w", err) } return nil }) if err != nil { - return errors.Wrap(err, "deleting gitea endpoint") + return fmt.Errorf("error deleting gitea endpoint: %w", err) } return nil } @@ -204,10 +205,10 @@ func (s *sqlDatabase) DeleteGiteaEndpoint(_ context.Context, name string) (err e func (s *sqlDatabase) CreateGiteaCredentials(ctx context.Context, param params.CreateGiteaCredentialsParams) (gtCreds params.ForgeCredentials, err error) { userID, err := getUIDFromContext(ctx) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "creating gitea credentials") + return params.ForgeCredentials{}, fmt.Errorf("error creating gitea credentials: %w", err) } if param.Endpoint == "" { - return params.ForgeCredentials{}, errors.Wrap(runnerErrors.ErrBadRequest, "endpoint name is required") + return params.ForgeCredentials{}, runnerErrors.NewBadRequestError("endpoint name is required") } defer func() { @@ -220,13 +221,13 @@ func (s *sqlDatabase) CreateGiteaCredentials(ctx context.Context, param params.C var endpoint GithubEndpoint if err := tx.Where("name = ? and endpoint_type = ?", param.Endpoint, params.GiteaEndpointType).First(&endpoint).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(runnerErrors.ErrNotFound, "gitea endpoint not found") + return runnerErrors.NewNotFoundError("gitea endpoint %q not found", param.Endpoint) } - return errors.Wrap(err, "fetching gitea endpoint") + return fmt.Errorf("error fetching gitea endpoint: %w", err) } if err := tx.Where("name = ? and user_id = ?", param.Name, userID).First(&creds).Error; err == nil { - return errors.Wrap(runnerErrors.ErrDuplicateEntity, "gitea credentials already exists") + return fmt.Errorf("gitea credentials already exists: %w", runnerErrors.ErrDuplicateEntity) } var data []byte @@ -235,10 +236,10 @@ func (s *sqlDatabase) CreateGiteaCredentials(ctx context.Context, param params.C case params.ForgeAuthTypePAT: data, err = s.marshalAndSeal(param.PAT) default: - return errors.Wrap(runnerErrors.ErrBadRequest, "invalid auth type") + return runnerErrors.NewBadRequestError("invalid auth type %q", param.AuthType) } if err != nil { - return errors.Wrap(err, "marshaling and sealing credentials") + return fmt.Errorf("error marshaling and sealing credentials: %w", err) } creds = GiteaCredentials{ @@ -251,7 +252,7 @@ func (s *sqlDatabase) CreateGiteaCredentials(ctx context.Context, param params.C } if err := tx.Create(&creds).Error; err != nil { - return errors.Wrap(err, "creating gitea credentials") + return fmt.Errorf("error creating gitea credentials: %w", err) } // Skip making an extra query. creds.Endpoint = endpoint @@ -259,11 +260,11 @@ func (s *sqlDatabase) CreateGiteaCredentials(ctx context.Context, param params.C return nil }) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "creating gitea credentials") + return params.ForgeCredentials{}, fmt.Errorf("error creating gitea credentials: %w", err) } gtCreds, err = s.sqlGiteaToCommonForgeCredentials(creds) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "converting gitea credentials") + return params.ForgeCredentials{}, fmt.Errorf("error converting gitea credentials: %w", err) } return gtCreds, nil } @@ -284,16 +285,16 @@ func (s *sqlDatabase) getGiteaCredentialsByName(ctx context.Context, tx *gorm.DB userID, err := getUIDFromContext(ctx) if err != nil { - return GiteaCredentials{}, errors.Wrap(err, "fetching gitea credentials") + return GiteaCredentials{}, fmt.Errorf("error fetching gitea credentials: %w", err) } q = q.Where("user_id = ?", userID) err = q.Where("name = ?", name).First(&creds).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return GiteaCredentials{}, errors.Wrap(runnerErrors.ErrNotFound, "gitea credentials not found") + return GiteaCredentials{}, runnerErrors.NewNotFoundError("gitea credentials %q not found", name) } - return GiteaCredentials{}, errors.Wrap(err, "fetching gitea credentials") + return GiteaCredentials{}, fmt.Errorf("error fetching gitea credentials: %w", err) } return creds, nil @@ -302,7 +303,7 @@ func (s *sqlDatabase) getGiteaCredentialsByName(ctx context.Context, tx *gorm.DB func (s *sqlDatabase) GetGiteaCredentialsByName(ctx context.Context, name string, detailed bool) (params.ForgeCredentials, error) { creds, err := s.getGiteaCredentialsByName(ctx, s.conn, name, detailed) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "fetching gitea credentials") + return params.ForgeCredentials{}, fmt.Errorf("error fetching gitea credentials: %w", err) } return s.sqlGiteaToCommonForgeCredentials(creds) @@ -325,7 +326,7 @@ func (s *sqlDatabase) GetGiteaCredentials(ctx context.Context, id uint, detailed if !auth.IsAdmin(ctx) { userID, err := getUIDFromContext(ctx) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "fetching gitea credentials") + return params.ForgeCredentials{}, fmt.Errorf("error fetching gitea credentials: %w", err) } q = q.Where("user_id = ?", userID) } @@ -333,9 +334,9 @@ func (s *sqlDatabase) GetGiteaCredentials(ctx context.Context, id uint, detailed err := q.Where("id = ?", id).First(&creds).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return params.ForgeCredentials{}, errors.Wrap(runnerErrors.ErrNotFound, "gitea credentials not found") + return params.ForgeCredentials{}, runnerErrors.NewNotFoundError("gitea credentials not found") } - return params.ForgeCredentials{}, errors.Wrap(err, "fetching gitea credentials") + return params.ForgeCredentials{}, fmt.Errorf("error fetching gitea credentials: %w", err) } return s.sqlGiteaToCommonForgeCredentials(creds) @@ -346,7 +347,7 @@ func (s *sqlDatabase) ListGiteaCredentials(ctx context.Context) ([]params.ForgeC if !auth.IsAdmin(ctx) { userID, err := getUIDFromContext(ctx) if err != nil { - return nil, errors.Wrap(err, "fetching gitea credentials") + return nil, fmt.Errorf("error fetching gitea credentials: %w", err) } q = q.Where("user_id = ?", userID) } @@ -354,14 +355,14 @@ func (s *sqlDatabase) ListGiteaCredentials(ctx context.Context) ([]params.ForgeC var creds []GiteaCredentials err := q.Preload("Endpoint").Find(&creds).Error if err != nil { - return nil, errors.Wrap(err, "fetching gitea credentials") + return nil, fmt.Errorf("error fetching gitea credentials: %w", err) } var ret []params.ForgeCredentials for _, c := range creds { commonCreds, err := s.sqlGiteaToCommonForgeCredentials(c) if err != nil { - return nil, errors.Wrap(err, "converting gitea credentials") + return nil, fmt.Errorf("error converting gitea credentials: %w", err) } ret = append(ret, commonCreds) } @@ -380,16 +381,16 @@ func (s *sqlDatabase) UpdateGiteaCredentials(ctx context.Context, id uint, param if !auth.IsAdmin(ctx) { userID, err := getUIDFromContext(ctx) if err != nil { - return errors.Wrap(err, "updating gitea credentials") + return fmt.Errorf("error updating gitea credentials: %w", err) } q = q.Where("user_id = ?", userID) } if err := q.Where("id = ?", id).First(&creds).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(runnerErrors.ErrNotFound, "gitea credentials not found") + return runnerErrors.NewNotFoundError("gitea credentials not found") } - return errors.Wrap(err, "fetching gitea credentials") + return fmt.Errorf("error fetching gitea credentials: %w", err) } if param.Name != nil { @@ -407,28 +408,28 @@ func (s *sqlDatabase) UpdateGiteaCredentials(ctx context.Context, id uint, param data, err = s.marshalAndSeal(param.PAT) } default: - return errors.Wrap(runnerErrors.ErrBadRequest, "invalid auth type") + return runnerErrors.NewBadRequestError("invalid auth type %q", creds.AuthType) } if err != nil { - return errors.Wrap(err, "marshaling and sealing credentials") + return fmt.Errorf("error marshaling and sealing credentials: %w", err) } if len(data) > 0 { creds.Payload = data } if err := tx.Save(&creds).Error; err != nil { - return errors.Wrap(err, "updating gitea credentials") + return fmt.Errorf("error updating gitea credentials: %w", err) } return nil }) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "updating gitea credentials") + return params.ForgeCredentials{}, fmt.Errorf("error updating gitea credentials: %w", err) } gtCreds, err = s.sqlGiteaToCommonForgeCredentials(creds) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "converting gitea credentials") + return params.ForgeCredentials{}, fmt.Errorf("error converting gitea credentials: %w", err) } return gtCreds, nil } @@ -454,7 +455,7 @@ func (s *sqlDatabase) DeleteGiteaCredentials(ctx context.Context, id uint) (err if !auth.IsAdmin(ctx) { userID, err := getUIDFromContext(ctx) if err != nil { - return errors.Wrap(err, "deleting gitea credentials") + return fmt.Errorf("error deleting gitea credentials: %w", err) } q = q.Where("user_id = ?", userID) } @@ -464,22 +465,22 @@ func (s *sqlDatabase) DeleteGiteaCredentials(ctx context.Context, id uint) (err if errors.Is(err, gorm.ErrRecordNotFound) { return nil } - return errors.Wrap(err, "fetching gitea credentials") + return fmt.Errorf("error fetching gitea credentials: %w", err) } if len(creds.Repositories) > 0 { - return errors.Wrap(runnerErrors.ErrBadRequest, "cannot delete credentials with repositories") + return runnerErrors.NewBadRequestError("cannot delete credentials with repositories") } if len(creds.Organizations) > 0 { - return errors.Wrap(runnerErrors.ErrBadRequest, "cannot delete credentials with organizations") + return runnerErrors.NewBadRequestError("cannot delete credentials with organizations") } if err := tx.Unscoped().Delete(&creds).Error; err != nil { - return errors.Wrap(err, "deleting gitea credentials") + return fmt.Errorf("error deleting gitea credentials: %w", err) } return nil }) if err != nil { - return errors.Wrap(err, "deleting gitea credentials") + return fmt.Errorf("error deleting gitea credentials: %w", err) } return nil } diff --git a/database/sql/gitea_test.go b/database/sql/gitea_test.go index 7ce6fb02..dff5c471 100644 --- a/database/sql/gitea_test.go +++ b/database/sql/gitea_test.go @@ -236,7 +236,7 @@ func (s *GiteaTestSuite) TestCreateCredentialsFailsWhenEndpointDoesNotExist() { _, err := s.db.CreateGiteaCredentials(ctx, params.CreateGiteaCredentialsParams{Endpoint: "non-existing"}) s.Require().Error(err) s.Require().ErrorIs(err, runnerErrors.ErrNotFound) - s.Require().Regexp("endpoint not found", err.Error()) + s.Require().Regexp("error creating gitea credentials: gitea endpoint \"non-existing\" not found", err.Error()) } func (s *GiteaTestSuite) TestCreateCredentialsFailsWhenAuthTypeIsInvalid() { @@ -807,7 +807,7 @@ func (s *GiteaTestSuite) TestUpdateEndpointURLsFailsIfCredentialsAreAssociated() _, err = s.db.UpdateGiteaEndpoint(ctx, testEndpointName, updateEpParams) s.Require().Error(err) s.Require().ErrorIs(err, runnerErrors.ErrBadRequest) - s.Require().EqualError(err, "updating gitea endpoint: cannot update endpoint URLs with existing credentials: invalid request") + s.Require().EqualError(err, "error updating gitea endpoint: cannot update endpoint URLs with existing credentials") updateEpParams = params.UpdateGiteaEndpointParams{ APIBaseURL: &newAPIBaseURL, @@ -815,7 +815,7 @@ func (s *GiteaTestSuite) TestUpdateEndpointURLsFailsIfCredentialsAreAssociated() _, err = s.db.UpdateGiteaEndpoint(ctx, testEndpointName, updateEpParams) s.Require().Error(err) s.Require().ErrorIs(err, runnerErrors.ErrBadRequest) - s.Require().EqualError(err, "updating gitea endpoint: cannot update endpoint URLs with existing credentials: invalid request") + s.Require().EqualError(err, "error updating gitea endpoint: cannot update endpoint URLs with existing credentials") updateEpParams = params.UpdateGiteaEndpointParams{ Description: &newDescription, diff --git a/database/sql/github.go b/database/sql/github.go index 0ad52049..626d138f 100644 --- a/database/sql/github.go +++ b/database/sql/github.go @@ -16,8 +16,9 @@ package sql import ( "context" + "errors" + "fmt" - "github.com/pkg/errors" "gorm.io/gorm" runnerErrors "github.com/cloudbase/garm-provider-common/errors" @@ -35,7 +36,7 @@ func (s *sqlDatabase) CreateGithubEndpoint(_ context.Context, param params.Creat var endpoint GithubEndpoint err = s.conn.Transaction(func(tx *gorm.DB) error { if err := tx.Where("name = ?", param.Name).First(&endpoint).Error; err == nil { - return errors.Wrap(runnerErrors.ErrDuplicateEntity, "github endpoint already exists") + return fmt.Errorf("error github endpoint already exists: %w", runnerErrors.ErrDuplicateEntity) } endpoint = GithubEndpoint{ Name: param.Name, @@ -48,16 +49,16 @@ func (s *sqlDatabase) CreateGithubEndpoint(_ context.Context, param params.Creat } if err := tx.Create(&endpoint).Error; err != nil { - return errors.Wrap(err, "creating github endpoint") + return fmt.Errorf("error creating github endpoint: %w", err) } return nil }) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "creating github endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("error creating github endpoint: %w", err) } ghEndpoint, err = s.sqlToCommonGithubEndpoint(endpoint) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "converting github endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("error converting github endpoint: %w", err) } return ghEndpoint, nil } @@ -66,14 +67,14 @@ func (s *sqlDatabase) ListGithubEndpoints(_ context.Context) ([]params.ForgeEndp var endpoints []GithubEndpoint err := s.conn.Where("endpoint_type = ?", params.GithubEndpointType).Find(&endpoints).Error if err != nil { - return nil, errors.Wrap(err, "fetching github endpoints") + return nil, fmt.Errorf("error fetching github endpoints: %w", err) } var ret []params.ForgeEndpoint for _, ep := range endpoints { commonEp, err := s.sqlToCommonGithubEndpoint(ep) if err != nil { - return nil, errors.Wrap(err, "converting github endpoint") + return nil, fmt.Errorf("error converting github endpoint: %w", err) } ret = append(ret, commonEp) } @@ -90,19 +91,19 @@ func (s *sqlDatabase) UpdateGithubEndpoint(_ context.Context, name string, param err = s.conn.Transaction(func(tx *gorm.DB) error { if err := tx.Where("name = ? and endpoint_type = ?", name, params.GithubEndpointType).First(&endpoint).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(runnerErrors.ErrNotFound, "github endpoint not found") + return fmt.Errorf("error github endpoint not found: %w", runnerErrors.ErrNotFound) } - return errors.Wrap(err, "fetching github endpoint") + return fmt.Errorf("error fetching github endpoint: %w", err) } var credsCount int64 if err := tx.Model(&GithubCredentials{}).Where("endpoint_name = ?", endpoint.Name).Count(&credsCount).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(err, "fetching github credentials") + return fmt.Errorf("error fetching github credentials: %w", err) } } if credsCount > 0 && (param.APIBaseURL != nil || param.BaseURL != nil || param.UploadBaseURL != nil) { - return errors.Wrap(runnerErrors.ErrBadRequest, "cannot update endpoint URLs with existing credentials") + return fmt.Errorf("cannot update endpoint URLs with existing credentials: %w", runnerErrors.ErrBadRequest) } if param.APIBaseURL != nil { @@ -126,17 +127,17 @@ func (s *sqlDatabase) UpdateGithubEndpoint(_ context.Context, name string, param } if err := tx.Save(&endpoint).Error; err != nil { - return errors.Wrap(err, "updating github endpoint") + return fmt.Errorf("error updating github endpoint: %w", err) } return nil }) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "updating github endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("error updating github endpoint: %w", err) } ghEndpoint, err = s.sqlToCommonGithubEndpoint(endpoint) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "converting github endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("error converting github endpoint: %w", err) } return ghEndpoint, nil } @@ -147,9 +148,9 @@ func (s *sqlDatabase) GetGithubEndpoint(_ context.Context, name string) (params. err := s.conn.Where("name = ? and endpoint_type = ?", name, params.GithubEndpointType).First(&endpoint).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return params.ForgeEndpoint{}, errors.Wrap(runnerErrors.ErrNotFound, "github endpoint not found") + return params.ForgeEndpoint{}, fmt.Errorf("github endpoint not found: %w", runnerErrors.ErrNotFound) } - return params.ForgeEndpoint{}, errors.Wrap(err, "fetching github endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("error fetching github endpoint: %w", err) } return s.sqlToCommonGithubEndpoint(endpoint) @@ -167,48 +168,48 @@ func (s *sqlDatabase) DeleteGithubEndpoint(_ context.Context, name string) (err if errors.Is(err, gorm.ErrRecordNotFound) { return nil } - return errors.Wrap(err, "fetching github endpoint") + return fmt.Errorf("error fetching github endpoint: %w", err) } var credsCount int64 if err := tx.Model(&GithubCredentials{}).Where("endpoint_name = ?", endpoint.Name).Count(&credsCount).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(err, "fetching github credentials") + return fmt.Errorf("error fetching github credentials: %w", err) } } var repoCnt int64 if err := tx.Model(&Repository{}).Where("endpoint_name = ?", endpoint.Name).Count(&repoCnt).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(err, "fetching github repositories") + return fmt.Errorf("error fetching github repositories: %w", err) } } var orgCnt int64 if err := tx.Model(&Organization{}).Where("endpoint_name = ?", endpoint.Name).Count(&orgCnt).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(err, "fetching github organizations") + return fmt.Errorf("error fetching github organizations: %w", err) } } var entCnt int64 if err := tx.Model(&Enterprise{}).Where("endpoint_name = ?", endpoint.Name).Count(&entCnt).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(err, "fetching github enterprises") + return fmt.Errorf("error fetching github enterprises: %w", err) } } if credsCount > 0 || repoCnt > 0 || orgCnt > 0 || entCnt > 0 { - return errors.Wrap(runnerErrors.ErrBadRequest, "cannot delete endpoint with associated entities") + return fmt.Errorf("cannot delete endpoint with associated entities: %w", runnerErrors.ErrBadRequest) } if err := tx.Unscoped().Delete(&endpoint).Error; err != nil { - return errors.Wrap(err, "deleting github endpoint") + return fmt.Errorf("error deleting github endpoint: %w", err) } return nil }) if err != nil { - return errors.Wrap(err, "deleting github endpoint") + return fmt.Errorf("error deleting github endpoint: %w", err) } return nil } @@ -216,10 +217,10 @@ func (s *sqlDatabase) DeleteGithubEndpoint(_ context.Context, name string) (err func (s *sqlDatabase) CreateGithubCredentials(ctx context.Context, param params.CreateGithubCredentialsParams) (ghCreds params.ForgeCredentials, err error) { userID, err := getUIDFromContext(ctx) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "creating github credentials") + return params.ForgeCredentials{}, fmt.Errorf("error creating github credentials: %w", err) } if param.Endpoint == "" { - return params.ForgeCredentials{}, errors.Wrap(runnerErrors.ErrBadRequest, "endpoint name is required") + return params.ForgeCredentials{}, fmt.Errorf("endpoint name is required: %w", runnerErrors.ErrBadRequest) } defer func() { @@ -232,13 +233,13 @@ func (s *sqlDatabase) CreateGithubCredentials(ctx context.Context, param params. var endpoint GithubEndpoint if err := tx.Where("name = ? and endpoint_type = ?", param.Endpoint, params.GithubEndpointType).First(&endpoint).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(runnerErrors.ErrNotFound, "github endpoint not found") + return fmt.Errorf("github endpoint not found: %w", runnerErrors.ErrNotFound) } - return errors.Wrap(err, "fetching github endpoint") + return fmt.Errorf("error fetching github endpoint: %w", err) } if err := tx.Where("name = ? and user_id = ?", param.Name, userID).First(&creds).Error; err == nil { - return errors.Wrap(runnerErrors.ErrDuplicateEntity, "github credentials already exists") + return fmt.Errorf("github credentials already exists: %w", runnerErrors.ErrDuplicateEntity) } var data []byte @@ -249,10 +250,10 @@ func (s *sqlDatabase) CreateGithubCredentials(ctx context.Context, param params. case params.ForgeAuthTypeApp: data, err = s.marshalAndSeal(param.App) default: - return errors.Wrap(runnerErrors.ErrBadRequest, "invalid auth type") + return fmt.Errorf("invalid auth type: %w", runnerErrors.ErrBadRequest) } if err != nil { - return errors.Wrap(err, "marshaling and sealing credentials") + return fmt.Errorf("error marshaling and sealing credentials: %w", err) } creds = GithubCredentials{ @@ -265,7 +266,7 @@ func (s *sqlDatabase) CreateGithubCredentials(ctx context.Context, param params. } if err := tx.Create(&creds).Error; err != nil { - return errors.Wrap(err, "creating github credentials") + return fmt.Errorf("error creating github credentials: %w", err) } // Skip making an extra query. creds.Endpoint = endpoint @@ -273,11 +274,11 @@ func (s *sqlDatabase) CreateGithubCredentials(ctx context.Context, param params. return nil }) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "creating github credentials") + return params.ForgeCredentials{}, fmt.Errorf("error creating github credentials: %w", err) } ghCreds, err = s.sqlToCommonForgeCredentials(creds) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "converting github credentials") + return params.ForgeCredentials{}, fmt.Errorf("error converting github credentials: %w", err) } return ghCreds, nil } @@ -298,16 +299,16 @@ func (s *sqlDatabase) getGithubCredentialsByName(ctx context.Context, tx *gorm.D userID, err := getUIDFromContext(ctx) if err != nil { - return GithubCredentials{}, errors.Wrap(err, "fetching github credentials") + return GithubCredentials{}, fmt.Errorf("error fetching github credentials: %w", err) } q = q.Where("user_id = ?", userID) err = q.Where("name = ?", name).First(&creds).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return GithubCredentials{}, errors.Wrap(runnerErrors.ErrNotFound, "github credentials not found") + return GithubCredentials{}, fmt.Errorf("github credentials not found: %w", runnerErrors.ErrNotFound) } - return GithubCredentials{}, errors.Wrap(err, "fetching github credentials") + return GithubCredentials{}, fmt.Errorf("error fetching github credentials: %w", err) } return creds, nil @@ -316,7 +317,7 @@ func (s *sqlDatabase) getGithubCredentialsByName(ctx context.Context, tx *gorm.D func (s *sqlDatabase) GetGithubCredentialsByName(ctx context.Context, name string, detailed bool) (params.ForgeCredentials, error) { creds, err := s.getGithubCredentialsByName(ctx, s.conn, name, detailed) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "fetching github credentials") + return params.ForgeCredentials{}, fmt.Errorf("error fetching github credentials: %w", err) } return s.sqlToCommonForgeCredentials(creds) } @@ -338,7 +339,7 @@ func (s *sqlDatabase) GetGithubCredentials(ctx context.Context, id uint, detaile if !auth.IsAdmin(ctx) { userID, err := getUIDFromContext(ctx) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "fetching github credentials") + return params.ForgeCredentials{}, fmt.Errorf("error fetching github credentials: %w", err) } q = q.Where("user_id = ?", userID) } @@ -346,9 +347,9 @@ func (s *sqlDatabase) GetGithubCredentials(ctx context.Context, id uint, detaile err := q.Where("id = ?", id).First(&creds).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return params.ForgeCredentials{}, errors.Wrap(runnerErrors.ErrNotFound, "github credentials not found") + return params.ForgeCredentials{}, fmt.Errorf("github credentials not found: %w", runnerErrors.ErrNotFound) } - return params.ForgeCredentials{}, errors.Wrap(err, "fetching github credentials") + return params.ForgeCredentials{}, fmt.Errorf("error fetching github credentials: %w", err) } return s.sqlToCommonForgeCredentials(creds) @@ -359,7 +360,7 @@ func (s *sqlDatabase) ListGithubCredentials(ctx context.Context) ([]params.Forge if !auth.IsAdmin(ctx) { userID, err := getUIDFromContext(ctx) if err != nil { - return nil, errors.Wrap(err, "fetching github credentials") + return nil, fmt.Errorf("error fetching github credentials: %w", err) } q = q.Where("user_id = ?", userID) } @@ -367,14 +368,14 @@ func (s *sqlDatabase) ListGithubCredentials(ctx context.Context) ([]params.Forge var creds []GithubCredentials err := q.Preload("Endpoint").Find(&creds).Error if err != nil { - return nil, errors.Wrap(err, "fetching github credentials") + return nil, fmt.Errorf("error fetching github credentials: %w", err) } var ret []params.ForgeCredentials for _, c := range creds { commonCreds, err := s.sqlToCommonForgeCredentials(c) if err != nil { - return nil, errors.Wrap(err, "converting github credentials") + return nil, fmt.Errorf("error converting github credentials: %w", err) } ret = append(ret, commonCreds) } @@ -393,16 +394,16 @@ func (s *sqlDatabase) UpdateGithubCredentials(ctx context.Context, id uint, para if !auth.IsAdmin(ctx) { userID, err := getUIDFromContext(ctx) if err != nil { - return errors.Wrap(err, "updating github credentials") + return fmt.Errorf("error updating github credentials: %w", err) } q = q.Where("user_id = ?", userID) } if err := q.Where("id = ?", id).First(&creds).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(runnerErrors.ErrNotFound, "github credentials not found") + return fmt.Errorf("github credentials not found: %w", runnerErrors.ErrNotFound) } - return errors.Wrap(err, "fetching github credentials") + return fmt.Errorf("error fetching github credentials: %w", err) } if param.Name != nil { @@ -421,7 +422,7 @@ func (s *sqlDatabase) UpdateGithubCredentials(ctx context.Context, id uint, para } if param.App != nil { - return errors.Wrap(runnerErrors.ErrBadRequest, "cannot update app credentials for PAT") + return fmt.Errorf("cannot update app credentials for PAT: %w", runnerErrors.ErrBadRequest) } case params.ForgeAuthTypeApp: if param.App != nil { @@ -429,33 +430,33 @@ func (s *sqlDatabase) UpdateGithubCredentials(ctx context.Context, id uint, para } if param.PAT != nil { - return errors.Wrap(runnerErrors.ErrBadRequest, "cannot update PAT credentials for app") + return fmt.Errorf("cannot update PAT credentials for app: %w", runnerErrors.ErrBadRequest) } default: // This should never happen, unless there was a bug in the DB migration code, // or the DB was manually modified. - return errors.Wrap(runnerErrors.ErrBadRequest, "invalid auth type") + return fmt.Errorf("invalid auth type: %w", runnerErrors.ErrBadRequest) } if err != nil { - return errors.Wrap(err, "marshaling and sealing credentials") + return fmt.Errorf("error marshaling and sealing credentials: %w", err) } if len(data) > 0 { creds.Payload = data } if err := tx.Save(&creds).Error; err != nil { - return errors.Wrap(err, "updating github credentials") + return fmt.Errorf("error updating github credentials: %w", err) } return nil }) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "updating github credentials") + return params.ForgeCredentials{}, fmt.Errorf("error updating github credentials: %w", err) } ghCreds, err = s.sqlToCommonForgeCredentials(creds) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "converting github credentials") + return params.ForgeCredentials{}, fmt.Errorf("error converting github credentials: %w", err) } return ghCreds, nil } @@ -475,7 +476,7 @@ func (s *sqlDatabase) DeleteGithubCredentials(ctx context.Context, id uint) (err if !auth.IsAdmin(ctx) { userID, err := getUIDFromContext(ctx) if err != nil { - return errors.Wrap(err, "deleting github credentials") + return fmt.Errorf("error deleting github credentials: %w", err) } q = q.Where("user_id = ?", userID) } @@ -486,27 +487,27 @@ func (s *sqlDatabase) DeleteGithubCredentials(ctx context.Context, id uint) (err if errors.Is(err, gorm.ErrRecordNotFound) { return nil } - return errors.Wrap(err, "fetching github credentials") + return fmt.Errorf("error fetching github credentials: %w", err) } name = creds.Name if len(creds.Repositories) > 0 { - return errors.Wrap(runnerErrors.ErrBadRequest, "cannot delete credentials with repositories") + return fmt.Errorf("cannot delete credentials with repositories: %w", runnerErrors.ErrBadRequest) } if len(creds.Organizations) > 0 { - return errors.Wrap(runnerErrors.ErrBadRequest, "cannot delete credentials with organizations") + return fmt.Errorf("cannot delete credentials with organizations: %w", runnerErrors.ErrBadRequest) } if len(creds.Enterprises) > 0 { - return errors.Wrap(runnerErrors.ErrBadRequest, "cannot delete credentials with enterprises") + return fmt.Errorf("cannot delete credentials with enterprises: %w", runnerErrors.ErrBadRequest) } if err := tx.Unscoped().Delete(&creds).Error; err != nil { - return errors.Wrap(err, "deleting github credentials") + return fmt.Errorf("error deleting github credentials: %w", err) } return nil }) if err != nil { - return errors.Wrap(err, "deleting github credentials") + return fmt.Errorf("error deleting github credentials: %w", err) } return nil } diff --git a/database/sql/github_test.go b/database/sql/github_test.go index cca58a50..ae3a3954 100644 --- a/database/sql/github_test.go +++ b/database/sql/github_test.go @@ -265,7 +265,7 @@ func (s *GithubTestSuite) TestUpdateEndpointURLsFailsIfCredentialsAreAssociated( _, err = s.db.UpdateGithubEndpoint(ctx, testEndpointName, updateEpParams) s.Require().Error(err) s.Require().ErrorIs(err, runnerErrors.ErrBadRequest) - s.Require().EqualError(err, "updating github endpoint: cannot update endpoint URLs with existing credentials: invalid request") + s.Require().EqualError(err, "error updating github endpoint: cannot update endpoint URLs with existing credentials: invalid request") updateEpParams = params.UpdateGithubEndpointParams{ UploadBaseURL: &newUploadBaseURL, @@ -274,7 +274,7 @@ func (s *GithubTestSuite) TestUpdateEndpointURLsFailsIfCredentialsAreAssociated( _, err = s.db.UpdateGithubEndpoint(ctx, testEndpointName, updateEpParams) s.Require().Error(err) s.Require().ErrorIs(err, runnerErrors.ErrBadRequest) - s.Require().EqualError(err, "updating github endpoint: cannot update endpoint URLs with existing credentials: invalid request") + s.Require().EqualError(err, "error updating github endpoint: cannot update endpoint URLs with existing credentials: invalid request") updateEpParams = params.UpdateGithubEndpointParams{ APIBaseURL: &newAPIBaseURL, @@ -282,7 +282,7 @@ func (s *GithubTestSuite) TestUpdateEndpointURLsFailsIfCredentialsAreAssociated( _, err = s.db.UpdateGithubEndpoint(ctx, testEndpointName, updateEpParams) s.Require().Error(err) s.Require().ErrorIs(err, runnerErrors.ErrBadRequest) - s.Require().EqualError(err, "updating github endpoint: cannot update endpoint URLs with existing credentials: invalid request") + s.Require().EqualError(err, "error updating github endpoint: cannot update endpoint URLs with existing credentials: invalid request") updateEpParams = params.UpdateGithubEndpointParams{ Description: &newDescription, @@ -737,7 +737,7 @@ func (s *GithubTestSuite) TestUpdateGithubCredentialsFailIfWrongCredentialTypeIs _, err = s.db.UpdateGithubCredentials(ctx, creds.ID, updateCredParams) s.Require().Error(err) s.Require().ErrorIs(err, runnerErrors.ErrBadRequest) - s.Require().EqualError(err, "updating github credentials: cannot update app credentials for PAT: invalid request") + s.Require().EqualError(err, "error updating github credentials: cannot update app credentials for PAT: invalid request") credParamsWithApp := params.CreateGithubCredentialsParams{ Name: "test-credsApp", @@ -764,7 +764,7 @@ func (s *GithubTestSuite) TestUpdateGithubCredentialsFailIfWrongCredentialTypeIs _, err = s.db.UpdateGithubCredentials(ctx, credsApp.ID, updateCredParams) s.Require().Error(err) s.Require().ErrorIs(err, runnerErrors.ErrBadRequest) - s.Require().EqualError(err, "updating github credentials: cannot update PAT credentials for app: invalid request") + s.Require().EqualError(err, "error updating github credentials: cannot update PAT credentials for app: invalid request") } func (s *GithubTestSuite) TestUpdateCredentialsFailsForNonExistingCredentials() { diff --git a/database/sql/instances.go b/database/sql/instances.go index c6c2d204..92194c5e 100644 --- a/database/sql/instances.go +++ b/database/sql/instances.go @@ -17,10 +17,11 @@ package sql import ( "context" "encoding/json" + "errors" + "fmt" "log/slog" "github.com/google/uuid" - "github.com/pkg/errors" "gorm.io/datatypes" "gorm.io/gorm" "gorm.io/gorm/clause" @@ -33,7 +34,7 @@ import ( func (s *sqlDatabase) CreateInstance(_ context.Context, poolID string, param params.CreateInstanceParams) (instance params.Instance, err error) { pool, err := s.getPoolByID(s.conn, poolID) if err != nil { - return params.Instance{}, errors.Wrap(err, "fetching pool") + return params.Instance{}, fmt.Errorf("error fetching pool: %w", err) } defer func() { @@ -46,7 +47,7 @@ func (s *sqlDatabase) CreateInstance(_ context.Context, poolID string, param par if len(param.AditionalLabels) > 0 { labels, err = json.Marshal(param.AditionalLabels) if err != nil { - return params.Instance{}, errors.Wrap(err, "marshalling labels") + return params.Instance{}, fmt.Errorf("error marshalling labels: %w", err) } } @@ -54,7 +55,7 @@ func (s *sqlDatabase) CreateInstance(_ context.Context, poolID string, param par if len(param.JitConfiguration) > 0 { secret, err = s.marshalAndSeal(param.JitConfiguration) if err != nil { - return params.Instance{}, errors.Wrap(err, "marshalling jit config") + return params.Instance{}, fmt.Errorf("error marshalling jit config: %w", err) } } @@ -74,7 +75,7 @@ func (s *sqlDatabase) CreateInstance(_ context.Context, poolID string, param par } q := s.conn.Create(&newInstance) if q.Error != nil { - return params.Instance{}, errors.Wrap(q.Error, "creating instance") + return params.Instance{}, fmt.Errorf("error creating instance: %w", q.Error) } return s.sqlToParamsInstance(newInstance) @@ -83,7 +84,7 @@ func (s *sqlDatabase) CreateInstance(_ context.Context, poolID string, param par func (s *sqlDatabase) getPoolInstanceByName(poolID string, instanceName string) (Instance, error) { pool, err := s.getPoolByID(s.conn, poolID) if err != nil { - return Instance{}, errors.Wrap(err, "fetching pool") + return Instance{}, fmt.Errorf("error fetching pool: %w", err) } var instance Instance @@ -93,9 +94,9 @@ func (s *sqlDatabase) getPoolInstanceByName(poolID string, instanceName string) First(&instance) if q.Error != nil { if errors.Is(q.Error, gorm.ErrRecordNotFound) { - return Instance{}, errors.Wrap(runnerErrors.ErrNotFound, "fetching pool instance by name") + return Instance{}, fmt.Errorf("error fetching pool instance by name: %w", runnerErrors.ErrNotFound) } - return Instance{}, errors.Wrap(q.Error, "fetching pool instance by name") + return Instance{}, fmt.Errorf("error fetching pool instance by name: %w", q.Error) } instance.Pool = pool @@ -119,9 +120,9 @@ func (s *sqlDatabase) getInstanceByName(_ context.Context, instanceName string, First(&instance) if q.Error != nil { if errors.Is(q.Error, gorm.ErrRecordNotFound) { - return Instance{}, errors.Wrap(runnerErrors.ErrNotFound, "fetching instance by name") + return Instance{}, fmt.Errorf("error fetching instance by name: %w", runnerErrors.ErrNotFound) } - return Instance{}, errors.Wrap(q.Error, "fetching instance by name") + return Instance{}, fmt.Errorf("error fetching instance by name: %w", q.Error) } return instance, nil } @@ -129,7 +130,7 @@ func (s *sqlDatabase) getInstanceByName(_ context.Context, instanceName string, func (s *sqlDatabase) GetPoolInstanceByName(_ context.Context, poolID string, instanceName string) (params.Instance, error) { instance, err := s.getPoolInstanceByName(poolID, instanceName) if err != nil { - return params.Instance{}, errors.Wrap(err, "fetching instance") + return params.Instance{}, fmt.Errorf("error fetching instance: %w", err) } return s.sqlToParamsInstance(instance) @@ -138,7 +139,7 @@ func (s *sqlDatabase) GetPoolInstanceByName(_ context.Context, poolID string, in func (s *sqlDatabase) GetInstanceByName(ctx context.Context, instanceName string) (params.Instance, error) { instance, err := s.getInstanceByName(ctx, instanceName, "StatusMessages", "Pool", "ScaleSet") if err != nil { - return params.Instance{}, errors.Wrap(err, "fetching instance") + return params.Instance{}, fmt.Errorf("error fetching instance: %w", err) } return s.sqlToParamsInstance(instance) @@ -150,7 +151,7 @@ func (s *sqlDatabase) DeleteInstance(_ context.Context, poolID string, instanceN if errors.Is(err, runnerErrors.ErrNotFound) { return nil } - return errors.Wrap(err, "deleting instance") + return fmt.Errorf("error deleting instance: %w", err) } defer func() { @@ -182,7 +183,7 @@ func (s *sqlDatabase) DeleteInstance(_ context.Context, poolID string, instanceN if errors.Is(q.Error, gorm.ErrRecordNotFound) { return nil } - return errors.Wrap(q.Error, "deleting instance") + return fmt.Errorf("error deleting instance: %w", q.Error) } return nil } @@ -193,7 +194,7 @@ func (s *sqlDatabase) DeleteInstanceByName(ctx context.Context, instanceName str if errors.Is(err, runnerErrors.ErrNotFound) { return nil } - return errors.Wrap(err, "deleting instance") + return fmt.Errorf("error deleting instance: %w", err) } defer func() { @@ -224,7 +225,7 @@ func (s *sqlDatabase) DeleteInstanceByName(ctx context.Context, instanceName str if errors.Is(q.Error, gorm.ErrRecordNotFound) { return nil } - return errors.Wrap(q.Error, "deleting instance") + return fmt.Errorf("error deleting instance: %w", q.Error) } return nil } @@ -232,7 +233,7 @@ func (s *sqlDatabase) DeleteInstanceByName(ctx context.Context, instanceName str func (s *sqlDatabase) AddInstanceEvent(ctx context.Context, instanceName string, event params.EventType, eventLevel params.EventLevel, statusMessage string) error { instance, err := s.getInstanceByName(ctx, instanceName) if err != nil { - return errors.Wrap(err, "updating instance") + return fmt.Errorf("error updating instance: %w", err) } msg := InstanceStatusUpdate{ @@ -242,7 +243,7 @@ func (s *sqlDatabase) AddInstanceEvent(ctx context.Context, instanceName string, } if err := s.conn.Model(&instance).Association("StatusMessages").Append(&msg); err != nil { - return errors.Wrap(err, "adding status message") + return fmt.Errorf("error adding status message: %w", err) } return nil } @@ -250,7 +251,7 @@ func (s *sqlDatabase) AddInstanceEvent(ctx context.Context, instanceName string, func (s *sqlDatabase) UpdateInstance(ctx context.Context, instanceName string, param params.UpdateInstanceParams) (params.Instance, error) { instance, err := s.getInstanceByName(ctx, instanceName, "Pool", "ScaleSet") if err != nil { - return params.Instance{}, errors.Wrap(err, "updating instance") + return params.Instance{}, fmt.Errorf("error updating instance: %w", err) } if param.AgentID != 0 { @@ -287,7 +288,7 @@ func (s *sqlDatabase) UpdateInstance(ctx context.Context, instanceName string, p if param.JitConfiguration != nil { secret, err := s.marshalAndSeal(param.JitConfiguration) if err != nil { - return params.Instance{}, errors.Wrap(err, "marshalling jit config") + return params.Instance{}, fmt.Errorf("error marshalling jit config: %w", err) } instance.JitConfiguration = secret } @@ -296,7 +297,7 @@ func (s *sqlDatabase) UpdateInstance(ctx context.Context, instanceName string, p q := s.conn.Save(&instance) if q.Error != nil { - return params.Instance{}, errors.Wrap(q.Error, "updating instance") + return params.Instance{}, fmt.Errorf("error updating instance: %w", q.Error) } if len(param.Addresses) > 0 { @@ -308,12 +309,12 @@ func (s *sqlDatabase) UpdateInstance(ctx context.Context, instanceName string, p }) } if err := s.conn.Model(&instance).Association("Addresses").Replace(addrs); err != nil { - return params.Instance{}, errors.Wrap(err, "updating addresses") + return params.Instance{}, fmt.Errorf("error updating addresses: %w", err) } } inst, err := s.sqlToParamsInstance(instance) if err != nil { - return params.Instance{}, errors.Wrap(err, "converting instance") + return params.Instance{}, fmt.Errorf("error converting instance: %w", err) } s.sendNotify(common.InstanceEntityType, common.UpdateOperation, inst) return inst, nil @@ -322,7 +323,7 @@ func (s *sqlDatabase) UpdateInstance(ctx context.Context, instanceName string, p func (s *sqlDatabase) ListPoolInstances(_ context.Context, poolID string) ([]params.Instance, error) { u, err := uuid.Parse(poolID) if err != nil { - return nil, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return nil, fmt.Errorf("error parsing id: %w", runnerErrors.ErrBadRequest) } var instances []Instance @@ -332,14 +333,14 @@ func (s *sqlDatabase) ListPoolInstances(_ context.Context, poolID string) ([]par Where("pool_id = ?", u) if err := query.Find(&instances); err.Error != nil { - return nil, errors.Wrap(err.Error, "fetching instances") + return nil, fmt.Errorf("error fetching instances: %w", err.Error) } ret := make([]params.Instance, len(instances)) for idx, inst := range instances { ret[idx], err = s.sqlToParamsInstance(inst) if err != nil { - return nil, errors.Wrap(err, "converting instance") + return nil, fmt.Errorf("error converting instance: %w", err) } } return ret, nil @@ -354,14 +355,14 @@ func (s *sqlDatabase) ListAllInstances(_ context.Context) ([]params.Instance, er Preload("Job"). Find(&instances) if q.Error != nil { - return nil, errors.Wrap(q.Error, "fetching instances") + return nil, fmt.Errorf("error fetching instances: %w", q.Error) } ret := make([]params.Instance, len(instances)) var err error for idx, instance := range instances { ret[idx], err = s.sqlToParamsInstance(instance) if err != nil { - return nil, errors.Wrap(err, "converting instance") + return nil, fmt.Errorf("error converting instance: %w", err) } } return ret, nil @@ -370,13 +371,13 @@ func (s *sqlDatabase) ListAllInstances(_ context.Context) ([]params.Instance, er func (s *sqlDatabase) PoolInstanceCount(_ context.Context, poolID string) (int64, error) { pool, err := s.getPoolByID(s.conn, poolID) if err != nil { - return 0, errors.Wrap(err, "fetching pool") + return 0, fmt.Errorf("error fetching pool: %w", err) } var cnt int64 q := s.conn.Model(&Instance{}).Where("pool_id = ?", pool.ID).Count(&cnt) if q.Error != nil { - return 0, errors.Wrap(q.Error, "fetching instance count") + return 0, fmt.Errorf("error fetching instance count: %w", q.Error) } return cnt, nil } diff --git a/database/sql/instances_test.go b/database/sql/instances_test.go index c70e35dd..c6093327 100644 --- a/database/sql/instances_test.go +++ b/database/sql/instances_test.go @@ -210,7 +210,7 @@ func (s *InstancesTestSuite) TestCreateInstance() { func (s *InstancesTestSuite) TestCreateInstanceInvalidPoolID() { _, err := s.Store.CreateInstance(s.adminCtx, "dummy-pool-id", params.CreateInstanceParams{}) - s.Require().Equal("fetching pool: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching pool: error parsing id: invalid request", err.Error()) } func (s *InstancesTestSuite) TestCreateInstanceDBCreateErr() { @@ -233,7 +233,7 @@ func (s *InstancesTestSuite) TestCreateInstanceDBCreateErr() { s.assertSQLMockExpectations() s.Require().NotNil(err) - s.Require().Equal("creating instance: mocked insert instance error", err.Error()) + s.Require().Equal("error creating instance: mocked insert instance error", err.Error()) } func (s *InstancesTestSuite) TestGetPoolInstanceByName() { @@ -252,7 +252,7 @@ func (s *InstancesTestSuite) TestGetPoolInstanceByName() { func (s *InstancesTestSuite) TestGetPoolInstanceByNameNotFound() { _, err := s.Store.GetPoolInstanceByName(s.adminCtx, s.Fixtures.Pool.ID, "not-existent-instance-name") - s.Require().Equal("fetching instance: fetching pool instance by name: not found", err.Error()) + s.Require().Equal("error fetching instance: error fetching pool instance by name: not found", err.Error()) } func (s *InstancesTestSuite) TestGetInstanceByName() { @@ -271,7 +271,7 @@ func (s *InstancesTestSuite) TestGetInstanceByName() { func (s *InstancesTestSuite) TestGetInstanceByNameFetchInstanceFailed() { _, err := s.Store.GetInstanceByName(s.adminCtx, "not-existent-instance-name") - s.Require().Equal("fetching instance: fetching instance by name: not found", err.Error()) + s.Require().Equal("error fetching instance: error fetching instance by name: not found", err.Error()) } func (s *InstancesTestSuite) TestDeleteInstance() { @@ -282,7 +282,7 @@ func (s *InstancesTestSuite) TestDeleteInstance() { s.Require().Nil(err) _, err = s.Store.GetPoolInstanceByName(s.adminCtx, s.Fixtures.Pool.ID, storeInstance.Name) - s.Require().Equal("fetching instance: fetching pool instance by name: not found", err.Error()) + s.Require().Equal("error fetching instance: error fetching pool instance by name: not found", err.Error()) err = s.Store.DeleteInstance(s.adminCtx, s.Fixtures.Pool.ID, storeInstance.Name) s.Require().Nil(err) @@ -296,7 +296,7 @@ func (s *InstancesTestSuite) TestDeleteInstanceByName() { s.Require().Nil(err) _, err = s.Store.GetPoolInstanceByName(s.adminCtx, s.Fixtures.Pool.ID, storeInstance.Name) - s.Require().Equal("fetching instance: fetching pool instance by name: not found", err.Error()) + s.Require().Equal("error fetching instance: error fetching pool instance by name: not found", err.Error()) err = s.Store.DeleteInstanceByName(s.adminCtx, storeInstance.Name) s.Require().Nil(err) @@ -305,7 +305,7 @@ func (s *InstancesTestSuite) TestDeleteInstanceByName() { func (s *InstancesTestSuite) TestDeleteInstanceInvalidPoolID() { err := s.Store.DeleteInstance(s.adminCtx, "dummy-pool-id", "dummy-instance-name") - s.Require().Equal("deleting instance: fetching pool: parsing id: invalid request", err.Error()) + s.Require().Equal("error deleting instance: error fetching pool: error parsing id: invalid request", err.Error()) } func (s *InstancesTestSuite) TestDeleteInstanceDBRecordNotFoundErr() { @@ -380,7 +380,7 @@ func (s *InstancesTestSuite) TestDeleteInstanceDBDeleteErr() { s.assertSQLMockExpectations() s.Require().NotNil(err) - s.Require().Equal("deleting instance: mocked delete instance error", err.Error()) + s.Require().Equal("error deleting instance: mocked delete instance error", err.Error()) } func (s *InstancesTestSuite) TestAddInstanceEvent() { @@ -431,7 +431,7 @@ func (s *InstancesTestSuite) TestAddInstanceEventDBUpdateErr() { err := s.StoreSQLMocked.AddInstanceEvent(s.adminCtx, instance.Name, params.StatusEvent, params.EventInfo, statusMsg) s.Require().NotNil(err) - s.Require().Equal("adding status message: mocked add status message error", err.Error()) + s.Require().Equal("error adding status message: mocked add status message error", err.Error()) s.assertSQLMockExpectations() } @@ -476,7 +476,7 @@ func (s *InstancesTestSuite) TestUpdateInstanceDBUpdateInstanceErr() { _, err := s.StoreSQLMocked.UpdateInstance(s.adminCtx, instance.Name, s.Fixtures.UpdateInstanceParams) s.Require().NotNil(err) - s.Require().Equal("updating instance: mocked update instance error", err.Error()) + s.Require().Equal("error updating instance: mocked update instance error", err.Error()) s.assertSQLMockExpectations() } @@ -522,7 +522,7 @@ func (s *InstancesTestSuite) TestUpdateInstanceDBUpdateAddressErr() { _, err := s.StoreSQLMocked.UpdateInstance(s.adminCtx, instance.Name, s.Fixtures.UpdateInstanceParams) s.Require().NotNil(err) - s.Require().Equal("updating addresses: update addresses mock error", err.Error()) + s.Require().Equal("error updating addresses: update addresses mock error", err.Error()) s.assertSQLMockExpectations() } @@ -536,7 +536,7 @@ func (s *InstancesTestSuite) TestListPoolInstances() { func (s *InstancesTestSuite) TestListPoolInstancesInvalidPoolID() { _, err := s.Store.ListPoolInstances(s.adminCtx, "dummy-pool-id") - s.Require().Equal("parsing id: invalid request", err.Error()) + s.Require().Equal("error parsing id: invalid request", err.Error()) } func (s *InstancesTestSuite) TestListAllInstances() { @@ -555,7 +555,7 @@ func (s *InstancesTestSuite) TestListAllInstancesDBFetchErr() { s.assertSQLMockExpectations() s.Require().NotNil(err) - s.Require().Equal("fetching instances: fetch instances mock error", err.Error()) + s.Require().Equal("error fetching instances: fetch instances mock error", err.Error()) } func (s *InstancesTestSuite) TestPoolInstanceCount() { @@ -568,7 +568,7 @@ func (s *InstancesTestSuite) TestPoolInstanceCount() { func (s *InstancesTestSuite) TestPoolInstanceCountInvalidPoolID() { _, err := s.Store.PoolInstanceCount(s.adminCtx, "dummy-pool-id") - s.Require().Equal("fetching pool: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching pool: error parsing id: invalid request", err.Error()) } func (s *InstancesTestSuite) TestPoolInstanceCountDBCountErr() { @@ -587,7 +587,7 @@ func (s *InstancesTestSuite) TestPoolInstanceCountDBCountErr() { s.assertSQLMockExpectations() s.Require().NotNil(err) - s.Require().Equal("fetching instance count: count mock error", err.Error()) + s.Require().Equal("error fetching instance count: count mock error", err.Error()) } func TestInstTestSuite(t *testing.T) { diff --git a/database/sql/jobs.go b/database/sql/jobs.go index ff19394f..f4d24e42 100644 --- a/database/sql/jobs.go +++ b/database/sql/jobs.go @@ -17,10 +17,11 @@ package sql import ( "context" "encoding/json" + "errors" + "fmt" "log/slog" "github.com/google/uuid" - "github.com/pkg/errors" "gorm.io/gorm" "gorm.io/gorm/clause" @@ -35,7 +36,7 @@ func sqlWorkflowJobToParamsJob(job WorkflowJob) (params.Job, error) { labels := []string{} if job.Labels != nil { if err := json.Unmarshal(job.Labels, &labels); err != nil { - return params.Job{}, errors.Wrap(err, "unmarshaling labels") + return params.Job{}, fmt.Errorf("error unmarshaling labels: %w", err) } } @@ -73,7 +74,7 @@ func sqlWorkflowJobToParamsJob(job WorkflowJob) (params.Job, error) { func (s *sqlDatabase) paramsJobToWorkflowJob(ctx context.Context, job params.Job) (WorkflowJob, error) { asJSON, err := json.Marshal(job.Labels) if err != nil { - return WorkflowJob{}, errors.Wrap(err, "marshaling labels") + return WorkflowJob{}, fmt.Errorf("error marshaling labels: %w", err) } workflofJob := WorkflowJob{ @@ -118,11 +119,11 @@ func (s *sqlDatabase) DeleteJob(_ context.Context, jobID int64) (err error) { if errors.Is(q.Error, gorm.ErrRecordNotFound) { return nil } - return errors.Wrap(q.Error, "fetching job") + return fmt.Errorf("error fetching job: %w", q.Error) } removedJob, err := sqlWorkflowJobToParamsJob(workflowJob) if err != nil { - return errors.Wrap(err, "converting job") + return fmt.Errorf("error converting job: %w", err) } defer func() { @@ -137,7 +138,7 @@ func (s *sqlDatabase) DeleteJob(_ context.Context, jobID int64) (err error) { if errors.Is(q.Error, gorm.ErrRecordNotFound) { return nil } - return errors.Wrap(q.Error, "deleting job") + return fmt.Errorf("error deleting job: %w", q.Error) } return nil } @@ -145,7 +146,7 @@ func (s *sqlDatabase) DeleteJob(_ context.Context, jobID int64) (err error) { func (s *sqlDatabase) LockJob(_ context.Context, jobID int64, entityID string) error { entityUUID, err := uuid.Parse(entityID) if err != nil { - return errors.Wrap(err, "parsing entity id") + return fmt.Errorf("error parsing entity id: %w", err) } var workflowJob WorkflowJob q := s.conn.Preload("Instance").Where("id = ?", jobID).First(&workflowJob) @@ -154,7 +155,7 @@ func (s *sqlDatabase) LockJob(_ context.Context, jobID int64, entityID string) e if errors.Is(q.Error, gorm.ErrRecordNotFound) { return runnerErrors.ErrNotFound } - return errors.Wrap(q.Error, "fetching job") + return fmt.Errorf("error fetching job: %w", q.Error) } if workflowJob.LockedBy.String() == entityID { @@ -169,12 +170,12 @@ func (s *sqlDatabase) LockJob(_ context.Context, jobID int64, entityID string) e workflowJob.LockedBy = entityUUID if err := s.conn.Save(&workflowJob).Error; err != nil { - return errors.Wrap(err, "saving job") + return fmt.Errorf("error saving job: %w", err) } asParams, err := sqlWorkflowJobToParamsJob(workflowJob) if err != nil { - return errors.Wrap(err, "converting job") + return fmt.Errorf("error converting job: %w", err) } s.sendNotify(common.JobEntityType, common.UpdateOperation, asParams) @@ -189,7 +190,7 @@ func (s *sqlDatabase) BreakLockJobIsQueued(_ context.Context, jobID int64) (err if errors.Is(q.Error, gorm.ErrRecordNotFound) { return nil } - return errors.Wrap(q.Error, "fetching job") + return fmt.Errorf("error fetching job: %w", q.Error) } if workflowJob.LockedBy == uuid.Nil { @@ -199,11 +200,11 @@ func (s *sqlDatabase) BreakLockJobIsQueued(_ context.Context, jobID int64) (err workflowJob.LockedBy = uuid.Nil if err := s.conn.Save(&workflowJob).Error; err != nil { - return errors.Wrap(err, "saving job") + return fmt.Errorf("error saving job: %w", err) } asParams, err := sqlWorkflowJobToParamsJob(workflowJob) if err != nil { - return errors.Wrap(err, "converting job") + return fmt.Errorf("error converting job: %w", err) } s.sendNotify(common.JobEntityType, common.UpdateOperation, asParams) return nil @@ -217,7 +218,7 @@ func (s *sqlDatabase) UnlockJob(_ context.Context, jobID int64, entityID string) if errors.Is(q.Error, gorm.ErrRecordNotFound) { return runnerErrors.ErrNotFound } - return errors.Wrap(q.Error, "fetching job") + return fmt.Errorf("error fetching job: %w", q.Error) } if workflowJob.LockedBy == uuid.Nil { @@ -231,12 +232,12 @@ func (s *sqlDatabase) UnlockJob(_ context.Context, jobID int64, entityID string) workflowJob.LockedBy = uuid.Nil if err := s.conn.Save(&workflowJob).Error; err != nil { - return errors.Wrap(err, "saving job") + return fmt.Errorf("error saving job: %w", err) } asParams, err := sqlWorkflowJobToParamsJob(workflowJob) if err != nil { - return errors.Wrap(err, "converting job") + return fmt.Errorf("error converting job: %w", err) } s.sendNotify(common.JobEntityType, common.UpdateOperation, asParams) return nil @@ -256,7 +257,7 @@ func (s *sqlDatabase) CreateOrUpdateJob(ctx context.Context, job params.Job) (pa if q.Error != nil { if !errors.Is(q.Error, gorm.ErrRecordNotFound) { - return params.Job{}, errors.Wrap(q.Error, "fetching job") + return params.Job{}, fmt.Errorf("error fetching job: %w", q.Error) } } var operation common.OperationType @@ -302,23 +303,23 @@ func (s *sqlDatabase) CreateOrUpdateJob(ctx context.Context, job params.Job) (pa workflowJob.EnterpriseID = job.EnterpriseID } if err := s.conn.Save(&workflowJob).Error; err != nil { - return params.Job{}, errors.Wrap(err, "saving job") + return params.Job{}, fmt.Errorf("error saving job: %w", err) } } else { operation = common.CreateOperation workflowJob, err = s.paramsJobToWorkflowJob(ctx, job) if err != nil { - return params.Job{}, errors.Wrap(err, "converting job") + return params.Job{}, fmt.Errorf("error converting job: %w", err) } if err := s.conn.Create(&workflowJob).Error; err != nil { - return params.Job{}, errors.Wrap(err, "creating job") + return params.Job{}, fmt.Errorf("error creating job: %w", err) } } asParams, err := sqlWorkflowJobToParamsJob(workflowJob) if err != nil { - return params.Job{}, errors.Wrap(err, "converting job") + return params.Job{}, fmt.Errorf("error converting job: %w", err) } s.sendNotify(common.JobEntityType, operation, asParams) @@ -338,7 +339,7 @@ func (s *sqlDatabase) ListJobsByStatus(_ context.Context, status params.JobStatu for idx, job := range jobs { jobParam, err := sqlWorkflowJobToParamsJob(job) if err != nil { - return nil, errors.Wrap(err, "converting job") + return nil, fmt.Errorf("error converting job: %w", err) } ret[idx] = jobParam } @@ -379,7 +380,7 @@ func (s *sqlDatabase) ListEntityJobsByStatus(_ context.Context, entityType param for idx, job := range jobs { jobParam, err := sqlWorkflowJobToParamsJob(job) if err != nil { - return nil, errors.Wrap(err, "converting job") + return nil, fmt.Errorf("error converting job: %w", err) } ret[idx] = jobParam } @@ -401,7 +402,7 @@ func (s *sqlDatabase) ListAllJobs(_ context.Context) ([]params.Job, error) { for idx, job := range jobs { jobParam, err := sqlWorkflowJobToParamsJob(job) if err != nil { - return nil, errors.Wrap(err, "converting job") + return nil, fmt.Errorf("error converting job: %w", err) } ret[idx] = jobParam } diff --git a/database/sql/models.go b/database/sql/models.go index 8944dee1..d3cb044a 100644 --- a/database/sql/models.go +++ b/database/sql/models.go @@ -15,10 +15,10 @@ package sql import ( + "fmt" "time" "github.com/google/uuid" - "github.com/pkg/errors" "gorm.io/datatypes" "gorm.io/gorm" @@ -40,7 +40,7 @@ func (b *Base) BeforeCreate(_ *gorm.DB) error { } newID, err := uuid.NewRandom() if err != nil { - return errors.Wrap(err, "generating id") + return fmt.Errorf("error generating id: %w", err) } b.ID = newID return nil diff --git a/database/sql/organizations.go b/database/sql/organizations.go index 3b1a05fa..22be6272 100644 --- a/database/sql/organizations.go +++ b/database/sql/organizations.go @@ -16,11 +16,11 @@ package sql import ( "context" + "errors" "fmt" "log/slog" "github.com/google/uuid" - "github.com/pkg/errors" "gorm.io/gorm" runnerErrors "github.com/cloudbase/garm-provider-common/errors" @@ -35,7 +35,7 @@ func (s *sqlDatabase) CreateOrganization(ctx context.Context, name string, crede } secret, err := util.Seal([]byte(webhookSecret), []byte(s.cfg.Passphrase)) if err != nil { - return params.Organization{}, errors.Wrap(err, "encoding secret") + return params.Organization{}, fmt.Errorf("error encoding secret: %w", err) } defer func() { @@ -56,23 +56,23 @@ func (s *sqlDatabase) CreateOrganization(ctx context.Context, name string, crede case params.GiteaEndpointType: newOrg.GiteaCredentialsID = &credentials.ID default: - return errors.Wrap(runnerErrors.ErrBadRequest, "unsupported credentials type") + return fmt.Errorf("unsupported credentials type: %w", runnerErrors.ErrBadRequest) } newOrg.EndpointName = &credentials.Endpoint.Name q := tx.Create(&newOrg) if q.Error != nil { - return errors.Wrap(q.Error, "creating org") + return fmt.Errorf("error creating org: %w", q.Error) } return nil }) if err != nil { - return params.Organization{}, errors.Wrap(err, "creating org") + return params.Organization{}, fmt.Errorf("error creating org: %w", err) } ret, err := s.GetOrganizationByID(ctx, newOrg.ID.String()) if err != nil { - return params.Organization{}, errors.Wrap(err, "creating org") + return params.Organization{}, fmt.Errorf("error creating org: %w", err) } return ret, nil @@ -81,12 +81,12 @@ func (s *sqlDatabase) CreateOrganization(ctx context.Context, name string, crede func (s *sqlDatabase) GetOrganization(ctx context.Context, name, endpointName string) (params.Organization, error) { org, err := s.getOrg(ctx, name, endpointName) if err != nil { - return params.Organization{}, errors.Wrap(err, "fetching org") + return params.Organization{}, fmt.Errorf("error fetching org: %w", err) } param, err := s.sqlToCommonOrganization(org, true) if err != nil { - return params.Organization{}, errors.Wrap(err, "fetching org") + return params.Organization{}, fmt.Errorf("error fetching org: %w", err) } return param, nil @@ -110,7 +110,7 @@ func (s *sqlDatabase) ListOrganizations(_ context.Context, filter params.Organiz } q = q.Find(&orgs) if q.Error != nil { - return []params.Organization{}, errors.Wrap(q.Error, "fetching org from database") + return []params.Organization{}, fmt.Errorf("error fetching org from database: %w", q.Error) } ret := make([]params.Organization, len(orgs)) @@ -118,7 +118,7 @@ func (s *sqlDatabase) ListOrganizations(_ context.Context, filter params.Organiz var err error ret[idx], err = s.sqlToCommonOrganization(val, true) if err != nil { - return nil, errors.Wrap(err, "fetching org") + return nil, fmt.Errorf("error fetching org: %w", err) } } @@ -128,7 +128,7 @@ func (s *sqlDatabase) ListOrganizations(_ context.Context, filter params.Organiz func (s *sqlDatabase) DeleteOrganization(ctx context.Context, orgID string) (err error) { org, err := s.getOrgByID(ctx, s.conn, orgID, "Endpoint", "Credentials", "Credentials.Endpoint", "GiteaCredentials", "GiteaCredentials.Endpoint") if err != nil { - return errors.Wrap(err, "fetching org") + return fmt.Errorf("error fetching org: %w", err) } defer func(org Organization) { @@ -144,7 +144,7 @@ func (s *sqlDatabase) DeleteOrganization(ctx context.Context, orgID string) (err q := s.conn.Unscoped().Delete(&org) if q.Error != nil && !errors.Is(q.Error, gorm.ErrRecordNotFound) { - return errors.Wrap(q.Error, "deleting org") + return fmt.Errorf("error deleting org: %w", q.Error) } return nil @@ -162,23 +162,23 @@ func (s *sqlDatabase) UpdateOrganization(ctx context.Context, orgID string, para var err error org, err = s.getOrgByID(ctx, tx, orgID) if err != nil { - return errors.Wrap(err, "fetching org") + return fmt.Errorf("error fetching org: %w", err) } if org.EndpointName == nil { - return errors.Wrap(runnerErrors.ErrUnprocessable, "org has no endpoint") + return fmt.Errorf("error org has no endpoint: %w", runnerErrors.ErrUnprocessable) } if param.CredentialsName != "" { creds, err = s.getGithubCredentialsByName(ctx, tx, param.CredentialsName, false) if err != nil { - return errors.Wrap(err, "fetching credentials") + return fmt.Errorf("error fetching credentials: %w", err) } if creds.EndpointName == nil { - return errors.Wrap(runnerErrors.ErrUnprocessable, "credentials have no endpoint") + return fmt.Errorf("error credentials have no endpoint: %w", runnerErrors.ErrUnprocessable) } if *creds.EndpointName != *org.EndpointName { - return errors.Wrap(runnerErrors.ErrBadRequest, "endpoint mismatch") + return fmt.Errorf("error endpoint mismatch: %w", runnerErrors.ErrBadRequest) } org.CredentialsID = &creds.ID } @@ -197,22 +197,22 @@ func (s *sqlDatabase) UpdateOrganization(ctx context.Context, orgID string, para q := tx.Save(&org) if q.Error != nil { - return errors.Wrap(q.Error, "saving org") + return fmt.Errorf("error saving org: %w", q.Error) } return nil }) if err != nil { - return params.Organization{}, errors.Wrap(err, "saving org") + return params.Organization{}, fmt.Errorf("error saving org: %w", err) } org, err = s.getOrgByID(ctx, s.conn, orgID, "Endpoint", "Credentials", "Credentials.Endpoint", "GiteaCredentials", "GiteaCredentials.Endpoint") if err != nil { - return params.Organization{}, errors.Wrap(err, "updating enterprise") + return params.Organization{}, fmt.Errorf("error updating enterprise: %w", err) } paramOrg, err = s.sqlToCommonOrganization(org, true) if err != nil { - return params.Organization{}, errors.Wrap(err, "saving org") + return params.Organization{}, fmt.Errorf("error saving org: %w", err) } return paramOrg, nil } @@ -229,12 +229,12 @@ func (s *sqlDatabase) GetOrganizationByID(ctx context.Context, orgID string) (pa } org, err := s.getOrgByID(ctx, s.conn, orgID, preloadList...) if err != nil { - return params.Organization{}, errors.Wrap(err, "fetching org") + return params.Organization{}, fmt.Errorf("error fetching org: %w", err) } param, err := s.sqlToCommonOrganization(org, true) if err != nil { - return params.Organization{}, errors.Wrap(err, "fetching org") + return params.Organization{}, fmt.Errorf("error fetching org: %w", err) } return param, nil } @@ -242,7 +242,7 @@ func (s *sqlDatabase) GetOrganizationByID(ctx context.Context, orgID string) (pa func (s *sqlDatabase) getOrgByID(_ context.Context, db *gorm.DB, id string, preload ...string) (Organization, error) { u, err := uuid.Parse(id) if err != nil { - return Organization{}, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return Organization{}, fmt.Errorf("error parsing id: %w", runnerErrors.ErrBadRequest) } var org Organization @@ -258,7 +258,7 @@ func (s *sqlDatabase) getOrgByID(_ context.Context, db *gorm.DB, id string, prel if errors.Is(q.Error, gorm.ErrRecordNotFound) { return Organization{}, runnerErrors.ErrNotFound } - return Organization{}, errors.Wrap(q.Error, "fetching org from database") + return Organization{}, fmt.Errorf("error fetching org from database: %w", q.Error) } return org, nil } @@ -277,7 +277,7 @@ func (s *sqlDatabase) getOrg(_ context.Context, name, endpointName string) (Orga if errors.Is(q.Error, gorm.ErrRecordNotFound) { return Organization{}, runnerErrors.ErrNotFound } - return Organization{}, errors.Wrap(q.Error, "fetching org from database") + return Organization{}, fmt.Errorf("error fetching org from database: %w", q.Error) } return org, nil } diff --git a/database/sql/organizations_test.go b/database/sql/organizations_test.go index df876ba1..651c2927 100644 --- a/database/sql/organizations_test.go +++ b/database/sql/organizations_test.go @@ -251,7 +251,7 @@ func (s *OrgTestSuite) TestCreateOrganizationInvalidForgeType() { s.Fixtures.CreateOrgParams.WebhookSecret, params.PoolBalancerTypeRoundRobin) s.Require().NotNil(err) - s.Require().Equal("creating org: unsupported credentials type: invalid request", err.Error()) + s.Require().Equal("error creating org: unsupported credentials type: invalid request", err.Error()) } func (s *OrgTestSuite) TestCreateOrganizationInvalidDBPassphrase() { @@ -275,7 +275,7 @@ func (s *OrgTestSuite) TestCreateOrganizationInvalidDBPassphrase() { params.PoolBalancerTypeRoundRobin) s.Require().NotNil(err) - s.Require().Equal("encoding secret: invalid passphrase length (expected length 32 characters)", err.Error()) + s.Require().Equal("error encoding secret: invalid passphrase length (expected length 32 characters)", err.Error()) } func (s *OrgTestSuite) TestCreateOrganizationDBCreateErr() { @@ -293,7 +293,7 @@ func (s *OrgTestSuite) TestCreateOrganizationDBCreateErr() { params.PoolBalancerTypeRoundRobin) s.Require().NotNil(err) - s.Require().Equal("creating org: creating org: creating org mock error", err.Error()) + s.Require().Equal("error creating org: error creating org: creating org mock error", err.Error()) s.assertSQLMockExpectations() } @@ -316,7 +316,7 @@ func (s *OrgTestSuite) TestGetOrganizationNotFound() { _, err := s.Store.GetOrganization(s.adminCtx, "dummy-name", "github.com") s.Require().NotNil(err) - s.Require().Equal("fetching org: not found", err.Error()) + s.Require().Equal("error fetching org: not found", err.Error()) } func (s *OrgTestSuite) TestGetOrganizationDBDecryptingErr() { @@ -328,7 +328,7 @@ func (s *OrgTestSuite) TestGetOrganizationDBDecryptingErr() { _, err := s.StoreSQLMocked.GetOrganization(s.adminCtx, s.Fixtures.Orgs[0].Name, s.Fixtures.Orgs[0].Endpoint.Name) s.Require().NotNil(err) - s.Require().Equal("fetching org: missing secret", err.Error()) + s.Require().Equal("error fetching org: missing secret", err.Error()) s.assertSQLMockExpectations() } @@ -404,7 +404,7 @@ func (s *OrgTestSuite) TestListOrganizationsDBFetchErr() { s.assertSQLMockExpectations() s.Require().NotNil(err) - s.Require().Equal("fetching org from database: fetching user from database mock error", err.Error()) + s.Require().Equal("error fetching org from database: fetching user from database mock error", err.Error()) } func (s *OrgTestSuite) TestDeleteOrganization() { @@ -413,14 +413,14 @@ func (s *OrgTestSuite) TestDeleteOrganization() { s.Require().Nil(err) _, err = s.Store.GetOrganizationByID(s.adminCtx, s.Fixtures.Orgs[0].ID) s.Require().NotNil(err) - s.Require().Equal("fetching org: not found", err.Error()) + s.Require().Equal("error fetching org: not found", err.Error()) } func (s *OrgTestSuite) TestDeleteOrganizationInvalidOrgID() { err := s.Store.DeleteOrganization(s.adminCtx, "dummy-org-id") s.Require().NotNil(err) - s.Require().Equal("fetching org: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching org: error parsing id: invalid request", err.Error()) } func (s *OrgTestSuite) TestDeleteOrganizationDBDeleteErr() { @@ -439,7 +439,7 @@ func (s *OrgTestSuite) TestDeleteOrganizationDBDeleteErr() { s.assertSQLMockExpectations() s.Require().NotNil(err) - s.Require().Equal("deleting org: mocked delete org error", err.Error()) + s.Require().Equal("error deleting org: mocked delete org error", err.Error()) } func (s *OrgTestSuite) TestUpdateOrganization() { @@ -454,7 +454,7 @@ func (s *OrgTestSuite) TestUpdateOrganizationInvalidOrgID() { _, err := s.Store.UpdateOrganization(s.adminCtx, "dummy-org-id", s.Fixtures.UpdateRepoParams) s.Require().NotNil(err) - s.Require().Equal("saving org: fetching org: parsing id: invalid request", err.Error()) + s.Require().Equal("error saving org: error fetching org: error parsing id: invalid request", err.Error()) } func (s *OrgTestSuite) TestUpdateOrganizationDBEncryptErr() { @@ -479,7 +479,7 @@ func (s *OrgTestSuite) TestUpdateOrganizationDBEncryptErr() { _, err := s.StoreSQLMocked.UpdateOrganization(s.adminCtx, s.Fixtures.Orgs[0].ID, s.Fixtures.UpdateRepoParams) s.Require().NotNil(err) - s.Require().Equal("saving org: saving org: failed to encrypt string: invalid passphrase length (expected length 32 characters)", err.Error()) + s.Require().Equal("error saving org: saving org: failed to encrypt string: invalid passphrase length (expected length 32 characters)", err.Error()) s.assertSQLMockExpectations() } @@ -507,7 +507,7 @@ func (s *OrgTestSuite) TestUpdateOrganizationDBSaveErr() { _, err := s.StoreSQLMocked.UpdateOrganization(s.adminCtx, s.Fixtures.Orgs[0].ID, s.Fixtures.UpdateRepoParams) s.Require().NotNil(err) - s.Require().Equal("saving org: saving org: saving org mock error", err.Error()) + s.Require().Equal("error saving org: error saving org: saving org mock error", err.Error()) s.assertSQLMockExpectations() } @@ -535,7 +535,7 @@ func (s *OrgTestSuite) TestUpdateOrganizationDBDecryptingErr() { _, err := s.StoreSQLMocked.UpdateOrganization(s.adminCtx, s.Fixtures.Orgs[0].ID, s.Fixtures.UpdateRepoParams) s.Require().NotNil(err) - s.Require().Equal("saving org: saving org: failed to encrypt string: invalid passphrase length (expected length 32 characters)", err.Error()) + s.Require().Equal("error saving org: saving org: failed to encrypt string: invalid passphrase length (expected length 32 characters)", err.Error()) s.assertSQLMockExpectations() } @@ -550,7 +550,7 @@ func (s *OrgTestSuite) TestGetOrganizationByIDInvalidOrgID() { _, err := s.Store.GetOrganizationByID(s.adminCtx, "dummy-org-id") s.Require().NotNil(err) - s.Require().Equal("fetching org: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching org: error parsing id: invalid request", err.Error()) } func (s *OrgTestSuite) TestGetOrganizationByIDDBDecryptingErr() { @@ -571,7 +571,7 @@ func (s *OrgTestSuite) TestGetOrganizationByIDDBDecryptingErr() { s.assertSQLMockExpectations() s.Require().NotNil(err) - s.Require().Equal("fetching org: missing secret", err.Error()) + s.Require().Equal("error fetching org: missing secret", err.Error()) } func (s *OrgTestSuite) TestCreateOrganizationPool() { @@ -610,7 +610,7 @@ func (s *OrgTestSuite) TestCreateOrganizationPoolInvalidOrgID() { _, err := s.Store.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("parsing id: invalid request", err.Error()) + s.Require().Equal("error parsing id: invalid request", err.Error()) } func (s *OrgTestSuite) TestCreateOrganizationPoolDBFetchTagErr() { @@ -628,7 +628,7 @@ func (s *OrgTestSuite) TestCreateOrganizationPoolDBFetchTagErr() { _, err = s.StoreSQLMocked.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("creating tag: fetching tag from database: mocked fetching tag error", err.Error()) + s.Require().Equal("error creating tag: error fetching tag from database: mocked fetching tag error", err.Error()) s.assertSQLMockExpectations() } @@ -656,7 +656,7 @@ func (s *OrgTestSuite) TestCreateOrganizationPoolDBAddingPoolErr() { _, err = s.StoreSQLMocked.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("creating pool: mocked adding pool error", err.Error()) + s.Require().Equal("error creating pool: mocked adding pool error", err.Error()) s.assertSQLMockExpectations() } @@ -687,7 +687,7 @@ func (s *OrgTestSuite) TestCreateOrganizationPoolDBSaveTagErr() { _, err = s.StoreSQLMocked.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("associating tags: mocked saving tag error", err.Error()) + s.Require().Equal("error associating tags: mocked saving tag error", err.Error()) s.assertSQLMockExpectations() } @@ -728,7 +728,7 @@ func (s *OrgTestSuite) TestCreateOrganizationPoolDBFetchPoolErr() { _, err = s.StoreSQLMocked.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("fetching pool: not found", err.Error()) + s.Require().Equal("error fetching pool: not found", err.Error()) s.assertSQLMockExpectations() } @@ -758,7 +758,7 @@ func (s *OrgTestSuite) TestListOrgPoolsInvalidOrgID() { _, err := s.Store.ListEntityPools(s.adminCtx, entity) s.Require().NotNil(err) - s.Require().Equal("fetching pools: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching pools: error parsing id: invalid request", err.Error()) } func (s *OrgTestSuite) TestGetOrganizationPool() { @@ -783,7 +783,7 @@ func (s *OrgTestSuite) TestGetOrganizationPoolInvalidOrgID() { _, err := s.Store.GetEntityPool(s.adminCtx, entity, "dummy-pool-id") s.Require().NotNil(err) - s.Require().Equal("fetching pool: parsing id: invalid request", err.Error()) + s.Require().Equal("fetching pool: error parsing id: invalid request", err.Error()) } func (s *OrgTestSuite) TestDeleteOrganizationPool() { @@ -798,7 +798,7 @@ func (s *OrgTestSuite) TestDeleteOrganizationPool() { s.Require().Nil(err) _, err = s.Store.GetEntityPool(s.adminCtx, entity, pool.ID) - s.Require().Equal("fetching pool: finding pool: not found", err.Error()) + s.Require().Equal("fetching pool: error finding pool: not found", err.Error()) } func (s *OrgTestSuite) TestDeleteOrganizationPoolInvalidOrgID() { @@ -809,7 +809,7 @@ func (s *OrgTestSuite) TestDeleteOrganizationPoolInvalidOrgID() { err := s.Store.DeleteEntityPool(s.adminCtx, entity, "dummy-pool-id") s.Require().NotNil(err) - s.Require().Equal("parsing id: invalid request", err.Error()) + s.Require().Equal("error parsing id: invalid request", err.Error()) } func (s *OrgTestSuite) TestDeleteOrganizationPoolDBDeleteErr() { @@ -831,7 +831,7 @@ func (s *OrgTestSuite) TestDeleteOrganizationPoolDBDeleteErr() { err = s.StoreSQLMocked.DeleteEntityPool(s.adminCtx, entity, pool.ID) s.Require().NotNil(err) - s.Require().Equal("removing pool: mocked deleting pool error", err.Error()) + s.Require().Equal("error removing pool: mocked deleting pool error", err.Error()) s.assertSQLMockExpectations() } @@ -866,7 +866,7 @@ func (s *OrgTestSuite) TestListOrgInstancesInvalidOrgID() { _, err := s.Store.ListEntityInstances(s.adminCtx, entity) s.Require().NotNil(err) - s.Require().Equal("fetching entity: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching entity: error parsing id: invalid request", err.Error()) } func (s *OrgTestSuite) TestUpdateOrganizationPool() { @@ -916,7 +916,7 @@ func (s *OrgTestSuite) TestUpdateOrganizationPoolInvalidOrgID() { _, err := s.Store.UpdateEntityPool(s.adminCtx, entity, "dummy-pool-id", s.Fixtures.UpdatePoolParams) s.Require().NotNil(err) - s.Require().Equal("fetching pool: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching pool: error parsing id: invalid request", err.Error()) } func TestOrgTestSuite(t *testing.T) { diff --git a/database/sql/pools.go b/database/sql/pools.go index 889cbc58..e873a150 100644 --- a/database/sql/pools.go +++ b/database/sql/pools.go @@ -16,10 +16,10 @@ package sql import ( "context" + "errors" "fmt" "github.com/google/uuid" - "github.com/pkg/errors" "gorm.io/datatypes" "gorm.io/gorm" @@ -48,7 +48,7 @@ func (s *sqlDatabase) ListAllPools(_ context.Context) ([]params.Pool, error) { Omit("extra_specs"). Find(&pools) if q.Error != nil { - return nil, errors.Wrap(q.Error, "fetching all pools") + return nil, fmt.Errorf("error fetching all pools: %w", q.Error) } ret := make([]params.Pool, len(pools)) @@ -56,7 +56,7 @@ func (s *sqlDatabase) ListAllPools(_ context.Context) ([]params.Pool, error) { for idx, val := range pools { ret[idx], err = s.sqlToCommonPool(val) if err != nil { - return nil, errors.Wrap(err, "converting pool") + return nil, fmt.Errorf("error converting pool: %w", err) } } return ret, nil @@ -75,7 +75,7 @@ func (s *sqlDatabase) GetPoolByID(_ context.Context, poolID string) (params.Pool } pool, err := s.getPoolByID(s.conn, poolID, preloadList...) if err != nil { - return params.Pool{}, errors.Wrap(err, "fetching pool by ID") + return params.Pool{}, fmt.Errorf("error fetching pool by ID: %w", err) } return s.sqlToCommonPool(pool) } @@ -83,7 +83,7 @@ func (s *sqlDatabase) GetPoolByID(_ context.Context, poolID string) (params.Pool func (s *sqlDatabase) DeletePoolByID(_ context.Context, poolID string) (err error) { pool, err := s.getPoolByID(s.conn, poolID) if err != nil { - return errors.Wrap(err, "fetching pool by ID") + return fmt.Errorf("error fetching pool by ID: %w", err) } defer func() { @@ -93,7 +93,7 @@ func (s *sqlDatabase) DeletePoolByID(_ context.Context, poolID string) (err erro }() if q := s.conn.Unscoped().Delete(&pool); q.Error != nil { - return errors.Wrap(q.Error, "removing pool") + return fmt.Errorf("error removing pool: %w", q.Error) } return nil @@ -101,12 +101,12 @@ func (s *sqlDatabase) DeletePoolByID(_ context.Context, poolID string) (err erro func (s *sqlDatabase) getEntityPool(tx *gorm.DB, entityType params.ForgeEntityType, entityID, poolID string, preload ...string) (Pool, error) { if entityID == "" { - return Pool{}, errors.Wrap(runnerErrors.ErrBadRequest, "missing entity id") + return Pool{}, fmt.Errorf("error missing entity id: %w", runnerErrors.ErrBadRequest) } u, err := uuid.Parse(poolID) if err != nil { - return Pool{}, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return Pool{}, fmt.Errorf("error parsing id: %w", runnerErrors.ErrBadRequest) } var fieldName string @@ -140,9 +140,9 @@ func (s *sqlDatabase) getEntityPool(tx *gorm.DB, entityType params.ForgeEntityTy First(&pool).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return Pool{}, errors.Wrap(runnerErrors.ErrNotFound, "finding pool") + return Pool{}, fmt.Errorf("error finding pool: %w", runnerErrors.ErrNotFound) } - return Pool{}, errors.Wrap(err, "fetching pool") + return Pool{}, fmt.Errorf("error fetching pool: %w", err) } return pool, nil @@ -150,11 +150,11 @@ func (s *sqlDatabase) getEntityPool(tx *gorm.DB, entityType params.ForgeEntityTy func (s *sqlDatabase) listEntityPools(tx *gorm.DB, entityType params.ForgeEntityType, entityID string, preload ...string) ([]Pool, error) { if _, err := uuid.Parse(entityID); err != nil { - return nil, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return nil, fmt.Errorf("error parsing id: %w", runnerErrors.ErrBadRequest) } if err := s.hasGithubEntity(tx, entityType, entityID); err != nil { - return nil, errors.Wrap(err, "checking entity existence") + return nil, fmt.Errorf("error checking entity existence: %w", err) } var preloadEntity string @@ -191,7 +191,7 @@ func (s *sqlDatabase) listEntityPools(tx *gorm.DB, entityType params.ForgeEntity if errors.Is(err, gorm.ErrRecordNotFound) { return []Pool{}, nil } - return nil, errors.Wrap(err, "fetching pool") + return nil, fmt.Errorf("error fetching pool: %w", err) } return pools, nil @@ -203,7 +203,7 @@ func (s *sqlDatabase) findPoolByTags(id string, poolType params.ForgeEntityType, } u, err := uuid.Parse(id) if err != nil { - return nil, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return nil, fmt.Errorf("error parsing id: %w", runnerErrors.ErrBadRequest) } var fieldName string @@ -233,7 +233,7 @@ func (s *sqlDatabase) findPoolByTags(id string, poolType params.ForgeEntityType, if errors.Is(q.Error, gorm.ErrRecordNotFound) { return nil, runnerErrors.ErrNotFound } - return nil, errors.Wrap(q.Error, "fetching pool") + return nil, fmt.Errorf("error fetching pool: %w", q.Error) } if len(pools) == 0 { @@ -244,7 +244,7 @@ func (s *sqlDatabase) findPoolByTags(id string, poolType params.ForgeEntityType, for idx, val := range pools { ret[idx], err = s.sqlToCommonPool(val) if err != nil { - return nil, errors.Wrap(err, "converting pool") + return nil, fmt.Errorf("error converting pool: %w", err) } } @@ -261,7 +261,7 @@ func (s *sqlDatabase) FindPoolsMatchingAllTags(_ context.Context, entityType par if errors.Is(err, runnerErrors.ErrNotFound) { return []params.Pool{}, nil } - return nil, errors.Wrap(err, "fetching pools") + return nil, fmt.Errorf("error fetching pools: %w", err) } return pools, nil @@ -298,7 +298,7 @@ func (s *sqlDatabase) CreateEntityPool(_ context.Context, entity params.ForgeEnt entityID, err := uuid.Parse(entity.ID) if err != nil { - return params.Pool{}, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return params.Pool{}, fmt.Errorf("error parsing id: %w", runnerErrors.ErrBadRequest) } switch entity.EntityType { @@ -311,26 +311,26 @@ func (s *sqlDatabase) CreateEntityPool(_ context.Context, entity params.ForgeEnt } err = s.conn.Transaction(func(tx *gorm.DB) error { if err := s.hasGithubEntity(tx, entity.EntityType, entity.ID); err != nil { - return errors.Wrap(err, "checking entity existence") + return fmt.Errorf("error checking entity existence: %w", err) } tags := []Tag{} for _, val := range param.Tags { t, err := s.getOrCreateTag(tx, val) if err != nil { - return errors.Wrap(err, "creating tag") + return fmt.Errorf("error creating tag: %w", err) } tags = append(tags, t) } q := tx.Create(&newPool) if q.Error != nil { - return errors.Wrap(q.Error, "creating pool") + return fmt.Errorf("error creating pool: %w", q.Error) } for i := range tags { if err := tx.Model(&newPool).Association("Tags").Append(&tags[i]); err != nil { - return errors.Wrap(err, "associating tags") + return fmt.Errorf("error associating tags: %w", err) } } return nil @@ -341,7 +341,7 @@ func (s *sqlDatabase) CreateEntityPool(_ context.Context, entity params.ForgeEnt dbPool, err := s.getPoolByID(s.conn, newPool.ID.String(), "Tags", "Instances", "Enterprise", "Organization", "Repository") if err != nil { - return params.Pool{}, errors.Wrap(err, "fetching pool") + return params.Pool{}, fmt.Errorf("error fetching pool: %w", err) } return s.sqlToCommonPool(dbPool) @@ -358,7 +358,7 @@ func (s *sqlDatabase) GetEntityPool(_ context.Context, entity params.ForgeEntity func (s *sqlDatabase) DeleteEntityPool(_ context.Context, entity params.ForgeEntity, poolID string) (err error) { entityID, err := uuid.Parse(entity.ID) if err != nil { - return errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return fmt.Errorf("error parsing id: %w", runnerErrors.ErrBadRequest) } defer func() { @@ -372,7 +372,7 @@ func (s *sqlDatabase) DeleteEntityPool(_ context.Context, entity params.ForgeEnt poolUUID, err := uuid.Parse(poolID) if err != nil { - return errors.Wrap(runnerErrors.ErrBadRequest, "parsing pool id") + return fmt.Errorf("error parsing pool id: %w", runnerErrors.ErrBadRequest) } var fieldName string switch entity.EntityType { @@ -387,7 +387,7 @@ func (s *sqlDatabase) DeleteEntityPool(_ context.Context, entity params.ForgeEnt } condition := fmt.Sprintf("id = ? and %s = ?", fieldName) if err := s.conn.Unscoped().Where(condition, poolUUID, entityID).Delete(&Pool{}).Error; err != nil { - return errors.Wrap(err, "removing pool") + return fmt.Errorf("error removing pool: %w", err) } return nil } @@ -401,12 +401,12 @@ func (s *sqlDatabase) UpdateEntityPool(ctx context.Context, entity params.ForgeE err = s.conn.Transaction(func(tx *gorm.DB) error { pool, err := s.getEntityPool(tx, entity.EntityType, entity.ID, poolID, "Tags", "Instances") if err != nil { - return errors.Wrap(err, "fetching pool") + return fmt.Errorf("error fetching pool: %w", err) } updatedPool, err = s.updatePool(tx, pool, param) if err != nil { - return errors.Wrap(err, "updating pool") + return fmt.Errorf("error updating pool: %w", err) } return nil }) @@ -424,14 +424,14 @@ func (s *sqlDatabase) UpdateEntityPool(ctx context.Context, entity params.ForgeE func (s *sqlDatabase) ListEntityPools(_ context.Context, entity params.ForgeEntity) ([]params.Pool, error) { pools, err := s.listEntityPools(s.conn, entity.EntityType, entity.ID, "Tags") if err != nil { - return nil, errors.Wrap(err, "fetching pools") + return nil, fmt.Errorf("error fetching pools: %w", err) } ret := make([]params.Pool, len(pools)) for idx, pool := range pools { ret[idx], err = s.sqlToCommonPool(pool) if err != nil { - return nil, errors.Wrap(err, "fetching pool") + return nil, fmt.Errorf("error fetching pool: %w", err) } } @@ -441,7 +441,7 @@ func (s *sqlDatabase) ListEntityPools(_ context.Context, entity params.ForgeEnti func (s *sqlDatabase) ListEntityInstances(_ context.Context, entity params.ForgeEntity) ([]params.Instance, error) { pools, err := s.listEntityPools(s.conn, entity.EntityType, entity.ID, "Instances", "Instances.Job") if err != nil { - return nil, errors.Wrap(err, "fetching entity") + return nil, fmt.Errorf("error fetching entity: %w", err) } ret := []params.Instance{} for _, pool := range pools { @@ -451,7 +451,7 @@ func (s *sqlDatabase) ListEntityInstances(_ context.Context, entity params.Forge instance.Pool = pool paramsInstance, err := s.sqlToParamsInstance(instance) if err != nil { - return nil, errors.Wrap(err, "fetching instance") + return nil, fmt.Errorf("error fetching instance: %w", err) } ret = append(ret, paramsInstance) } diff --git a/database/sql/pools_test.go b/database/sql/pools_test.go index 9044bf18..297f4cdf 100644 --- a/database/sql/pools_test.go +++ b/database/sql/pools_test.go @@ -157,7 +157,7 @@ func (s *PoolsTestSuite) TestListAllPoolsDBFetchErr() { s.assertSQLMockExpectations() s.Require().NotNil(err) - s.Require().Equal("fetching all pools: mocked fetching all pools error", err.Error()) + s.Require().Equal("error fetching all pools: mocked fetching all pools error", err.Error()) } func (s *PoolsTestSuite) TestGetPoolByID() { @@ -171,7 +171,7 @@ func (s *PoolsTestSuite) TestGetPoolByIDInvalidPoolID() { _, err := s.Store.GetPoolByID(s.adminCtx, "dummy-pool-id") s.Require().NotNil(err) - s.Require().Equal("fetching pool by ID: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching pool by ID: error parsing id: invalid request", err.Error()) } func (s *PoolsTestSuite) TestDeletePoolByID() { @@ -179,14 +179,14 @@ func (s *PoolsTestSuite) TestDeletePoolByID() { s.Require().Nil(err) _, err = s.Store.GetPoolByID(s.adminCtx, s.Fixtures.Pools[0].ID) - s.Require().Equal("fetching pool by ID: not found", err.Error()) + s.Require().Equal("error fetching pool by ID: not found", err.Error()) } func (s *PoolsTestSuite) TestDeletePoolByIDInvalidPoolID() { err := s.Store.DeletePoolByID(s.adminCtx, "dummy-pool-id") s.Require().NotNil(err) - s.Require().Equal("fetching pool by ID: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching pool by ID: error parsing id: invalid request", err.Error()) } func (s *PoolsTestSuite) TestDeletePoolByIDDBRemoveErr() { @@ -204,7 +204,7 @@ func (s *PoolsTestSuite) TestDeletePoolByIDDBRemoveErr() { s.assertSQLMockExpectations() s.Require().NotNil(err) - s.Require().Equal("removing pool: mocked removing pool error", err.Error()) + s.Require().Equal("error removing pool: mocked removing pool error", err.Error()) } func (s *PoolsTestSuite) TestEntityPoolOperations() { diff --git a/database/sql/repositories.go b/database/sql/repositories.go index a18eb001..72b535e8 100644 --- a/database/sql/repositories.go +++ b/database/sql/repositories.go @@ -16,11 +16,11 @@ package sql import ( "context" + "errors" "fmt" "log/slog" "github.com/google/uuid" - "github.com/pkg/errors" "gorm.io/gorm" runnerErrors "github.com/cloudbase/garm-provider-common/errors" @@ -57,23 +57,23 @@ func (s *sqlDatabase) CreateRepository(ctx context.Context, owner, name string, case params.GiteaEndpointType: newRepo.GiteaCredentialsID = &credentials.ID default: - return errors.Wrap(runnerErrors.ErrBadRequest, "unsupported credentials type") + return runnerErrors.NewBadRequestError("unsupported credentials type") } newRepo.EndpointName = &credentials.Endpoint.Name q := tx.Create(&newRepo) if q.Error != nil { - return errors.Wrap(q.Error, "creating repository") + return fmt.Errorf("error creating repository: %w", q.Error) } return nil }) if err != nil { - return params.Repository{}, errors.Wrap(err, "creating repository") + return params.Repository{}, fmt.Errorf("error creating repository: %w", err) } ret, err := s.GetRepositoryByID(ctx, newRepo.ID.String()) if err != nil { - return params.Repository{}, errors.Wrap(err, "creating repository") + return params.Repository{}, fmt.Errorf("error creating repository: %w", err) } return ret, nil @@ -82,12 +82,12 @@ func (s *sqlDatabase) CreateRepository(ctx context.Context, owner, name string, func (s *sqlDatabase) GetRepository(ctx context.Context, owner, name, endpointName string) (params.Repository, error) { repo, err := s.getRepo(ctx, owner, name, endpointName) if err != nil { - return params.Repository{}, errors.Wrap(err, "fetching repo") + return params.Repository{}, fmt.Errorf("error fetching repo: %w", err) } param, err := s.sqlToCommonRepository(repo, true) if err != nil { - return params.Repository{}, errors.Wrap(err, "fetching repo") + return params.Repository{}, fmt.Errorf("error fetching repo: %w", err) } return param, nil @@ -112,7 +112,7 @@ func (s *sqlDatabase) ListRepositories(_ context.Context, filter params.Reposito } q = q.Find(&repos) if q.Error != nil { - return []params.Repository{}, errors.Wrap(q.Error, "fetching user from database") + return []params.Repository{}, fmt.Errorf("error fetching user from database: %w", q.Error) } ret := make([]params.Repository, len(repos)) @@ -120,7 +120,7 @@ func (s *sqlDatabase) ListRepositories(_ context.Context, filter params.Reposito var err error ret[idx], err = s.sqlToCommonRepository(val, true) if err != nil { - return nil, errors.Wrap(err, "fetching repositories") + return nil, fmt.Errorf("error fetching repositories: %w", err) } } @@ -130,7 +130,7 @@ func (s *sqlDatabase) ListRepositories(_ context.Context, filter params.Reposito func (s *sqlDatabase) DeleteRepository(ctx context.Context, repoID string) (err error) { repo, err := s.getRepoByID(ctx, s.conn, repoID, "Endpoint", "Credentials", "Credentials.Endpoint", "GiteaCredentials", "GiteaCredentials.Endpoint") if err != nil { - return errors.Wrap(err, "fetching repo") + return fmt.Errorf("error fetching repo: %w", err) } defer func(repo Repository) { @@ -146,7 +146,7 @@ func (s *sqlDatabase) DeleteRepository(ctx context.Context, repoID string) (err q := s.conn.Unscoped().Delete(&repo) if q.Error != nil && !errors.Is(q.Error, gorm.ErrRecordNotFound) { - return errors.Wrap(q.Error, "deleting repo") + return fmt.Errorf("error deleting repo: %w", q.Error) } return nil @@ -164,23 +164,23 @@ func (s *sqlDatabase) UpdateRepository(ctx context.Context, repoID string, param var err error repo, err = s.getRepoByID(ctx, tx, repoID) if err != nil { - return errors.Wrap(err, "fetching repo") + return fmt.Errorf("error fetching repo: %w", err) } if repo.EndpointName == nil { - return errors.Wrap(runnerErrors.ErrUnprocessable, "repository has no endpoint") + return runnerErrors.NewUnprocessableError("repository has no endpoint") } if param.CredentialsName != "" { creds, err = s.getGithubCredentialsByName(ctx, tx, param.CredentialsName, false) if err != nil { - return errors.Wrap(err, "fetching credentials") + return fmt.Errorf("error fetching credentials: %w", err) } if creds.EndpointName == nil { - return errors.Wrap(runnerErrors.ErrUnprocessable, "credentials have no endpoint") + return runnerErrors.NewUnprocessableError("credentials have no endpoint") } if *creds.EndpointName != *repo.EndpointName { - return errors.Wrap(runnerErrors.ErrBadRequest, "endpoint mismatch") + return runnerErrors.NewBadRequestError("endpoint mismatch") } repo.CredentialsID = &creds.ID } @@ -199,23 +199,23 @@ func (s *sqlDatabase) UpdateRepository(ctx context.Context, repoID string, param q := tx.Save(&repo) if q.Error != nil { - return errors.Wrap(q.Error, "saving repo") + return fmt.Errorf("error saving repo: %w", q.Error) } return nil }) if err != nil { - return params.Repository{}, errors.Wrap(err, "saving repo") + return params.Repository{}, fmt.Errorf("error saving repo: %w", err) } repo, err = s.getRepoByID(ctx, s.conn, repoID, "Endpoint", "Credentials", "Credentials.Endpoint", "GiteaCredentials", "GiteaCredentials.Endpoint") if err != nil { - return params.Repository{}, errors.Wrap(err, "updating enterprise") + return params.Repository{}, fmt.Errorf("error updating enterprise: %w", err) } newParams, err = s.sqlToCommonRepository(repo, true) if err != nil { - return params.Repository{}, errors.Wrap(err, "saving repo") + return params.Repository{}, fmt.Errorf("error saving repo: %w", err) } return newParams, nil } @@ -232,12 +232,12 @@ func (s *sqlDatabase) GetRepositoryByID(ctx context.Context, repoID string) (par } repo, err := s.getRepoByID(ctx, s.conn, repoID, preloadList...) if err != nil { - return params.Repository{}, errors.Wrap(err, "fetching repo") + return params.Repository{}, fmt.Errorf("error fetching repo: %w", err) } param, err := s.sqlToCommonRepository(repo, true) if err != nil { - return params.Repository{}, errors.Wrap(err, "fetching repo") + return params.Repository{}, fmt.Errorf("error fetching repo: %w", err) } return param, nil } @@ -259,7 +259,7 @@ func (s *sqlDatabase) getRepo(_ context.Context, owner, name, endpointName strin if errors.Is(q.Error, gorm.ErrRecordNotFound) { return Repository{}, runnerErrors.ErrNotFound } - return Repository{}, errors.Wrap(q.Error, "fetching repository from database") + return Repository{}, fmt.Errorf("error fetching repository from database: %w", q.Error) } return repo, nil } @@ -267,7 +267,7 @@ func (s *sqlDatabase) getRepo(_ context.Context, owner, name, endpointName strin func (s *sqlDatabase) getRepoByID(_ context.Context, tx *gorm.DB, id string, preload ...string) (Repository, error) { u, err := uuid.Parse(id) if err != nil { - return Repository{}, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return Repository{}, runnerErrors.NewBadRequestError("error parsing id: %s", err) } var repo Repository @@ -283,7 +283,7 @@ func (s *sqlDatabase) getRepoByID(_ context.Context, tx *gorm.DB, id string, pre if errors.Is(q.Error, gorm.ErrRecordNotFound) { return Repository{}, runnerErrors.ErrNotFound } - return Repository{}, errors.Wrap(q.Error, "fetching repository from database") + return Repository{}, fmt.Errorf("error fetching repository from database: %w", q.Error) } return repo, nil } diff --git a/database/sql/repositories_test.go b/database/sql/repositories_test.go index 4609a357..31591e89 100644 --- a/database/sql/repositories_test.go +++ b/database/sql/repositories_test.go @@ -284,7 +284,7 @@ func (s *RepoTestSuite) TestCreateRepositoryInvalidForgeType() { ) s.Require().NotNil(err) - s.Require().Equal("creating repository: unsupported credentials type: invalid request", err.Error()) + s.Require().Equal("error creating repository: unsupported credentials type", err.Error()) } func (s *RepoTestSuite) TestCreateRepositoryInvalidDBPassphrase() { @@ -330,7 +330,7 @@ func (s *RepoTestSuite) TestCreateRepositoryInvalidDBCreateErr() { ) s.Require().NotNil(err) - s.Require().Equal("creating repository: creating repository: creating repo mock error", err.Error()) + s.Require().Equal("error creating repository: error creating repository: creating repo mock error", err.Error()) s.assertSQLMockExpectations() } @@ -355,7 +355,7 @@ func (s *RepoTestSuite) TestGetRepositoryNotFound() { _, err := s.Store.GetRepository(s.adminCtx, "dummy-owner", "dummy-name", "github.com") s.Require().NotNil(err) - s.Require().Equal("fetching repo: not found", err.Error()) + s.Require().Equal("error fetching repo: not found", err.Error()) } func (s *RepoTestSuite) TestGetRepositoryDBDecryptingErr() { @@ -371,7 +371,7 @@ func (s *RepoTestSuite) TestGetRepositoryDBDecryptingErr() { _, err := s.StoreSQLMocked.GetRepository(s.adminCtx, s.Fixtures.Repos[0].Owner, s.Fixtures.Repos[0].Name, s.Fixtures.Repos[0].Endpoint.Name) s.Require().NotNil(err) - s.Require().Equal("fetching repo: missing secret", err.Error()) + s.Require().Equal("error fetching repo: missing secret", err.Error()) s.assertSQLMockExpectations() } @@ -471,7 +471,7 @@ func (s *RepoTestSuite) TestListRepositoriesDBFetchErr() { _, err := s.StoreSQLMocked.ListRepositories(s.adminCtx, params.RepositoryFilter{}) s.Require().NotNil(err) - s.Require().Equal("fetching user from database: fetching user from database mock error", err.Error()) + s.Require().Equal("error fetching user from database: fetching user from database mock error", err.Error()) s.assertSQLMockExpectations() } @@ -485,7 +485,7 @@ func (s *RepoTestSuite) TestListRepositoriesDBDecryptingErr() { _, err := s.StoreSQLMocked.ListRepositories(s.adminCtx, params.RepositoryFilter{}) s.Require().NotNil(err) - s.Require().Equal("fetching repositories: decrypting secret: invalid passphrase length (expected length 32 characters)", err.Error()) + s.Require().Equal("error fetching repositories: error decrypting secret: invalid passphrase length (expected length 32 characters)", err.Error()) s.assertSQLMockExpectations() } @@ -495,14 +495,14 @@ func (s *RepoTestSuite) TestDeleteRepository() { s.Require().Nil(err) _, err = s.Store.GetRepositoryByID(s.adminCtx, s.Fixtures.Repos[0].ID) s.Require().NotNil(err) - s.Require().Equal("fetching repo: not found", err.Error()) + s.Require().Equal("error fetching repo: not found", err.Error()) } func (s *RepoTestSuite) TestDeleteRepositoryInvalidRepoID() { err := s.Store.DeleteRepository(s.adminCtx, "dummy-repo-id") s.Require().NotNil(err) - s.Require().Equal("fetching repo: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching repo: error parsing id: invalid UUID length: 13", err.Error()) } func (s *RepoTestSuite) TestDeleteRepositoryDBRemoveErr() { @@ -520,7 +520,7 @@ func (s *RepoTestSuite) TestDeleteRepositoryDBRemoveErr() { err := s.StoreSQLMocked.DeleteRepository(s.adminCtx, s.Fixtures.Repos[0].ID) s.Require().NotNil(err) - s.Require().Equal("deleting repo: mocked deleting repo error", err.Error()) + s.Require().Equal("error deleting repo: mocked deleting repo error", err.Error()) s.assertSQLMockExpectations() } @@ -536,7 +536,7 @@ func (s *RepoTestSuite) TestUpdateRepositoryInvalidRepoID() { _, err := s.Store.UpdateRepository(s.adminCtx, "dummy-repo-id", s.Fixtures.UpdateRepoParams) s.Require().NotNil(err) - s.Require().Equal("saving repo: fetching repo: parsing id: invalid request", err.Error()) + s.Require().Equal("error saving repo: error fetching repo: error parsing id: invalid UUID length: 13", err.Error()) } func (s *RepoTestSuite) TestUpdateRepositoryDBEncryptErr() { @@ -561,7 +561,7 @@ func (s *RepoTestSuite) TestUpdateRepositoryDBEncryptErr() { _, err := s.StoreSQLMocked.UpdateRepository(s.adminCtx, s.Fixtures.Repos[0].ID, s.Fixtures.UpdateRepoParams) s.Require().NotNil(err) - s.Require().Equal("saving repo: saving repo: failed to encrypt string: invalid passphrase length (expected length 32 characters)", err.Error()) + s.Require().Equal("error saving repo: saving repo: failed to encrypt string: invalid passphrase length (expected length 32 characters)", err.Error()) s.assertSQLMockExpectations() } @@ -589,7 +589,7 @@ func (s *RepoTestSuite) TestUpdateRepositoryDBSaveErr() { _, err := s.StoreSQLMocked.UpdateRepository(s.adminCtx, s.Fixtures.Repos[0].ID, s.Fixtures.UpdateRepoParams) s.Require().NotNil(err) - s.Require().Equal("saving repo: saving repo: saving repo mock error", err.Error()) + s.Require().Equal("error saving repo: error saving repo: saving repo mock error", err.Error()) s.assertSQLMockExpectations() } @@ -616,7 +616,7 @@ func (s *RepoTestSuite) TestUpdateRepositoryDBDecryptingErr() { _, err := s.StoreSQLMocked.UpdateRepository(s.adminCtx, s.Fixtures.Repos[0].ID, s.Fixtures.UpdateRepoParams) s.Require().NotNil(err) - s.Require().Equal("saving repo: saving repo: failed to encrypt string: invalid passphrase length (expected length 32 characters)", err.Error()) + s.Require().Equal("error saving repo: saving repo: failed to encrypt string: invalid passphrase length (expected length 32 characters)", err.Error()) s.assertSQLMockExpectations() } @@ -631,7 +631,7 @@ func (s *RepoTestSuite) TestGetRepositoryByIDInvalidRepoID() { _, err := s.Store.GetRepositoryByID(s.adminCtx, "dummy-repo-id") s.Require().NotNil(err) - s.Require().Equal("fetching repo: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching repo: error parsing id: invalid UUID length: 13", err.Error()) } func (s *RepoTestSuite) TestGetRepositoryByIDDBDecryptingErr() { @@ -651,7 +651,7 @@ func (s *RepoTestSuite) TestGetRepositoryByIDDBDecryptingErr() { _, err := s.StoreSQLMocked.GetRepositoryByID(s.adminCtx, s.Fixtures.Repos[0].ID) s.Require().NotNil(err) - s.Require().Equal("fetching repo: missing secret", err.Error()) + s.Require().Equal("error fetching repo: missing secret", err.Error()) s.assertSQLMockExpectations() } @@ -690,7 +690,7 @@ func (s *RepoTestSuite) TestCreateRepositoryPoolInvalidRepoID() { _, err := s.Store.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("parsing id: invalid request", err.Error()) + s.Require().Equal("error parsing id: invalid request", err.Error()) } func (s *RepoTestSuite) TestCreateRepositoryPoolDBFetchTagErr() { @@ -709,7 +709,7 @@ func (s *RepoTestSuite) TestCreateRepositoryPoolDBFetchTagErr() { _, err = s.StoreSQLMocked.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("creating tag: fetching tag from database: mocked fetching tag error", err.Error()) + s.Require().Equal("error creating tag: error fetching tag from database: mocked fetching tag error", err.Error()) s.assertSQLMockExpectations() } @@ -738,7 +738,7 @@ func (s *RepoTestSuite) TestCreateRepositoryPoolDBAddingPoolErr() { _, err = s.StoreSQLMocked.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("creating pool: mocked adding pool error", err.Error()) + s.Require().Equal("error creating pool: mocked adding pool error", err.Error()) s.assertSQLMockExpectations() } @@ -769,7 +769,7 @@ func (s *RepoTestSuite) TestCreateRepositoryPoolDBSaveTagErr() { _, err = s.StoreSQLMocked.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("associating tags: mocked saving tag error", err.Error()) + s.Require().Equal("error associating tags: mocked saving tag error", err.Error()) s.assertSQLMockExpectations() } @@ -810,7 +810,7 @@ func (s *RepoTestSuite) TestCreateRepositoryPoolDBFetchPoolErr() { _, err = s.StoreSQLMocked.CreateEntityPool(s.adminCtx, entity, s.Fixtures.CreatePoolParams) s.Require().NotNil(err) - s.Require().Equal("fetching pool: not found", err.Error()) + s.Require().Equal("error fetching pool: not found", err.Error()) s.assertSQLMockExpectations() } @@ -841,7 +841,7 @@ func (s *RepoTestSuite) TestListRepoPoolsInvalidRepoID() { _, err := s.Store.ListEntityPools(s.adminCtx, entity) s.Require().NotNil(err) - s.Require().Equal("fetching pools: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching pools: error parsing id: invalid request", err.Error()) } func (s *RepoTestSuite) TestGetRepositoryPool() { @@ -866,7 +866,7 @@ func (s *RepoTestSuite) TestGetRepositoryPoolInvalidRepoID() { _, err := s.Store.GetEntityPool(s.adminCtx, entity, "dummy-pool-id") s.Require().NotNil(err) - s.Require().Equal("fetching pool: parsing id: invalid request", err.Error()) + s.Require().Equal("fetching pool: error parsing id: invalid request", err.Error()) } func (s *RepoTestSuite) TestDeleteRepositoryPool() { @@ -881,7 +881,7 @@ func (s *RepoTestSuite) TestDeleteRepositoryPool() { s.Require().Nil(err) _, err = s.Store.GetEntityPool(s.adminCtx, entity, pool.ID) - s.Require().Equal("fetching pool: finding pool: not found", err.Error()) + s.Require().Equal("fetching pool: error finding pool: not found", err.Error()) } func (s *RepoTestSuite) TestDeleteRepositoryPoolInvalidRepoID() { @@ -892,7 +892,7 @@ func (s *RepoTestSuite) TestDeleteRepositoryPoolInvalidRepoID() { err := s.Store.DeleteEntityPool(s.adminCtx, entity, "dummy-pool-id") s.Require().NotNil(err) - s.Require().Equal("parsing id: invalid request", err.Error()) + s.Require().Equal("error parsing id: invalid request", err.Error()) } func (s *RepoTestSuite) TestDeleteRepositoryPoolDBDeleteErr() { @@ -913,7 +913,7 @@ func (s *RepoTestSuite) TestDeleteRepositoryPoolDBDeleteErr() { err = s.StoreSQLMocked.DeleteEntityPool(s.adminCtx, entity, pool.ID) s.Require().NotNil(err) - s.Require().Equal("removing pool: mocked deleting pool error", err.Error()) + s.Require().Equal("error removing pool: mocked deleting pool error", err.Error()) s.assertSQLMockExpectations() } @@ -948,7 +948,7 @@ func (s *RepoTestSuite) TestListRepoInstancesInvalidRepoID() { _, err := s.Store.ListEntityInstances(s.adminCtx, entity) s.Require().NotNil(err) - s.Require().Equal("fetching entity: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching entity: error parsing id: invalid request", err.Error()) } func (s *RepoTestSuite) TestUpdateRepositoryPool() { @@ -976,7 +976,7 @@ func (s *RepoTestSuite) TestUpdateRepositoryPoolInvalidRepoID() { _, err := s.Store.UpdateEntityPool(s.adminCtx, entity, "dummy-repo-id", s.Fixtures.UpdatePoolParams) s.Require().NotNil(err) - s.Require().Equal("fetching pool: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching pool: error parsing id: invalid request", err.Error()) } func (s *RepoTestSuite) TestAddRepoEntityEvent() { diff --git a/database/sql/scaleset_instances.go b/database/sql/scaleset_instances.go index 61271e8b..457c99b5 100644 --- a/database/sql/scaleset_instances.go +++ b/database/sql/scaleset_instances.go @@ -16,8 +16,7 @@ package sql import ( "context" - - "github.com/pkg/errors" + "fmt" "github.com/cloudbase/garm/database/common" "github.com/cloudbase/garm/params" @@ -26,7 +25,7 @@ import ( func (s *sqlDatabase) CreateScaleSetInstance(_ context.Context, scaleSetID uint, param params.CreateInstanceParams) (instance params.Instance, err error) { scaleSet, err := s.getScaleSetByID(s.conn, scaleSetID) if err != nil { - return params.Instance{}, errors.Wrap(err, "fetching scale set") + return params.Instance{}, fmt.Errorf("error fetching scale set: %w", err) } defer func() { @@ -39,7 +38,7 @@ func (s *sqlDatabase) CreateScaleSetInstance(_ context.Context, scaleSetID uint, if len(param.JitConfiguration) > 0 { secret, err = s.marshalAndSeal(param.JitConfiguration) if err != nil { - return params.Instance{}, errors.Wrap(err, "marshalling jit config") + return params.Instance{}, fmt.Errorf("error marshalling jit config: %w", err) } } @@ -58,7 +57,7 @@ func (s *sqlDatabase) CreateScaleSetInstance(_ context.Context, scaleSetID uint, } q := s.conn.Create(&newInstance) if q.Error != nil { - return params.Instance{}, errors.Wrap(q.Error, "creating instance") + return params.Instance{}, fmt.Errorf("error creating instance: %w", q.Error) } return s.sqlToParamsInstance(newInstance) @@ -72,7 +71,7 @@ func (s *sqlDatabase) ListScaleSetInstances(_ context.Context, scalesetID uint) Where("scale_set_fk_id = ?", scalesetID) if err := query.Find(&instances); err.Error != nil { - return nil, errors.Wrap(err.Error, "fetching instances") + return nil, fmt.Errorf("error fetching instances: %w", err.Error) } var err error @@ -80,7 +79,7 @@ func (s *sqlDatabase) ListScaleSetInstances(_ context.Context, scalesetID uint) for idx, inst := range instances { ret[idx], err = s.sqlToParamsInstance(inst) if err != nil { - return nil, errors.Wrap(err, "converting instance") + return nil, fmt.Errorf("error converting instance: %w", err) } } return ret, nil diff --git a/database/sql/scalesets.go b/database/sql/scalesets.go index 4748ed66..b247b7a8 100644 --- a/database/sql/scalesets.go +++ b/database/sql/scalesets.go @@ -16,10 +16,10 @@ package sql import ( "context" + "errors" "fmt" "github.com/google/uuid" - "github.com/pkg/errors" "gorm.io/datatypes" "gorm.io/gorm" @@ -42,7 +42,7 @@ func (s *sqlDatabase) ListAllScaleSets(_ context.Context) ([]params.ScaleSet, er Omit("status_messages"). Find(&scaleSets) if q.Error != nil { - return nil, errors.Wrap(q.Error, "fetching all scale sets") + return nil, fmt.Errorf("error fetching all scale sets: %w", q.Error) } ret := make([]params.ScaleSet, len(scaleSets)) @@ -50,7 +50,7 @@ func (s *sqlDatabase) ListAllScaleSets(_ context.Context) ([]params.ScaleSet, er for idx, val := range scaleSets { ret[idx], err = s.sqlToCommonScaleSet(val) if err != nil { - return nil, errors.Wrap(err, "converting scale sets") + return nil, fmt.Errorf("error converting scale sets: %w", err) } } return ret, nil @@ -91,7 +91,7 @@ func (s *sqlDatabase) CreateEntityScaleSet(_ context.Context, entity params.Forg entityID, err := uuid.Parse(entity.ID) if err != nil { - return params.ScaleSet{}, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return params.ScaleSet{}, fmt.Errorf("error parsing id: %w", runnerErrors.ErrBadRequest) } switch entity.EntityType { @@ -104,12 +104,12 @@ func (s *sqlDatabase) CreateEntityScaleSet(_ context.Context, entity params.Forg } err = s.conn.Transaction(func(tx *gorm.DB) error { if err := s.hasGithubEntity(tx, entity.EntityType, entity.ID); err != nil { - return errors.Wrap(err, "checking entity existence") + return fmt.Errorf("error checking entity existence: %w", err) } q := tx.Create(&newScaleSet) if q.Error != nil { - return errors.Wrap(q.Error, "creating scale set") + return fmt.Errorf("error creating scale set: %w", q.Error) } return nil @@ -120,7 +120,7 @@ func (s *sqlDatabase) CreateEntityScaleSet(_ context.Context, entity params.Forg dbScaleSet, err := s.getScaleSetByID(s.conn, newScaleSet.ID, "Instances", "Enterprise", "Organization", "Repository") if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "fetching scale set") + return params.ScaleSet{}, fmt.Errorf("error fetching scale set: %w", err) } return s.sqlToCommonScaleSet(dbScaleSet) @@ -128,11 +128,11 @@ func (s *sqlDatabase) CreateEntityScaleSet(_ context.Context, entity params.Forg func (s *sqlDatabase) listEntityScaleSets(tx *gorm.DB, entityType params.ForgeEntityType, entityID string, preload ...string) ([]ScaleSet, error) { if _, err := uuid.Parse(entityID); err != nil { - return nil, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return nil, fmt.Errorf("error parsing id: %w", runnerErrors.ErrBadRequest) } if err := s.hasGithubEntity(tx, entityType, entityID); err != nil { - return nil, errors.Wrap(err, "checking entity existence") + return nil, fmt.Errorf("error checking entity existence: %w", err) } var preloadEntity string @@ -170,7 +170,7 @@ func (s *sqlDatabase) listEntityScaleSets(tx *gorm.DB, entityType params.ForgeEn if errors.Is(err, gorm.ErrRecordNotFound) { return []ScaleSet{}, nil } - return nil, errors.Wrap(err, "fetching scale sets") + return nil, fmt.Errorf("error fetching scale sets: %w", err) } return scaleSets, nil @@ -179,14 +179,14 @@ func (s *sqlDatabase) listEntityScaleSets(tx *gorm.DB, entityType params.ForgeEn func (s *sqlDatabase) ListEntityScaleSets(_ context.Context, entity params.ForgeEntity) ([]params.ScaleSet, error) { scaleSets, err := s.listEntityScaleSets(s.conn, entity.EntityType, entity.ID) if err != nil { - return nil, errors.Wrap(err, "fetching scale sets") + return nil, fmt.Errorf("error fetching scale sets: %w", err) } ret := make([]params.ScaleSet, len(scaleSets)) for idx, set := range scaleSets { ret[idx], err = s.sqlToCommonScaleSet(set) if err != nil { - return nil, errors.Wrap(err, "conbverting scale set") + return nil, fmt.Errorf("error conbverting scale set: %w", err) } } @@ -202,22 +202,22 @@ func (s *sqlDatabase) UpdateEntityScaleSet(ctx context.Context, entity params.Fo err = s.conn.Transaction(func(tx *gorm.DB) error { scaleSet, err := s.getEntityScaleSet(tx, entity.EntityType, entity.ID, scaleSetID, "Instances") if err != nil { - return errors.Wrap(err, "fetching scale set") + return fmt.Errorf("error fetching scale set: %w", err) } old, err := s.sqlToCommonScaleSet(scaleSet) if err != nil { - return errors.Wrap(err, "converting scale set") + return fmt.Errorf("error converting scale set: %w", err) } updatedScaleSet, err = s.updateScaleSet(tx, scaleSet, param) if err != nil { - return errors.Wrap(err, "updating scale set") + return fmt.Errorf("error updating scale set: %w", err) } if callback != nil { if err := callback(old, updatedScaleSet); err != nil { - return errors.Wrap(err, "executing update callback") + return fmt.Errorf("error executing update callback: %w", err) } } return nil @@ -235,11 +235,11 @@ func (s *sqlDatabase) UpdateEntityScaleSet(ctx context.Context, entity params.Fo func (s *sqlDatabase) getEntityScaleSet(tx *gorm.DB, entityType params.ForgeEntityType, entityID string, scaleSetID uint, preload ...string) (ScaleSet, error) { if entityID == "" { - return ScaleSet{}, errors.Wrap(runnerErrors.ErrBadRequest, "missing entity id") + return ScaleSet{}, fmt.Errorf("error missing entity id: %w", runnerErrors.ErrBadRequest) } if scaleSetID == 0 { - return ScaleSet{}, errors.Wrap(runnerErrors.ErrBadRequest, "missing scaleset id") + return ScaleSet{}, fmt.Errorf("error missing scaleset id: %w", runnerErrors.ErrBadRequest) } var fieldName string @@ -273,9 +273,9 @@ func (s *sqlDatabase) getEntityScaleSet(tx *gorm.DB, entityType params.ForgeEnti First(&scaleSet).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return ScaleSet{}, errors.Wrap(runnerErrors.ErrNotFound, "finding scale set") + return ScaleSet{}, fmt.Errorf("error finding scale set: %w", runnerErrors.ErrNotFound) } - return ScaleSet{}, errors.Wrap(err, "fetching scale set") + return ScaleSet{}, fmt.Errorf("error fetching scale set: %w", err) } return scaleSet, nil @@ -343,7 +343,7 @@ func (s *sqlDatabase) updateScaleSet(tx *gorm.DB, scaleSet ScaleSet, param param } if q := tx.Save(&scaleSet); q.Error != nil { - return params.ScaleSet{}, errors.Wrap(q.Error, "saving database entry") + return params.ScaleSet{}, fmt.Errorf("error saving database entry: %w", q.Error) } return s.sqlToCommonScaleSet(scaleSet) @@ -362,7 +362,7 @@ func (s *sqlDatabase) GetScaleSetByID(_ context.Context, scaleSet uint) (params. "Repository.Endpoint", ) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "fetching scale set by ID") + return params.ScaleSet{}, fmt.Errorf("error fetching scale set by ID: %w", err) } return s.sqlToCommonScaleSet(set) } @@ -377,7 +377,7 @@ func (s *sqlDatabase) DeleteScaleSetByID(_ context.Context, scaleSetID uint) (er err = s.conn.Transaction(func(tx *gorm.DB) error { dbSet, err := s.getScaleSetByID(tx, scaleSetID, "Instances", "Enterprise", "Organization", "Repository") if err != nil { - return errors.Wrap(err, "fetching scale set") + return fmt.Errorf("error fetching scale set: %w", err) } if len(dbSet.Instances) > 0 { @@ -385,16 +385,16 @@ func (s *sqlDatabase) DeleteScaleSetByID(_ context.Context, scaleSetID uint) (er } scaleSet, err = s.sqlToCommonScaleSet(dbSet) if err != nil { - return errors.Wrap(err, "converting scale set") + return fmt.Errorf("error converting scale set: %w", err) } if q := tx.Unscoped().Delete(&dbSet); q.Error != nil { - return errors.Wrap(q.Error, "deleting scale set") + return fmt.Errorf("error deleting scale set: %w", q.Error) } return nil }) if err != nil { - return errors.Wrap(err, "removing scale set") + return fmt.Errorf("error removing scale set: %w", err) } return nil } @@ -409,19 +409,19 @@ func (s *sqlDatabase) SetScaleSetLastMessageID(_ context.Context, scaleSetID uin if err := s.conn.Transaction(func(tx *gorm.DB) error { dbSet, err := s.getScaleSetByID(tx, scaleSetID, "Instances", "Enterprise", "Organization", "Repository") if err != nil { - return errors.Wrap(err, "fetching scale set") + return fmt.Errorf("error fetching scale set: %w", err) } dbSet.LastMessageID = lastMessageID if err := tx.Save(&dbSet).Error; err != nil { - return errors.Wrap(err, "saving database entry") + return fmt.Errorf("error saving database entry: %w", err) } scaleSet, err = s.sqlToCommonScaleSet(dbSet) if err != nil { - return errors.Wrap(err, "converting scale set") + return fmt.Errorf("error converting scale set: %w", err) } return nil }); err != nil { - return errors.Wrap(err, "setting last message ID") + return fmt.Errorf("error setting last message ID: %w", err) } return nil } @@ -436,19 +436,19 @@ func (s *sqlDatabase) SetScaleSetDesiredRunnerCount(_ context.Context, scaleSetI if err := s.conn.Transaction(func(tx *gorm.DB) error { dbSet, err := s.getScaleSetByID(tx, scaleSetID, "Instances", "Enterprise", "Organization", "Repository") if err != nil { - return errors.Wrap(err, "fetching scale set") + return fmt.Errorf("error fetching scale set: %w", err) } dbSet.DesiredRunnerCount = desiredRunnerCount if err := tx.Save(&dbSet).Error; err != nil { - return errors.Wrap(err, "saving database entry") + return fmt.Errorf("error saving database entry: %w", err) } scaleSet, err = s.sqlToCommonScaleSet(dbSet) if err != nil { - return errors.Wrap(err, "converting scale set") + return fmt.Errorf("error converting scale set: %w", err) } return nil }); err != nil { - return errors.Wrap(err, "setting desired runner count") + return fmt.Errorf("error setting desired runner count: %w", err) } return nil } diff --git a/database/sql/sql.go b/database/sql/sql.go index 16411364..7d1fc96c 100644 --- a/database/sql/sql.go +++ b/database/sql/sql.go @@ -16,12 +16,12 @@ package sql import ( "context" + "errors" "fmt" "log/slog" "net/url" "strings" - "github.com/pkg/errors" "gorm.io/driver/mysql" "gorm.io/driver/sqlite" "gorm.io/gorm" @@ -46,7 +46,7 @@ const ( func newDBConn(dbCfg config.Database) (conn *gorm.DB, err error) { dbType, connURI, err := dbCfg.GormParams() if err != nil { - return nil, errors.Wrap(err, "getting DB URI string") + return nil, fmt.Errorf("error getting DB URI string: %w", err) } gormConfig := &gorm.Config{} @@ -61,7 +61,7 @@ func newDBConn(dbCfg config.Database) (conn *gorm.DB, err error) { conn, err = gorm.Open(sqlite.Open(connURI), gormConfig) } if err != nil { - return nil, errors.Wrap(err, "connecting to database") + return nil, fmt.Errorf("error connecting to database: %w", err) } if dbCfg.Debug { @@ -73,11 +73,11 @@ func newDBConn(dbCfg config.Database) (conn *gorm.DB, err error) { func NewSQLDatabase(ctx context.Context, cfg config.Database) (common.Store, error) { conn, err := newDBConn(cfg) if err != nil { - return nil, errors.Wrap(err, "creating DB connection") + return nil, fmt.Errorf("error creating DB connection: %w", err) } producer, err := watcher.RegisterProducer(ctx, "sql") if err != nil { - return nil, errors.Wrap(err, "registering producer") + return nil, fmt.Errorf("error registering producer: %w", err) } db := &sqlDatabase{ conn: conn, @@ -87,7 +87,7 @@ func NewSQLDatabase(ctx context.Context, cfg config.Database) (common.Store, err } if err := db.migrateDB(); err != nil { - return nil, errors.Wrap(err, "migrating database") + return nil, fmt.Errorf("error migrating database: %w", err) } return db, nil } @@ -221,14 +221,14 @@ func (s *sqlDatabase) ensureGithubEndpoint() error { var epCount int64 if err := s.conn.Model(&GithubEndpoint{}).Count(&epCount).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(err, "counting github endpoints") + return fmt.Errorf("error counting github endpoints: %w", err) } } if epCount == 0 { if _, err := s.CreateGithubEndpoint(context.Background(), createEndpointParams); err != nil { if !errors.Is(err, runnerErrors.ErrDuplicateEntity) { - return errors.Wrap(err, "creating default github endpoint") + return fmt.Errorf("error creating default github endpoint: %w", err) } } } @@ -246,7 +246,7 @@ func (s *sqlDatabase) migrateCredentialsToDB() (err error) { // Admin user doesn't exist. This is a new deploy. Nothing to migrate. return nil } - return errors.Wrap(err, "getting admin user") + return fmt.Errorf("error getting admin user: %w", err) } // Impersonate the admin user. We're migrating from config credentials to @@ -259,7 +259,7 @@ func (s *sqlDatabase) migrateCredentialsToDB() (err error) { slog.Info("migrating credentials to DB") slog.Info("creating github endpoints table") if err := s.conn.AutoMigrate(&GithubEndpoint{}); err != nil { - return errors.Wrap(err, "migrating github endpoints") + return fmt.Errorf("error migrating github endpoints: %w", err) } defer func() { @@ -271,7 +271,7 @@ func (s *sqlDatabase) migrateCredentialsToDB() (err error) { slog.Info("creating github credentials table") if err := s.conn.AutoMigrate(&GithubCredentials{}); err != nil { - return errors.Wrap(err, "migrating github credentials") + return fmt.Errorf("error migrating github credentials: %w", err) } defer func() { @@ -291,12 +291,12 @@ func (s *sqlDatabase) migrateCredentialsToDB() (err error) { slog.Info("importing credential", "name", cred.Name) parsed, err := url.Parse(cred.BaseEndpoint()) if err != nil { - return errors.Wrap(err, "parsing base URL") + return fmt.Errorf("error parsing base URL: %w", err) } certBundle, err := cred.CACertBundle() if err != nil { - return errors.Wrap(err, "getting CA cert bundle") + return fmt.Errorf("error getting CA cert bundle: %w", err) } hostname := parsed.Hostname() createParams := params.CreateGithubEndpointParams{ @@ -312,11 +312,11 @@ func (s *sqlDatabase) migrateCredentialsToDB() (err error) { endpoint, err = s.GetGithubEndpoint(adminCtx, hostname) if err != nil { if !errors.Is(err, runnerErrors.ErrNotFound) { - return errors.Wrap(err, "getting github endpoint") + return fmt.Errorf("error getting github endpoint: %w", err) } endpoint, err = s.CreateGithubEndpoint(adminCtx, createParams) if err != nil { - return errors.Wrap(err, "creating default github endpoint") + return fmt.Errorf("error creating default github endpoint: %w", err) } } @@ -330,7 +330,7 @@ func (s *sqlDatabase) migrateCredentialsToDB() (err error) { case params.ForgeAuthTypeApp: keyBytes, err := cred.App.PrivateKeyBytes() if err != nil { - return errors.Wrap(err, "getting private key bytes") + return fmt.Errorf("error getting private key bytes: %w", err) } credParams.App = params.GithubApp{ AppID: cred.App.AppID, @@ -339,7 +339,7 @@ func (s *sqlDatabase) migrateCredentialsToDB() (err error) { } if err := credParams.App.Validate(); err != nil { - return errors.Wrap(err, "validating app credentials") + return fmt.Errorf("error validating app credentials: %w", err) } case params.ForgeAuthTypePAT: token := cred.PAT.OAuth2Token @@ -356,19 +356,19 @@ func (s *sqlDatabase) migrateCredentialsToDB() (err error) { creds, err := s.CreateGithubCredentials(adminCtx, credParams) if err != nil { - return errors.Wrap(err, "creating github credentials") + return fmt.Errorf("error creating github credentials: %w", err) } if err := s.conn.Exec("update repositories set credentials_id = ?,endpoint_name = ? where credentials_name = ?", creds.ID, creds.Endpoint.Name, creds.Name).Error; err != nil { - return errors.Wrap(err, "updating repositories") + return fmt.Errorf("error updating repositories: %w", err) } if err := s.conn.Exec("update organizations set credentials_id = ?,endpoint_name = ? where credentials_name = ?", creds.ID, creds.Endpoint.Name, creds.Name).Error; err != nil { - return errors.Wrap(err, "updating organizations") + return fmt.Errorf("error updating organizations: %w", err) } if err := s.conn.Exec("update enterprises set credentials_id = ?,endpoint_name = ? where credentials_name = ?", creds.ID, creds.Endpoint.Name, creds.Name).Error; err != nil { - return errors.Wrap(err, "updating enterprises") + return fmt.Errorf("error updating enterprises: %w", err) } } return nil @@ -380,10 +380,10 @@ func (s *sqlDatabase) migrateWorkflow() error { // Remove jobs that are not in "queued" status. We really only care about queued jobs. Once they transition // to something else, we don't really consume them anyway. if err := s.conn.Exec("delete from workflow_jobs where status is not 'queued'").Error; err != nil { - return errors.Wrap(err, "updating workflow_jobs") + return fmt.Errorf("error updating workflow_jobs: %w", err) } if err := s.conn.Migrator().DropColumn(&WorkflowJob{}, "runner_name"); err != nil { - return errors.Wrap(err, "updating workflow_jobs") + return fmt.Errorf("error updating workflow_jobs: %w", err) } } } @@ -404,34 +404,34 @@ func (s *sqlDatabase) migrateDB() error { } if err := s.cascadeMigration(); err != nil { - return errors.Wrap(err, "running cascade migration") + return fmt.Errorf("error running cascade migration: %w", err) } if s.conn.Migrator().HasTable(&Pool{}) { if err := s.conn.Exec("update pools set repo_id=NULL where repo_id='00000000-0000-0000-0000-000000000000'").Error; err != nil { - return errors.Wrap(err, "updating pools") + return fmt.Errorf("error updating pools %w", err) } if err := s.conn.Exec("update pools set org_id=NULL where org_id='00000000-0000-0000-0000-000000000000'").Error; err != nil { - return errors.Wrap(err, "updating pools") + return fmt.Errorf("error updating pools: %w", err) } if err := s.conn.Exec("update pools set enterprise_id=NULL where enterprise_id='00000000-0000-0000-0000-000000000000'").Error; err != nil { - return errors.Wrap(err, "updating pools") + return fmt.Errorf("error updating pools: %w", err) } } if err := s.migrateWorkflow(); err != nil { - return errors.Wrap(err, "migrating workflows") + return fmt.Errorf("error migrating workflows: %w", err) } if s.conn.Migrator().HasTable(&GithubEndpoint{}) { if !s.conn.Migrator().HasColumn(&GithubEndpoint{}, "endpoint_type") { if err := s.conn.Migrator().AutoMigrate(&GithubEndpoint{}); err != nil { - return errors.Wrap(err, "migrating github endpoints") + return fmt.Errorf("error migrating github endpoints: %w", err) } if err := s.conn.Exec("update github_endpoints set endpoint_type = 'github' where endpoint_type is null").Error; err != nil { - return errors.Wrap(err, "updating github endpoints") + return fmt.Errorf("error updating github endpoints: %w", err) } } } @@ -467,7 +467,7 @@ func (s *sqlDatabase) migrateDB() error { &WorkflowJob{}, &ScaleSet{}, ); err != nil { - return errors.Wrap(err, "running auto migrate") + return fmt.Errorf("error running auto migrate: %w", err) } s.conn.Exec("PRAGMA foreign_keys = ON") @@ -475,23 +475,23 @@ func (s *sqlDatabase) migrateDB() error { var controller ControllerInfo if err := s.conn.First(&controller).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(err, "updating controller info") + return fmt.Errorf("error updating controller info: %w", err) } } else { controller.MinimumJobAgeBackoff = 30 if err := s.conn.Save(&controller).Error; err != nil { - return errors.Wrap(err, "updating controller info") + return fmt.Errorf("error updating controller info: %w", err) } } } if err := s.ensureGithubEndpoint(); err != nil { - return errors.Wrap(err, "ensuring github endpoint") + return fmt.Errorf("error ensuring github endpoint: %w", err) } if needsCredentialMigration { if err := s.migrateCredentialsToDB(); err != nil { - return errors.Wrap(err, "migrating credentials") + return fmt.Errorf("error migrating credentials: %w", err) } } return nil diff --git a/database/sql/users.go b/database/sql/users.go index 7d604a83..ca78c5e8 100644 --- a/database/sql/users.go +++ b/database/sql/users.go @@ -16,9 +16,9 @@ package sql import ( "context" + "errors" "fmt" - "github.com/pkg/errors" "gorm.io/gorm" runnerErrors "github.com/cloudbase/garm-provider-common/errors" @@ -39,7 +39,7 @@ func (s *sqlDatabase) getUserByUsernameOrEmail(tx *gorm.DB, user string) (User, if errors.Is(q.Error, gorm.ErrRecordNotFound) { return User{}, runnerErrors.ErrNotFound } - return User{}, errors.Wrap(q.Error, "fetching user") + return User{}, fmt.Errorf("error fetching user: %w", q.Error) } return dbUser, nil } @@ -51,7 +51,7 @@ func (s *sqlDatabase) getUserByID(tx *gorm.DB, userID string) (User, error) { if errors.Is(q.Error, gorm.ErrRecordNotFound) { return User{}, runnerErrors.ErrNotFound } - return User{}, errors.Wrap(q.Error, "fetching user") + return User{}, fmt.Errorf("error fetching user: %w", q.Error) } return dbUser, nil } @@ -82,12 +82,12 @@ func (s *sqlDatabase) CreateUser(_ context.Context, user params.NewUserParams) ( q := tx.Save(&newUser) if q.Error != nil { - return errors.Wrap(q.Error, "creating user") + return fmt.Errorf("error creating user: %w", q.Error) } return nil }) if err != nil { - return params.User{}, errors.Wrap(err, "creating user") + return params.User{}, fmt.Errorf("error creating user: %w", err) } return s.sqlToParamsUser(newUser), nil } @@ -105,7 +105,7 @@ func (s *sqlDatabase) HasAdminUser(_ context.Context) bool { func (s *sqlDatabase) GetUser(_ context.Context, user string) (params.User, error) { dbUser, err := s.getUserByUsernameOrEmail(s.conn, user) if err != nil { - return params.User{}, errors.Wrap(err, "fetching user") + return params.User{}, fmt.Errorf("error fetching user: %w", err) } return s.sqlToParamsUser(dbUser), nil } @@ -113,7 +113,7 @@ func (s *sqlDatabase) GetUser(_ context.Context, user string) (params.User, erro func (s *sqlDatabase) GetUserByID(_ context.Context, userID string) (params.User, error) { dbUser, err := s.getUserByID(s.conn, userID) if err != nil { - return params.User{}, errors.Wrap(err, "fetching user") + return params.User{}, fmt.Errorf("error fetching user: %w", err) } return s.sqlToParamsUser(dbUser), nil } @@ -124,7 +124,7 @@ func (s *sqlDatabase) UpdateUser(_ context.Context, user string, param params.Up err = s.conn.Transaction(func(tx *gorm.DB) error { dbUser, err = s.getUserByUsernameOrEmail(tx, user) if err != nil { - return errors.Wrap(err, "fetching user") + return fmt.Errorf("error fetching user: %w", err) } if param.FullName != "" { @@ -141,12 +141,12 @@ func (s *sqlDatabase) UpdateUser(_ context.Context, user string, param params.Up } if q := tx.Save(&dbUser); q.Error != nil { - return errors.Wrap(q.Error, "saving user") + return fmt.Errorf("error saving user: %w", q.Error) } return nil }) if err != nil { - return params.User{}, errors.Wrap(err, "updating user") + return params.User{}, fmt.Errorf("error updating user: %w", err) } return s.sqlToParamsUser(dbUser), nil } @@ -159,7 +159,7 @@ func (s *sqlDatabase) GetAdminUser(_ context.Context) (params.User, error) { if errors.Is(q.Error, gorm.ErrRecordNotFound) { return params.User{}, runnerErrors.ErrNotFound } - return params.User{}, errors.Wrap(q.Error, "fetching admin user") + return params.User{}, fmt.Errorf("error fetching admin user: %w", q.Error) } return s.sqlToParamsUser(user), nil } diff --git a/database/sql/users_test.go b/database/sql/users_test.go index db24adc3..369abff3 100644 --- a/database/sql/users_test.go +++ b/database/sql/users_test.go @@ -161,7 +161,7 @@ func (s *UserTestSuite) TestCreateUserUsernameAlreadyExist() { _, err := s.Store.CreateUser(context.Background(), s.Fixtures.NewUserParams) s.Require().NotNil(err) - s.Require().Equal(("creating user: username already exists"), err.Error()) + s.Require().Equal(("error creating user: username already exists"), err.Error()) } func (s *UserTestSuite) TestCreateUserEmailAlreadyExist() { @@ -170,7 +170,7 @@ func (s *UserTestSuite) TestCreateUserEmailAlreadyExist() { _, err := s.Store.CreateUser(context.Background(), s.Fixtures.NewUserParams) s.Require().NotNil(err) - s.Require().Equal(("creating user: email already exists"), err.Error()) + s.Require().Equal(("error creating user: email already exists"), err.Error()) } func (s *UserTestSuite) TestCreateUserDBCreateErr() { @@ -191,7 +191,7 @@ func (s *UserTestSuite) TestCreateUserDBCreateErr() { _, err := s.StoreSQLMocked.CreateUser(context.Background(), s.Fixtures.NewUserParams) s.Require().NotNil(err) - s.Require().Equal("creating user: creating user: creating user mock error", err.Error()) + s.Require().Equal("error creating user: error creating user: creating user mock error", err.Error()) s.assertSQLMockExpectations() } @@ -230,7 +230,7 @@ func (s *UserTestSuite) TestGetUserNotFound() { _, err := s.Store.GetUser(context.Background(), "dummy-user") s.Require().NotNil(err) - s.Require().Equal("fetching user: not found", err.Error()) + s.Require().Equal("error fetching user: not found", err.Error()) } func (s *UserTestSuite) TestGetUserByID() { @@ -244,7 +244,7 @@ func (s *UserTestSuite) TestGetUserByIDNotFound() { _, err := s.Store.GetUserByID(context.Background(), "dummy-user-id") s.Require().NotNil(err) - s.Require().Equal("fetching user: not found", err.Error()) + s.Require().Equal("error fetching user: not found", err.Error()) } func (s *UserTestSuite) TestUpdateUser() { @@ -260,7 +260,7 @@ func (s *UserTestSuite) TestUpdateUserNotFound() { _, err := s.Store.UpdateUser(context.Background(), "dummy-user", s.Fixtures.UpdateUserParams) s.Require().NotNil(err) - s.Require().Equal("updating user: fetching user: not found", err.Error()) + s.Require().Equal("error updating user: error fetching user: not found", err.Error()) } func (s *UserTestSuite) TestUpdateUserDBSaveErr() { @@ -278,7 +278,7 @@ func (s *UserTestSuite) TestUpdateUserDBSaveErr() { s.assertSQLMockExpectations() s.Require().NotNil(err) - s.Require().Equal("updating user: saving user: saving user mock error", err.Error()) + s.Require().Equal("error updating user: error saving user: saving user mock error", err.Error()) } func TestUserTestSuite(t *testing.T) { diff --git a/database/sql/util.go b/database/sql/util.go index ebb3c57c..9509aacf 100644 --- a/database/sql/util.go +++ b/database/sql/util.go @@ -17,10 +17,10 @@ package sql import ( "context" "encoding/json" + "errors" "fmt" "github.com/google/uuid" - "github.com/pkg/errors" "gorm.io/datatypes" "gorm.io/gorm" @@ -41,14 +41,14 @@ func (s *sqlDatabase) sqlToParamsInstance(instance Instance) (params.Instance, e var labels []string if len(instance.AditionalLabels) > 0 { if err := json.Unmarshal(instance.AditionalLabels, &labels); err != nil { - return params.Instance{}, errors.Wrap(err, "unmarshalling labels") + return params.Instance{}, fmt.Errorf("error unmarshalling labels: %w", err) } } var jitConfig map[string]string if len(instance.JitConfiguration) > 0 { if err := s.unsealAndUnmarshal(instance.JitConfiguration, &jitConfig); err != nil { - return params.Instance{}, errors.Wrap(err, "unmarshalling jit configuration") + return params.Instance{}, fmt.Errorf("error unmarshalling jit configuration: %w", err) } } ret := params.Instance{ @@ -95,7 +95,7 @@ func (s *sqlDatabase) sqlToParamsInstance(instance Instance) (params.Instance, e if instance.Job != nil { paramJob, err := sqlWorkflowJobToParamsJob(*instance.Job) if err != nil { - return params.Instance{}, errors.Wrap(err, "converting job") + return params.Instance{}, fmt.Errorf("error converting job: %w", err) } ret.Job = ¶mJob } @@ -132,12 +132,12 @@ func (s *sqlDatabase) sqlToCommonOrganization(org Organization, detailed bool) ( } secret, err := util.Unseal(org.WebhookSecret, []byte(s.cfg.Passphrase)) if err != nil { - return params.Organization{}, errors.Wrap(err, "decrypting secret") + return params.Organization{}, fmt.Errorf("error decrypting secret: %w", err) } endpoint, err := s.sqlToCommonGithubEndpoint(org.Endpoint) if err != nil { - return params.Organization{}, errors.Wrap(err, "converting endpoint") + return params.Organization{}, fmt.Errorf("error converting endpoint: %w", err) } ret := params.Organization{ ID: org.ID.String(), @@ -163,7 +163,7 @@ func (s *sqlDatabase) sqlToCommonOrganization(org Organization, detailed bool) ( } if err != nil { - return params.Organization{}, errors.Wrap(err, "converting credentials") + return params.Organization{}, fmt.Errorf("error converting credentials: %w", err) } if len(org.Events) > 0 { @@ -191,7 +191,7 @@ func (s *sqlDatabase) sqlToCommonOrganization(org Organization, detailed bool) ( for idx, pool := range org.Pools { ret.Pools[idx], err = s.sqlToCommonPool(pool) if err != nil { - return params.Organization{}, errors.Wrap(err, "converting pool") + return params.Organization{}, fmt.Errorf("error converting pool: %w", err) } } @@ -204,12 +204,12 @@ func (s *sqlDatabase) sqlToCommonEnterprise(enterprise Enterprise, detailed bool } secret, err := util.Unseal(enterprise.WebhookSecret, []byte(s.cfg.Passphrase)) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "decrypting secret") + return params.Enterprise{}, fmt.Errorf("error decrypting secret: %w", err) } endpoint, err := s.sqlToCommonGithubEndpoint(enterprise.Endpoint) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "converting endpoint") + return params.Enterprise{}, fmt.Errorf("error converting endpoint: %w", err) } ret := params.Enterprise{ ID: enterprise.ID.String(), @@ -243,7 +243,7 @@ func (s *sqlDatabase) sqlToCommonEnterprise(enterprise Enterprise, detailed bool if detailed { creds, err := s.sqlToCommonForgeCredentials(enterprise.Credentials) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "converting credentials") + return params.Enterprise{}, fmt.Errorf("error converting credentials: %w", err) } ret.Credentials = creds } @@ -255,7 +255,7 @@ func (s *sqlDatabase) sqlToCommonEnterprise(enterprise Enterprise, detailed bool for idx, pool := range enterprise.Pools { ret.Pools[idx], err = s.sqlToCommonPool(pool) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "converting pool") + return params.Enterprise{}, fmt.Errorf("error converting pool: %w", err) } } @@ -309,7 +309,7 @@ func (s *sqlDatabase) sqlToCommonPool(pool Pool) (params.Pool, error) { endpoint, err := s.sqlToCommonGithubEndpoint(ep) if err != nil { - return params.Pool{}, errors.Wrap(err, "converting endpoint") + return params.Pool{}, fmt.Errorf("error converting endpoint: %w", err) } ret.Endpoint = endpoint @@ -320,7 +320,7 @@ func (s *sqlDatabase) sqlToCommonPool(pool Pool) (params.Pool, error) { for idx, inst := range pool.Instances { ret.Instances[idx], err = s.sqlToParamsInstance(inst) if err != nil { - return params.Pool{}, errors.Wrap(err, "converting instance") + return params.Pool{}, fmt.Errorf("error converting instance: %w", err) } } @@ -380,14 +380,14 @@ func (s *sqlDatabase) sqlToCommonScaleSet(scaleSet ScaleSet) (params.ScaleSet, e endpoint, err := s.sqlToCommonGithubEndpoint(ep) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "converting endpoint") + return params.ScaleSet{}, fmt.Errorf("error converting endpoint: %w", err) } ret.Endpoint = endpoint for idx, inst := range scaleSet.Instances { ret.Instances[idx], err = s.sqlToParamsInstance(inst) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "converting instance") + return params.ScaleSet{}, fmt.Errorf("error converting instance: %w", err) } } @@ -407,11 +407,11 @@ func (s *sqlDatabase) sqlToCommonRepository(repo Repository, detailed bool) (par } secret, err := util.Unseal(repo.WebhookSecret, []byte(s.cfg.Passphrase)) if err != nil { - return params.Repository{}, errors.Wrap(err, "decrypting secret") + return params.Repository{}, fmt.Errorf("error decrypting secret: %w", err) } endpoint, err := s.sqlToCommonGithubEndpoint(repo.Endpoint) if err != nil { - return params.Repository{}, errors.Wrap(err, "converting endpoint") + return params.Repository{}, fmt.Errorf("error converting endpoint: %w", err) } ret := params.Repository{ ID: repo.ID.String(), @@ -442,7 +442,7 @@ func (s *sqlDatabase) sqlToCommonRepository(repo Repository, detailed bool) (par } if err != nil { - return params.Repository{}, errors.Wrap(err, "converting credentials") + return params.Repository{}, fmt.Errorf("error converting credentials: %w", err) } if len(repo.Events) > 0 { @@ -470,7 +470,7 @@ func (s *sqlDatabase) sqlToCommonRepository(repo Repository, detailed bool) (par for idx, pool := range repo.Pools { ret.Pools[idx], err = s.sqlToCommonPool(pool) if err != nil { - return params.Repository{}, errors.Wrap(err, "converting pool") + return params.Repository{}, fmt.Errorf("error converting pool: %w", err) } } @@ -499,14 +499,14 @@ func (s *sqlDatabase) getOrCreateTag(tx *gorm.DB, tagName string) (Tag, error) { return tag, nil } if !errors.Is(q.Error, gorm.ErrRecordNotFound) { - return Tag{}, errors.Wrap(q.Error, "fetching tag from database") + return Tag{}, fmt.Errorf("error fetching tag from database: %w", q.Error) } newTag := Tag{ Name: tagName, } if err := tx.Create(&newTag).Error; err != nil { - return Tag{}, errors.Wrap(err, "creating tag") + return Tag{}, fmt.Errorf("error creating tag: %w", err) } return newTag, nil } @@ -561,7 +561,7 @@ func (s *sqlDatabase) updatePool(tx *gorm.DB, pool Pool, param params.UpdatePool } if q := tx.Save(&pool); q.Error != nil { - return params.Pool{}, errors.Wrap(q.Error, "saving database entry") + return params.Pool{}, fmt.Errorf("error saving database entry: %w", q.Error) } tags := []Tag{} @@ -569,13 +569,13 @@ func (s *sqlDatabase) updatePool(tx *gorm.DB, pool Pool, param params.UpdatePool for _, val := range param.Tags { t, err := s.getOrCreateTag(tx, val) if err != nil { - return params.Pool{}, errors.Wrap(err, "fetching tag") + return params.Pool{}, fmt.Errorf("error fetching tag: %w", err) } tags = append(tags, t) } if err := tx.Model(&pool).Association("Tags").Replace(&tags); err != nil { - return params.Pool{}, errors.Wrap(err, "replacing tags") + return params.Pool{}, fmt.Errorf("error replacing tags: %w", err) } } @@ -585,7 +585,7 @@ func (s *sqlDatabase) updatePool(tx *gorm.DB, pool Pool, param params.UpdatePool func (s *sqlDatabase) getPoolByID(tx *gorm.DB, poolID string, preload ...string) (Pool, error) { u, err := uuid.Parse(poolID) if err != nil { - return Pool{}, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return Pool{}, fmt.Errorf("error parsing id: %w", runnerErrors.ErrBadRequest) } var pool Pool q := tx.Model(&Pool{}) @@ -601,7 +601,7 @@ func (s *sqlDatabase) getPoolByID(tx *gorm.DB, poolID string, preload ...string) if errors.Is(q.Error, gorm.ErrRecordNotFound) { return Pool{}, runnerErrors.ErrNotFound } - return Pool{}, errors.Wrap(q.Error, "fetching org from database") + return Pool{}, fmt.Errorf("error fetching org from database: %w", q.Error) } return pool, nil } @@ -621,7 +621,7 @@ func (s *sqlDatabase) getScaleSetByID(tx *gorm.DB, scaleSetID uint, preload ...s if errors.Is(q.Error, gorm.ErrRecordNotFound) { return ScaleSet{}, runnerErrors.ErrNotFound } - return ScaleSet{}, errors.Wrap(q.Error, "fetching scale set from database") + return ScaleSet{}, fmt.Errorf("error fetching scale set from database: %w", q.Error) } return scaleSet, nil } @@ -629,7 +629,7 @@ func (s *sqlDatabase) getScaleSetByID(tx *gorm.DB, scaleSetID uint, preload ...s func (s *sqlDatabase) hasGithubEntity(tx *gorm.DB, entityType params.ForgeEntityType, entityID string) error { u, err := uuid.Parse(entityID) if err != nil { - return errors.Wrap(runnerErrors.ErrBadRequest, "parsing id") + return fmt.Errorf("error parsing id: %w", runnerErrors.ErrBadRequest) } var q *gorm.DB switch entityType { @@ -640,15 +640,15 @@ func (s *sqlDatabase) hasGithubEntity(tx *gorm.DB, entityType params.ForgeEntity case params.ForgeEntityTypeEnterprise: q = tx.Model(&Enterprise{}).Where("id = ?", u) default: - return errors.Wrap(runnerErrors.ErrBadRequest, "invalid entity type") + return fmt.Errorf("error invalid entity type: %w", runnerErrors.ErrBadRequest) } var entity interface{} if err := q.First(entity).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return errors.Wrap(runnerErrors.ErrNotFound, "entity not found") + return fmt.Errorf("error entity not found: %w", runnerErrors.ErrNotFound) } - return errors.Wrap(err, "fetching entity from database") + return fmt.Errorf("error fetching entity from database: %w", err) } return nil } @@ -656,7 +656,7 @@ func (s *sqlDatabase) hasGithubEntity(tx *gorm.DB, entityType params.ForgeEntity func (s *sqlDatabase) marshalAndSeal(data interface{}) ([]byte, error) { enc, err := json.Marshal(data) if err != nil { - return nil, errors.Wrap(err, "marshalling data") + return nil, fmt.Errorf("error marshalling data: %w", err) } return util.Seal(enc, []byte(s.cfg.Passphrase)) } @@ -664,10 +664,10 @@ func (s *sqlDatabase) marshalAndSeal(data interface{}) ([]byte, error) { func (s *sqlDatabase) unsealAndUnmarshal(data []byte, target interface{}) error { decrypted, err := util.Unseal(data, []byte(s.cfg.Passphrase)) if err != nil { - return errors.Wrap(err, "decrypting data") + return fmt.Errorf("error decrypting data: %w", err) } if err := json.Unmarshal(decrypted, target); err != nil { - return errors.Wrap(err, "unmarshalling data") + return fmt.Errorf("error unmarshalling data: %w", err) } return nil } @@ -699,15 +699,15 @@ func (s *sqlDatabase) GetForgeEntity(_ context.Context, entityType params.ForgeE case params.ForgeEntityTypeRepository: ghEntity, err = s.GetRepositoryByID(s.ctx, entityID) default: - return params.ForgeEntity{}, errors.Wrap(runnerErrors.ErrBadRequest, "invalid entity type") + return params.ForgeEntity{}, fmt.Errorf("error invalid entity type: %w", runnerErrors.ErrBadRequest) } if err != nil { - return params.ForgeEntity{}, errors.Wrap(err, "failed to get ") + return params.ForgeEntity{}, fmt.Errorf("error failed to get entity from db: %w", err) } entity, err := ghEntity.GetEntity() if err != nil { - return params.ForgeEntity{}, errors.Wrap(err, "failed to get entity") + return params.ForgeEntity{}, fmt.Errorf("error failed to get entity: %w", err) } return entity, nil } @@ -715,7 +715,7 @@ func (s *sqlDatabase) GetForgeEntity(_ context.Context, entityType params.ForgeE func (s *sqlDatabase) addRepositoryEvent(ctx context.Context, repoID string, event params.EventType, eventLevel params.EventLevel, statusMessage string, maxEvents int) error { repo, err := s.getRepoByID(ctx, s.conn, repoID) if err != nil { - return errors.Wrap(err, "updating instance") + return fmt.Errorf("error updating instance: %w", err) } msg := RepositoryEvent{ @@ -725,7 +725,7 @@ func (s *sqlDatabase) addRepositoryEvent(ctx context.Context, repoID string, eve } if err := s.conn.Model(&repo).Association("Events").Append(&msg); err != nil { - return errors.Wrap(err, "adding status message") + return fmt.Errorf("error adding status message: %w", err) } if maxEvents > 0 { @@ -734,12 +734,12 @@ func (s *sqlDatabase) addRepositoryEvent(ctx context.Context, repoID string, eve Limit(maxEvents).Order("id desc"). Where("repo_id = ?", repo.ID).Find(&latestEvents) if q.Error != nil { - return errors.Wrap(q.Error, "fetching latest events") + return fmt.Errorf("error fetching latest events: %w", q.Error) } if len(latestEvents) == maxEvents { lastInList := latestEvents[len(latestEvents)-1] if err := s.conn.Where("repo_id = ? and id < ?", repo.ID, lastInList.ID).Unscoped().Delete(&RepositoryEvent{}).Error; err != nil { - return errors.Wrap(err, "deleting old events") + return fmt.Errorf("error deleting old events: %w", err) } } } @@ -749,7 +749,7 @@ func (s *sqlDatabase) addRepositoryEvent(ctx context.Context, repoID string, eve func (s *sqlDatabase) addOrgEvent(ctx context.Context, orgID string, event params.EventType, eventLevel params.EventLevel, statusMessage string, maxEvents int) error { org, err := s.getOrgByID(ctx, s.conn, orgID) if err != nil { - return errors.Wrap(err, "updating instance") + return fmt.Errorf("error updating instance: %w", err) } msg := OrganizationEvent{ @@ -759,7 +759,7 @@ func (s *sqlDatabase) addOrgEvent(ctx context.Context, orgID string, event param } if err := s.conn.Model(&org).Association("Events").Append(&msg); err != nil { - return errors.Wrap(err, "adding status message") + return fmt.Errorf("error adding status message: %w", err) } if maxEvents > 0 { @@ -768,12 +768,12 @@ func (s *sqlDatabase) addOrgEvent(ctx context.Context, orgID string, event param Limit(maxEvents).Order("id desc"). Where("org_id = ?", org.ID).Find(&latestEvents) if q.Error != nil { - return errors.Wrap(q.Error, "fetching latest events") + return fmt.Errorf("error fetching latest events: %w", q.Error) } if len(latestEvents) == maxEvents { lastInList := latestEvents[len(latestEvents)-1] if err := s.conn.Where("org_id = ? and id < ?", org.ID, lastInList.ID).Unscoped().Delete(&OrganizationEvent{}).Error; err != nil { - return errors.Wrap(err, "deleting old events") + return fmt.Errorf("error deleting old events: %w", err) } } } @@ -783,7 +783,7 @@ func (s *sqlDatabase) addOrgEvent(ctx context.Context, orgID string, event param func (s *sqlDatabase) addEnterpriseEvent(ctx context.Context, entID string, event params.EventType, eventLevel params.EventLevel, statusMessage string, maxEvents int) error { ent, err := s.getEnterpriseByID(ctx, s.conn, entID) if err != nil { - return errors.Wrap(err, "updating instance") + return fmt.Errorf("error updating instance: %w", err) } msg := EnterpriseEvent{ @@ -793,7 +793,7 @@ func (s *sqlDatabase) addEnterpriseEvent(ctx context.Context, entID string, even } if err := s.conn.Model(&ent).Association("Events").Append(&msg); err != nil { - return errors.Wrap(err, "adding status message") + return fmt.Errorf("error adding status message: %w", err) } if maxEvents > 0 { @@ -802,12 +802,12 @@ func (s *sqlDatabase) addEnterpriseEvent(ctx context.Context, entID string, even Limit(maxEvents).Order("id desc"). Where("enterprise_id = ?", ent.ID).Find(&latestEvents) if q.Error != nil { - return errors.Wrap(q.Error, "fetching latest events") + return fmt.Errorf("error fetching latest events: %w", q.Error) } if len(latestEvents) == maxEvents { lastInList := latestEvents[len(latestEvents)-1] if err := s.conn.Where("enterprise_id = ? and id < ?", ent.ID, lastInList.ID).Unscoped().Delete(&EnterpriseEvent{}).Error; err != nil { - return errors.Wrap(err, "deleting old events") + return fmt.Errorf("error deleting old events: %w", err) } } } @@ -817,7 +817,7 @@ func (s *sqlDatabase) addEnterpriseEvent(ctx context.Context, entID string, even func (s *sqlDatabase) AddEntityEvent(ctx context.Context, entity params.ForgeEntity, event params.EventType, eventLevel params.EventLevel, statusMessage string, maxEvents int) error { if maxEvents == 0 { - return errors.Wrap(runnerErrors.ErrBadRequest, "max events cannot be 0") + return fmt.Errorf("max events cannot be 0: %w", runnerErrors.ErrBadRequest) } switch entity.EntityType { @@ -828,7 +828,7 @@ func (s *sqlDatabase) AddEntityEvent(ctx context.Context, entity params.ForgeEnt case params.ForgeEntityTypeEnterprise: return s.addEnterpriseEvent(ctx, entity.ID, event, eventLevel, statusMessage, maxEvents) default: - return errors.Wrap(runnerErrors.ErrBadRequest, "invalid entity type") + return fmt.Errorf("invalid entity type: %w", runnerErrors.ErrBadRequest) } } @@ -838,12 +838,12 @@ func (s *sqlDatabase) sqlToCommonForgeCredentials(creds GithubCredentials) (para } data, err := util.Unseal(creds.Payload, []byte(s.cfg.Passphrase)) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "unsealing credentials") + return params.ForgeCredentials{}, fmt.Errorf("error unsealing credentials: %w", err) } ep, err := s.sqlToCommonGithubEndpoint(creds.Endpoint) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "converting github endpoint") + return params.ForgeCredentials{}, fmt.Errorf("error converting github endpoint: %w", err) } commonCreds := params.ForgeCredentials{ @@ -865,7 +865,7 @@ func (s *sqlDatabase) sqlToCommonForgeCredentials(creds GithubCredentials) (para for _, repo := range creds.Repositories { commonRepo, err := s.sqlToCommonRepository(repo, false) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "converting github repository") + return params.ForgeCredentials{}, fmt.Errorf("error converting github repository: %w", err) } commonCreds.Repositories = append(commonCreds.Repositories, commonRepo) } @@ -873,7 +873,7 @@ func (s *sqlDatabase) sqlToCommonForgeCredentials(creds GithubCredentials) (para for _, org := range creds.Organizations { commonOrg, err := s.sqlToCommonOrganization(org, false) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "converting github organization") + return params.ForgeCredentials{}, fmt.Errorf("error converting github organization: %w", err) } commonCreds.Organizations = append(commonCreds.Organizations, commonOrg) } @@ -881,7 +881,7 @@ func (s *sqlDatabase) sqlToCommonForgeCredentials(creds GithubCredentials) (para for _, ent := range creds.Enterprises { commonEnt, err := s.sqlToCommonEnterprise(ent, false) if err != nil { - return params.ForgeCredentials{}, errors.Wrapf(err, "converting github enterprise: %s", ent.Name) + return params.ForgeCredentials{}, fmt.Errorf("error converting github enterprise %s: %w", ent.Name, err) } commonCreds.Enterprises = append(commonCreds.Enterprises, commonEnt) } @@ -895,12 +895,12 @@ func (s *sqlDatabase) sqlGiteaToCommonForgeCredentials(creds GiteaCredentials) ( } data, err := util.Unseal(creds.Payload, []byte(s.cfg.Passphrase)) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "unsealing credentials") + return params.ForgeCredentials{}, fmt.Errorf("error unsealing credentials: %w", err) } ep, err := s.sqlToCommonGithubEndpoint(creds.Endpoint) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "converting github endpoint") + return params.ForgeCredentials{}, fmt.Errorf("error converting github endpoint: %w", err) } commonCreds := params.ForgeCredentials{ @@ -921,7 +921,7 @@ func (s *sqlDatabase) sqlGiteaToCommonForgeCredentials(creds GiteaCredentials) ( for _, repo := range creds.Repositories { commonRepo, err := s.sqlToCommonRepository(repo, false) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "converting github repository") + return params.ForgeCredentials{}, fmt.Errorf("error converting github repository: %w", err) } commonCreds.Repositories = append(commonCreds.Repositories, commonRepo) } @@ -929,7 +929,7 @@ func (s *sqlDatabase) sqlGiteaToCommonForgeCredentials(creds GiteaCredentials) ( for _, org := range creds.Organizations { commonOrg, err := s.sqlToCommonOrganization(org, false) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "converting github organization") + return params.ForgeCredentials{}, fmt.Errorf("error converting github organization: %w", err) } commonCreds.Organizations = append(commonCreds.Organizations, commonOrg) } @@ -954,12 +954,12 @@ func (s *sqlDatabase) sqlToCommonGithubEndpoint(ep GithubEndpoint) (params.Forge func getUIDFromContext(ctx context.Context) (uuid.UUID, error) { userID := auth.UserID(ctx) if userID == "" { - return uuid.Nil, errors.Wrap(runnerErrors.ErrUnauthorized, "getting UID from context") + return uuid.Nil, fmt.Errorf("error getting UID from context: %w", runnerErrors.ErrUnauthorized) } asUUID, err := uuid.Parse(userID) if err != nil { - return uuid.Nil, errors.Wrap(runnerErrors.ErrUnauthorized, "parsing UID from context") + return uuid.Nil, fmt.Errorf("error parsing UID from context: %w", runnerErrors.ErrUnauthorized) } return asUUID, nil } diff --git a/database/watcher/watcher.go b/database/watcher/watcher.go index a7e1cd67..804dec70 100644 --- a/database/watcher/watcher.go +++ b/database/watcher/watcher.go @@ -16,11 +16,10 @@ package watcher import ( "context" + "fmt" "log/slog" "sync" - "github.com/pkg/errors" - "github.com/cloudbase/garm/database/common" garmUtil "github.com/cloudbase/garm/util" ) @@ -83,7 +82,7 @@ func (w *watcher) RegisterProducer(ctx context.Context, id string) (common.Produ defer w.mux.Unlock() if _, ok := w.producers[id]; ok { - return nil, errors.Wrapf(common.ErrProducerAlreadyRegistered, "producer_id: %s", id) + return nil, fmt.Errorf("producer_id %s: %w", id, common.ErrProducerAlreadyRegistered) } p := &producer{ id: id, diff --git a/database/watcher/watcher_test.go b/database/watcher/watcher_test.go index 5b7ecdce..fcbcc4eb 100644 --- a/database/watcher/watcher_test.go +++ b/database/watcher/watcher_test.go @@ -17,11 +17,11 @@ package watcher_test import ( "context" + "fmt" "testing" "time" "github.com/google/uuid" - "github.com/pkg/errors" "github.com/stretchr/testify/suite" commonParams "github.com/cloudbase/garm-provider-common/params" @@ -310,7 +310,7 @@ func maybeInitController(db common.Store) error { } if _, err := db.InitController(); err != nil { - return errors.Wrap(err, "initializing controller") + return fmt.Errorf("error initializing controller: %w", err) } return nil diff --git a/go.mod b/go.mod index da91a90d..9002cf2a 100644 --- a/go.mod +++ b/go.mod @@ -20,11 +20,8 @@ require ( github.com/gorilla/mux v1.8.1 github.com/gorilla/websocket v1.5.4-0.20240702125206-a62d9d2a8413 github.com/jedib0t/go-pretty/v6 v6.6.8 - github.com/juju/clock v1.1.1 - github.com/juju/retry v1.0.1 github.com/manifoldco/promptui v0.9.0 github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 - github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.23.0 github.com/spf13/cobra v1.9.1 github.com/stretchr/testify v1.10.0 @@ -62,9 +59,6 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/juju/errors v1.0.0 // indirect - github.com/juju/loggo v1.0.0 // indirect - github.com/juju/testing v1.0.2 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect @@ -74,6 +68,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.65.0 // indirect diff --git a/go.sum b/go.sum index 2008dff3..4cbbe8d3 100644 --- a/go.sum +++ b/go.sum @@ -95,19 +95,6 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= -github.com/juju/clock v1.1.1 h1:NvgHG9DQmOpBevgt6gzkyimdWBooLXDy1cQn89qJzBI= -github.com/juju/clock v1.1.1/go.mod h1:HIBvJ8kiV/n7UHwKuCkdYL4l/MDECztHR2sAvWDxxf0= -github.com/juju/errors v1.0.0 h1:yiq7kjCLll1BiaRuNY53MGI0+EQ3rF6GB+wvboZDefM= -github.com/juju/errors v1.0.0/go.mod h1:B5x9thDqx0wIMH3+aLIMP9HjItInYWObRovoCFM5Qe8= -github.com/juju/loggo v1.0.0 h1:Y6ZMQOGR9Aj3BGkiWx7HBbIx6zNwNkxhVNOHU2i1bl0= -github.com/juju/loggo v1.0.0/go.mod h1:NIXFioti1SmKAlKNuUwbMenNdef59IF52+ZzuOmHYkg= -github.com/juju/retry v1.0.1 h1:EVwOPq273wO1o0BCU7Ay7XE/bNb+bTNYsCK6y+BboAk= -github.com/juju/retry v1.0.1/go.mod h1:SssN1eYeK3A2qjnFGTiVMbdzGJ2BfluaJblJXvuvgqA= -github.com/juju/testing v1.0.2 h1:OR90RqCd9CJONxXamZAjLknpZdtqDyxqW8IwCbgw3i4= -github.com/juju/testing v1.0.2/go.mod h1:h3Vd2rzB57KrdsBEy6R7bmSKPzP76BnNavt7i8PerwQ= -github.com/juju/utils/v3 v3.0.0 h1:Gg3n63mGPbBuoXCo+EPJuMi44hGZfloI8nlCIebHu2Q= -github.com/juju/utils/v3 v3.0.0/go.mod h1:8csUcj1VRkfjNIRzBFWzLFCMLwLqsRWvkmhfVAUwbC4= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -116,13 +103,10 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lunixbochs/vtclean v0.0.0-20160125035106-4fbf7632a2c6/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= -github.com/mattn/go-colorable v0.0.6/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-isatty v0.0.0-20160806122752-66b8e73f3f5c/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= @@ -213,13 +197,10 @@ google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/ gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY= gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20160105164936-4f90aeace3a2/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/datatypes v1.2.6 h1:KafLdXvFUhzNeL2ncm03Gl3eTLONQfNKZ+wJ+9Y4Nck= diff --git a/internal/testing/testing.go b/internal/testing/testing.go index 98bfd34c..38725882 100644 --- a/internal/testing/testing.go +++ b/internal/testing/testing.go @@ -19,13 +19,13 @@ package testing import ( "context" + "errors" "fmt" "os" "path/filepath" "sort" "testing" - "github.com/pkg/errors" "github.com/stretchr/testify/require" runnerErrors "github.com/cloudbase/garm-provider-common/errors" diff --git a/params/requests.go b/params/requests.go index 3f4e1737..7bc17959 100644 --- a/params/requests.go +++ b/params/requests.go @@ -21,8 +21,6 @@ import ( "fmt" "net/url" - "github.com/pkg/errors" - runnerErrors "github.com/cloudbase/garm-provider-common/errors" commonParams "github.com/cloudbase/garm-provider-common/params" ) @@ -497,7 +495,7 @@ func (c CreateGithubCredentialsParams) Validate() error { if c.AuthType == ForgeAuthTypeApp { if err := c.App.Validate(); err != nil { - return errors.Wrap(err, "invalid app") + return fmt.Errorf("invalid app: %w", err) } } @@ -525,7 +523,7 @@ func (u UpdateGithubCredentialsParams) Validate() error { if u.App != nil { if err := u.App.Validate(); err != nil { - return errors.Wrap(err, "invalid app") + return fmt.Errorf("invalid app: %w", err) } } diff --git a/runner/common.go b/runner/common.go index 63d4887c..b1682c0c 100644 --- a/runner/common.go +++ b/runner/common.go @@ -2,8 +2,8 @@ package runner import ( "context" - - "github.com/pkg/errors" + "errors" + "fmt" runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/params" @@ -12,11 +12,11 @@ import ( func (r *Runner) ResolveForgeCredentialByName(ctx context.Context, credentialsName string) (params.ForgeCredentials, error) { githubCred, err := r.store.GetGithubCredentialsByName(ctx, credentialsName, false) if err != nil && !errors.Is(err, runnerErrors.ErrNotFound) { - return params.ForgeCredentials{}, errors.Wrap(err, "fetching github credentials") + return params.ForgeCredentials{}, fmt.Errorf("error fetching github credentials: %w", err) } giteaCred, err := r.store.GetGiteaCredentialsByName(ctx, credentialsName, false) if err != nil && !errors.Is(err, runnerErrors.ErrNotFound) { - return params.ForgeCredentials{}, errors.Wrap(err, "fetching gitea credentials") + return params.ForgeCredentials{}, fmt.Errorf("error fetching gitea credentials: %w", err) } if githubCred.ID != 0 && giteaCred.ID != 0 { return params.ForgeCredentials{}, runnerErrors.NewBadRequestError("credentials %s are defined for both GitHub and Gitea, please specify the forge type", credentialsName) diff --git a/runner/enterprises.go b/runner/enterprises.go index 341cf5b9..6b393abd 100644 --- a/runner/enterprises.go +++ b/runner/enterprises.go @@ -16,12 +16,11 @@ package runner import ( "context" + "errors" "fmt" "log/slog" "strings" - "github.com/pkg/errors" - runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/auth" "github.com/cloudbase/garm/params" @@ -36,7 +35,7 @@ func (r *Runner) CreateEnterprise(ctx context.Context, param params.CreateEnterp err = param.Validate() if err != nil { - return params.Enterprise{}, errors.Wrap(err, "validating params") + return params.Enterprise{}, fmt.Errorf("error validating params: %w", err) } creds, err := r.store.GetGithubCredentialsByName(ctx, param.CredentialsName, true) @@ -47,7 +46,7 @@ func (r *Runner) CreateEnterprise(ctx context.Context, param params.CreateEnterp _, err = r.store.GetEnterprise(ctx, param.Name, creds.Endpoint.Name) if err != nil { if !errors.Is(err, runnerErrors.ErrNotFound) { - return params.Enterprise{}, errors.Wrap(err, "fetching enterprise") + return params.Enterprise{}, fmt.Errorf("error fetching enterprise: %w", err) } } else { return params.Enterprise{}, runnerErrors.NewConflictError("enterprise %s already exists", param.Name) @@ -55,7 +54,7 @@ func (r *Runner) CreateEnterprise(ctx context.Context, param params.CreateEnterp enterprise, err = r.store.CreateEnterprise(ctx, param.Name, creds, param.WebhookSecret, param.PoolBalancerType) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "creating enterprise") + return params.Enterprise{}, fmt.Errorf("error creating enterprise: %w", err) } defer func() { @@ -73,7 +72,7 @@ func (r *Runner) CreateEnterprise(ctx context.Context, param params.CreateEnterp var poolMgr common.PoolManager poolMgr, err = r.poolManagerCtrl.CreateEnterprisePoolManager(r.ctx, enterprise, r.providers, r.store) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "creating enterprise pool manager") + return params.Enterprise{}, fmt.Errorf("error creating enterprise pool manager: %w", err) } if err := poolMgr.Start(); err != nil { if deleteErr := r.poolManagerCtrl.DeleteEnterprisePoolManager(enterprise); deleteErr != nil { @@ -81,7 +80,7 @@ func (r *Runner) CreateEnterprise(ctx context.Context, param params.CreateEnterp ctx, "failed to cleanup pool manager for enterprise", "enterprise_id", enterprise.ID) } - return params.Enterprise{}, errors.Wrap(err, "starting enterprise pool manager") + return params.Enterprise{}, fmt.Errorf("error starting enterprise pool manager: %w", err) } return enterprise, nil } @@ -93,7 +92,7 @@ func (r *Runner) ListEnterprises(ctx context.Context, filter params.EnterpriseFi enterprises, err := r.store.ListEnterprises(ctx, filter) if err != nil { - return nil, errors.Wrap(err, "listing enterprises") + return nil, fmt.Errorf("error listing enterprises: %w", err) } var allEnterprises []params.Enterprise @@ -119,7 +118,7 @@ func (r *Runner) GetEnterpriseByID(ctx context.Context, enterpriseID string) (pa enterprise, err := r.store.GetEnterpriseByID(ctx, enterpriseID) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "fetching enterprise") + return params.Enterprise{}, fmt.Errorf("error fetching enterprise: %w", err) } poolMgr, err := r.poolManagerCtrl.GetEnterprisePoolManager(enterprise) if err != nil { @@ -137,17 +136,17 @@ func (r *Runner) DeleteEnterprise(ctx context.Context, enterpriseID string) erro enterprise, err := r.store.GetEnterpriseByID(ctx, enterpriseID) if err != nil { - return errors.Wrap(err, "fetching enterprise") + return fmt.Errorf("error fetching enterprise: %w", err) } entity, err := enterprise.GetEntity() if err != nil { - return errors.Wrap(err, "getting entity") + return fmt.Errorf("error getting entity: %w", err) } pools, err := r.store.ListEntityPools(ctx, entity) if err != nil { - return errors.Wrap(err, "fetching enterprise pools") + return fmt.Errorf("error fetching enterprise pools: %w", err) } if len(pools) > 0 { @@ -161,7 +160,7 @@ func (r *Runner) DeleteEnterprise(ctx context.Context, enterpriseID string) erro scaleSets, err := r.store.ListEntityScaleSets(ctx, entity) if err != nil { - return errors.Wrap(err, "fetching enterprise scale sets") + return fmt.Errorf("error fetching enterprise scale sets: %w", err) } if len(scaleSets) > 0 { @@ -169,11 +168,11 @@ func (r *Runner) DeleteEnterprise(ctx context.Context, enterpriseID string) erro } if err := r.poolManagerCtrl.DeleteEnterprisePoolManager(enterprise); err != nil { - return errors.Wrap(err, "deleting enterprise pool manager") + return fmt.Errorf("error deleting enterprise pool manager: %w", err) } if err := r.store.DeleteEnterprise(ctx, enterpriseID); err != nil { - return errors.Wrapf(err, "removing enterprise %s", enterpriseID) + return fmt.Errorf("error removing enterprise %s: %w", enterpriseID, err) } return nil } @@ -194,7 +193,7 @@ func (r *Runner) UpdateEnterprise(ctx context.Context, enterpriseID string, para enterprise, err := r.store.UpdateEnterprise(ctx, enterpriseID, param) if err != nil { - return params.Enterprise{}, errors.Wrap(err, "updating enterprise") + return params.Enterprise{}, fmt.Errorf("error updating enterprise: %w", err) } poolMgr, err := r.poolManagerCtrl.GetEnterprisePoolManager(enterprise) @@ -243,7 +242,7 @@ func (r *Runner) GetEnterprisePoolByID(ctx context.Context, enterpriseID, poolID } pool, err := r.store.GetEntityPool(ctx, entity, poolID) if err != nil { - return params.Pool{}, errors.Wrap(err, "fetching pool") + return params.Pool{}, fmt.Errorf("error fetching pool: %w", err) } return pool, nil } @@ -260,7 +259,7 @@ func (r *Runner) DeleteEnterprisePool(ctx context.Context, enterpriseID, poolID pool, err := r.store.GetEntityPool(ctx, entity, poolID) if err != nil { - return errors.Wrap(err, "fetching pool") + return fmt.Errorf("error fetching pool: %w", err) } // nolint:golangci-lint,godox @@ -274,7 +273,7 @@ func (r *Runner) DeleteEnterprisePool(ctx context.Context, enterpriseID, poolID } if err := r.store.DeleteEntityPool(ctx, entity, poolID); err != nil { - return errors.Wrap(err, "deleting pool") + return fmt.Errorf("error deleting pool: %w", err) } return nil } @@ -290,7 +289,7 @@ func (r *Runner) ListEnterprisePools(ctx context.Context, enterpriseID string) ( } pools, err := r.store.ListEntityPools(ctx, entity) if err != nil { - return nil, errors.Wrap(err, "fetching pools") + return nil, fmt.Errorf("error fetching pools: %w", err) } return pools, nil } @@ -306,7 +305,7 @@ func (r *Runner) UpdateEnterprisePool(ctx context.Context, enterpriseID, poolID } pool, err := r.store.GetEntityPool(ctx, entity, poolID) if err != nil { - return params.Pool{}, errors.Wrap(err, "fetching pool") + return params.Pool{}, fmt.Errorf("error fetching pool: %w", err) } maxRunners := pool.MaxRunners @@ -325,7 +324,7 @@ func (r *Runner) UpdateEnterprisePool(ctx context.Context, enterpriseID, poolID newPool, err := r.store.UpdateEntityPool(ctx, entity, poolID, param) if err != nil { - return params.Pool{}, errors.Wrap(err, "updating pool") + return params.Pool{}, fmt.Errorf("error updating pool: %w", err) } return newPool, nil } @@ -340,7 +339,7 @@ func (r *Runner) ListEnterpriseInstances(ctx context.Context, enterpriseID strin } instances, err := r.store.ListEntityInstances(ctx, entity) if err != nil { - return []params.Instance{}, errors.Wrap(err, "fetching instances") + return []params.Instance{}, fmt.Errorf("error fetching instances: %w", err) } return instances, nil } @@ -351,12 +350,12 @@ func (r *Runner) findEnterprisePoolManager(name, endpointName string) (common.Po enterprise, err := r.store.GetEnterprise(r.ctx, name, endpointName) if err != nil { - return nil, errors.Wrap(err, "fetching enterprise") + return nil, fmt.Errorf("error fetching enterprise: %w", err) } poolManager, err := r.poolManagerCtrl.GetEnterprisePoolManager(enterprise) if err != nil { - return nil, errors.Wrap(err, "fetching pool manager for enterprise") + return nil, fmt.Errorf("error fetching pool manager for enterprise: %w", err) } return poolManager, nil } diff --git a/runner/enterprises_test.go b/runner/enterprises_test.go index ce791e55..0724ccf9 100644 --- a/runner/enterprises_test.go +++ b/runner/enterprises_test.go @@ -16,10 +16,10 @@ package runner import ( "context" + "errors" "fmt" "testing" - "github.com/pkg/errors" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" @@ -210,7 +210,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterprisePoolMgrFailed() { s.Fixtures.PoolMgrMock.AssertExpectations(s.T()) s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T()) - s.Require().Equal(fmt.Sprintf("creating enterprise pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) + s.Require().Equal(fmt.Sprintf("error creating enterprise pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) } func (s *EnterpriseTestSuite) TestCreateEnterpriseStartPoolMgrFailed() { @@ -222,7 +222,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterpriseStartPoolMgrFailed() { s.Fixtures.PoolMgrMock.AssertExpectations(s.T()) s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T()) - s.Require().Equal(fmt.Sprintf("starting enterprise pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) + s.Require().Equal(fmt.Sprintf("error starting enterprise pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) } func (s *EnterpriseTestSuite) TestListEnterprises() { @@ -324,7 +324,7 @@ func (s *EnterpriseTestSuite) TestDeleteEnterprise() { s.Require().Nil(err) _, err = s.Fixtures.Store.GetEnterpriseByID(s.Fixtures.AdminContext, s.Fixtures.StoreEnterprises["test-enterprise-3"].ID) - s.Require().Equal("fetching enterprise: not found", err.Error()) + s.Require().Equal("error fetching enterprise: not found", err.Error()) } func (s *EnterpriseTestSuite) TestDeleteEnterpriseErrUnauthorized() { @@ -354,7 +354,7 @@ func (s *EnterpriseTestSuite) TestDeleteEnterprisePoolMgrFailed() { err := s.Runner.DeleteEnterprise(s.Fixtures.AdminContext, s.Fixtures.StoreEnterprises["test-enterprise-1"].ID) s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T()) - s.Require().Equal(fmt.Sprintf("deleting enterprise pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) + s.Require().Equal(fmt.Sprintf("error deleting enterprise pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) } func (s *EnterpriseTestSuite) TestUpdateEnterprise() { @@ -477,7 +477,7 @@ func (s *EnterpriseTestSuite) TestDeleteEnterprisePool() { s.Require().Nil(err) _, err = s.Fixtures.Store.GetEntityPool(s.Fixtures.AdminContext, entity, pool.ID) - s.Require().Equal("fetching pool: finding pool: not found", err.Error()) + s.Require().Equal("fetching pool: error finding pool: not found", err.Error()) } func (s *EnterpriseTestSuite) TestDeleteEnterprisePoolErrUnauthorized() { diff --git a/runner/gitea_credentials.go b/runner/gitea_credentials.go index 4fdad1d2..d66212f9 100644 --- a/runner/gitea_credentials.go +++ b/runner/gitea_credentials.go @@ -16,8 +16,7 @@ package runner import ( "context" - - "github.com/pkg/errors" + "fmt" runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/auth" @@ -35,7 +34,7 @@ func (r *Runner) ListGiteaCredentials(ctx context.Context) ([]params.ForgeCreden // there is a posibillity that not all creds will be in the cache. creds, err := r.store.ListGiteaCredentials(ctx) if err != nil { - return nil, errors.Wrap(err, "fetching gitea credentials") + return nil, fmt.Errorf("error fetching gitea credentials: %w", err) } return creds, nil } @@ -46,12 +45,12 @@ func (r *Runner) CreateGiteaCredentials(ctx context.Context, param params.Create } if err := param.Validate(); err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "failed to validate gitea credentials params") + return params.ForgeCredentials{}, fmt.Errorf("error failed to validate gitea credentials params: %w", err) } creds, err := r.store.CreateGiteaCredentials(ctx, param) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "failed to create gitea credentials") + return params.ForgeCredentials{}, fmt.Errorf("error failed to create gitea credentials: %w", err) } return creds, nil @@ -64,7 +63,7 @@ func (r *Runner) GetGiteaCredentials(ctx context.Context, id uint) (params.Forge creds, err := r.store.GetGiteaCredentials(ctx, id, true) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "failed to get gitea credentials") + return params.ForgeCredentials{}, fmt.Errorf("error failed to get gitea credentials: %w", err) } return creds, nil @@ -76,7 +75,7 @@ func (r *Runner) DeleteGiteaCredentials(ctx context.Context, id uint) error { } if err := r.store.DeleteGiteaCredentials(ctx, id); err != nil { - return errors.Wrap(err, "failed to delete gitea credentials") + return fmt.Errorf("error failed to delete gitea credentials: %w", err) } return nil @@ -88,12 +87,12 @@ func (r *Runner) UpdateGiteaCredentials(ctx context.Context, id uint, param para } if err := param.Validate(); err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "failed to validate gitea credentials params") + return params.ForgeCredentials{}, fmt.Errorf("error failed to validate gitea credentials params: %w", err) } newCreds, err := r.store.UpdateGiteaCredentials(ctx, id, param) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "failed to update gitea credentials") + return params.ForgeCredentials{}, fmt.Errorf("error failed to update gitea credentials: %w", err) } return newCreds, nil diff --git a/runner/gitea_endpoints.go b/runner/gitea_endpoints.go index 181f8e7e..4a7e32d9 100644 --- a/runner/gitea_endpoints.go +++ b/runner/gitea_endpoints.go @@ -16,8 +16,7 @@ package runner import ( "context" - - "github.com/pkg/errors" + "fmt" runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/auth" @@ -30,12 +29,12 @@ func (r *Runner) CreateGiteaEndpoint(ctx context.Context, param params.CreateGit } if err := param.Validate(); err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "failed to validate gitea endpoint params") + return params.ForgeEndpoint{}, fmt.Errorf("failed to validate gitea endpoint params: %w", err) } ep, err := r.store.CreateGiteaEndpoint(ctx, param) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "failed to create gitea endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("failed to create gitea endpoint: %w", err) } return ep, nil @@ -47,7 +46,7 @@ func (r *Runner) GetGiteaEndpoint(ctx context.Context, name string) (params.Forg } endpoint, err := r.store.GetGiteaEndpoint(ctx, name) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "failed to get gitea endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("failed to get gitea endpoint: %w", err) } return endpoint, nil @@ -60,7 +59,7 @@ func (r *Runner) DeleteGiteaEndpoint(ctx context.Context, name string) error { err := r.store.DeleteGiteaEndpoint(ctx, name) if err != nil { - return errors.Wrap(err, "failed to delete gitea endpoint") + return fmt.Errorf("failed to delete gitea endpoint: %w", err) } return nil @@ -72,12 +71,12 @@ func (r *Runner) UpdateGiteaEndpoint(ctx context.Context, name string, param par } if err := param.Validate(); err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "failed to validate gitea endpoint params") + return params.ForgeEndpoint{}, fmt.Errorf("failed to validate gitea endpoint params: %w", err) } newEp, err := r.store.UpdateGiteaEndpoint(ctx, name, param) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "failed to update gitea endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("failed to update gitea endpoint: %w", err) } return newEp, nil } @@ -89,7 +88,7 @@ func (r *Runner) ListGiteaEndpoints(ctx context.Context) ([]params.ForgeEndpoint endpoints, err := r.store.ListGiteaEndpoints(ctx) if err != nil { - return nil, errors.Wrap(err, "failed to list gitea endpoints") + return nil, fmt.Errorf("failed to list gitea endpoints: %w", err) } return endpoints, nil diff --git a/runner/github_credentials.go b/runner/github_credentials.go index ec524056..5e1291ff 100644 --- a/runner/github_credentials.go +++ b/runner/github_credentials.go @@ -16,8 +16,7 @@ package runner import ( "context" - - "github.com/pkg/errors" + "fmt" runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/auth" @@ -36,7 +35,7 @@ func (r *Runner) ListCredentials(ctx context.Context) ([]params.ForgeCredentials // there is a posibillity that not all creds will be in the cache. creds, err := r.store.ListGithubCredentials(ctx) if err != nil { - return nil, errors.Wrap(err, "fetching github credentials") + return nil, fmt.Errorf("error fetching github credentials: %w", err) } // If we do have cache, update the rate limit for each credential. The rate limits are queried @@ -57,12 +56,12 @@ func (r *Runner) CreateGithubCredentials(ctx context.Context, param params.Creat } if err := param.Validate(); err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "failed to validate github credentials params") + return params.ForgeCredentials{}, fmt.Errorf("failed to validate github credentials params: %w", err) } creds, err := r.store.CreateGithubCredentials(ctx, param) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "failed to create github credentials") + return params.ForgeCredentials{}, fmt.Errorf("failed to create github credentials: %w", err) } return creds, nil @@ -75,7 +74,7 @@ func (r *Runner) GetGithubCredentials(ctx context.Context, id uint) (params.Forg creds, err := r.store.GetGithubCredentials(ctx, id, true) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "failed to get github credentials") + return params.ForgeCredentials{}, fmt.Errorf("failed to get github credentials: %w", err) } cached, ok := cache.GetGithubCredentials((creds.ID)) @@ -92,7 +91,7 @@ func (r *Runner) DeleteGithubCredentials(ctx context.Context, id uint) error { } if err := r.store.DeleteGithubCredentials(ctx, id); err != nil { - return errors.Wrap(err, "failed to delete github credentials") + return fmt.Errorf("failed to delete github credentials: %w", err) } return nil @@ -104,12 +103,12 @@ func (r *Runner) UpdateGithubCredentials(ctx context.Context, id uint, param par } if err := param.Validate(); err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "failed to validate github credentials params") + return params.ForgeCredentials{}, fmt.Errorf("failed to validate github credentials params: %w", err) } newCreds, err := r.store.UpdateGithubCredentials(ctx, id, param) if err != nil { - return params.ForgeCredentials{}, errors.Wrap(err, "failed to update github credentials") + return params.ForgeCredentials{}, fmt.Errorf("failed to update github credentials: %w", err) } return newCreds, nil diff --git a/runner/github_endpoints.go b/runner/github_endpoints.go index 0e144447..29965081 100644 --- a/runner/github_endpoints.go +++ b/runner/github_endpoints.go @@ -16,8 +16,7 @@ package runner import ( "context" - - "github.com/pkg/errors" + "fmt" runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/auth" @@ -30,12 +29,12 @@ func (r *Runner) CreateGithubEndpoint(ctx context.Context, param params.CreateGi } if err := param.Validate(); err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "failed to validate github endpoint params") + return params.ForgeEndpoint{}, fmt.Errorf("error failed to validate github endpoint params: %w", err) } ep, err := r.store.CreateGithubEndpoint(ctx, param) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "failed to create github endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("failed to create github endpoint: %w", err) } return ep, nil @@ -47,7 +46,7 @@ func (r *Runner) GetGithubEndpoint(ctx context.Context, name string) (params.For } endpoint, err := r.store.GetGithubEndpoint(ctx, name) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "failed to get github endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("failed to get github endpoint: %w", err) } return endpoint, nil @@ -60,7 +59,7 @@ func (r *Runner) DeleteGithubEndpoint(ctx context.Context, name string) error { err := r.store.DeleteGithubEndpoint(ctx, name) if err != nil { - return errors.Wrap(err, "failed to delete github endpoint") + return fmt.Errorf("failed to delete github endpoint: %w", err) } return nil @@ -72,12 +71,12 @@ func (r *Runner) UpdateGithubEndpoint(ctx context.Context, name string, param pa } if err := param.Validate(); err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "failed to validate github endpoint params") + return params.ForgeEndpoint{}, fmt.Errorf("failed to validate github endpoint params: %w", err) } newEp, err := r.store.UpdateGithubEndpoint(ctx, name, param) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "failed to update github endpoint") + return params.ForgeEndpoint{}, fmt.Errorf("failed to update github endpoint: %w", err) } return newEp, nil } @@ -89,7 +88,7 @@ func (r *Runner) ListGithubEndpoints(ctx context.Context) ([]params.ForgeEndpoin endpoints, err := r.store.ListGithubEndpoints(ctx) if err != nil { - return nil, errors.Wrap(err, "failed to list github endpoints") + return nil, fmt.Errorf("failed to list github endpoints: %w", err) } return endpoints, nil diff --git a/runner/metadata.go b/runner/metadata.go index 2c917ea0..b309b96e 100644 --- a/runner/metadata.go +++ b/runner/metadata.go @@ -18,12 +18,11 @@ import ( "bytes" "context" "encoding/base64" + "errors" "fmt" "html/template" "log/slog" - "github.com/pkg/errors" - "github.com/cloudbase/garm-provider-common/defaults" runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/auth" @@ -92,7 +91,7 @@ func (r *Runner) getForgeEntityFromInstance(ctx context.Context, instance params slog.With(slog.Any("error", err)).ErrorContext( ctx, "failed to get entity getter", "instance", instance.Name) - return params.ForgeEntity{}, errors.Wrap(err, "fetching entity getter") + return params.ForgeEntity{}, fmt.Errorf("error fetching entity getter: %w", err) } poolEntity, err := entityGetter.GetEntity() @@ -100,7 +99,7 @@ func (r *Runner) getForgeEntityFromInstance(ctx context.Context, instance params slog.With(slog.Any("error", err)).ErrorContext( ctx, "failed to get entity", "instance", instance.Name) - return params.ForgeEntity{}, errors.Wrap(err, "fetching entity") + return params.ForgeEntity{}, fmt.Errorf("error fetching entity: %w", err) } entity, err := r.store.GetForgeEntity(r.ctx, poolEntity.EntityType, poolEntity.ID) @@ -108,7 +107,7 @@ func (r *Runner) getForgeEntityFromInstance(ctx context.Context, instance params slog.With(slog.Any("error", err)).ErrorContext( ctx, "failed to get entity", "instance", instance.Name) - return params.ForgeEntity{}, errors.Wrap(err, "fetching entity") + return params.ForgeEntity{}, fmt.Errorf("error fetching entity: %w", err) } return entity, nil } @@ -136,13 +135,13 @@ func (r *Runner) GetRunnerServiceName(ctx context.Context) (string, error) { entity, err := r.getForgeEntityFromInstance(ctx, instance) if err != nil { slog.ErrorContext(r.ctx, "failed to get entity", "error", err) - return "", errors.Wrap(err, "fetching entity") + return "", fmt.Errorf("error fetching entity: %w", err) } serviceName, err := r.getServiceNameForEntity(entity) if err != nil { slog.ErrorContext(r.ctx, "failed to get service name", "error", err) - return "", errors.Wrap(err, "fetching service name") + return "", fmt.Errorf("error fetching service name: %w", err) } return serviceName, nil } @@ -157,13 +156,13 @@ func (r *Runner) GenerateSystemdUnitFile(ctx context.Context, runAsUser string) entity, err := r.getForgeEntityFromInstance(ctx, instance) if err != nil { slog.ErrorContext(r.ctx, "failed to get entity", "error", err) - return nil, errors.Wrap(err, "fetching entity") + return nil, fmt.Errorf("error fetching entity: %w", err) } serviceName, err := r.getServiceNameForEntity(entity) if err != nil { slog.ErrorContext(r.ctx, "failed to get service name", "error", err) - return nil, errors.Wrap(err, "fetching service name") + return nil, fmt.Errorf("error fetching service name: %w", err) } var unitTemplate *template.Template @@ -178,7 +177,7 @@ func (r *Runner) GenerateSystemdUnitFile(ctx context.Context, runAsUser string) } if err != nil { slog.ErrorContext(r.ctx, "failed to parse template", "error", err) - return nil, errors.Wrap(err, "parsing template") + return nil, fmt.Errorf("error parsing template: %w", err) } if runAsUser == "" { @@ -196,14 +195,14 @@ func (r *Runner) GenerateSystemdUnitFile(ctx context.Context, runAsUser string) var unitFile bytes.Buffer if err := unitTemplate.Execute(&unitFile, data); err != nil { slog.ErrorContext(r.ctx, "failed to execute template", "error", err) - return nil, errors.Wrap(err, "executing template") + return nil, fmt.Errorf("error executing template: %w", err) } return unitFile.Bytes(), nil } func (r *Runner) GetJITConfigFile(ctx context.Context, file string) ([]byte, error) { if !auth.InstanceHasJITConfig(ctx) { - return nil, fmt.Errorf("instance not configured for JIT: %w", runnerErrors.ErrNotFound) + return nil, runnerErrors.NewNotFoundError("instance not configured for JIT") } instance, err := validateInstanceState(ctx) @@ -215,12 +214,12 @@ func (r *Runner) GetJITConfigFile(ctx context.Context, file string) ([]byte, err jitConfig := instance.JitConfiguration contents, ok := jitConfig[file] if !ok { - return nil, errors.Wrap(runnerErrors.ErrNotFound, "retrieving file") + return nil, runnerErrors.NewNotFoundError("could not find file %q", file) } decoded, err := base64.StdEncoding.DecodeString(contents) if err != nil { - return nil, errors.Wrap(err, "decoding file contents") + return nil, fmt.Errorf("error decoding file contents: %w", err) } return decoded, nil @@ -249,12 +248,12 @@ func (r *Runner) GetInstanceGithubRegistrationToken(ctx context.Context) (string poolMgr, err := r.getPoolManagerFromInstance(ctx, instance) if err != nil { - return "", errors.Wrap(err, "fetching pool manager for instance") + return "", fmt.Errorf("error fetching pool manager for instance: %w", err) } token, err := poolMgr.GithubRunnerRegistrationToken() if err != nil { - return "", errors.Wrap(err, "fetching runner token") + return "", fmt.Errorf("error fetching runner token: %w", err) } tokenFetched := true @@ -263,11 +262,11 @@ func (r *Runner) GetInstanceGithubRegistrationToken(ctx context.Context) (string } if _, err := r.store.UpdateInstance(r.ctx, instance.Name, updateParams); err != nil { - return "", errors.Wrap(err, "setting token_fetched for instance") + return "", fmt.Errorf("error setting token_fetched for instance: %w", err) } if err := r.store.AddInstanceEvent(ctx, instance.Name, params.FetchTokenEvent, params.EventInfo, "runner registration token was retrieved"); err != nil { - return "", errors.Wrap(err, "recording event") + return "", fmt.Errorf("error recording event: %w", err) } return token, nil @@ -283,7 +282,7 @@ func (r *Runner) GetRootCertificateBundle(ctx context.Context) (params.Certifica poolMgr, err := r.getPoolManagerFromInstance(ctx, instance) if err != nil { - return params.CertificateBundle{}, errors.Wrap(err, "fetching pool manager for instance") + return params.CertificateBundle{}, fmt.Errorf("error fetching pool manager for instance: %w", err) } bundle, err := poolMgr.RootCABundle() diff --git a/runner/organizations.go b/runner/organizations.go index 0ec4bfa2..ffdd1c6c 100644 --- a/runner/organizations.go +++ b/runner/organizations.go @@ -16,12 +16,11 @@ package runner import ( "context" + "errors" "fmt" "log/slog" "strings" - "github.com/pkg/errors" - runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/auth" "github.com/cloudbase/garm/params" @@ -35,7 +34,7 @@ func (r *Runner) CreateOrganization(ctx context.Context, param params.CreateOrgP } if err := param.Validate(); err != nil { - return params.Organization{}, errors.Wrap(err, "validating params") + return params.Organization{}, fmt.Errorf("error validating params: %w", err) } var creds params.ForgeCredentials @@ -57,7 +56,7 @@ func (r *Runner) CreateOrganization(ctx context.Context, param params.CreateOrgP _, err = r.store.GetOrganization(ctx, param.Name, creds.Endpoint.Name) if err != nil { if !errors.Is(err, runnerErrors.ErrNotFound) { - return params.Organization{}, errors.Wrap(err, "fetching org") + return params.Organization{}, fmt.Errorf("error fetching org: %w", err) } } else { return params.Organization{}, runnerErrors.NewConflictError("organization %s already exists", param.Name) @@ -65,7 +64,7 @@ func (r *Runner) CreateOrganization(ctx context.Context, param params.CreateOrgP org, err = r.store.CreateOrganization(ctx, param.Name, creds, param.WebhookSecret, param.PoolBalancerType) if err != nil { - return params.Organization{}, errors.Wrap(err, "creating organization") + return params.Organization{}, fmt.Errorf("error creating organization: %w", err) } defer func() { @@ -82,7 +81,7 @@ func (r *Runner) CreateOrganization(ctx context.Context, param params.CreateOrgP // updating the store. poolMgr, err := r.poolManagerCtrl.CreateOrgPoolManager(r.ctx, org, r.providers, r.store) if err != nil { - return params.Organization{}, errors.Wrap(err, "creating org pool manager") + return params.Organization{}, fmt.Errorf("error creating org pool manager: %w", err) } if err := poolMgr.Start(); err != nil { if deleteErr := r.poolManagerCtrl.DeleteOrgPoolManager(org); deleteErr != nil { @@ -90,7 +89,7 @@ func (r *Runner) CreateOrganization(ctx context.Context, param params.CreateOrgP ctx, "failed to cleanup pool manager for org", "org_id", org.ID) } - return params.Organization{}, errors.Wrap(err, "starting org pool manager") + return params.Organization{}, fmt.Errorf("error starting org pool manager: %w", err) } return org, nil } @@ -102,7 +101,7 @@ func (r *Runner) ListOrganizations(ctx context.Context, filter params.Organizati orgs, err := r.store.ListOrganizations(ctx, filter) if err != nil { - return nil, errors.Wrap(err, "listing organizations") + return nil, fmt.Errorf("error listing organizations: %w", err) } var allOrgs []params.Organization @@ -129,7 +128,7 @@ func (r *Runner) GetOrganizationByID(ctx context.Context, orgID string) (params. org, err := r.store.GetOrganizationByID(ctx, orgID) if err != nil { - return params.Organization{}, errors.Wrap(err, "fetching organization") + return params.Organization{}, fmt.Errorf("error fetching organization: %w", err) } poolMgr, err := r.poolManagerCtrl.GetOrgPoolManager(org) @@ -148,17 +147,17 @@ func (r *Runner) DeleteOrganization(ctx context.Context, orgID string, keepWebho org, err := r.store.GetOrganizationByID(ctx, orgID) if err != nil { - return errors.Wrap(err, "fetching org") + return fmt.Errorf("error fetching org: %w", err) } entity, err := org.GetEntity() if err != nil { - return errors.Wrap(err, "getting entity") + return fmt.Errorf("error getting entity: %w", err) } pools, err := r.store.ListEntityPools(ctx, entity) if err != nil { - return errors.Wrap(err, "fetching org pools") + return fmt.Errorf("error fetching org pools: %w", err) } if len(pools) > 0 { @@ -172,7 +171,7 @@ func (r *Runner) DeleteOrganization(ctx context.Context, orgID string, keepWebho scaleSets, err := r.store.ListEntityScaleSets(ctx, entity) if err != nil { - return errors.Wrap(err, "fetching organization scale sets") + return fmt.Errorf("error fetching organization scale sets: %w", err) } if len(scaleSets) > 0 { @@ -182,7 +181,7 @@ func (r *Runner) DeleteOrganization(ctx context.Context, orgID string, keepWebho if !keepWebhook && r.config.Default.EnableWebhookManagement { poolMgr, err := r.poolManagerCtrl.GetOrgPoolManager(org) if err != nil { - return errors.Wrap(err, "fetching pool manager") + return fmt.Errorf("error fetching pool manager: %w", err) } if err := poolMgr.UninstallWebhook(ctx); err != nil { @@ -195,11 +194,11 @@ func (r *Runner) DeleteOrganization(ctx context.Context, orgID string, keepWebho } if err := r.poolManagerCtrl.DeleteOrgPoolManager(org); err != nil { - return errors.Wrap(err, "deleting org pool manager") + return fmt.Errorf("error deleting org pool manager: %w", err) } if err := r.store.DeleteOrganization(ctx, orgID); err != nil { - return errors.Wrapf(err, "removing organization %s", orgID) + return fmt.Errorf("error removing organization %s: %w", orgID, err) } return nil } @@ -220,7 +219,7 @@ func (r *Runner) UpdateOrganization(ctx context.Context, orgID string, param par org, err := r.store.UpdateOrganization(ctx, orgID, param) if err != nil { - return params.Organization{}, errors.Wrap(err, "updating org") + return params.Organization{}, fmt.Errorf("error updating org: %w", err) } poolMgr, err := r.poolManagerCtrl.GetOrgPoolManager(org) @@ -239,7 +238,7 @@ func (r *Runner) CreateOrgPool(ctx context.Context, orgID string, param params.C createPoolParams, err := r.appendTagsToCreatePoolParams(param) if err != nil { - return params.Pool{}, errors.Wrap(err, "fetching pool params") + return params.Pool{}, fmt.Errorf("error fetching pool params: %w", err) } if param.RunnerBootstrapTimeout == 0 { @@ -253,7 +252,7 @@ func (r *Runner) CreateOrgPool(ctx context.Context, orgID string, param params.C pool, err := r.store.CreateEntityPool(ctx, entity, createPoolParams) if err != nil { - return params.Pool{}, errors.Wrap(err, "creating pool") + return params.Pool{}, fmt.Errorf("error creating pool: %w", err) } return pool, nil @@ -271,7 +270,7 @@ func (r *Runner) GetOrgPoolByID(ctx context.Context, orgID, poolID string) (para pool, err := r.store.GetEntityPool(ctx, entity, poolID) if err != nil { - return params.Pool{}, errors.Wrap(err, "fetching pool") + return params.Pool{}, fmt.Errorf("error fetching pool: %w", err) } return pool, nil @@ -290,7 +289,7 @@ func (r *Runner) DeleteOrgPool(ctx context.Context, orgID, poolID string) error pool, err := r.store.GetEntityPool(ctx, entity, poolID) if err != nil { if !errors.Is(err, runnerErrors.ErrNotFound) { - return errors.Wrap(err, "fetching pool") + return fmt.Errorf("error fetching pool: %w", err) } return nil } @@ -306,7 +305,7 @@ func (r *Runner) DeleteOrgPool(ctx context.Context, orgID, poolID string) error } if err := r.store.DeleteEntityPool(ctx, entity, poolID); err != nil { - return errors.Wrap(err, "deleting pool") + return fmt.Errorf("error deleting pool: %w", err) } return nil } @@ -321,7 +320,7 @@ func (r *Runner) ListOrgPools(ctx context.Context, orgID string) ([]params.Pool, } pools, err := r.store.ListEntityPools(ctx, entity) if err != nil { - return nil, errors.Wrap(err, "fetching pools") + return nil, fmt.Errorf("error fetching pools: %w", err) } return pools, nil } @@ -338,7 +337,7 @@ func (r *Runner) UpdateOrgPool(ctx context.Context, orgID, poolID string, param pool, err := r.store.GetEntityPool(ctx, entity, poolID) if err != nil { - return params.Pool{}, errors.Wrap(err, "fetching pool") + return params.Pool{}, fmt.Errorf("error fetching pool: %w", err) } maxRunners := pool.MaxRunners @@ -357,7 +356,7 @@ func (r *Runner) UpdateOrgPool(ctx context.Context, orgID, poolID string, param newPool, err := r.store.UpdateEntityPool(ctx, entity, poolID, param) if err != nil { - return params.Pool{}, errors.Wrap(err, "updating pool") + return params.Pool{}, fmt.Errorf("error updating pool: %w", err) } return newPool, nil } @@ -374,7 +373,7 @@ func (r *Runner) ListOrgInstances(ctx context.Context, orgID string) ([]params.I instances, err := r.store.ListEntityInstances(ctx, entity) if err != nil { - return []params.Instance{}, errors.Wrap(err, "fetching instances") + return []params.Instance{}, fmt.Errorf("error fetching instances: %w", err) } return instances, nil } @@ -385,12 +384,12 @@ func (r *Runner) findOrgPoolManager(name, endpointName string) (common.PoolManag org, err := r.store.GetOrganization(r.ctx, name, endpointName) if err != nil { - return nil, errors.Wrap(err, "fetching org") + return nil, fmt.Errorf("error fetching org: %w", err) } poolManager, err := r.poolManagerCtrl.GetOrgPoolManager(org) if err != nil { - return nil, errors.Wrap(err, "fetching pool manager for org") + return nil, fmt.Errorf("error fetching pool manager for org: %w", err) } return poolManager, nil } @@ -402,17 +401,17 @@ func (r *Runner) InstallOrgWebhook(ctx context.Context, orgID string, param para org, err := r.store.GetOrganizationByID(ctx, orgID) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "fetching org") + return params.HookInfo{}, fmt.Errorf("error fetching org: %w", err) } poolMgr, err := r.poolManagerCtrl.GetOrgPoolManager(org) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "fetching pool manager for org") + return params.HookInfo{}, fmt.Errorf("error fetching pool manager for org: %w", err) } info, err := poolMgr.InstallWebhook(ctx, param) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "installing webhook") + return params.HookInfo{}, fmt.Errorf("error installing webhook: %w", err) } return info, nil } @@ -424,16 +423,16 @@ func (r *Runner) UninstallOrgWebhook(ctx context.Context, orgID string) error { org, err := r.store.GetOrganizationByID(ctx, orgID) if err != nil { - return errors.Wrap(err, "fetching org") + return fmt.Errorf("error fetching org: %w", err) } poolMgr, err := r.poolManagerCtrl.GetOrgPoolManager(org) if err != nil { - return errors.Wrap(err, "fetching pool manager for org") + return fmt.Errorf("error fetching pool manager for org: %w", err) } if err := poolMgr.UninstallWebhook(ctx); err != nil { - return errors.Wrap(err, "uninstalling webhook") + return fmt.Errorf("error uninstalling webhook: %w", err) } return nil } @@ -445,17 +444,17 @@ func (r *Runner) GetOrgWebhookInfo(ctx context.Context, orgID string) (params.Ho org, err := r.store.GetOrganizationByID(ctx, orgID) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "fetching org") + return params.HookInfo{}, fmt.Errorf("error fetching org: %w", err) } poolMgr, err := r.poolManagerCtrl.GetOrgPoolManager(org) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "fetching pool manager for org") + return params.HookInfo{}, fmt.Errorf("error fetching pool manager for org: %w", err) } info, err := poolMgr.GetWebhookInfo(ctx) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "fetching webhook info") + return params.HookInfo{}, fmt.Errorf("error fetching webhook info: %w", err) } return info, nil } diff --git a/runner/organizations_test.go b/runner/organizations_test.go index 9de6d2b4..8d2aa3f6 100644 --- a/runner/organizations_test.go +++ b/runner/organizations_test.go @@ -16,10 +16,10 @@ package runner import ( "context" + "errors" "fmt" "testing" - "github.com/pkg/errors" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" @@ -224,7 +224,7 @@ func (s *OrgTestSuite) TestCreateOrganizationPoolMgrFailed() { s.Fixtures.PoolMgrMock.AssertExpectations(s.T()) s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T()) - s.Require().Equal(fmt.Sprintf("creating org pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) + s.Require().Equal(fmt.Sprintf("error creating org pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) } func (s *OrgTestSuite) TestCreateOrganizationStartPoolMgrFailed() { @@ -236,7 +236,7 @@ func (s *OrgTestSuite) TestCreateOrganizationStartPoolMgrFailed() { s.Fixtures.PoolMgrMock.AssertExpectations(s.T()) s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T()) - s.Require().Equal(fmt.Sprintf("starting org pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) + s.Require().Equal(fmt.Sprintf("error starting org pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) } func (s *OrgTestSuite) TestListOrganizations() { @@ -338,7 +338,7 @@ func (s *OrgTestSuite) TestDeleteOrganization() { s.Require().Nil(err) _, err = s.Fixtures.Store.GetOrganizationByID(s.Fixtures.AdminContext, s.Fixtures.StoreOrgs["test-org-3"].ID) - s.Require().Equal("fetching org: not found", err.Error()) + s.Require().Equal("error fetching org: not found", err.Error()) } func (s *OrgTestSuite) TestDeleteOrganizationErrUnauthorized() { @@ -368,7 +368,7 @@ func (s *OrgTestSuite) TestDeleteOrganizationPoolMgrFailed() { err := s.Runner.DeleteOrganization(s.Fixtures.AdminContext, s.Fixtures.StoreOrgs["test-org-1"].ID, true) s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T()) - s.Require().Equal(fmt.Sprintf("deleting org pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) + s.Require().Equal(fmt.Sprintf("error deleting org pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) } func (s *OrgTestSuite) TestUpdateOrganization() { @@ -502,7 +502,7 @@ func (s *OrgTestSuite) TestDeleteOrgPool() { s.Require().Nil(err) _, err = s.Fixtures.Store.GetEntityPool(s.Fixtures.AdminContext, entity, pool.ID) - s.Require().Equal("fetching pool: finding pool: not found", err.Error()) + s.Require().Equal("fetching pool: error finding pool: not found", err.Error()) } func (s *OrgTestSuite) TestDeleteOrgPoolErrUnauthorized() { diff --git a/runner/pool/common.go b/runner/pool/common.go index 066866a2..fa2f7e5a 100644 --- a/runner/pool/common.go +++ b/runner/pool/common.go @@ -16,12 +16,12 @@ package pool import ( "context" + "fmt" "net/http" "net/url" "strings" "github.com/google/go-github/v72/github" - "github.com/pkg/errors" runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/params" @@ -30,7 +30,7 @@ import ( func validateHookRequest(controllerID, baseURL string, allHooks []*github.Hook, req *github.Hook) error { parsed, err := url.Parse(baseURL) if err != nil { - return errors.Wrap(err, "parsing webhook url") + return fmt.Errorf("error parsing webhook url: %w", err) } partialMatches := []string{} @@ -80,7 +80,7 @@ func (r *basePoolManager) listHooks(ctx context.Context) ([]*github.Hook, error) if ghResp != nil && ghResp.StatusCode == http.StatusNotFound { return nil, runnerErrors.NewBadRequestError("repository not found or your PAT does not have access to manage webhooks") } - return nil, errors.Wrap(err, "fetching hooks") + return nil, fmt.Errorf("error fetching hooks: %w", err) } allHooks = append(allHooks, hooks...) if ghResp.NextPage == 0 { diff --git a/runner/pool/pool.go b/runner/pool/pool.go index 1afee56e..690fed93 100644 --- a/runner/pool/pool.go +++ b/runner/pool/pool.go @@ -17,6 +17,7 @@ package pool import ( "context" "crypto/rand" + "errors" "fmt" "log/slog" "math" @@ -29,7 +30,6 @@ import ( "github.com/google/go-github/v72/github" "github.com/google/uuid" - "github.com/pkg/errors" "golang.org/x/sync/errgroup" runnerErrors "github.com/cloudbase/garm-provider-common/errors" @@ -76,16 +76,16 @@ func NewEntityPoolManager(ctx context.Context, entity params.ForgeEntity, instan ) ghc, err := ghClient.Client(ctx, entity) if err != nil { - return nil, errors.Wrap(err, "getting github client") + return nil, fmt.Errorf("error getting github client: %w", err) } if entity.WebhookSecret == "" { - return nil, errors.New("webhook secret is empty") + return nil, fmt.Errorf("webhook secret is empty") } controllerInfo, err := store.ControllerInfo() if err != nil { - return nil, errors.Wrap(err, "getting controller info") + return nil, fmt.Errorf("error getting controller info: %w", err) } consumerID := fmt.Sprintf("pool-manager-%s-%s", entity.String(), entity.Credentials.Endpoint.Name) @@ -95,13 +95,13 @@ func NewEntityPoolManager(ctx context.Context, entity params.ForgeEntity, instan composeWatcherFilters(entity), ) if err != nil { - return nil, errors.Wrap(err, "registering consumer") + return nil, fmt.Errorf("error registering consumer: %w", err) } wg := &sync.WaitGroup{} backoff, err := locking.NewInstanceDeleteBackoff(ctx) if err != nil { - return nil, errors.Wrap(err, "creating backoff") + return nil, fmt.Errorf("error creating backoff: %w", err) } repo := &basePoolManager{ @@ -158,7 +158,7 @@ func (r *basePoolManager) getProviderBaseParams(pool params.Pool) common.Provide func (r *basePoolManager) HandleWorkflowJob(job params.WorkflowJob) error { if err := r.ValidateOwner(job); err != nil { slog.ErrorContext(r.ctx, "failed to validate owner", "error", err) - return errors.Wrap(err, "validating owner") + return fmt.Errorf("error validating owner: %w", err) } // we see events where the lables seem to be missing. We should ignore these @@ -171,7 +171,7 @@ func (r *basePoolManager) HandleWorkflowJob(job params.WorkflowJob) error { jobParams, err := r.paramsWorkflowJobToParamsJob(job) if err != nil { slog.ErrorContext(r.ctx, "failed to convert job to params", "error", err) - return errors.Wrap(err, "converting job to params") + return fmt.Errorf("error converting job to params: %w", err) } var triggeredBy int64 @@ -249,7 +249,7 @@ func (r *basePoolManager) HandleWorkflowJob(job params.WorkflowJob) error { slog.With(slog.Any("error", err)).ErrorContext( r.ctx, "failed to update runner status", "runner_name", util.SanitizeLogEntry(jobParams.RunnerName)) - return errors.Wrap(err, "updating runner") + return fmt.Errorf("error updating runner: %w", err) } slog.DebugContext( r.ctx, "marking instance as pending_delete", @@ -261,7 +261,7 @@ func (r *basePoolManager) HandleWorkflowJob(job params.WorkflowJob) error { slog.With(slog.Any("error", err)).ErrorContext( r.ctx, "failed to update runner status", "runner_name", util.SanitizeLogEntry(jobParams.RunnerName)) - return errors.Wrap(err, "updating runner") + return fmt.Errorf("error updating runner: %w", err) } case "in_progress": fromCache, ok := cache.GetInstanceCache(jobParams.RunnerName) @@ -284,7 +284,7 @@ func (r *basePoolManager) HandleWorkflowJob(job params.WorkflowJob) error { slog.With(slog.Any("error", err)).ErrorContext( r.ctx, "failed to update runner status", "runner_name", util.SanitizeLogEntry(jobParams.RunnerName)) - return errors.Wrap(err, "updating runner") + return fmt.Errorf("error updating runner: %w", err) } // Set triggeredBy here so we break the lock on any potential queued job. triggeredBy = jobIDFromLabels(instance.AditionalLabels) @@ -396,7 +396,7 @@ func (r *basePoolManager) updateTools() error { func (r *basePoolManager) cleanupOrphanedProviderRunners(runners []*github.Runner) error { dbInstances, err := r.store.ListEntityInstances(r.ctx, r.entity) if err != nil { - return errors.Wrap(err, "fetching instances from db") + return fmt.Errorf("error fetching instances from db: %w", err) } runnerNames := map[string]bool{} @@ -435,7 +435,7 @@ func (r *basePoolManager) cleanupOrphanedProviderRunners(runners []*github.Runne } pool, err := r.store.GetEntityPool(r.ctx, r.entity, instance.PoolID) if err != nil { - return errors.Wrap(err, "fetching instance pool info") + return fmt.Errorf("error fetching instance pool info: %w", err) } switch instance.RunnerStatus { @@ -463,7 +463,7 @@ func (r *basePoolManager) cleanupOrphanedProviderRunners(runners []*github.Runne slog.With(slog.Any("error", err)).ErrorContext( r.ctx, "failed to update runner", "runner_name", instance.Name) - return errors.Wrap(err, "updating runner") + return fmt.Errorf("error updating runner: %w", err) } } } @@ -476,7 +476,7 @@ func (r *basePoolManager) cleanupOrphanedProviderRunners(runners []*github.Runne func (r *basePoolManager) reapTimedOutRunners(runners []*github.Runner) error { dbInstances, err := r.store.ListEntityInstances(r.ctx, r.entity) if err != nil { - return errors.Wrap(err, "fetching instances from db") + return fmt.Errorf("error fetching instances from db: %w", err) } runnersByName := map[string]*github.Runner{} @@ -510,7 +510,7 @@ func (r *basePoolManager) reapTimedOutRunners(runners []*github.Runner) error { pool, err := r.store.GetEntityPool(r.ctx, r.entity, instance.PoolID) if err != nil { - return errors.Wrap(err, "fetching instance pool info") + return fmt.Errorf("error fetching instance pool info: %w", err) } if time.Since(instance.UpdatedAt).Minutes() < float64(pool.RunnerTimeout()) { continue @@ -529,7 +529,7 @@ func (r *basePoolManager) reapTimedOutRunners(runners []*github.Runner) error { slog.With(slog.Any("error", err)).ErrorContext( r.ctx, "failed to update runner status", "runner_name", instance.Name) - return errors.Wrap(err, "updating runner") + return fmt.Errorf("error updating runner: %w", err) } } } @@ -560,7 +560,7 @@ func (r *basePoolManager) cleanupOrphanedGithubRunners(runners []*github.Runner) dbInstance, err := r.store.GetInstanceByName(r.ctx, *runner.Name) if err != nil { if !errors.Is(err, runnerErrors.ErrNotFound) { - return errors.Wrap(err, "fetching instance from DB") + return fmt.Errorf("error fetching instance from DB: %w", err) } // We no longer have a DB entry for this instance, and the runner appears offline in github. // Previous forceful removal may have failed? @@ -572,7 +572,7 @@ func (r *basePoolManager) cleanupOrphanedGithubRunners(runners []*github.Runner) if errors.Is(err, runnerErrors.ErrNotFound) { continue } - return errors.Wrap(err, "removing runner") + return fmt.Errorf("error removing runner: %w", err) } continue } @@ -606,7 +606,7 @@ func (r *basePoolManager) cleanupOrphanedGithubRunners(runners []*github.Runner) pool, err := r.store.GetEntityPool(r.ctx, r.entity, dbInstance.PoolID) if err != nil { - return errors.Wrap(err, "fetching pool") + return fmt.Errorf("error fetching pool: %w", err) } // check if the provider still has the instance. @@ -628,7 +628,7 @@ func (r *basePoolManager) cleanupOrphanedGithubRunners(runners []*github.Runner) } poolInstances, err = provider.ListInstances(r.ctx, pool.ID, listInstancesParams) if err != nil { - return errors.Wrapf(err, "fetching instances for pool %s", dbInstance.PoolID) + return fmt.Errorf("error fetching instances for pool %s: %w", dbInstance.PoolID, err) } poolInstanceCache[dbInstance.PoolID] = poolInstances } @@ -662,7 +662,7 @@ func (r *basePoolManager) cleanupOrphanedGithubRunners(runners []*github.Runner) r.ctx, "runner disappeared from github", "runner_name", dbInstance.Name) } else { - return errors.Wrap(err, "removing runner from github") + return fmt.Errorf("error removing runner from github: %w", err) } } // Remove the database entry for the runner. @@ -670,7 +670,7 @@ func (r *basePoolManager) cleanupOrphanedGithubRunners(runners []*github.Runner) r.ctx, "Removing from database", "runner_name", dbInstance.Name) if err := r.store.DeleteInstance(ctx, dbInstance.PoolID, dbInstance.Name); err != nil { - return errors.Wrap(err, "removing runner from database") + return fmt.Errorf("error removing runner from database: %w", err) } deleteMux = true return nil @@ -696,13 +696,13 @@ func (r *basePoolManager) cleanupOrphanedGithubRunners(runners []*github.Runner) }, } if err := provider.Start(r.ctx, dbInstance.ProviderID, startParams); err != nil { - return errors.Wrapf(err, "starting instance %s", dbInstance.ProviderID) + return fmt.Errorf("error starting instance %s: %w", dbInstance.ProviderID, err) } return nil }) } if err := r.waitForErrorGroupOrContextCancelled(g); err != nil { - return errors.Wrap(err, "removing orphaned github runners") + return fmt.Errorf("error removing orphaned github runners: %w", err) } return nil } @@ -732,7 +732,7 @@ func (r *basePoolManager) setInstanceRunnerStatus(runnerName string, status para } instance, err := r.store.UpdateInstance(r.ctx, runnerName, updateParams) if err != nil { - return params.Instance{}, errors.Wrap(err, "updating runner state") + return params.Instance{}, fmt.Errorf("error updating runner state: %w", err) } return instance, nil } @@ -745,7 +745,7 @@ func (r *basePoolManager) setInstanceStatus(runnerName string, status commonPara instance, err := r.store.UpdateInstance(r.ctx, runnerName, updateParams) if err != nil { - return params.Instance{}, errors.Wrap(err, "updating runner state") + return params.Instance{}, fmt.Errorf("error updating runner state: %w", err) } return instance, nil } @@ -753,7 +753,7 @@ func (r *basePoolManager) setInstanceStatus(runnerName string, status commonPara func (r *basePoolManager) AddRunner(ctx context.Context, poolID string, aditionalLabels []string) (err error) { pool, err := r.store.GetEntityPool(r.ctx, r.entity, poolID) if err != nil { - return errors.Wrap(err, "fetching pool") + return fmt.Errorf("error fetching pool: %w", err) } provider, ok := r.providers[pool.ProviderName] @@ -796,7 +796,7 @@ func (r *basePoolManager) AddRunner(ctx context.Context, poolID string, aditiona instance, err := r.store.CreateInstance(r.ctx, poolID, createParams) if err != nil { - return errors.Wrap(err, "creating instance") + return fmt.Errorf("error creating instance: %w", err) } defer func() { @@ -864,7 +864,7 @@ func (r *basePoolManager) getLabelsForInstance(pool params.Pool) []string { func (r *basePoolManager) addInstanceToProvider(instance params.Instance) error { pool, err := r.store.GetEntityPool(r.ctx, r.entity, instance.PoolID) if err != nil { - return errors.Wrap(err, "fetching pool") + return fmt.Errorf("error fetching pool: %w", err) } provider, ok := r.providers[pool.ProviderName] @@ -876,7 +876,7 @@ func (r *basePoolManager) addInstanceToProvider(instance params.Instance) error jwtToken, err := r.instanceTokenGetter.NewInstanceJWTToken(instance, r.entity, pool.PoolType(), jwtValidity) if err != nil { - return errors.Wrap(err, "fetching instance jwt token") + return fmt.Errorf("error fetching instance jwt token: %w", err) } hasJITConfig := len(instance.JitConfiguration) > 0 @@ -933,7 +933,7 @@ func (r *basePoolManager) addInstanceToProvider(instance params.Instance) error providerInstance, err := provider.CreateInstance(r.ctx, bootstrapArgs, createInstanceParams) if err != nil { instanceIDToDelete = instance.Name - return errors.Wrap(err, "creating instance") + return fmt.Errorf("error creating instance: %w", err) } if providerInstance.Status == commonParams.InstanceError { @@ -945,7 +945,7 @@ func (r *basePoolManager) addInstanceToProvider(instance params.Instance) error updateInstanceArgs := r.updateArgsFromProviderInstance(providerInstance) if _, err := r.store.UpdateInstance(r.ctx, instance.Name, updateInstanceArgs); err != nil { - return errors.Wrap(err, "updating instance") + return fmt.Errorf("error updating instance: %w", err) } return nil } @@ -966,7 +966,7 @@ func (r *basePoolManager) addInstanceToProvider(instance params.Instance) error func (r *basePoolManager) paramsWorkflowJobToParamsJob(job params.WorkflowJob) (params.Job, error) { asUUID, err := uuid.Parse(r.ID()) if err != nil { - return params.Job{}, errors.Wrap(err, "parsing pool ID as UUID") + return params.Job{}, fmt.Errorf("error parsing pool ID as UUID: %w", err) } jobParams := params.Job{ @@ -995,7 +995,7 @@ func (r *basePoolManager) paramsWorkflowJobToParamsJob(job params.WorkflowJob) ( case params.ForgeEntityTypeOrganization: jobParams.OrgID = &asUUID default: - return jobParams, errors.Errorf("unknown pool type: %s", r.entity.EntityType) + return jobParams, fmt.Errorf("unknown pool type: %s", r.entity.EntityType) } return jobParams, nil @@ -1101,7 +1101,7 @@ func (r *basePoolManager) scaleDownOnePool(ctx context.Context, pool params.Pool // instead of returning a bunch of results and filtering manually. queued, err := r.store.ListEntityJobsByStatus(r.ctx, r.entity.EntityType, r.entity.ID, params.JobStatusQueued) if err != nil && !errors.Is(err, runnerErrors.ErrNotFound) { - return errors.Wrap(err, "listing queued jobs") + return fmt.Errorf("error listing queued jobs: %w", err) } for _, job := range queued { @@ -1341,7 +1341,7 @@ func (r *basePoolManager) ensureMinIdleRunners() error { func (r *basePoolManager) deleteInstanceFromProvider(ctx context.Context, instance params.Instance) error { pool, err := r.store.GetEntityPool(r.ctx, r.entity, instance.PoolID) if err != nil { - return errors.Wrap(err, "fetching pool") + return fmt.Errorf("error fetching pool: %w", err) } provider, ok := r.providers[instance.ProviderName] @@ -1367,7 +1367,7 @@ func (r *basePoolManager) deleteInstanceFromProvider(ctx context.Context, instan }, } if err := provider.DeleteInstance(ctx, identifier, deleteInstanceParams); err != nil { - return errors.Wrap(err, "removing instance") + return fmt.Errorf("error removing instance: %w", err) } return nil @@ -1583,7 +1583,7 @@ func (r *basePoolManager) Wait() error { select { case <-done: case <-timer.C: - return errors.Wrap(runnerErrors.ErrTimeout, "waiting for pool to stop") + return runnerErrors.NewTimeoutError("waiting for pool to stop") } return nil } @@ -1609,11 +1609,11 @@ func (r *basePoolManager) runnerCleanup() (err error) { func (r *basePoolManager) cleanupOrphanedRunners(runners []*github.Runner) error { if err := r.cleanupOrphanedProviderRunners(runners); err != nil { - return errors.Wrap(err, "cleaning orphaned instances") + return fmt.Errorf("error cleaning orphaned instances: %w", err) } if err := r.cleanupOrphanedGithubRunners(runners); err != nil { - return errors.Wrap(err, "cleaning orphaned github runners") + return fmt.Errorf("error cleaning orphaned github runners: %w", err) } return nil @@ -1693,10 +1693,10 @@ func (r *basePoolManager) DeleteRunner(runner params.Instance, forceRemove, bypa if bypassGHUnauthorizedError { slog.Info("bypass github unauthorized error is set, marking runner for deletion") } else { - return errors.Wrap(err, "removing runner") + return fmt.Errorf("error removing runner: %w", err) } } else { - return errors.Wrap(err, "removing runner") + return fmt.Errorf("error removing runner: %w", err) } } } @@ -1714,7 +1714,7 @@ func (r *basePoolManager) DeleteRunner(runner params.Instance, forceRemove, bypa slog.With(slog.Any("error", err)).ErrorContext( r.ctx, "failed to update runner", "runner_name", runner.Name) - return errors.Wrap(err, "updating runner") + return fmt.Errorf("error updating runner: %w", err) } return nil } @@ -1745,7 +1745,7 @@ func (r *basePoolManager) DeleteRunner(runner params.Instance, forceRemove, bypa func (r *basePoolManager) consumeQueuedJobs() error { queued, err := r.store.ListEntityJobsByStatus(r.ctx, r.entity.EntityType, r.entity.ID, params.JobStatusQueued) if err != nil { - return errors.Wrap(err, "listing queued jobs") + return fmt.Errorf("error listing queued jobs: %w", err) } poolsCache := poolsForTags{ @@ -1860,7 +1860,7 @@ func (r *basePoolManager) consumeQueuedJobs() error { slog.With(slog.Any("error", err)).ErrorContext( r.ctx, "failed to unlock job", "job_id", job.WorkflowJobID) - return errors.Wrap(err, "unlocking job") + return fmt.Errorf("error unlocking job: %w", err) } } } @@ -1874,12 +1874,12 @@ func (r *basePoolManager) consumeQueuedJobs() error { func (r *basePoolManager) UninstallWebhook(ctx context.Context) error { if r.controllerInfo.ControllerWebhookURL == "" { - return errors.Wrap(runnerErrors.ErrBadRequest, "controller webhook url is empty") + return runnerErrors.NewBadRequestError("controller webhook url is empty") } allHooks, err := r.listHooks(ctx) if err != nil { - return errors.Wrap(err, "listing hooks") + return fmt.Errorf("error listing hooks: %w", err) } var controllerHookID int64 @@ -1917,16 +1917,16 @@ func (r *basePoolManager) UninstallWebhook(ctx context.Context) error { func (r *basePoolManager) InstallHook(ctx context.Context, req *github.Hook) (params.HookInfo, error) { allHooks, err := r.listHooks(ctx) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "listing hooks") + return params.HookInfo{}, fmt.Errorf("error listing hooks: %w", err) } if err := validateHookRequest(r.controllerInfo.ControllerID.String(), r.controllerInfo.WebhookURL, allHooks, req); err != nil { - return params.HookInfo{}, errors.Wrap(err, "validating hook request") + return params.HookInfo{}, fmt.Errorf("error validating hook request: %w", err) } hook, err := r.ghcli.CreateEntityHook(ctx, req) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "creating entity hook") + return params.HookInfo{}, fmt.Errorf("error creating entity hook: %w", err) } if _, err := r.ghcli.PingEntityHook(ctx, hook.GetID()); err != nil { @@ -1941,7 +1941,7 @@ func (r *basePoolManager) InstallHook(ctx context.Context, req *github.Hook) (pa func (r *basePoolManager) InstallWebhook(ctx context.Context, param params.InstallWebhookParams) (params.HookInfo, error) { if r.controllerInfo.ControllerWebhookURL == "" { - return params.HookInfo{}, errors.Wrap(runnerErrors.ErrBadRequest, "controller webhook url is empty") + return params.HookInfo{}, runnerErrors.NewBadRequestError("controller webhook url is empty") } insecureSSL := "0" @@ -1989,9 +1989,9 @@ func (r *basePoolManager) GithubRunnerRegistrationToken() (string, error) { tk, ghResp, err := r.ghcli.CreateEntityRegistrationToken(r.ctx) if err != nil { if ghResp != nil && ghResp.StatusCode == http.StatusUnauthorized { - return "", errors.Wrap(runnerErrors.ErrUnauthorized, "fetching token") + return "", runnerErrors.NewUnauthorizedError("error fetching token") } - return "", errors.Wrap(err, "creating runner token") + return "", fmt.Errorf("error creating runner token: %w", err) } return *tk.Token, nil } @@ -2000,9 +2000,9 @@ func (r *basePoolManager) FetchTools() ([]commonParams.RunnerApplicationDownload tools, ghResp, err := r.ghcli.ListEntityRunnerApplicationDownloads(r.ctx) if err != nil { if ghResp != nil && ghResp.StatusCode == http.StatusUnauthorized { - return nil, errors.Wrap(runnerErrors.ErrUnauthorized, "fetching tools") + return nil, runnerErrors.NewUnauthorizedError("error fetching tools") } - return nil, errors.Wrap(err, "fetching runner tools") + return nil, fmt.Errorf("error fetching runner tools: %w", err) } ret := []commonParams.RunnerApplicationDownload{} @@ -2027,9 +2027,9 @@ func (r *basePoolManager) GetGithubRunners() ([]*github.Runner, error) { runners, ghResp, err := r.ghcli.ListEntityRunners(r.ctx, &opts) if err != nil { if ghResp != nil && ghResp.StatusCode == http.StatusUnauthorized { - return nil, errors.Wrap(runnerErrors.ErrUnauthorized, "fetching runners") + return nil, runnerErrors.NewUnauthorizedError("error fetching runners") } - return nil, errors.Wrap(err, "fetching runners") + return nil, fmt.Errorf("error fetching runners: %w", err) } allRunners = append(allRunners, runners.Runners...) if ghResp.NextPage == 0 { @@ -2044,7 +2044,7 @@ func (r *basePoolManager) GetGithubRunners() ([]*github.Runner, error) { func (r *basePoolManager) GetWebhookInfo(ctx context.Context) (params.HookInfo, error) { allHooks, err := r.listHooks(ctx) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "listing hooks") + return params.HookInfo{}, fmt.Errorf("error listing hooks: %w", err) } trimmedBase := strings.TrimRight(r.controllerInfo.WebhookURL, "/") trimmedController := strings.TrimRight(r.controllerInfo.ControllerWebhookURL, "/") diff --git a/runner/pool/watcher.go b/runner/pool/watcher.go index 324643ce..999b52c6 100644 --- a/runner/pool/watcher.go +++ b/runner/pool/watcher.go @@ -17,8 +17,6 @@ package pool import ( "log/slog" - "github.com/pkg/errors" - runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/database/common" "github.com/cloudbase/garm/params" @@ -46,7 +44,7 @@ func (r *basePoolManager) getClientOrStub() runnerCommon.GithubClient { if err != nil { slog.WarnContext(r.ctx, "failed to create github client", "error", err) ghc = &stubGithubClient{ - err: errors.Wrapf(runnerErrors.ErrUnauthorized, "failed to create github client; please update credentials: %v", err), + err: runnerErrors.NewUnauthorizedError("failed to create github client; please update credentials"), } } return ghc diff --git a/runner/pools.go b/runner/pools.go index 15aecb5e..ffd3b9c8 100644 --- a/runner/pools.go +++ b/runner/pools.go @@ -16,8 +16,8 @@ package runner import ( "context" - - "github.com/pkg/errors" + "errors" + "fmt" runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/auth" @@ -31,7 +31,7 @@ func (r *Runner) ListAllPools(ctx context.Context) ([]params.Pool, error) { pools, err := r.store.ListAllPools(ctx) if err != nil { - return nil, errors.Wrap(err, "fetching pools") + return nil, fmt.Errorf("error fetching pools: %w", err) } return pools, nil } @@ -43,7 +43,7 @@ func (r *Runner) GetPoolByID(ctx context.Context, poolID string) (params.Pool, e pool, err := r.store.GetPoolByID(ctx, poolID) if err != nil { - return params.Pool{}, errors.Wrap(err, "fetching pool") + return params.Pool{}, fmt.Errorf("error fetching pool: %w", err) } return pool, nil } @@ -56,7 +56,7 @@ func (r *Runner) DeletePoolByID(ctx context.Context, poolID string) error { pool, err := r.store.GetPoolByID(ctx, poolID) if err != nil { if !errors.Is(err, runnerErrors.ErrNotFound) { - return errors.Wrap(err, "fetching pool") + return fmt.Errorf("error fetching pool: %w", err) } return nil } @@ -66,7 +66,7 @@ func (r *Runner) DeletePoolByID(ctx context.Context, poolID string) error { } if err := r.store.DeletePoolByID(ctx, poolID); err != nil { - return errors.Wrap(err, "deleting pool") + return fmt.Errorf("error deleting pool: %w", err) } return nil } @@ -78,7 +78,7 @@ func (r *Runner) UpdatePoolByID(ctx context.Context, poolID string, param params pool, err := r.store.GetPoolByID(ctx, poolID) if err != nil { - return params.Pool{}, errors.Wrap(err, "fetching pool") + return params.Pool{}, fmt.Errorf("error fetching pool: %w", err) } maxRunners := pool.MaxRunners @@ -101,12 +101,12 @@ func (r *Runner) UpdatePoolByID(ctx context.Context, poolID string, param params entity, err := pool.GetEntity() if err != nil { - return params.Pool{}, errors.Wrap(err, "getting entity") + return params.Pool{}, fmt.Errorf("error getting entity: %w", err) } newPool, err := r.store.UpdateEntityPool(ctx, entity, poolID, param) if err != nil { - return params.Pool{}, errors.Wrap(err, "updating pool") + return params.Pool{}, fmt.Errorf("error updating pool: %w", err) } return newPool, nil } @@ -118,7 +118,7 @@ func (r *Runner) ListAllJobs(ctx context.Context) ([]params.Job, error) { jobs, err := r.store.ListAllJobs(ctx) if err != nil { - return nil, errors.Wrap(err, "fetching jobs") + return nil, fmt.Errorf("error fetching jobs: %w", err) } return jobs, nil } diff --git a/runner/pools_test.go b/runner/pools_test.go index 3bc5d4b3..2a2aea5d 100644 --- a/runner/pools_test.go +++ b/runner/pools_test.go @@ -169,7 +169,7 @@ func (s *PoolTestSuite) TestGetPoolByIDNotFound() { s.Require().Nil(err) _, err = s.Runner.GetPoolByID(s.Fixtures.AdminContext, s.Fixtures.Pools[0].ID) s.Require().NotNil(err) - s.Require().Equal("fetching pool: fetching pool by ID: not found", err.Error()) + s.Require().Equal("error fetching pool: error fetching pool by ID: not found", err.Error()) } func (s *PoolTestSuite) TestDeletePoolByID() { @@ -178,7 +178,7 @@ func (s *PoolTestSuite) TestDeletePoolByID() { s.Require().Nil(err) _, err = s.Fixtures.Store.GetPoolByID(s.Fixtures.AdminContext, s.Fixtures.Pools[0].ID) s.Require().NotNil(err) - s.Require().Equal("fetching pool by ID: not found", err.Error()) + s.Require().Equal("error fetching pool by ID: not found", err.Error()) } func (s *PoolTestSuite) TestDeletePoolByIDErrUnauthorized() { @@ -220,7 +220,7 @@ func (s *PoolTestSuite) TestTestUpdatePoolByIDInvalidPoolID() { _, err := s.Runner.UpdatePoolByID(s.Fixtures.AdminContext, "dummy-pool-id", s.Fixtures.UpdatePoolParams) s.Require().NotNil(err) - s.Require().Equal("fetching pool: fetching pool by ID: parsing id: invalid request", err.Error()) + s.Require().Equal("error fetching pool: error fetching pool by ID: error parsing id: invalid request", err.Error()) } func (s *PoolTestSuite) TestTestUpdatePoolByIDRunnerBootstrapTimeoutFailed() { diff --git a/runner/providers/providers.go b/runner/providers/providers.go index 165fb585..ada11729 100644 --- a/runner/providers/providers.go +++ b/runner/providers/providers.go @@ -16,10 +16,9 @@ package providers import ( "context" + "fmt" "log/slog" - "github.com/pkg/errors" - "github.com/cloudbase/garm/config" "github.com/cloudbase/garm/params" "github.com/cloudbase/garm/runner/common" @@ -39,11 +38,11 @@ func LoadProvidersFromConfig(ctx context.Context, cfg config.Config, controllerI conf := providerCfg provider, err := external.NewProvider(ctx, &conf, controllerID) if err != nil { - return nil, errors.Wrap(err, "creating provider") + return nil, fmt.Errorf("error creating provider: %w", err) } providers[providerCfg.Name] = provider default: - return nil, errors.Errorf("unknown provider type %s", providerCfg.ProviderType) + return nil, fmt.Errorf("unknown provider type %s", providerCfg.ProviderType) } } return providers, nil diff --git a/runner/providers/v0.1.0/external.go b/runner/providers/v0.1.0/external.go index 60c5ca1b..bb96f4d7 100644 --- a/runner/providers/v0.1.0/external.go +++ b/runner/providers/v0.1.0/external.go @@ -17,12 +17,11 @@ package v010 import ( "context" "encoding/json" + "errors" "fmt" "log/slog" "os/exec" - "github.com/pkg/errors" - garmErrors "github.com/cloudbase/garm-provider-common/errors" commonExecution "github.com/cloudbase/garm-provider-common/execution/common" commonParams "github.com/cloudbase/garm-provider-common/params" @@ -44,7 +43,7 @@ func NewProvider(ctx context.Context, cfg *config.Provider, controllerID string) execPath, err := cfg.External.ExecutablePath() if err != nil { - return nil, errors.Wrap(err, "fetching executable path") + return nil, fmt.Errorf("error fetching executable path: %w", err) } // Set GARM_INTERFACE_VERSION to the version of the interface that the external @@ -83,7 +82,7 @@ func (e *external) CreateInstance(ctx context.Context, bootstrapParams commonPar asJs, err := json.Marshal(bootstrapParams) if err != nil { - return commonParams.ProviderInstance{}, errors.Wrap(err, "serializing bootstrap params") + return commonParams.ProviderInstance{}, fmt.Errorf("error serializing bootstrap params: %w", err) } metrics.InstanceOperationCount.WithLabelValues( diff --git a/runner/providers/v0.1.1/external.go b/runner/providers/v0.1.1/external.go index 192f735d..6e43dce7 100644 --- a/runner/providers/v0.1.1/external.go +++ b/runner/providers/v0.1.1/external.go @@ -18,12 +18,11 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "log/slog" "os/exec" - "github.com/pkg/errors" - garmErrors "github.com/cloudbase/garm-provider-common/errors" commonExecution "github.com/cloudbase/garm-provider-common/execution/common" commonParams "github.com/cloudbase/garm-provider-common/params" @@ -44,7 +43,7 @@ func NewProvider(ctx context.Context, cfg *config.Provider, controllerID string) execPath, err := cfg.External.ExecutablePath() if err != nil { - return nil, errors.Wrap(err, "fetching executable path") + return nil, fmt.Errorf("error fetching executable path: %w", err) } // Set GARM_INTERFACE_VERSION to the version of the interface that the external @@ -75,7 +74,7 @@ func (e *external) CreateInstance(ctx context.Context, bootstrapParams commonPar extraspecs := bootstrapParams.ExtraSpecs extraspecsValue, err := json.Marshal(extraspecs) if err != nil { - return commonParams.ProviderInstance{}, errors.Wrap(err, "serializing extraspecs") + return commonParams.ProviderInstance{}, fmt.Errorf("error serializing extraspecs: %w", err) } // Encode the extraspecs as base64 to avoid issues with special characters. base64EncodedExtraSpecs := base64.StdEncoding.EncodeToString(extraspecsValue) @@ -90,7 +89,7 @@ func (e *external) CreateInstance(ctx context.Context, bootstrapParams commonPar asJs, err := json.Marshal(bootstrapParams) if err != nil { - return commonParams.ProviderInstance{}, errors.Wrap(err, "serializing bootstrap params") + return commonParams.ProviderInstance{}, fmt.Errorf("error serializing bootstrap params: %w", err) } metrics.InstanceOperationCount.WithLabelValues( @@ -136,7 +135,7 @@ func (e *external) DeleteInstance(ctx context.Context, instance string, deleteIn extraspecs := deleteInstanceParams.DeleteInstanceV011.PoolInfo.ExtraSpecs extraspecsValue, err := json.Marshal(extraspecs) if err != nil { - return errors.Wrap(err, "serializing extraspecs") + return fmt.Errorf("error serializing extraspecs: %w", err) } // Encode the extraspecs as base64 to avoid issues with special characters. base64EncodedExtraSpecs := base64.StdEncoding.EncodeToString(extraspecsValue) @@ -173,7 +172,7 @@ func (e *external) GetInstance(ctx context.Context, instance string, getInstance extraspecs := getInstanceParams.GetInstanceV011.PoolInfo.ExtraSpecs extraspecsValue, err := json.Marshal(extraspecs) if err != nil { - return commonParams.ProviderInstance{}, errors.Wrap(err, "serializing extraspecs") + return commonParams.ProviderInstance{}, fmt.Errorf("error serializing extraspecs: %w", err) } // Encode the extraspecs as base64 to avoid issues with special characters. base64EncodedExtraSpecs := base64.StdEncoding.EncodeToString(extraspecsValue) @@ -228,7 +227,7 @@ func (e *external) ListInstances(ctx context.Context, poolID string, listInstanc extraspecs := listInstancesParams.ListInstancesV011.PoolInfo.ExtraSpecs extraspecsValue, err := json.Marshal(extraspecs) if err != nil { - return []commonParams.ProviderInstance{}, errors.Wrap(err, "serializing extraspecs") + return []commonParams.ProviderInstance{}, fmt.Errorf("error serializing extraspecs: %w", err) } // Encode the extraspecs as base64 to avoid issues with special characters. base64EncodedExtraSpecs := base64.StdEncoding.EncodeToString(extraspecsValue) @@ -283,7 +282,7 @@ func (e *external) RemoveAllInstances(ctx context.Context, removeAllInstances co extraspecs := removeAllInstances.RemoveAllInstancesV011.PoolInfo.ExtraSpecs extraspecsValue, err := json.Marshal(extraspecs) if err != nil { - return errors.Wrap(err, "serializing extraspecs") + return fmt.Errorf("error serializing extraspecs: %w", err) } // Encode the extraspecs as base64 to avoid issues with special characters. base64EncodedExtraSpecs := base64.StdEncoding.EncodeToString(extraspecsValue) @@ -317,7 +316,7 @@ func (e *external) Stop(ctx context.Context, instance string, stopParams common. extraspecs := stopParams.StopV011.PoolInfo.ExtraSpecs extraspecsValue, err := json.Marshal(extraspecs) if err != nil { - return errors.Wrap(err, "serializing extraspecs") + return fmt.Errorf("error serializing extraspecs: %w", err) } // Encode the extraspecs as base64 to avoid issues with special characters. base64EncodedExtraSpecs := base64.StdEncoding.EncodeToString(extraspecsValue) @@ -351,7 +350,7 @@ func (e *external) Start(ctx context.Context, instance string, startParams commo extraspecs := startParams.StartV011.PoolInfo.ExtraSpecs extraspecsValue, err := json.Marshal(extraspecs) if err != nil { - return errors.Wrap(err, "serializing extraspecs") + return fmt.Errorf("error serializing extraspecs: %w", err) } // Encode the extraspecs as base64 to avoid issues with special characters. base64EncodedExtraSpecs := base64.StdEncoding.EncodeToString(extraspecsValue) diff --git a/runner/repositories.go b/runner/repositories.go index 24beaa07..0f21d882 100644 --- a/runner/repositories.go +++ b/runner/repositories.go @@ -16,12 +16,11 @@ package runner import ( "context" + "errors" "fmt" "log/slog" "strings" - "github.com/pkg/errors" - runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/auth" "github.com/cloudbase/garm/params" @@ -35,7 +34,7 @@ func (r *Runner) CreateRepository(ctx context.Context, param params.CreateRepoPa } if err := param.Validate(); err != nil { - return params.Repository{}, errors.Wrap(err, "validating params") + return params.Repository{}, fmt.Errorf("error validating params: %w", err) } var creds params.ForgeCredentials @@ -55,7 +54,7 @@ func (r *Runner) CreateRepository(ctx context.Context, param params.CreateRepoPa _, err = r.store.GetRepository(ctx, param.Owner, param.Name, creds.Endpoint.Name) if err != nil { if !errors.Is(err, runnerErrors.ErrNotFound) { - return params.Repository{}, errors.Wrap(err, "fetching repo") + return params.Repository{}, fmt.Errorf("error fetching repo: %w", err) } } else { return params.Repository{}, runnerErrors.NewConflictError("repository %s/%s already exists", param.Owner, param.Name) @@ -63,7 +62,7 @@ func (r *Runner) CreateRepository(ctx context.Context, param params.CreateRepoPa repo, err = r.store.CreateRepository(ctx, param.Owner, param.Name, creds, param.WebhookSecret, param.PoolBalancerType) if err != nil { - return params.Repository{}, errors.Wrap(err, "creating repository") + return params.Repository{}, fmt.Errorf("error creating repository: %w", err) } defer func() { @@ -80,7 +79,7 @@ func (r *Runner) CreateRepository(ctx context.Context, param params.CreateRepoPa // updating the store. poolMgr, err := r.poolManagerCtrl.CreateRepoPoolManager(r.ctx, repo, r.providers, r.store) if err != nil { - return params.Repository{}, errors.Wrap(err, "creating repo pool manager") + return params.Repository{}, fmt.Errorf("error creating repo pool manager: %w", err) } if err := poolMgr.Start(); err != nil { if deleteErr := r.poolManagerCtrl.DeleteRepoPoolManager(repo); deleteErr != nil { @@ -88,7 +87,7 @@ func (r *Runner) CreateRepository(ctx context.Context, param params.CreateRepoPa ctx, "failed to cleanup pool manager for repo", "repository_id", repo.ID) } - return params.Repository{}, errors.Wrap(err, "starting repo pool manager") + return params.Repository{}, fmt.Errorf("error starting repo pool manager: %w", err) } return repo, nil } @@ -100,7 +99,7 @@ func (r *Runner) ListRepositories(ctx context.Context, filter params.RepositoryF repos, err := r.store.ListRepositories(ctx, filter) if err != nil { - return nil, errors.Wrap(err, "listing repositories") + return nil, fmt.Errorf("error listing repositories: %w", err) } var allRepos []params.Repository @@ -126,7 +125,7 @@ func (r *Runner) GetRepositoryByID(ctx context.Context, repoID string) (params.R repo, err := r.store.GetRepositoryByID(ctx, repoID) if err != nil { - return params.Repository{}, errors.Wrap(err, "fetching repository") + return params.Repository{}, fmt.Errorf("error fetching repository: %w", err) } poolMgr, err := r.poolManagerCtrl.GetRepoPoolManager(repo) @@ -145,17 +144,17 @@ func (r *Runner) DeleteRepository(ctx context.Context, repoID string, keepWebhoo repo, err := r.store.GetRepositoryByID(ctx, repoID) if err != nil { - return errors.Wrap(err, "fetching repo") + return fmt.Errorf("error fetching repo: %w", err) } entity, err := repo.GetEntity() if err != nil { - return errors.Wrap(err, "getting entity") + return fmt.Errorf("error getting entity: %w", err) } pools, err := r.store.ListEntityPools(ctx, entity) if err != nil { - return errors.Wrap(err, "fetching repo pools") + return fmt.Errorf("error fetching repo pools: %w", err) } if len(pools) > 0 { @@ -169,7 +168,7 @@ func (r *Runner) DeleteRepository(ctx context.Context, repoID string, keepWebhoo scaleSets, err := r.store.ListEntityScaleSets(ctx, entity) if err != nil { - return errors.Wrap(err, "fetching repo scale sets") + return fmt.Errorf("error fetching repo scale sets: %w", err) } if len(scaleSets) > 0 { @@ -179,7 +178,7 @@ func (r *Runner) DeleteRepository(ctx context.Context, repoID string, keepWebhoo if !keepWebhook && r.config.Default.EnableWebhookManagement { poolMgr, err := r.poolManagerCtrl.GetRepoPoolManager(repo) if err != nil { - return errors.Wrap(err, "fetching pool manager") + return fmt.Errorf("error fetching pool manager: %w", err) } if err := poolMgr.UninstallWebhook(ctx); err != nil { @@ -192,11 +191,11 @@ func (r *Runner) DeleteRepository(ctx context.Context, repoID string, keepWebhoo } if err := r.poolManagerCtrl.DeleteRepoPoolManager(repo); err != nil { - return errors.Wrap(err, "deleting repo pool manager") + return fmt.Errorf("error deleting repo pool manager: %w", err) } if err := r.store.DeleteRepository(ctx, repoID); err != nil { - return errors.Wrap(err, "removing repository") + return fmt.Errorf("error removing repository: %w", err) } return nil } @@ -218,12 +217,12 @@ func (r *Runner) UpdateRepository(ctx context.Context, repoID string, param para slog.InfoContext(ctx, "updating repository", "repo_id", repoID, "param", param) repo, err := r.store.UpdateRepository(ctx, repoID, param) if err != nil { - return params.Repository{}, errors.Wrap(err, "updating repo") + return params.Repository{}, fmt.Errorf("error updating repo: %w", err) } poolMgr, err := r.poolManagerCtrl.GetRepoPoolManager(repo) if err != nil { - return params.Repository{}, errors.Wrap(err, "getting pool manager") + return params.Repository{}, fmt.Errorf("error getting pool manager: %w", err) } repo.PoolManagerStatus = poolMgr.Status() @@ -237,7 +236,7 @@ func (r *Runner) CreateRepoPool(ctx context.Context, repoID string, param params createPoolParams, err := r.appendTagsToCreatePoolParams(param) if err != nil { - return params.Pool{}, errors.Wrap(err, "appending tags to create pool params") + return params.Pool{}, fmt.Errorf("error appending tags to create pool params: %w", err) } if createPoolParams.RunnerBootstrapTimeout == 0 { @@ -251,7 +250,7 @@ func (r *Runner) CreateRepoPool(ctx context.Context, repoID string, param params pool, err := r.store.CreateEntityPool(ctx, entity, createPoolParams) if err != nil { - return params.Pool{}, errors.Wrap(err, "creating pool") + return params.Pool{}, fmt.Errorf("error creating pool: %w", err) } return pool, nil @@ -269,7 +268,7 @@ func (r *Runner) GetRepoPoolByID(ctx context.Context, repoID, poolID string) (pa pool, err := r.store.GetEntityPool(ctx, entity, poolID) if err != nil { - return params.Pool{}, errors.Wrap(err, "fetching pool") + return params.Pool{}, fmt.Errorf("error fetching pool: %w", err) } return pool, nil @@ -286,7 +285,7 @@ func (r *Runner) DeleteRepoPool(ctx context.Context, repoID, poolID string) erro } pool, err := r.store.GetEntityPool(ctx, entity, poolID) if err != nil { - return errors.Wrap(err, "fetching pool") + return fmt.Errorf("error fetching pool: %w", err) } // nolint:golangci-lint,godox @@ -300,7 +299,7 @@ func (r *Runner) DeleteRepoPool(ctx context.Context, repoID, poolID string) erro } if err := r.store.DeleteEntityPool(ctx, entity, poolID); err != nil { - return errors.Wrap(err, "deleting pool") + return fmt.Errorf("error deleting pool: %w", err) } return nil } @@ -315,7 +314,7 @@ func (r *Runner) ListRepoPools(ctx context.Context, repoID string) ([]params.Poo } pools, err := r.store.ListEntityPools(ctx, entity) if err != nil { - return nil, errors.Wrap(err, "fetching pools") + return nil, fmt.Errorf("error fetching pools: %w", err) } return pools, nil } @@ -327,7 +326,7 @@ func (r *Runner) ListPoolInstances(ctx context.Context, poolID string) ([]params instances, err := r.store.ListPoolInstances(ctx, poolID) if err != nil { - return []params.Instance{}, errors.Wrap(err, "fetching instances") + return []params.Instance{}, fmt.Errorf("error fetching instances: %w", err) } return instances, nil } @@ -343,7 +342,7 @@ func (r *Runner) UpdateRepoPool(ctx context.Context, repoID, poolID string, para } pool, err := r.store.GetEntityPool(ctx, entity, poolID) if err != nil { - return params.Pool{}, errors.Wrap(err, "fetching pool") + return params.Pool{}, fmt.Errorf("error fetching pool: %w", err) } maxRunners := pool.MaxRunners @@ -362,7 +361,7 @@ func (r *Runner) UpdateRepoPool(ctx context.Context, repoID, poolID string, para newPool, err := r.store.UpdateEntityPool(ctx, entity, poolID, param) if err != nil { - return params.Pool{}, errors.Wrap(err, "updating pool") + return params.Pool{}, fmt.Errorf("error updating pool: %w", err) } return newPool, nil } @@ -377,7 +376,7 @@ func (r *Runner) ListRepoInstances(ctx context.Context, repoID string) ([]params } instances, err := r.store.ListEntityInstances(ctx, entity) if err != nil { - return []params.Instance{}, errors.Wrap(err, "fetching instances") + return []params.Instance{}, fmt.Errorf("error , errfetching instances: %w", err) } return instances, nil } @@ -388,12 +387,12 @@ func (r *Runner) findRepoPoolManager(owner, name, endpointName string) (common.P repo, err := r.store.GetRepository(r.ctx, owner, name, endpointName) if err != nil { - return nil, errors.Wrap(err, "fetching repo") + return nil, fmt.Errorf("error fetching repo: %w", err) } poolManager, err := r.poolManagerCtrl.GetRepoPoolManager(repo) if err != nil { - return nil, errors.Wrap(err, "fetching pool manager for repo") + return nil, fmt.Errorf("error fetching pool manager for repo: %w", err) } return poolManager, nil } @@ -405,17 +404,17 @@ func (r *Runner) InstallRepoWebhook(ctx context.Context, repoID string, param pa repo, err := r.store.GetRepositoryByID(ctx, repoID) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "fetching repo") + return params.HookInfo{}, fmt.Errorf("error fetching repo: %w", err) } poolManager, err := r.poolManagerCtrl.GetRepoPoolManager(repo) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "fetching pool manager for repo") + return params.HookInfo{}, fmt.Errorf("error fetching pool manager for repo: %w", err) } info, err := poolManager.InstallWebhook(ctx, param) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "installing webhook") + return params.HookInfo{}, fmt.Errorf("error installing webhook: %w", err) } return info, nil } @@ -427,16 +426,16 @@ func (r *Runner) UninstallRepoWebhook(ctx context.Context, repoID string) error repo, err := r.store.GetRepositoryByID(ctx, repoID) if err != nil { - return errors.Wrap(err, "fetching repo") + return fmt.Errorf("error fetching repo: %w", err) } poolManager, err := r.poolManagerCtrl.GetRepoPoolManager(repo) if err != nil { - return errors.Wrap(err, "fetching pool manager for repo") + return fmt.Errorf("error fetching pool manager for repo: %w", err) } if err := poolManager.UninstallWebhook(ctx); err != nil { - return errors.Wrap(err, "uninstalling webhook") + return fmt.Errorf("error uninstalling webhook: %w", err) } return nil } @@ -448,17 +447,17 @@ func (r *Runner) GetRepoWebhookInfo(ctx context.Context, repoID string) (params. repo, err := r.store.GetRepositoryByID(ctx, repoID) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "fetching repo") + return params.HookInfo{}, fmt.Errorf("error fetching repo: %w", err) } poolManager, err := r.poolManagerCtrl.GetRepoPoolManager(repo) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "fetching pool manager for repo") + return params.HookInfo{}, fmt.Errorf("error fetching pool manager for repo: %w", err) } info, err := poolManager.GetWebhookInfo(ctx) if err != nil { - return params.HookInfo{}, errors.Wrap(err, "getting webhook info") + return params.HookInfo{}, fmt.Errorf("error getting webhook info: %w", err) } return info, nil } diff --git a/runner/repositories_test.go b/runner/repositories_test.go index 53fe5869..8f195ae3 100644 --- a/runner/repositories_test.go +++ b/runner/repositories_test.go @@ -16,10 +16,10 @@ package runner import ( "context" + "errors" "fmt" "testing" - "github.com/pkg/errors" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" @@ -240,7 +240,7 @@ func (s *RepoTestSuite) TestCreateRepositoryPoolMgrFailed() { s.Fixtures.PoolMgrMock.AssertExpectations(s.T()) s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T()) - s.Require().Equal(fmt.Sprintf("creating repo pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) + s.Require().Equal(fmt.Sprintf("error creating repo pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) } func (s *RepoTestSuite) TestCreateRepositoryStartPoolMgrFailed() { @@ -252,7 +252,7 @@ func (s *RepoTestSuite) TestCreateRepositoryStartPoolMgrFailed() { s.Fixtures.PoolMgrMock.AssertExpectations(s.T()) s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T()) - s.Require().Equal(fmt.Sprintf("starting repo pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) + s.Require().Equal(fmt.Sprintf("error starting repo pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) } func (s *RepoTestSuite) TestListRepositories() { @@ -361,7 +361,7 @@ func (s *RepoTestSuite) TestDeleteRepository() { s.Require().Nil(err) _, err = s.Fixtures.Store.GetRepositoryByID(s.Fixtures.AdminContext, s.Fixtures.StoreRepos["test-repo-1"].ID) - s.Require().Equal("fetching repo: not found", err.Error()) + s.Require().Equal("error fetching repo: not found", err.Error()) } func (s *RepoTestSuite) TestDeleteRepositoryErrUnauthorized() { @@ -391,7 +391,7 @@ func (s *RepoTestSuite) TestDeleteRepositoryPoolMgrFailed() { err := s.Runner.DeleteRepository(s.Fixtures.AdminContext, s.Fixtures.StoreRepos["test-repo-1"].ID, true) s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T()) - s.Require().Equal(fmt.Sprintf("deleting repo pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) + s.Require().Equal(fmt.Sprintf("error deleting repo pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) } func (s *RepoTestSuite) TestUpdateRepository() { @@ -445,7 +445,7 @@ func (s *RepoTestSuite) TestUpdateRepositoryPoolMgrFailed() { _, err := s.Runner.UpdateRepository(s.Fixtures.AdminContext, s.Fixtures.StoreRepos["test-repo-1"].ID, s.Fixtures.UpdateRepoParams) s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T()) - s.Require().Equal(fmt.Sprintf("getting pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) + s.Require().Equal(fmt.Sprintf("error getting pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) } func (s *RepoTestSuite) TestUpdateRepositoryCreateRepoPoolMgrFailed() { @@ -454,7 +454,7 @@ func (s *RepoTestSuite) TestUpdateRepositoryCreateRepoPoolMgrFailed() { _, err := s.Runner.UpdateRepository(s.Fixtures.AdminContext, s.Fixtures.StoreRepos["test-repo-1"].ID, s.Fixtures.UpdateRepoParams) s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T()) - s.Require().Equal(fmt.Sprintf("getting pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) + s.Require().Equal(fmt.Sprintf("error getting pool manager: %s", s.Fixtures.ErrMock.Error()), err.Error()) } func (s *RepoTestSuite) TestCreateRepoPool() { @@ -527,7 +527,7 @@ func (s *RepoTestSuite) TestDeleteRepoPool() { s.Require().Nil(err) _, err = s.Fixtures.Store.GetEntityPool(s.Fixtures.AdminContext, entity, pool.ID) - s.Require().Equal("fetching pool: finding pool: not found", err.Error()) + s.Require().Equal("fetching pool: error finding pool: not found", err.Error()) } func (s *RepoTestSuite) TestDeleteRepoPoolErrUnauthorized() { diff --git a/runner/runner.go b/runner/runner.go index da3f35ea..2c12071d 100644 --- a/runner/runner.go +++ b/runner/runner.go @@ -21,6 +21,7 @@ import ( "crypto/sha256" "encoding/hex" "encoding/json" + "errors" "fmt" "hash" "log/slog" @@ -30,9 +31,6 @@ import ( "sync" "time" - "github.com/juju/clock" - "github.com/juju/retry" - "github.com/pkg/errors" "golang.org/x/sync/errgroup" runnerErrors "github.com/cloudbase/garm-provider-common/errors" @@ -52,12 +50,12 @@ import ( func NewRunner(ctx context.Context, cfg config.Config, db dbCommon.Store) (*Runner, error) { ctrlID, err := db.ControllerInfo() if err != nil { - return nil, errors.Wrap(err, "fetching controller info") + return nil, fmt.Errorf("error fetching controller info: %w", err) } providers, err := providers.LoadProvidersFromConfig(ctx, cfg, ctrlID.ControllerID.String()) if err != nil { - return nil, errors.Wrap(err, "loading providers") + return nil, fmt.Errorf("error loading providers: %w", err) } creds := map[string]config.Github{} @@ -82,7 +80,7 @@ func NewRunner(ctx context.Context, cfg config.Config, db dbCommon.Store) (*Runn } if err := runner.loadReposOrgsAndEnterprises(); err != nil { - return nil, errors.Wrap(err, "loading pool managers") + return nil, fmt.Errorf("error loading pool managers: %w", err) } return runner, nil @@ -105,16 +103,16 @@ func (p *poolManagerCtrl) CreateRepoPoolManager(ctx context.Context, repo params entity, err := repo.GetEntity() if err != nil { - return nil, errors.Wrap(err, "getting entity") + return nil, fmt.Errorf("error getting entity: %w", err) } instanceTokenGetter, err := auth.NewInstanceTokenGetter(p.config.JWTAuth.Secret) if err != nil { - return nil, errors.Wrap(err, "creating instance token getter") + return nil, fmt.Errorf("error creating instance token getter: %w", err) } poolManager, err := pool.NewEntityPoolManager(ctx, entity, instanceTokenGetter, providers, store) if err != nil { - return nil, errors.Wrap(err, "creating repo pool manager") + return nil, fmt.Errorf("error creating repo pool manager: %w", err) } p.repositories[repo.ID] = poolManager return poolManager, nil @@ -124,7 +122,7 @@ func (p *poolManagerCtrl) GetRepoPoolManager(repo params.Repository) (common.Poo if repoPoolMgr, ok := p.repositories[repo.ID]; ok { return repoPoolMgr, nil } - return nil, errors.Wrapf(runnerErrors.ErrNotFound, "repository %s/%s pool manager not loaded", repo.Owner, repo.Name) + return nil, fmt.Errorf("repository %s/%s pool manager not loaded: %w", repo.Owner, repo.Name, runnerErrors.ErrNotFound) } func (p *poolManagerCtrl) DeleteRepoPoolManager(repo params.Repository) error { @@ -134,7 +132,7 @@ func (p *poolManagerCtrl) DeleteRepoPoolManager(repo params.Repository) error { poolMgr, ok := p.repositories[repo.ID] if ok { if err := poolMgr.Stop(); err != nil { - return errors.Wrap(err, "stopping repo pool manager") + return fmt.Errorf("error stopping repo pool manager: %w", err) } delete(p.repositories, repo.ID) } @@ -151,16 +149,16 @@ func (p *poolManagerCtrl) CreateOrgPoolManager(ctx context.Context, org params.O entity, err := org.GetEntity() if err != nil { - return nil, errors.Wrap(err, "getting entity") + return nil, fmt.Errorf("error getting entity: %w", err) } instanceTokenGetter, err := auth.NewInstanceTokenGetter(p.config.JWTAuth.Secret) if err != nil { - return nil, errors.Wrap(err, "creating instance token getter") + return nil, fmt.Errorf("error creating instance token getter: %w", err) } poolManager, err := pool.NewEntityPoolManager(ctx, entity, instanceTokenGetter, providers, store) if err != nil { - return nil, errors.Wrap(err, "creating org pool manager") + return nil, fmt.Errorf("error creating org pool manager: %w", err) } p.organizations[org.ID] = poolManager return poolManager, nil @@ -170,7 +168,7 @@ func (p *poolManagerCtrl) GetOrgPoolManager(org params.Organization) (common.Poo if orgPoolMgr, ok := p.organizations[org.ID]; ok { return orgPoolMgr, nil } - return nil, errors.Wrapf(runnerErrors.ErrNotFound, "organization %s pool manager not loaded", org.Name) + return nil, fmt.Errorf("organization %s pool manager not loaded: %w", org.Name, runnerErrors.ErrNotFound) } func (p *poolManagerCtrl) DeleteOrgPoolManager(org params.Organization) error { @@ -180,7 +178,7 @@ func (p *poolManagerCtrl) DeleteOrgPoolManager(org params.Organization) error { poolMgr, ok := p.organizations[org.ID] if ok { if err := poolMgr.Stop(); err != nil { - return errors.Wrap(err, "stopping org pool manager") + return fmt.Errorf("error stopping org pool manager: %w", err) } delete(p.organizations, org.ID) } @@ -197,16 +195,16 @@ func (p *poolManagerCtrl) CreateEnterprisePoolManager(ctx context.Context, enter entity, err := enterprise.GetEntity() if err != nil { - return nil, errors.Wrap(err, "getting entity") + return nil, fmt.Errorf("error getting entity: %w", err) } instanceTokenGetter, err := auth.NewInstanceTokenGetter(p.config.JWTAuth.Secret) if err != nil { - return nil, errors.Wrap(err, "creating instance token getter") + return nil, fmt.Errorf("error creating instance token getter: %w", err) } poolManager, err := pool.NewEntityPoolManager(ctx, entity, instanceTokenGetter, providers, store) if err != nil { - return nil, errors.Wrap(err, "creating enterprise pool manager") + return nil, fmt.Errorf("error creating enterprise pool manager: %w", err) } p.enterprises[enterprise.ID] = poolManager return poolManager, nil @@ -216,7 +214,7 @@ func (p *poolManagerCtrl) GetEnterprisePoolManager(enterprise params.Enterprise) if enterprisePoolMgr, ok := p.enterprises[enterprise.ID]; ok { return enterprisePoolMgr, nil } - return nil, errors.Wrapf(runnerErrors.ErrNotFound, "enterprise %s pool manager not loaded", enterprise.Name) + return nil, fmt.Errorf("enterprise %s pool manager not loaded: %w", enterprise.Name, runnerErrors.ErrNotFound) } func (p *poolManagerCtrl) DeleteEnterprisePoolManager(enterprise params.Enterprise) error { @@ -226,7 +224,7 @@ func (p *poolManagerCtrl) DeleteEnterprisePoolManager(enterprise params.Enterpri poolMgr, ok := p.enterprises[enterprise.ID] if ok { if err := poolMgr.Stop(); err != nil { - return errors.Wrap(err, "stopping enterprise pool manager") + return fmt.Errorf("error stopping enterprise pool manager: %w", err) } delete(p.enterprises, enterprise.ID) } @@ -256,12 +254,12 @@ func (r *Runner) UpdateController(ctx context.Context, param params.UpdateContro } if err := param.Validate(); err != nil { - return params.ControllerInfo{}, errors.Wrap(err, "validating controller update params") + return params.ControllerInfo{}, fmt.Errorf("error validating controller update params: %w", err) } info, err := r.store.UpdateController(param) if err != nil { - return params.ControllerInfo{}, errors.Wrap(err, "updating controller info") + return params.ControllerInfo{}, fmt.Errorf("error updating controller info: %w", err) } return info, nil } @@ -281,26 +279,26 @@ func (r *Runner) GetControllerInfo(ctx context.Context) (params.ControllerInfo, // As a side note, Windows requires a reboot for the hostname change to take effect, // so if we'll ever support Windows as a target system, the hostname can be cached. var hostname string - err := retry.Call(retry.CallArgs{ - Func: func() error { - var err error - hostname, err = os.Hostname() - if err != nil { - return errors.Wrap(err, "fetching hostname") + var err error + for range 10 { + hostname, err = os.Hostname() + if err != nil { + select { + case <-time.After(10 * time.Millisecond): + continue + case <-ctx.Done(): } - return nil - }, - Attempts: 10, - Delay: 100 * time.Millisecond, - Clock: clock.WallClock, - }) + return params.ControllerInfo{}, fmt.Errorf("error fetching hostname: %w", err) + } + break + } if err != nil { - return params.ControllerInfo{}, errors.Wrap(err, "fetching hostname") + return params.ControllerInfo{}, fmt.Errorf("error fetching hostname: %w", err) } info, err := r.store.ControllerInfo() if err != nil { - return params.ControllerInfo{}, errors.Wrap(err, "fetching controller info") + return params.ControllerInfo{}, fmt.Errorf("error fetching controller info: %w", err) } // This is temporary. Right now, GARM is a single-instance deployment. When we add the @@ -329,17 +327,17 @@ func (r *Runner) loadReposOrgsAndEnterprises() error { repos, err := r.store.ListRepositories(r.ctx, params.RepositoryFilter{}) if err != nil { - return errors.Wrap(err, "fetching repositories") + return fmt.Errorf("error fetching repositories: %w", err) } orgs, err := r.store.ListOrganizations(r.ctx, params.OrganizationFilter{}) if err != nil { - return errors.Wrap(err, "fetching organizations") + return fmt.Errorf("error fetching organizations: %w", err) } enterprises, err := r.store.ListEnterprises(r.ctx, params.EnterpriseFilter{}) if err != nil { - return errors.Wrap(err, "fetching enterprises") + return fmt.Errorf("error fetching enterprises: %w", err) } g, _ := errgroup.WithContext(r.ctx) @@ -384,17 +382,17 @@ func (r *Runner) Start() error { repositories, err := r.poolManagerCtrl.GetRepoPoolManagers() if err != nil { - return errors.Wrap(err, "fetch repo pool managers") + return fmt.Errorf("error fetch repo pool managers: %w", err) } organizations, err := r.poolManagerCtrl.GetOrgPoolManagers() if err != nil { - return errors.Wrap(err, "fetch org pool managers") + return fmt.Errorf("error fetch org pool managers: %w", err) } enterprises, err := r.poolManagerCtrl.GetEnterprisePoolManagers() if err != nil { - return errors.Wrap(err, "fetch enterprise pool managers") + return fmt.Errorf("error fetch enterprise pool managers: %w", err) } g, _ := errgroup.WithContext(r.ctx) @@ -450,17 +448,17 @@ func (r *Runner) Stop() error { repos, err := r.poolManagerCtrl.GetRepoPoolManagers() if err != nil { - return errors.Wrap(err, "fetch repo pool managers") + return fmt.Errorf("error fetching repo pool managers: %w", err) } orgs, err := r.poolManagerCtrl.GetOrgPoolManagers() if err != nil { - return errors.Wrap(err, "fetch org pool managers") + return fmt.Errorf("error fetching org pool managers: %w", err) } enterprises, err := r.poolManagerCtrl.GetEnterprisePoolManagers() if err != nil { - return errors.Wrap(err, "fetch enterprise pool managers") + return fmt.Errorf("error fetching enterprise pool managers: %w", err) } g, _ := errgroup.WithContext(r.ctx) @@ -512,17 +510,17 @@ func (r *Runner) Wait() error { repos, err := r.poolManagerCtrl.GetRepoPoolManagers() if err != nil { - return errors.Wrap(err, "fetch repo pool managers") + return fmt.Errorf("error fetching repo pool managers: %w", err) } orgs, err := r.poolManagerCtrl.GetOrgPoolManagers() if err != nil { - return errors.Wrap(err, "fetch org pool managers") + return fmt.Errorf("error fetching org pool managers: %w", err) } enterprises, err := r.poolManagerCtrl.GetEnterprisePoolManagers() if err != nil { - return errors.Wrap(err, "fetch enterprise pool managers") + return fmt.Errorf("error fetching enterprise pool managers: %w", err) } for poolID, repo := range repos { @@ -591,7 +589,7 @@ func (r *Runner) validateHookBody(signature, secret string, body []byte) error { mac := hmac.New(hashFunc, []byte(secret)) _, err := mac.Write(body) if err != nil { - return errors.Wrap(err, "failed to compute sha256") + return fmt.Errorf("failed to compute sha256: %w", err) } expectedMAC := hex.EncodeToString(mac.Sum(nil)) @@ -605,7 +603,7 @@ func (r *Runner) validateHookBody(signature, secret string, body []byte) error { func (r *Runner) findEndpointForJob(job params.WorkflowJob, forgeType params.EndpointType) (params.ForgeEndpoint, error) { uri, err := url.ParseRequestURI(job.WorkflowJob.HTMLURL) if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "parsing job URL") + return params.ForgeEndpoint{}, fmt.Errorf("error parsing job URL: %w", err) } baseURI := fmt.Sprintf("%s://%s", uri.Scheme, uri.Host) @@ -625,7 +623,7 @@ func (r *Runner) findEndpointForJob(job params.WorkflowJob, forgeType params.End } if err != nil { - return params.ForgeEndpoint{}, errors.Wrap(err, "fetching github endpoints") + return params.ForgeEndpoint{}, fmt.Errorf("error fetching github endpoints: %w", err) } for _, ep := range endpoints { slog.DebugContext(r.ctx, "checking endpoint", "base_uri", baseURI, "endpoint", ep.BaseURL) @@ -647,13 +645,13 @@ func (r *Runner) DispatchWorkflowJob(hookTargetType, signature string, forgeType var job params.WorkflowJob if err := json.Unmarshal(jobData, &job); err != nil { slog.ErrorContext(r.ctx, "failed to unmarshal job data", "error", err) - return errors.Wrapf(runnerErrors.ErrBadRequest, "invalid job data: %s", err) + return fmt.Errorf("invalid job data %s: %w", err, runnerErrors.ErrBadRequest) } endpoint, err := r.findEndpointForJob(job, forgeType) if err != nil { slog.ErrorContext(r.ctx, "failed to find endpoint for job", "error", err) - return errors.Wrap(err, "finding endpoint for job") + return fmt.Errorf("error finding endpoint for job: %w", err) } var poolManager common.PoolManager @@ -687,7 +685,7 @@ func (r *Runner) DispatchWorkflowJob(hookTargetType, signature string, forgeType slog.ErrorContext(r.ctx, "failed to find pool manager", "error", err, "hook_target_type", hookTargetType) // We don't have a repository or organization configured that // can handle this workflow job. - return errors.Wrap(err, "fetching poolManager") + return fmt.Errorf("error fetching poolManager: %w", err) } // We found a pool. Validate the webhook job. If a secret is configured, @@ -695,12 +693,12 @@ func (r *Runner) DispatchWorkflowJob(hookTargetType, signature string, forgeType secret := poolManager.WebhookSecret() if err := r.validateHookBody(signature, secret, jobData); err != nil { slog.ErrorContext(r.ctx, "failed to validate webhook data", "error", err) - return errors.Wrap(err, "validating webhook data") + return fmt.Errorf("error validating webhook data: %w", err) } if err := poolManager.HandleWorkflowJob(job); err != nil { slog.ErrorContext(r.ctx, "failed to handle workflow job", "error", err) - return errors.Wrap(err, "handling workflow job") + return fmt.Errorf("error handling workflow job: %w", err) } return nil @@ -735,7 +733,7 @@ func (r *Runner) GetInstance(ctx context.Context, instanceName string) (params.I instance, err := r.store.GetInstanceByName(ctx, instanceName) if err != nil { - return params.Instance{}, errors.Wrap(err, "fetching instance") + return params.Instance{}, fmt.Errorf("error fetching instance: %w", err) } return instance, nil } @@ -747,7 +745,7 @@ func (r *Runner) ListAllInstances(ctx context.Context) ([]params.Instance, error instances, err := r.store.ListAllInstances(ctx) if err != nil { - return nil, errors.Wrap(err, "fetching instances") + return nil, fmt.Errorf("error fetching instances: %w", err) } return instances, nil } @@ -759,7 +757,7 @@ func (r *Runner) AddInstanceStatusMessage(ctx context.Context, param params.Inst } if err := r.store.AddInstanceEvent(ctx, instanceName, params.StatusEvent, params.EventInfo, param.Message); err != nil { - return errors.Wrap(err, "adding status update") + return fmt.Errorf("error adding status update: %w", err) } updateParams := params.UpdateInstanceParams{ @@ -771,7 +769,7 @@ func (r *Runner) AddInstanceStatusMessage(ctx context.Context, param params.Inst } if _, err := r.store.UpdateInstance(r.ctx, instanceName, updateParams); err != nil { - return errors.Wrap(err, "updating runner agent ID") + return fmt.Errorf("error updating runner agent ID: %w", err) } return nil @@ -799,7 +797,7 @@ func (r *Runner) UpdateSystemInfo(ctx context.Context, param params.UpdateSystem } if _, err := r.store.UpdateInstance(r.ctx, instanceName, updateParams); err != nil { - return errors.Wrap(err, "updating runner system info") + return fmt.Errorf("error updating runner system info: %w", err) } return nil @@ -808,7 +806,7 @@ func (r *Runner) UpdateSystemInfo(ctx context.Context, param params.UpdateSystem func (r *Runner) getPoolManagerFromInstance(ctx context.Context, instance params.Instance) (common.PoolManager, error) { pool, err := r.store.GetPoolByID(ctx, instance.PoolID) if err != nil { - return nil, errors.Wrap(err, "fetching pool") + return nil, fmt.Errorf("error fetching pool: %w", err) } var poolMgr common.PoolManager @@ -817,29 +815,29 @@ func (r *Runner) getPoolManagerFromInstance(ctx context.Context, instance params case pool.RepoID != "": repo, err := r.store.GetRepositoryByID(ctx, pool.RepoID) if err != nil { - return nil, errors.Wrap(err, "fetching repo") + return nil, fmt.Errorf("error fetching repo: %w", err) } poolMgr, err = r.findRepoPoolManager(repo.Owner, repo.Name, repo.Endpoint.Name) if err != nil { - return nil, errors.Wrapf(err, "fetching pool manager for repo %s", pool.RepoName) + return nil, fmt.Errorf("error fetching pool manager for repo %s: %w", pool.RepoName, err) } case pool.OrgID != "": org, err := r.store.GetOrganizationByID(ctx, pool.OrgID) if err != nil { - return nil, errors.Wrap(err, "fetching org") + return nil, fmt.Errorf("error fetching org: %w", err) } poolMgr, err = r.findOrgPoolManager(org.Name, org.Endpoint.Name) if err != nil { - return nil, errors.Wrapf(err, "fetching pool manager for org %s", pool.OrgName) + return nil, fmt.Errorf("error fetching pool manager for org %s: %w", pool.OrgName, err) } case pool.EnterpriseID != "": enterprise, err := r.store.GetEnterpriseByID(ctx, pool.EnterpriseID) if err != nil { - return nil, errors.Wrap(err, "fetching enterprise") + return nil, fmt.Errorf("error fetching enterprise: %w", err) } poolMgr, err = r.findEnterprisePoolManager(enterprise.Name, enterprise.Endpoint.Name) if err != nil { - return nil, errors.Wrapf(err, "fetching pool manager for enterprise %s", pool.EnterpriseName) + return nil, fmt.Errorf("error fetching pool manager for enterprise %s: %w", pool.EnterpriseName, err) } } @@ -856,7 +854,7 @@ func (r *Runner) DeleteRunner(ctx context.Context, instanceName string, forceDel instance, err := r.store.GetInstanceByName(ctx, instanceName) if err != nil { - return errors.Wrap(err, "fetching instance") + return fmt.Errorf("error fetching instance: %w", err) } switch instance.Status { @@ -874,7 +872,7 @@ func (r *Runner) DeleteRunner(ctx context.Context, instanceName string, forceDel ghCli, ssCli, err := r.getGHCliFromInstance(ctx, instance) if err != nil { - return errors.Wrap(err, "fetching github client") + return fmt.Errorf("error fetching github client: %w", err) } if instance.AgentID != 0 { @@ -892,12 +890,12 @@ func (r *Runner) DeleteRunner(ctx context.Context, instanceName string, forceDel if errors.Is(err, runnerErrors.ErrUnauthorized) && instance.PoolID != "" { poolMgr, err := r.getPoolManagerFromInstance(ctx, instance) if err != nil { - return errors.Wrap(err, "fetching pool manager for instance") + return fmt.Errorf("error fetching pool manager for instance: %w", err) } poolMgr.SetPoolRunningState(false, fmt.Sprintf("failed to remove runner: %q", err)) } if !bypassGithubUnauthorized { - return errors.Wrap(err, "removing runner from github") + return fmt.Errorf("error removing runner from github: %w", err) } } } @@ -918,7 +916,7 @@ func (r *Runner) DeleteRunner(ctx context.Context, instanceName string, forceDel } _, err = r.store.UpdateInstance(r.ctx, instance.Name, updateParams) if err != nil { - return errors.Wrap(err, "updating runner state") + return fmt.Errorf("error updating runner state: %w", err) } return nil @@ -934,12 +932,12 @@ func (r *Runner) getGHCliFromInstance(ctx context.Context, instance params.Insta case instance.PoolID != "": entityGetter, err = r.store.GetPoolByID(ctx, instance.PoolID) if err != nil { - return nil, nil, errors.Wrap(err, "fetching pool") + return nil, nil, fmt.Errorf("error fetching pool: %w", err) } case instance.ScaleSetID != 0: entityGetter, err = r.store.GetScaleSetByID(ctx, instance.ScaleSetID) if err != nil { - return nil, nil, errors.Wrap(err, "fetching scale set") + return nil, nil, fmt.Errorf("error fetching scale set: %w", err) } default: return nil, nil, errors.New("instance does not have a pool or scale set") @@ -947,23 +945,23 @@ func (r *Runner) getGHCliFromInstance(ctx context.Context, instance params.Insta entity, err := entityGetter.GetEntity() if err != nil { - return nil, nil, errors.Wrap(err, "fetching entity") + return nil, nil, fmt.Errorf("error fetching entity: %w", err) } // Fetching the entity from the database will populate all fields, including credentials. entity, err = r.store.GetForgeEntity(ctx, entity.EntityType, entity.ID) if err != nil { - return nil, nil, errors.Wrap(err, "fetching entity") + return nil, nil, fmt.Errorf("error fetching entity: %w", err) } ghCli, err := github.Client(ctx, entity) if err != nil { - return nil, nil, errors.Wrap(err, "creating github client") + return nil, nil, fmt.Errorf("error creating github client: %w", err) } scaleSetCli, err := scalesets.NewClient(ghCli) if err != nil { - return nil, nil, errors.Wrap(err, "creating scaleset client") + return nil, nil, fmt.Errorf("error creating scaleset client: %w", err) } return ghCli, scaleSetCli, nil } diff --git a/runner/scalesets.go b/runner/scalesets.go index e7af9c22..d9361698 100644 --- a/runner/scalesets.go +++ b/runner/scalesets.go @@ -16,11 +16,10 @@ package runner import ( "context" + "errors" "fmt" "log/slog" - "github.com/pkg/errors" - runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/auth" "github.com/cloudbase/garm/params" @@ -36,7 +35,7 @@ func (r *Runner) ListAllScaleSets(ctx context.Context) ([]params.ScaleSet, error scalesets, err := r.store.ListAllScaleSets(ctx) if err != nil { - return nil, errors.Wrap(err, "fetching pools") + return nil, fmt.Errorf("error fetching pools: %w", err) } return scalesets, nil } @@ -48,7 +47,7 @@ func (r *Runner) GetScaleSetByID(ctx context.Context, scaleSet uint) (params.Sca set, err := r.store.GetScaleSetByID(ctx, scaleSet) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "fetching scale set") + return params.ScaleSet{}, fmt.Errorf("error fetching scale set: %w", err) } return set, nil } @@ -61,7 +60,7 @@ func (r *Runner) DeleteScaleSetByID(ctx context.Context, scaleSetID uint) error scaleSet, err := r.store.GetScaleSetByID(ctx, scaleSetID) if err != nil { if !errors.Is(err, runnerErrors.ErrNotFound) { - return errors.Wrap(err, "fetching scale set") + return fmt.Errorf("error fetching scale set: %w", err) } return nil } @@ -76,22 +75,22 @@ func (r *Runner) DeleteScaleSetByID(ctx context.Context, scaleSetID uint) error paramEntity, err := scaleSet.GetEntity() if err != nil { - return errors.Wrap(err, "getting entity") + return fmt.Errorf("error getting entity: %w", err) } entity, err := r.store.GetForgeEntity(ctx, paramEntity.EntityType, paramEntity.ID) if err != nil { - return errors.Wrap(err, "getting entity") + return fmt.Errorf("error getting entity: %w", err) } ghCli, err := github.Client(ctx, entity) if err != nil { - return errors.Wrap(err, "creating github client") + return fmt.Errorf("error creating github client: %w", err) } scalesetCli, err := scalesets.NewClient(ghCli) if err != nil { - return errors.Wrap(err, "getting scaleset client") + return fmt.Errorf("error getting scaleset client: %w", err) } slog.DebugContext(ctx, "deleting scale set", "scale_set_id", scaleSet.ScaleSetID) @@ -101,10 +100,10 @@ func (r *Runner) DeleteScaleSetByID(ctx context.Context, scaleSetID uint) error return nil } slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to delete scale set from github") - return errors.Wrap(err, "deleting scale set from github") + return fmt.Errorf("error deleting scale set from github: %w", err) } if err := r.store.DeleteScaleSetByID(ctx, scaleSetID); err != nil { - return errors.Wrap(err, "deleting scale set") + return fmt.Errorf("error deleting scale set: %w", err) } return nil } @@ -116,7 +115,7 @@ func (r *Runner) UpdateScaleSetByID(ctx context.Context, scaleSetID uint, param scaleSet, err := r.store.GetScaleSetByID(ctx, scaleSetID) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "fetching scale set") + return params.ScaleSet{}, fmt.Errorf("error fetching scale set: %w", err) } maxRunners := scaleSet.MaxRunners @@ -139,22 +138,22 @@ func (r *Runner) UpdateScaleSetByID(ctx context.Context, scaleSetID uint, param paramEntity, err := scaleSet.GetEntity() if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "getting entity") + return params.ScaleSet{}, fmt.Errorf("error getting entity: %w", err) } entity, err := r.store.GetForgeEntity(ctx, paramEntity.EntityType, paramEntity.ID) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "getting entity") + return params.ScaleSet{}, fmt.Errorf("error getting entity: %w", err) } ghCli, err := github.Client(ctx, entity) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "creating github client") + return params.ScaleSet{}, fmt.Errorf("error creating github client: %w", err) } scalesetCli, err := scalesets.NewClient(ghCli) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "getting scaleset client") + return params.ScaleSet{}, fmt.Errorf("error getting scaleset client: %w", err) } callback := func(old, newSet params.ScaleSet) error { @@ -190,7 +189,7 @@ func (r *Runner) UpdateScaleSetByID(ctx context.Context, scaleSetID uint, param newScaleSet, err := r.store.UpdateEntityScaleSet(ctx, entity, scaleSetID, param, callback) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "updating pool") + return params.ScaleSet{}, fmt.Errorf("error updating pool: %w", err) } return newScaleSet, nil } @@ -210,7 +209,7 @@ func (r *Runner) CreateEntityScaleSet(ctx context.Context, entityType params.For entity, err := r.store.GetForgeEntity(ctx, entityType, entityID) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "getting entity") + return params.ScaleSet{}, fmt.Errorf("error getting entity: %w", err) } if entity.Credentials.ForgeType != params.GithubEndpointType { @@ -219,18 +218,18 @@ func (r *Runner) CreateEntityScaleSet(ctx context.Context, entityType params.For ghCli, err := github.Client(ctx, entity) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "creating github client") + return params.ScaleSet{}, fmt.Errorf("error creating github client: %w", err) } scalesetCli, err := scalesets.NewClient(ghCli) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "getting scaleset client") + return params.ScaleSet{}, fmt.Errorf("error getting scaleset client: %w", err) } var runnerGroupID int64 = 1 if param.GitHubRunnerGroup != "Default" { runnerGroup, err := scalesetCli.GetRunnerGroupByName(ctx, param.GitHubRunnerGroup) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "getting runner group") + return params.ScaleSet{}, fmt.Errorf("error getting runner group: %w", err) } runnerGroupID = runnerGroup.ID } @@ -253,7 +252,7 @@ func (r *Runner) CreateEntityScaleSet(ctx context.Context, entityType params.For runnerScaleSet, err := scalesetCli.CreateRunnerScaleSet(ctx, createParam) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "creating runner scale set") + return params.ScaleSet{}, fmt.Errorf("error creating runner scale set: %w", err) } defer func() { @@ -267,7 +266,7 @@ func (r *Runner) CreateEntityScaleSet(ctx context.Context, entityType params.For scaleSet, err := r.store.CreateEntityScaleSet(ctx, entity, param) if err != nil { - return params.ScaleSet{}, errors.Wrap(err, "creating scale set") + return params.ScaleSet{}, fmt.Errorf("error creating scale set: %w", err) } return scaleSet, nil @@ -280,7 +279,7 @@ func (r *Runner) ListScaleSetInstances(ctx context.Context, scalesetID uint) ([] instances, err := r.store.ListScaleSetInstances(ctx, scalesetID) if err != nil { - return []params.Instance{}, errors.Wrap(err, "fetching instances") + return []params.Instance{}, fmt.Errorf("error fetching instances: %w", err) } return instances, nil } @@ -295,7 +294,7 @@ func (r *Runner) ListEntityScaleSets(ctx context.Context, entityType params.Forg } scaleSets, err := r.store.ListEntityScaleSets(ctx, entity) if err != nil { - return nil, errors.Wrap(err, "fetching scale sets") + return nil, fmt.Errorf("error fetching scale sets: %w", err) } return scaleSets, nil } diff --git a/util/github/client.go b/util/github/client.go index 46b6a170..19380587 100644 --- a/util/github/client.go +++ b/util/github/client.go @@ -18,6 +18,7 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "log/slog" "net/http" @@ -25,7 +26,6 @@ import ( "strings" "github.com/google/go-github/v72/github" - "github.com/pkg/errors" runnerErrors "github.com/cloudbase/garm-provider-common/errors" "github.com/cloudbase/garm/metrics" @@ -309,7 +309,7 @@ func (g *githubClient) RemoveEntityRunner(ctx context.Context, runnerID int64) e } if err := parseError(response, err); err != nil { - return errors.Wrapf(err, "removing runner %d", runnerID) + return fmt.Errorf("error removing runner %d: %w", runnerID, err) } return nil @@ -366,9 +366,9 @@ func (g *githubClient) getOrganizationRunnerGroupIDByName(ctx context.Context, e entity.LabelScope(), // label: scope ).Inc() if ghResp != nil && ghResp.StatusCode == http.StatusUnauthorized { - return 0, errors.Wrap(runnerErrors.ErrUnauthorized, "fetching runners") + return 0, fmt.Errorf("error fetching runners: %w", runnerErrors.ErrUnauthorized) } - return 0, errors.Wrap(err, "fetching runners") + return 0, fmt.Errorf("error fetching runners: %w", err) } for _, runnerGroup := range runnerGroups.RunnerGroups { if runnerGroup.Name != nil && *runnerGroup.Name == rgName { @@ -402,9 +402,9 @@ func (g *githubClient) getEnterpriseRunnerGroupIDByName(ctx context.Context, ent entity.LabelScope(), // label: scope ).Inc() if ghResp != nil && ghResp.StatusCode == http.StatusUnauthorized { - return 0, errors.Wrap(runnerErrors.ErrUnauthorized, "fetching runners") + return 0, fmt.Errorf("error fetching runners: %w", runnerErrors.ErrUnauthorized) } - return 0, errors.Wrap(err, "fetching runners") + return 0, fmt.Errorf("error fetching runners: %w", err) } for _, runnerGroup := range runnerGroups.RunnerGroups { if runnerGroup.Name != nil && *runnerGroup.Name == rgName { @@ -520,7 +520,7 @@ func (g *githubClient) GithubBaseURL() *url.URL { func NewRateLimitClient(ctx context.Context, credentials params.ForgeCredentials) (common.RateLimitClient, error) { httpClient, err := credentials.GetHTTPClient(ctx) if err != nil { - return nil, errors.Wrap(err, "fetching http client") + return nil, fmt.Errorf("error fetching http client: %w", err) } slog.DebugContext( @@ -531,7 +531,7 @@ func NewRateLimitClient(ctx context.Context, credentials params.ForgeCredentials ghClient, err := github.NewClient(httpClient).WithEnterpriseURLs( credentials.APIBaseURL, credentials.UploadBaseURL) if err != nil { - return nil, errors.Wrap(err, "fetching github client") + return nil, fmt.Errorf("error fetching github client: %w", err) } cli := &githubClient{ rateLimit: ghClient.RateLimit, @@ -552,7 +552,7 @@ func withGiteaURLs(client *github.Client, apiBaseURL string) (*github.Client, er parsedBaseURL, err := url.ParseRequestURI(apiBaseURL) if err != nil { - return nil, errors.Wrap(err, "parsing gitea base URL") + return nil, fmt.Errorf("error parsing gitea base URL: %w", err) } if !strings.HasSuffix(parsedBaseURL.Path, "/") { @@ -573,7 +573,7 @@ func Client(ctx context.Context, entity params.ForgeEntity) (common.GithubClient // func GithubClient(ctx context.Context, entity params.ForgeEntity) (common.GithubClient, error) { httpClient, err := entity.Credentials.GetHTTPClient(ctx) if err != nil { - return nil, errors.Wrap(err, "fetching http client") + return nil, fmt.Errorf("error fetching http client: %w", err) } slog.DebugContext( @@ -590,7 +590,7 @@ func Client(ctx context.Context, entity params.ForgeEntity) (common.GithubClient } if err != nil { - return nil, errors.Wrap(err, "fetching github client") + return nil, fmt.Errorf("error fetching github client: %w", err) } cli := &githubClient{ diff --git a/util/github/gitea.go b/util/github/gitea.go index 51f340b7..5d35190b 100644 --- a/util/github/gitea.go +++ b/util/github/gitea.go @@ -16,11 +16,11 @@ package github import ( "context" + "errors" "fmt" "net/http" "github.com/google/go-github/v72/github" - "github.com/pkg/errors" "github.com/cloudbase/garm/metrics" "github.com/cloudbase/garm/params" diff --git a/util/util.go b/util/util.go index 994e4637..dc92ce0e 100644 --- a/util/util.go +++ b/util/util.go @@ -16,11 +16,10 @@ package util import ( "context" + "fmt" "net/http" "unicode/utf8" - "github.com/pkg/errors" - runnerErrors "github.com/cloudbase/garm-provider-common/errors" commonParams "github.com/cloudbase/garm-provider-common/params" "github.com/cloudbase/garm/runner/common" @@ -30,9 +29,9 @@ func FetchTools(ctx context.Context, cli common.GithubClient) ([]commonParams.Ru tools, ghResp, err := cli.ListEntityRunnerApplicationDownloads(ctx) if err != nil { if ghResp != nil && ghResp.StatusCode == http.StatusUnauthorized { - return nil, errors.Wrap(runnerErrors.ErrUnauthorized, "fetching tools") + return nil, fmt.Errorf("error fetching tools: %w", runnerErrors.ErrUnauthorized) } - return nil, errors.Wrap(err, "fetching runner tools") + return nil, fmt.Errorf("error fetching runner tools: %w", err) } ret := []commonParams.RunnerApplicationDownload{} diff --git a/vendor/github.com/juju/clock/.gitignore b/vendor/github.com/juju/clock/.gitignore deleted file mode 100644 index 1d74e219..00000000 --- a/vendor/github.com/juju/clock/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.vscode/ diff --git a/vendor/github.com/juju/clock/LICENSE b/vendor/github.com/juju/clock/LICENSE deleted file mode 100644 index ade9307b..00000000 --- a/vendor/github.com/juju/clock/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -All files in this repository are licensed as follows. If you contribute -to this repository, it is assumed that you license your contribution -under the same license unless you state otherwise. - -All files Copyright (C) 2015 Canonical Ltd. unless otherwise specified in the file. - -This software is licensed under the LGPLv3, included below. - -As a special exception to the GNU Lesser General Public License version 3 -("LGPL3"), the copyright holders of this Library give you permission to -convey to a third party a Combined Work that links statically or dynamically -to this Library without providing any Minimal Corresponding Source or -Minimal Application Code as set out in 4d or providing the installation -information set out in section 4e, provided that you comply with the other -provisions of LGPL3 and provided that you meet, for the Application the -terms and conditions of the license(s) which apply to the Application. - -Except as stated in this special exception, the provisions of LGPL3 will -continue to comply in full to this Library. If you modify this Library, you -may apply this exception to your version of this Library, but you are not -obliged to do so. If you do not wish to do so, delete this exception -statement from your version. This exception does not (and cannot) modify any -license terms which apply to the Application, with which you must still -comply. - - - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/vendor/github.com/juju/clock/Makefile b/vendor/github.com/juju/clock/Makefile deleted file mode 100644 index 900ccf75..00000000 --- a/vendor/github.com/juju/clock/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -PROJECT := github.com/juju/clock - -.PHONY: check-licence check-go check - -check: check-licence check-go - go test $(PROJECT)/... - -check-licence: - @(fgrep -rl "Licensed under the LGPLv3" --exclude *.s .;\ - fgrep -rl "MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT" --exclude *.s .;\ - find . -name "*.go") | sed -e 's,\./,,' | sort | uniq -u | \ - xargs -I {} echo FAIL: licence missed: {} - -check-go: - $(eval GOFMT := $(strip $(shell gofmt -l .| sed -e "s/^/ /g"))) - @(if [ x$(GOFMT) != x"" ]; then \ - echo go fmt is sad: $(GOFMT); \ - exit 1; \ - fi ) - @(go vet -all -composites=false -copylocks=false .) diff --git a/vendor/github.com/juju/clock/README.md b/vendor/github.com/juju/clock/README.md deleted file mode 100644 index a5ac464d..00000000 --- a/vendor/github.com/juju/clock/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# clock - -An interface definition for a fully defined clock. - -An WallClock implementation of that interface using the time package. - -A testing clock. diff --git a/vendor/github.com/juju/clock/clock.go b/vendor/github.com/juju/clock/clock.go deleted file mode 100644 index 6303cf65..00000000 --- a/vendor/github.com/juju/clock/clock.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2015 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package clock - -import "time" - -// Clock provides an interface for dealing with clocks. -type Clock interface { - // Now returns the current clock time. - Now() time.Time - - // After waits for the duration to elapse and then sends the - // current time on the returned channel. - After(time.Duration) <-chan time.Time - - // AfterFunc waits for the duration to elapse and then calls f in its own goroutine. - // It returns a Timer that can be used to cancel the call using its Stop method. - AfterFunc(d time.Duration, f func()) Timer - - // NewTimer creates a new Timer that will send the current time - // on its channel after at least duration d. - NewTimer(d time.Duration) Timer - - // At waits for the time to pass and then sends the - // current time on the returned channel. - At(t time.Time) <-chan time.Time - - // AtFunc waits for the time to pass and then calls f in its own goroutine. - // It returns an Alarm that can be used to cancel the call using its Stop method. - AtFunc(t time.Time, f func()) Alarm - - // NewAlarm creates a new Alarm that will send the current time - // on its channel at or after time t has passed. - NewAlarm(t time.Time) Alarm -} - -// Timer type represents a single event. -// Timers must be created with AfterFunc or NewTimer. -// This interface follows time.Timer's methods but provides easier mocking. -type Timer interface { - // When the timer expires, the current time will be sent on the - // channel returned from Chan, unless the timer was created by - // AfterFunc. - Chan() <-chan time.Time - - // Reset changes the timer to expire after duration d. - // It returns true if the timer had been active, false if - // the timer had expired or been stopped. - Reset(d time.Duration) bool - - // Stop prevents the Timer from firing. It returns true if - // the call stops the timer, false if the timer has already expired or been stopped. - // Stop does not close the channel, to prevent a read - // from the channel succeeding incorrectly. - Stop() bool -} - -// Alarm type represents a single event. -// Alarms must be created with AtFunc or NewAlarm. -type Alarm interface { - // When the alarm expires, the current time will be sent on the - // channel returned from Chan, unless the alarm was created by - // AtFunc. - Chan() <-chan time.Time - - // Reset changes the alarm to expire at or after time t. - // It returns true if the alarm had been active, false if - // the alarm had fired or been stopped. - Reset(t time.Time) bool - - // Stop prevents the alarm from firing. It returns true if - // the call stops the alarm, false if the alarm has already fired or been stopped. - // Stop does not close the channel, to prevent a read - // from the channel succeeding incorrectly. - Stop() bool -} diff --git a/vendor/github.com/juju/clock/wall.go b/vendor/github.com/juju/clock/wall.go deleted file mode 100644 index 1a4b021e..00000000 --- a/vendor/github.com/juju/clock/wall.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2015 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package clock - -import ( - "time" -) - -// WallClock exposes wall-clock time via the Clock interface. -var WallClock wallClock - -// ensure that WallClock does actually implement the Clock interface. -var _ Clock = WallClock - -// WallClock exposes wall-clock time as returned by time.Now. -type wallClock struct{} - -// Now is part of the Clock interface. -func (wallClock) Now() time.Time { - return time.Now() -} - -// After implements Clock.After. -func (wallClock) After(d time.Duration) <-chan time.Time { - return time.After(d) -} - -// AfterFunc implements Clock.AfterFunc. -func (wallClock) AfterFunc(d time.Duration, f func()) Timer { - return wallTimer{time.AfterFunc(d, f)} -} - -// NewTimer implements Clock.NewTimer. -func (wallClock) NewTimer(d time.Duration) Timer { - return wallTimer{time.NewTimer(d)} -} - -// wallTimer implements the Timer interface. -type wallTimer struct { - *time.Timer -} - -// Chan implements Timer.Chan. -func (t wallTimer) Chan() <-chan time.Time { - return t.C -} - -// At implements Clock.At. -func (wallClock) At(t time.Time) <-chan time.Time { - return time.After(time.Until(t)) -} - -// AtFunc implements Clock.AtFunc. -func (wallClock) AtFunc(t time.Time, f func()) Alarm { - return wallAlarm{time.AfterFunc(time.Until(t), f)} -} - -// NewAlarm implements Clock.NewAlarm. -func (wallClock) NewAlarm(t time.Time) Alarm { - return wallAlarm{time.NewTimer(time.Until(t))} -} - -// wallAlarm implements the Alarm interface. -type wallAlarm struct { - *time.Timer -} - -// Chan implements Alarm.Chan. -func (a wallAlarm) Chan() <-chan time.Time { - return a.C -} - -// Reset implements Alarm.Reset -func (a wallAlarm) Reset(t time.Time) bool { - return a.Timer.Reset(time.Until(t)) -} diff --git a/vendor/github.com/juju/errors/.gitignore b/vendor/github.com/juju/errors/.gitignore deleted file mode 100644 index 83656241..00000000 --- a/vendor/github.com/juju/errors/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test diff --git a/vendor/github.com/juju/errors/LICENSE b/vendor/github.com/juju/errors/LICENSE deleted file mode 100644 index ade9307b..00000000 --- a/vendor/github.com/juju/errors/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -All files in this repository are licensed as follows. If you contribute -to this repository, it is assumed that you license your contribution -under the same license unless you state otherwise. - -All files Copyright (C) 2015 Canonical Ltd. unless otherwise specified in the file. - -This software is licensed under the LGPLv3, included below. - -As a special exception to the GNU Lesser General Public License version 3 -("LGPL3"), the copyright holders of this Library give you permission to -convey to a third party a Combined Work that links statically or dynamically -to this Library without providing any Minimal Corresponding Source or -Minimal Application Code as set out in 4d or providing the installation -information set out in section 4e, provided that you comply with the other -provisions of LGPL3 and provided that you meet, for the Application the -terms and conditions of the license(s) which apply to the Application. - -Except as stated in this special exception, the provisions of LGPL3 will -continue to comply in full to this Library. If you modify this Library, you -may apply this exception to your version of this Library, but you are not -obliged to do so. If you do not wish to do so, delete this exception -statement from your version. This exception does not (and cannot) modify any -license terms which apply to the Application, with which you must still -comply. - - - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/vendor/github.com/juju/errors/Makefile b/vendor/github.com/juju/errors/Makefile deleted file mode 100644 index a5bc81e6..00000000 --- a/vendor/github.com/juju/errors/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -PROJECT := github.com/juju/errors - -.PHONY: check-licence check-go check docs - -check: check-licence check-go - go test $(PROJECT)/... - -check-licence: - @(fgrep -rl "Licensed under the LGPLv3" --exclude *.s .;\ - fgrep -rl "MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT" --exclude *.s .;\ - find . -name "*.go") | sed -e 's,\./,,' | sort | uniq -u | \ - xargs -I {} echo FAIL: licence missed: {} - -check-go: - $(eval GOFMT := $(strip $(shell gofmt -l .| sed -e "s/^/ /g"))) - @(if [ x$(GOFMT) != x"" ]; then \ - echo go fmt is sad: $(GOFMT); \ - exit 1; \ - fi ) - @(go vet -all -composites=false -copylocks=false .) - -docs: - godoc2md github.com/juju/errors > README.md - sed -i '5i[\[GoDoc](https://godoc.org/github.com/juju/errors?status.svg)](https://godoc.org/github.com/juju/errors)' README.md diff --git a/vendor/github.com/juju/errors/README.md b/vendor/github.com/juju/errors/README.md deleted file mode 100644 index 271aa78c..00000000 --- a/vendor/github.com/juju/errors/README.md +++ /dev/null @@ -1,707 +0,0 @@ - -# errors - import "github.com/juju/errors" - -[![GoDoc](https://godoc.org/github.com/juju/errors?status.svg)](https://godoc.org/github.com/juju/errors) - -The juju/errors provides an easy way to annotate errors without losing the -original error context. - -The exported `New` and `Errorf` functions are designed to replace the -`errors.New` and `fmt.Errorf` functions respectively. The same underlying -error is there, but the package also records the location at which the error -was created. - -A primary use case for this library is to add extra context any time an -error is returned from a function. - - - if err := SomeFunc(); err != nil { - return err - } - -This instead becomes: - - - if err := SomeFunc(); err != nil { - return errors.Trace(err) - } - -which just records the file and line number of the Trace call, or - - - if err := SomeFunc(); err != nil { - return errors.Annotate(err, "more context") - } - -which also adds an annotation to the error. - -When you want to check to see if an error is of a particular type, a helper -function is normally exported by the package that returned the error, like the -`os` package does. The underlying cause of the error is available using the -`Cause` function. - - - os.IsNotExist(errors.Cause(err)) - -The result of the `Error()` call on an annotated error is the annotations joined -with colons, then the result of the `Error()` method for the underlying error -that was the cause. - - - err := errors.Errorf("original") - err = errors.Annotatef(err, "context") - err = errors.Annotatef(err, "more context") - err.Error() -> "more context: context: original" - -Obviously recording the file, line and functions is not very useful if you -cannot get them back out again. - - - errors.ErrorStack(err) - -will return something like: - - - first error - github.com/juju/errors/annotation_test.go:193: - github.com/juju/errors/annotation_test.go:194: annotation - github.com/juju/errors/annotation_test.go:195: - github.com/juju/errors/annotation_test.go:196: more context - github.com/juju/errors/annotation_test.go:197: - -The first error was generated by an external system, so there was no location -associated. The second, fourth, and last lines were generated with Trace calls, -and the other two through Annotate. - -Sometimes when responding to an error you want to return a more specific error -for the situation. - - - if err := FindField(field); err != nil { - return errors.Wrap(err, errors.NotFoundf(field)) - } - -This returns an error where the complete error stack is still available, and -`errors.Cause()` will return the `NotFound` error. - - - - - - -## func AlreadyExistsf -``` go -func AlreadyExistsf(format string, args ...interface{}) error -``` -AlreadyExistsf returns an error which satisfies IsAlreadyExists(). - - -## func Annotate -``` go -func Annotate(other error, message string) error -``` -Annotate is used to add extra context to an existing error. The location of -the Annotate call is recorded with the annotations. The file, line and -function are also recorded. - -For example: - - - if err := SomeFunc(); err != nil { - return errors.Annotate(err, "failed to frombulate") - } - - -## func Annotatef -``` go -func Annotatef(other error, format string, args ...interface{}) error -``` -Annotatef is used to add extra context to an existing error. The location of -the Annotate call is recorded with the annotations. The file, line and -function are also recorded. - -For example: - - - if err := SomeFunc(); err != nil { - return errors.Annotatef(err, "failed to frombulate the %s", arg) - } - - -## func BadRequestf -``` go -func BadRequestf(format string, args ...interface{}) error -``` -BadRequestf returns an error which satisfies IsBadRequest(). - - -## func Cause -``` go -func Cause(err error) error -``` -Cause returns the cause of the given error. This will be either the -original error, or the result of a Wrap or Mask call. - -Cause is the usual way to diagnose errors that may have been wrapped by -the other errors functions. - - -## func DeferredAnnotatef -``` go -func DeferredAnnotatef(err *error, format string, args ...interface{}) -``` -DeferredAnnotatef annotates the given error (when it is not nil) with the given -format string and arguments (like fmt.Sprintf). If *err is nil, DeferredAnnotatef -does nothing. This method is used in a defer statement in order to annotate any -resulting error with the same message. - -For example: - - - defer DeferredAnnotatef(&err, "failed to frombulate the %s", arg) - - -## func Details -``` go -func Details(err error) string -``` -Details returns information about the stack of errors wrapped by err, in -the format: - - - [{filename:99: error one} {otherfile:55: cause of error one}] - -This is a terse alternative to ErrorStack as it returns a single line. - - -## func ErrorStack -``` go -func ErrorStack(err error) string -``` -ErrorStack returns a string representation of the annotated error. If the -error passed as the parameter is not an annotated error, the result is -simply the result of the Error() method on that error. - -If the error is an annotated error, a multi-line string is returned where -each line represents one entry in the annotation stack. The full filename -from the call stack is used in the output. - - - first error - github.com/juju/errors/annotation_test.go:193: - github.com/juju/errors/annotation_test.go:194: annotation - github.com/juju/errors/annotation_test.go:195: - github.com/juju/errors/annotation_test.go:196: more context - github.com/juju/errors/annotation_test.go:197: - - -## func Errorf -``` go -func Errorf(format string, args ...interface{}) error -``` -Errorf creates a new annotated error and records the location that the -error is created. This should be a drop in replacement for fmt.Errorf. - -For example: - - - return errors.Errorf("validation failed: %s", message) - - -## func Forbiddenf -``` go -func Forbiddenf(format string, args ...interface{}) error -``` -Forbiddenf returns an error which satistifes IsForbidden() - - -## func IsAlreadyExists -``` go -func IsAlreadyExists(err error) bool -``` -IsAlreadyExists reports whether the error was created with -AlreadyExistsf() or NewAlreadyExists(). - - -## func IsBadRequest -``` go -func IsBadRequest(err error) bool -``` -IsBadRequest reports whether err was created with BadRequestf() or -NewBadRequest(). - - -## func IsForbidden -``` go -func IsForbidden(err error) bool -``` -IsForbidden reports whether err was created with Forbiddenf() or -NewForbidden(). - - -## func IsMethodNotAllowed -``` go -func IsMethodNotAllowed(err error) bool -``` -IsMethodNotAllowed reports whether err was created with MethodNotAllowedf() or -NewMethodNotAllowed(). - - -## func IsNotAssigned -``` go -func IsNotAssigned(err error) bool -``` -IsNotAssigned reports whether err was created with NotAssignedf() or -NewNotAssigned(). - - -## func IsNotFound -``` go -func IsNotFound(err error) bool -``` -IsNotFound reports whether err was created with NotFoundf() or -NewNotFound(). - - -## func IsNotImplemented -``` go -func IsNotImplemented(err error) bool -``` -IsNotImplemented reports whether err was created with -NotImplementedf() or NewNotImplemented(). - - -## func IsNotProvisioned -``` go -func IsNotProvisioned(err error) bool -``` -IsNotProvisioned reports whether err was created with NotProvisionedf() or -NewNotProvisioned(). - - -## func IsNotSupported -``` go -func IsNotSupported(err error) bool -``` -IsNotSupported reports whether the error was created with -NotSupportedf() or NewNotSupported(). - - -## func IsNotValid -``` go -func IsNotValid(err error) bool -``` -IsNotValid reports whether the error was created with NotValidf() or -NewNotValid(). - - -## func IsUnauthorized -``` go -func IsUnauthorized(err error) bool -``` -IsUnauthorized reports whether err was created with Unauthorizedf() or -NewUnauthorized(). - - -## func IsUserNotFound -``` go -func IsUserNotFound(err error) bool -``` -IsUserNotFound reports whether err was created with UserNotFoundf() or -NewUserNotFound(). - - -## func Mask -``` go -func Mask(other error) error -``` -Mask hides the underlying error type, and records the location of the masking. - - -## func Maskf -``` go -func Maskf(other error, format string, args ...interface{}) error -``` -Mask masks the given error with the given format string and arguments (like -fmt.Sprintf), returning a new error that maintains the error stack, but -hides the underlying error type. The error string still contains the full -annotations. If you want to hide the annotations, call Wrap. - - -## func MethodNotAllowedf -``` go -func MethodNotAllowedf(format string, args ...interface{}) error -``` -MethodNotAllowedf returns an error which satisfies IsMethodNotAllowed(). - - -## func New -``` go -func New(message string) error -``` -New is a drop in replacement for the standard library errors module that records -the location that the error is created. - -For example: - - - return errors.New("validation failed") - - -## func NewAlreadyExists -``` go -func NewAlreadyExists(err error, msg string) error -``` -NewAlreadyExists returns an error which wraps err and satisfies -IsAlreadyExists(). - - -## func NewBadRequest -``` go -func NewBadRequest(err error, msg string) error -``` -NewBadRequest returns an error which wraps err that satisfies -IsBadRequest(). - - -## func NewForbidden -``` go -func NewForbidden(err error, msg string) error -``` -NewForbidden returns an error which wraps err that satisfies -IsForbidden(). - - -## func NewMethodNotAllowed -``` go -func NewMethodNotAllowed(err error, msg string) error -``` -NewMethodNotAllowed returns an error which wraps err that satisfies -IsMethodNotAllowed(). - - -## func NewNotAssigned -``` go -func NewNotAssigned(err error, msg string) error -``` -NewNotAssigned returns an error which wraps err that satisfies -IsNotAssigned(). - - -## func NewNotFound -``` go -func NewNotFound(err error, msg string) error -``` -NewNotFound returns an error which wraps err that satisfies -IsNotFound(). - - -## func NewNotImplemented -``` go -func NewNotImplemented(err error, msg string) error -``` -NewNotImplemented returns an error which wraps err and satisfies -IsNotImplemented(). - - -## func NewNotProvisioned -``` go -func NewNotProvisioned(err error, msg string) error -``` -NewNotProvisioned returns an error which wraps err that satisfies -IsNotProvisioned(). - - -## func NewNotSupported -``` go -func NewNotSupported(err error, msg string) error -``` -NewNotSupported returns an error which wraps err and satisfies -IsNotSupported(). - - -## func NewNotValid -``` go -func NewNotValid(err error, msg string) error -``` -NewNotValid returns an error which wraps err and satisfies IsNotValid(). - - -## func NewUnauthorized -``` go -func NewUnauthorized(err error, msg string) error -``` -NewUnauthorized returns an error which wraps err and satisfies -IsUnauthorized(). - - -## func NewUserNotFound -``` go -func NewUserNotFound(err error, msg string) error -``` -NewUserNotFound returns an error which wraps err and satisfies -IsUserNotFound(). - - -## func NotAssignedf -``` go -func NotAssignedf(format string, args ...interface{}) error -``` -NotAssignedf returns an error which satisfies IsNotAssigned(). - - -## func NotFoundf -``` go -func NotFoundf(format string, args ...interface{}) error -``` -NotFoundf returns an error which satisfies IsNotFound(). - - -## func NotImplementedf -``` go -func NotImplementedf(format string, args ...interface{}) error -``` -NotImplementedf returns an error which satisfies IsNotImplemented(). - - -## func NotProvisionedf -``` go -func NotProvisionedf(format string, args ...interface{}) error -``` -NotProvisionedf returns an error which satisfies IsNotProvisioned(). - - -## func NotSupportedf -``` go -func NotSupportedf(format string, args ...interface{}) error -``` -NotSupportedf returns an error which satisfies IsNotSupported(). - - -## func NotValidf -``` go -func NotValidf(format string, args ...interface{}) error -``` -NotValidf returns an error which satisfies IsNotValid(). - - -## func Trace -``` go -func Trace(other error) error -``` -Trace adds the location of the Trace call to the stack. The Cause of the -resulting error is the same as the error parameter. If the other error is -nil, the result will be nil. - -For example: - - - if err := SomeFunc(); err != nil { - return errors.Trace(err) - } - - -## func Unauthorizedf -``` go -func Unauthorizedf(format string, args ...interface{}) error -``` -Unauthorizedf returns an error which satisfies IsUnauthorized(). - - -## func UserNotFoundf -``` go -func UserNotFoundf(format string, args ...interface{}) error -``` -UserNotFoundf returns an error which satisfies IsUserNotFound(). - - -## func Wrap -``` go -func Wrap(other, newDescriptive error) error -``` -Wrap changes the Cause of the error. The location of the Wrap call is also -stored in the error stack. - -For example: - - - if err := SomeFunc(); err != nil { - newErr := &packageError{"more context", private_value} - return errors.Wrap(err, newErr) - } - - -## func Wrapf -``` go -func Wrapf(other, newDescriptive error, format string, args ...interface{}) error -``` -Wrapf changes the Cause of the error, and adds an annotation. The location -of the Wrap call is also stored in the error stack. - -For example: - - - if err := SomeFunc(); err != nil { - return errors.Wrapf(err, simpleErrorType, "invalid value %q", value) - } - - - -## type Err -``` go -type Err struct { - // contains filtered or unexported fields -} -``` -Err holds a description of an error along with information about -where the error was created. - -It may be embedded in custom error types to add extra information that -this errors package can understand. - - - - - - - - - -### func NewErr -``` go -func NewErr(format string, args ...interface{}) Err -``` -NewErr is used to return an Err for the purpose of embedding in other -structures. The location is not specified, and needs to be set with a call -to SetLocation. - -For example: - - - type FooError struct { - errors.Err - code int - } - - func NewFooError(code int) error { - err := &FooError{errors.NewErr("foo"), code} - err.SetLocation(1) - return err - } - - -### func NewErrWithCause -``` go -func NewErrWithCause(other error, format string, args ...interface{}) Err -``` -NewErrWithCause is used to return an Err with cause by other error for the purpose of embedding in other -structures. The location is not specified, and needs to be set with a call -to SetLocation. - -For example: - - - type FooError struct { - errors.Err - code int - } - - func (e *FooError) Annotate(format string, args ...interface{}) error { - err := &FooError{errors.NewErrWithCause(e.Err, format, args...), e.code} - err.SetLocation(1) - return err - }) - - - - -### func (\*Err) Cause -``` go -func (e *Err) Cause() error -``` -The Cause of an error is the most recent error in the error stack that -meets one of these criteria: the original error that was raised; the new -error that was passed into the Wrap function; the most recently masked -error; or nil if the error itself is considered the Cause. Normally this -method is not invoked directly, but instead through the Cause stand alone -function. - - - -### func (\*Err) Error -``` go -func (e *Err) Error() string -``` -Error implements error.Error. - - - -### func (\*Err) Format -``` go -func (e *Err) Format(s fmt.State, verb rune) -``` -Format implements fmt.Formatter -When printing errors with %+v it also prints the stack trace. -%#v unsurprisingly will print the real underlying type. - - - -### func (\*Err) Location -``` go -func (e *Err) Location() (filename string, line int) -``` -Location is the file and line of where the error was most recently -created or annotated. - - - -### func (\*Err) Message -``` go -func (e *Err) Message() string -``` -Message returns the message stored with the most recent location. This is -the empty string if the most recent call was Trace, or the message stored -with Annotate or Mask. - - - -### func (\*Err) SetLocation -``` go -func (e *Err) SetLocation(callDepth int) -``` -SetLocation records the source location of the error at callDepth stack -frames above the call. - - - -### func (\*Err) StackTrace -``` go -func (e *Err) StackTrace() []string -``` -StackTrace returns one string for each location recorded in the stack of -errors. The first value is the originating error, with a line for each -other annotation or tracing of the error. - - - -### func (\*Err) Underlying -``` go -func (e *Err) Underlying() error -``` -Underlying returns the previous error in the error stack, if any. A client -should not ever really call this method. It is used to build the error -stack and should not be introspected by client calls. Or more -specifically, clients should not depend on anything but the `Cause` of an -error. - - - - - - - - - -- - - -Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) diff --git a/vendor/github.com/juju/errors/doc.go b/vendor/github.com/juju/errors/doc.go deleted file mode 100644 index d4403662..00000000 --- a/vendor/github.com/juju/errors/doc.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2013, 2014 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -/* -Package errors provides an easy way to annotate errors without losing the -original error context. - -The exported `New` and `Errorf` functions are designed to replace the -`errors.New` and `fmt.Errorf` functions respectively. The same underlying -error is there, but the package also records the location at which the error -was created. - -A primary use case for this library is to add extra context any time an -error is returned from a function. - - if err := SomeFunc(); err != nil { - return err - } - -This instead becomes: - - if err := SomeFunc(); err != nil { - return errors.Trace(err) - } - -which just records the file and line number of the Trace call, or - - if err := SomeFunc(); err != nil { - return errors.Annotate(err, "more context") - } - -which also adds an annotation to the error. - -When you want to check to see if an error is of a particular type, a helper -function is normally exported by the package that returned the error, like the -`os` package does. The underlying cause of the error is available using the -`Cause` function. - - os.IsNotExist(errors.Cause(err)) - -The result of the `Error()` call on an annotated error is the annotations joined -with colons, then the result of the `Error()` method for the underlying error -that was the cause. - - err := errors.Errorf("original") - err = errors.Annotatef(err, "context") - err = errors.Annotatef(err, "more context") - err.Error() -> "more context: context: original" - -Obviously recording the file, line and functions is not very useful if you -cannot get them back out again. - - errors.ErrorStack(err) - -will return something like: - - first error - github.com/juju/errors/annotation_test.go:193: - github.com/juju/errors/annotation_test.go:194: annotation - github.com/juju/errors/annotation_test.go:195: - github.com/juju/errors/annotation_test.go:196: more context - github.com/juju/errors/annotation_test.go:197: - -The first error was generated by an external system, so there was no location -associated. The second, fourth, and last lines were generated with Trace calls, -and the other two through Annotate. - -Sometimes when responding to an error you want to return a more specific error -for the situation. - - if err := FindField(field); err != nil { - return errors.Wrap(err, errors.NotFoundf(field)) - } - -This returns an error where the complete error stack is still available, and -`errors.Cause()` will return the `NotFound` error. - -*/ -package errors diff --git a/vendor/github.com/juju/errors/error.go b/vendor/github.com/juju/errors/error.go deleted file mode 100644 index 326b917a..00000000 --- a/vendor/github.com/juju/errors/error.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2014 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package errors - -import ( - "fmt" - "reflect" -) - -// Err holds a description of an error along with information about -// where the error was created. -// -// It may be embedded in custom error types to add extra information that -// this errors package can understand. -type Err struct { - // message holds an annotation of the error. - message string - - // cause holds the cause of the error as returned - // by the Cause method. - cause error - - // previous holds the previous error in the error stack, if any. - previous error - - // function is the package path-qualified function name where the - // error was created. - function string - - // line is the line number the error was created on inside of function - line int -} - -// Locationer is an interface that represents a certain class of errors that -// contain the location information from where they were raised. -type Locationer interface { - // Location returns the path-qualified function name where the error was - // created and the line number - Location() (function string, line int) -} - -// locationError is the internal implementation of the Locationer interface. -type locationError struct { - error - - // function is the package path-qualified function name where the - // error was created. - function string - - // line is the line number the error was created on inside of function - line int -} - -// newLocationError constructs a new Locationer error from the supplied error -// with the location set to callDepth in the stack. If a nill error is provided -// to this function then a new empty error is constructed. -func newLocationError(err error, callDepth int) *locationError { - le := &locationError{error: err} - le.function, le.line = getLocation(callDepth + 1) - return le -} - -// Error implementes the error interface. -func (l *locationError) Error() string { - if l.error == nil { - return "" - } - return l.error.Error() -} - -// *locationError implements Locationer.Location interface -func (l *locationError) Location() (string, int) { - return l.function, l.line -} - -func (l *locationError) Unwrap() error { - return l.error -} - -// NewErr is used to return an Err for the purpose of embedding in other -// structures. The location is not specified, and needs to be set with a call -// to SetLocation. -// -// For example: -// type FooError struct { -// errors.Err -// code int -// } -// -// func NewFooError(code int) error { -// err := &FooError{errors.NewErr("foo"), code} -// err.SetLocation(1) -// return err -// } -func NewErr(format string, args ...interface{}) Err { - return Err{ - message: fmt.Sprintf(format, args...), - } -} - -// NewErrWithCause is used to return an Err with cause by other error for the purpose of embedding in other -// structures. The location is not specified, and needs to be set with a call -// to SetLocation. -// -// For example: -// type FooError struct { -// errors.Err -// code int -// } -// -// func (e *FooError) Annotate(format string, args ...interface{}) error { -// err := &FooError{errors.NewErrWithCause(e.Err, format, args...), e.code} -// err.SetLocation(1) -// return err -// }) -func NewErrWithCause(other error, format string, args ...interface{}) Err { - return Err{ - message: fmt.Sprintf(format, args...), - cause: Cause(other), - previous: other, - } -} - -// Location returns the package path-qualified function name and line of where -// the error was most recently created or annotated. -func (e *Err) Location() (function string, line int) { - return e.function, e.line -} - -// Underlying returns the previous error in the error stack, if any. A client -// should not ever really call this method. It is used to build the error -// stack and should not be introspected by client calls. Or more -// specifically, clients should not depend on anything but the `Cause` of an -// error. -func (e *Err) Underlying() error { - return e.previous -} - -// Cause returns the most recent error in the error stack that -// meets one of these criteria: the original error that was raised; the new -// error that was passed into the Wrap function; the most recently masked -// error; or nil if the error itself is considered the Cause. Normally this -// method is not invoked directly, but instead through the Cause stand alone -// function. -func (e *Err) Cause() error { - return e.cause -} - -// Message returns the message stored with the most recent location. This is -// the empty string if the most recent call was Trace, or the message stored -// with Annotate or Mask. -func (e *Err) Message() string { - return e.message -} - -// Error implements error.Error. -func (e *Err) Error() string { - // We want to walk up the stack of errors showing the annotations - // as long as the cause is the same. - err := e.previous - if !sameError(Cause(err), e.cause) && e.cause != nil { - err = e.cause - } - switch { - case err == nil: - return e.message - case e.message == "": - return err.Error() - } - return fmt.Sprintf("%s: %v", e.message, err) -} - -// Format implements fmt.Formatter -// When printing errors with %+v it also prints the stack trace. -// %#v unsurprisingly will print the real underlying type. -func (e *Err) Format(s fmt.State, verb rune) { - switch verb { - case 'v': - switch { - case s.Flag('+'): - fmt.Fprintf(s, "%s", ErrorStack(e)) - return - case s.Flag('#'): - // avoid infinite recursion by wrapping e into a type - // that doesn't implement Formatter. - fmt.Fprintf(s, "%#v", (*unformatter)(e)) - return - } - fallthrough - case 's': - fmt.Fprintf(s, "%s", e.Error()) - case 'q': - fmt.Fprintf(s, "%q", e.Error()) - default: - fmt.Fprintf(s, "%%!%c(%T=%s)", verb, e, e.Error()) - } -} - -// helper for Format -type unformatter Err - -func (unformatter) Format() { /* break the fmt.Formatter interface */ } - -// SetLocation records the package path-qualified function name of the error at -// callDepth stack frames above the call. -func (e *Err) SetLocation(callDepth int) { - e.function, e.line = getLocation(callDepth + 1) -} - -// StackTrace returns one string for each location recorded in the stack of -// errors. The first value is the originating error, with a line for each -// other annotation or tracing of the error. -func (e *Err) StackTrace() []string { - return errorStack(e) -} - -// Ideally we'd have a way to check identity, but deep equals will do. -func sameError(e1, e2 error) bool { - return reflect.DeepEqual(e1, e2) -} - -// Unwrap is a synonym for Underlying, which allows Err to be used with the -// Unwrap, Is and As functions in Go's standard `errors` library. -func (e *Err) Unwrap() error { - return e.previous -} diff --git a/vendor/github.com/juju/errors/errortypes.go b/vendor/github.com/juju/errors/errortypes.go deleted file mode 100644 index 0029f91d..00000000 --- a/vendor/github.com/juju/errors/errortypes.go +++ /dev/null @@ -1,473 +0,0 @@ -// Copyright 2014 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package errors - -import ( - "errors" - stderror "errors" - "fmt" - "strings" -) - -// a ConstError is a prototype for a certain type of error -type ConstError string - -// ConstError implements error -func (e ConstError) Error() string { - return string(e) -} - -// Different types of errors -const ( - // Timeout represents an error on timeout. - Timeout = ConstError("timeout") - // NotFound represents an error when something has not been found. - NotFound = ConstError("not found") - // UserNotFound represents an error when a non-existent user is looked up. - UserNotFound = ConstError("user not found") - // Unauthorized represents an error when an operation is unauthorized. - Unauthorized = ConstError("unauthorized") - // NotImplemented represents an error when something is not - // implemented. - NotImplemented = ConstError("not implemented") - // AlreadyExists represents and error when something already exists. - AlreadyExists = ConstError("already exists") - // NotSupported represents an error when something is not supported. - NotSupported = ConstError("not supported") - // NotValid represents an error when something is not valid. - NotValid = ConstError("not valid") - // NotProvisioned represents an error when something is not yet provisioned. - NotProvisioned = ConstError("not provisioned") - // NotAssigned represents an error when something is not yet assigned to - // something else. - NotAssigned = ConstError("not assigned") - // BadRequest represents an error when a request has bad parameters. - BadRequest = ConstError("bad request") - // MethodNotAllowed represents an error when an HTTP request - // is made with an inappropriate method. - MethodNotAllowed = ConstError("method not allowed") - // Forbidden represents an error when a request cannot be completed because of - // missing privileges. - Forbidden = ConstError("forbidden") - // QuotaLimitExceeded is emitted when an action failed due to a quota limit check. - QuotaLimitExceeded = ConstError("quota limit exceeded") - // NotYetAvailable is the error returned when a resource is not yet available - // but it might be in the future. - NotYetAvailable = ConstError("not yet available") -) - -// errWithType is an Err bundled with its error type (a ConstError) -type errWithType struct { - error - errType ConstError -} - -// Is compares `target` with e's error type -func (e *errWithType) Is(target error) bool { - if &e.errType == nil { - return false - } - return target == e.errType -} - -// Unwrap an errWithType gives the underlying Err -func (e *errWithType) Unwrap() error { - return e.error -} - -func wrapErrorWithMsg(err error, msg string) error { - if err == nil { - return stderror.New(msg) - } - if msg == "" { - return err - } - return fmt.Errorf("%s: %w", msg, err) -} - -func makeWrappedConstError(err error, format string, args ...interface{}) error { - separator := " " - if err.Error() == "" || errors.Is(err, &fmtNoop{}) { - separator = "" - } - return fmt.Errorf(strings.Join([]string{format, "%w"}, separator), append(args, err)...) -} - -// WithType is responsible for annotating an already existing error so that it -// also satisfies that of a ConstError. The resultant error returned should -// satisfy Is(err, errType). If err is nil then a nil error will also be returned. -// -// Now with Go's Is, As and Unwrap support it no longer makes sense to Wrap() -// 2 errors as both of those errors could be chains of errors in their own right. -// WithType aims to solve some of the usefulness of Wrap with the ability to -// make a pre-existing error also satisfy a ConstError type. -func WithType(err error, errType ConstError) error { - if err == nil { - return nil - } - return &errWithType{ - error: err, - errType: errType, - } -} - -// Timeoutf returns an error which satisfies Is(err, Timeout) and the Locationer -// interface. -func Timeoutf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(Timeout, format, args...), - 1, - ) -} - -// NewTimeout returns an error which wraps err and satisfies Is(err, Timeout) -// and the Locationer interface. -func NewTimeout(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: Timeout, - } -} - -// Deprecated: IsTimeout reports whether err is a Timeout error. Use -// Is(err, Timeout). -func IsTimeout(err error) bool { - return Is(err, Timeout) -} - -// NotFoundf returns an error which satisfies Is(err, NotFound) and the -// Locationer interface. -func NotFoundf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(NotFound, format, args...), - 1, - ) -} - -// NewNotFound returns an error which wraps err and satisfies Is(err, NotFound) -// and the Locationer interface. -func NewNotFound(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: NotFound, - } -} - -// Deprecated: IsNotFound reports whether err is a NotFound error. Use -// Is(err, NotFound). -func IsNotFound(err error) bool { - return Is(err, NotFound) -} - -// UserNotFoundf returns an error which satisfies Is(err, UserNotFound) and the -// Locationer interface. -func UserNotFoundf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(UserNotFound, format, args...), - 1, - ) -} - -// NewUserNotFound returns an error which wraps err and satisfies -// Is(err, UserNotFound) and the Locationer interface. -func NewUserNotFound(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: UserNotFound, - } -} - -// Deprecated: IsUserNotFound reports whether err is a UserNotFound error. Use -// Is(err, UserNotFound). -func IsUserNotFound(err error) bool { - return Is(err, UserNotFound) -} - -// Unauthorizedf returns an error that satisfies Is(err, Unauthorized) and -// the Locationer interface. -func Unauthorizedf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(Hide(Unauthorized), format, args...), - 1, - ) -} - -// NewUnauthorized returns an error which wraps err and satisfies -// Is(err, Unathorized) and the Locationer interface. -func NewUnauthorized(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: Unauthorized, - } -} - -// Deprecated: IsUnauthorized reports whether err is a Unauthorized error. Use -// Is(err, Unauthorized). -func IsUnauthorized(err error) bool { - return Is(err, Unauthorized) -} - -// NotImplementedf returns an error which satisfies Is(err, NotImplemented) and -// the Locationer interface. -func NotImplementedf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(NotImplemented, format, args...), - 1, - ) -} - -// NewNotImplemented returns an error which wraps err and satisfies -// Is(err, NotImplemented) and the Locationer interface. -func NewNotImplemented(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: NotImplemented, - } -} - -// Deprecated: IsNotImplemented reports whether err is a NotImplemented error. -// Use Is(err, NotImplemented). -func IsNotImplemented(err error) bool { - return Is(err, NotImplemented) -} - -// AlreadyExistsf returns an error which satisfies Is(err, AlreadyExists) and -// the Locationer interface. -func AlreadyExistsf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(AlreadyExists, format, args...), - 1, - ) -} - -// NewAlreadyExists returns an error which wraps err and satisfies -// Is(err, AlreadyExists) and the Locationer interface. -func NewAlreadyExists(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: AlreadyExists, - } -} - -// Deprecated: IsAlreadyExists reports whether the err is a AlreadyExists -// error. Use Is(err, AlreadyExists). -func IsAlreadyExists(err error) bool { - return Is(err, AlreadyExists) -} - -// NotSupportedf returns an error which satisfies Is(err, NotSupported) and the -// Locationer interface. -func NotSupportedf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(NotSupported, format, args...), - 1, - ) -} - -// NewNotSupported returns an error which satisfies Is(err, NotSupported) and -// the Locationer interface. -func NewNotSupported(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: NotSupported, - } -} - -// Deprecated: IsNotSupported reports whether err is a NotSupported error. Use -// Is(err, NotSupported). -func IsNotSupported(err error) bool { - return Is(err, NotSupported) -} - -// NotValidf returns an error which satisfies Is(err, NotValid) and the -// Locationer interface. -func NotValidf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(NotValid, format, args...), - 1, - ) -} - -// NewNotValid returns an error which wraps err and satisfies Is(err, NotValid) -// and the Locationer interface. -func NewNotValid(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: NotValid, - } -} - -// Deprecated: IsNotValid reports whether err is a NotValid error. Use -// Is(err, NotValid). -func IsNotValid(err error) bool { - return Is(err, NotValid) -} - -// NotProvisionedf returns an error which satisfies Is(err, NotProvisioned) and -// the Locationer interface. -func NotProvisionedf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(NotProvisioned, format, args...), - 1, - ) -} - -// NewNotProvisioned returns an error which wraps err and satisfies -// Is(err, NotProvisioned) and the Locationer interface. -func NewNotProvisioned(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: NotProvisioned, - } -} - -// Deprecated: IsNotProvisioned reports whether err is a NotProvisioned error. -// Use Is(err, NotProvisioned). -func IsNotProvisioned(err error) bool { - return Is(err, NotProvisioned) -} - -// NotAssignedf returns an error which satisfies Is(err, NotAssigned) and the -// Locationer interface. -func NotAssignedf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(NotAssigned, format, args...), - 1, - ) -} - -// NewNotAssigned returns an error which wraps err and satisfies -// Is(err, NotAssigned) and the Locationer interface. -func NewNotAssigned(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: NotAssigned, - } -} - -// Deprecated: IsNotAssigned reports whether err is a NotAssigned error. -// Use Is(err, NotAssigned) -func IsNotAssigned(err error) bool { - return Is(err, NotAssigned) -} - -// BadRequestf returns an error which satisfies Is(err, BadRequest) and the -// Locationer interface. -func BadRequestf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(Hide(BadRequest), format, args...), - 1, - ) -} - -// NewBadRequest returns an error which wraps err and satisfies -// Is(err, BadRequest) and the Locationer interface. -func NewBadRequest(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: BadRequest, - } -} - -// Deprecated: IsBadRequest reports whether err is a BadRequest error. -// Use Is(err, BadRequest) -func IsBadRequest(err error) bool { - return Is(err, BadRequest) -} - -// MethodNotAllowedf returns an error which satisfies Is(err, MethodNotAllowed) -// and the Locationer interface. -func MethodNotAllowedf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(Hide(MethodNotAllowed), format, args...), - 1, - ) -} - -// NewMethodNotAllowed returns an error which wraps err and satisfies -// Is(err, MethodNotAllowed) and the Locationer interface. -func NewMethodNotAllowed(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: MethodNotAllowed, - } -} - -// Deprecated: IsMethodNotAllowed reports whether err is a MethodNotAllowed -// error. Use Is(err, MethodNotAllowed) -func IsMethodNotAllowed(err error) bool { - return Is(err, MethodNotAllowed) -} - -// Forbiddenf returns an error which satistifes Is(err, Forbidden) and the -// Locationer interface. -func Forbiddenf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(Hide(Forbidden), format, args...), - 1, - ) -} - -// NewForbidden returns an error which wraps err and satisfies -// Is(err, Forbidden) and the Locationer interface. -func NewForbidden(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: Forbidden, - } -} - -// Deprecated: IsForbidden reports whether err is a Forbidden error. Use -// Is(err, Forbidden). -func IsForbidden(err error) bool { - return Is(err, Forbidden) -} - -// QuotaLimitExceededf returns an error which satisfies -// Is(err, QuotaLimitExceeded) and the Locationer interface. -func QuotaLimitExceededf(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(Hide(QuotaLimitExceeded), format, args...), - 1, - ) -} - -// NewQuotaLimitExceeded returns an error which wraps err and satisfies -// Is(err, QuotaLimitExceeded) and the Locationer interface. -func NewQuotaLimitExceeded(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: QuotaLimitExceeded, - } -} - -// Deprecated: IsQuotaLimitExceeded reports whether err is a QuoteLimitExceeded -// err. Use Is(err, QuotaLimitExceeded). -func IsQuotaLimitExceeded(err error) bool { - return Is(err, QuotaLimitExceeded) -} - -// NotYetAvailablef returns an error which satisfies Is(err, NotYetAvailable) -// and the Locationer interface. -func NotYetAvailablef(format string, args ...interface{}) error { - return newLocationError( - makeWrappedConstError(Hide(NotYetAvailable), format, args...), - 1, - ) -} - -// NewNotYetAvailable returns an error which wraps err and satisfies -// Is(err, NotYetAvailable) and the Locationer interface. -func NewNotYetAvailable(err error, msg string) error { - return &errWithType{ - error: newLocationError(wrapErrorWithMsg(err, msg), 1), - errType: NotYetAvailable, - } -} - -// Deprecated: IsNotYetAvailable reports whether err is a NotYetAvailable err. -// Use Is(err, NotYetAvailable) -func IsNotYetAvailable(err error) bool { - return Is(err, NotYetAvailable) -} diff --git a/vendor/github.com/juju/errors/functions.go b/vendor/github.com/juju/errors/functions.go deleted file mode 100644 index 952a6739..00000000 --- a/vendor/github.com/juju/errors/functions.go +++ /dev/null @@ -1,454 +0,0 @@ -// Copyright 2014 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package errors - -import ( - stderrors "errors" - "fmt" - "runtime" - "strings" -) - -// New is a drop in replacement for the standard library errors module that records -// the location that the error is created. -// -// For example: -// return errors.New("validation failed") -// -func New(message string) error { - err := &Err{message: message} - err.SetLocation(1) - return err -} - -// Errorf creates a new annotated error and records the location that the -// error is created. This should be a drop in replacement for fmt.Errorf. -// -// For example: -// return errors.Errorf("validation failed: %s", message) -// -func Errorf(format string, args ...interface{}) error { - err := &Err{message: fmt.Sprintf(format, args...)} - err.SetLocation(1) - return err -} - -// getLocation records the package path-qualified function name of the error at -// callDepth stack frames above the call. -func getLocation(callDepth int) (string, int) { - rpc := make([]uintptr, 1) - n := runtime.Callers(callDepth+2, rpc[:]) - if n < 1 { - return "", 0 - } - frame, _ := runtime.CallersFrames(rpc).Next() - return frame.Function, frame.Line -} - -// Trace adds the location of the Trace call to the stack. The Cause of the -// resulting error is the same as the error parameter. If the other error is -// nil, the result will be nil. -// -// For example: -// if err := SomeFunc(); err != nil { -// return errors.Trace(err) -// } -// -func Trace(other error) error { - //return SetLocation(other, 2) - if other == nil { - return nil - } - err := &Err{previous: other, cause: Cause(other)} - err.SetLocation(1) - return err -} - -// Annotate is used to add extra context to an existing error. The location of -// the Annotate call is recorded with the annotations. The file, line and -// function are also recorded. -// -// For example: -// if err := SomeFunc(); err != nil { -// return errors.Annotate(err, "failed to frombulate") -// } -// -func Annotate(other error, message string) error { - if other == nil { - return nil - } - err := &Err{ - previous: other, - cause: Cause(other), - message: message, - } - err.SetLocation(1) - return err -} - -// Annotatef is used to add extra context to an existing error. The location of -// the Annotate call is recorded with the annotations. The file, line and -// function are also recorded. -// -// For example: -// if err := SomeFunc(); err != nil { -// return errors.Annotatef(err, "failed to frombulate the %s", arg) -// } -// -func Annotatef(other error, format string, args ...interface{}) error { - if other == nil { - return nil - } - err := &Err{ - previous: other, - cause: Cause(other), - message: fmt.Sprintf(format, args...), - } - err.SetLocation(1) - return err -} - -// DeferredAnnotatef annotates the given error (when it is not nil) with the given -// format string and arguments (like fmt.Sprintf). If *err is nil, DeferredAnnotatef -// does nothing. This method is used in a defer statement in order to annotate any -// resulting error with the same message. -// -// For example: -// -// defer DeferredAnnotatef(&err, "failed to frombulate the %s", arg) -// -func DeferredAnnotatef(err *error, format string, args ...interface{}) { - if *err == nil { - return - } - newErr := &Err{ - message: fmt.Sprintf(format, args...), - cause: Cause(*err), - previous: *err, - } - newErr.SetLocation(1) - *err = newErr -} - -// Wrap changes the Cause of the error. The location of the Wrap call is also -// stored in the error stack. -// -// For example: -// if err := SomeFunc(); err != nil { -// newErr := &packageError{"more context", private_value} -// return errors.Wrap(err, newErr) -// } -// -func Wrap(other, newDescriptive error) error { - err := &Err{ - previous: other, - cause: newDescriptive, - } - err.SetLocation(1) - return err -} - -// Wrapf changes the Cause of the error, and adds an annotation. The location -// of the Wrap call is also stored in the error stack. -// -// For example: -// if err := SomeFunc(); err != nil { -// return errors.Wrapf(err, simpleErrorType, "invalid value %q", value) -// } -// -func Wrapf(other, newDescriptive error, format string, args ...interface{}) error { - err := &Err{ - message: fmt.Sprintf(format, args...), - previous: other, - cause: newDescriptive, - } - err.SetLocation(1) - return err -} - -// Maskf masks the given error with the given format string and arguments (like -// fmt.Sprintf), returning a new error that maintains the error stack, but -// hides the underlying error type. The error string still contains the full -// annotations. If you want to hide the annotations, call Wrap. -func Maskf(other error, format string, args ...interface{}) error { - if other == nil { - return nil - } - err := &Err{ - message: fmt.Sprintf(format, args...), - previous: other, - } - err.SetLocation(1) - return err -} - -// Mask hides the underlying error type, and records the location of the masking. -func Mask(other error) error { - if other == nil { - return nil - } - err := &Err{ - previous: other, - } - err.SetLocation(1) - return err -} - -// Cause returns the cause of the given error. This will be either the -// original error, or the result of a Wrap or Mask call. -// -// Cause is the usual way to diagnose errors that may have been wrapped by -// the other errors functions. -func Cause(err error) error { - var diag error - if err, ok := err.(causer); ok { - diag = err.Cause() - } - if diag != nil { - return diag - } - return err -} - -type causer interface { - Cause() error -} - -type wrapper interface { - // Message returns the top level error message, - // not including the message from the Previous - // error. - Message() string - - // Underlying returns the Previous error, or nil - // if there is none. - Underlying() error -} - -var ( - _ wrapper = (*Err)(nil) - _ Locationer = (*Err)(nil) - _ causer = (*Err)(nil) -) - -// Details returns information about the stack of errors wrapped by err, in -// the format: -// -// [{filename:99: error one} {otherfile:55: cause of error one}] -// -// This is a terse alternative to ErrorStack as it returns a single line. -func Details(err error) string { - if err == nil { - return "[]" - } - var s []byte - s = append(s, '[') - for { - s = append(s, '{') - if err, ok := err.(Locationer); ok { - file, line := err.Location() - if file != "" { - s = append(s, fmt.Sprintf("%s:%d", file, line)...) - s = append(s, ": "...) - } - } - if cerr, ok := err.(wrapper); ok { - s = append(s, cerr.Message()...) - err = cerr.Underlying() - } else { - s = append(s, err.Error()...) - err = nil - } - s = append(s, '}') - if err == nil { - break - } - s = append(s, ' ') - } - s = append(s, ']') - return string(s) -} - -// ErrorStack returns a string representation of the annotated error. If the -// error passed as the parameter is not an annotated error, the result is -// simply the result of the Error() method on that error. -// -// If the error is an annotated error, a multi-line string is returned where -// each line represents one entry in the annotation stack. The full filename -// from the call stack is used in the output. -// -// first error -// github.com/juju/errors/annotation_test.go:193: -// github.com/juju/errors/annotation_test.go:194: annotation -// github.com/juju/errors/annotation_test.go:195: -// github.com/juju/errors/annotation_test.go:196: more context -// github.com/juju/errors/annotation_test.go:197: -func ErrorStack(err error) string { - return strings.Join(errorStack(err), "\n") -} - -func errorStack(err error) []string { - if err == nil { - return nil - } - - // We want the first error first - var lines []string - for { - var buff []byte - if err, ok := err.(Locationer); ok { - file, line := err.Location() - // Strip off the leading GOPATH/src path elements. - if file != "" { - buff = append(buff, fmt.Sprintf("%s:%d", file, line)...) - buff = append(buff, ": "...) - } - } - if cerr, ok := err.(wrapper); ok { - message := cerr.Message() - buff = append(buff, message...) - // If there is a cause for this error, and it is different to the cause - // of the underlying error, then output the error string in the stack trace. - var cause error - if err1, ok := err.(causer); ok { - cause = err1.Cause() - } - err = cerr.Underlying() - if cause != nil && !sameError(Cause(err), cause) { - if message != "" { - buff = append(buff, ": "...) - } - buff = append(buff, cause.Error()...) - } - } else { - buff = append(buff, err.Error()...) - err = nil - } - lines = append(lines, string(buff)) - if err == nil { - break - } - } - // reverse the lines to get the original error, which was at the end of - // the list, back to the start. - var result []string - for i := len(lines); i > 0; i-- { - result = append(result, lines[i-1]) - } - return result -} - -// Unwrap is a proxy for the Unwrap function in Go's standard `errors` library -// (pkg.go.dev/errors). -func Unwrap(err error) error { - return stderrors.Unwrap(err) -} - -// Is is a proxy for the Is function in Go's standard `errors` library -// (pkg.go.dev/errors). -func Is(err, target error) bool { - return stderrors.Is(err, target) -} - -// HasType is a function wrapper around AsType dropping the where return value -// from AsType() making a function that can be used like this: -// -// return HasType[*MyError](err) -// -// Or -// -// if HasType[*MyError](err) {} -func HasType[T error](err error) bool { - _, rval := AsType[T](err) - return rval -} - -// As is a proxy for the As function in Go's standard `errors` library -// (pkg.go.dev/errors). -func As(err error, target interface{}) bool { - return stderrors.As(err, target) -} - -// AsType is a convenience method for checking and getting an error from within -// a chain that is of type T. If no error is found of type T in the chain the -// zero value of T is returned with false. If an error in the chain implementes -// As(any) bool then it's As method will be called if it's type is not of type T. - -// AsType finds the first error in err's chain that is assignable to type T, and -// if a match is found, returns that error value and true. Otherwise, it returns -// T's zero value and false. -// -// AsType is equivalent to errors.As, but uses a type parameter and returns -// the target, to avoid having to define a variable before the call. For -// example, callers can replace this: -// -// var pathError *fs.PathError -// if errors.As(err, &pathError) { -// fmt.Println("Failed at path:", pathError.Path) -// } -// -// With: -// -// if pathError, ok := errors.AsType[*fs.PathError](err); ok { -// fmt.Println("Failed at path:", pathError.Path) -// } -func AsType[T error](err error) (T, bool) { - for err != nil { - if e, is := err.(T); is { - return e, true - } - var res T - if x, ok := err.(interface{ As(any) bool }); ok && x.As(&res) { - return res, true - } - err = stderrors.Unwrap(err) - } - var zero T - return zero, false -} - -// SetLocation takes a given error and records where in the stack SetLocation -// was called from and returns the wrapped error with the location information -// set. The returned error implements the Locationer interface. If err is nil -// then a nil error is returned. -func SetLocation(err error, callDepth int) error { - if err == nil { - return nil - } - - return newLocationError(err, callDepth) -} - -// fmtNoop provides an internal type for wrapping errors so they won't be -// printed in fmt type commands. As this type is used by the Hide function it's -// expected that error not be nil. -type fmtNoop struct { - error -} - -// Format implements the fmt.Formatter interface so that the error wrapped by -// fmtNoop will not be printed. -func (*fmtNoop) Format(_ fmt.State, r rune) {} - -// Is implements errors.Is. It useful for us to be able to check if an error -// chain has fmtNoop for formatting purposes. -func (f *fmtNoop) Is(err error) bool { - _, is := err.(*fmtNoop) - return is -} - -// Unwrap implements the errors.Unwrap method returning the error wrapped by -// fmtNoop. -func (f *fmtNoop) Unwrap() error { - return f.error -} - -// Hide takes an error and silences it's error string from appearing in fmt -// like -func Hide(err error) error { - if err == nil { - return nil - } - return &fmtNoop{err} -} diff --git a/vendor/github.com/juju/retry/.gitignore b/vendor/github.com/juju/retry/.gitignore deleted file mode 100644 index 9ed3b07c..00000000 --- a/vendor/github.com/juju/retry/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.test diff --git a/vendor/github.com/juju/retry/LICENSE b/vendor/github.com/juju/retry/LICENSE deleted file mode 100644 index ade9307b..00000000 --- a/vendor/github.com/juju/retry/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -All files in this repository are licensed as follows. If you contribute -to this repository, it is assumed that you license your contribution -under the same license unless you state otherwise. - -All files Copyright (C) 2015 Canonical Ltd. unless otherwise specified in the file. - -This software is licensed under the LGPLv3, included below. - -As a special exception to the GNU Lesser General Public License version 3 -("LGPL3"), the copyright holders of this Library give you permission to -convey to a third party a Combined Work that links statically or dynamically -to this Library without providing any Minimal Corresponding Source or -Minimal Application Code as set out in 4d or providing the installation -information set out in section 4e, provided that you comply with the other -provisions of LGPL3 and provided that you meet, for the Application the -terms and conditions of the license(s) which apply to the Application. - -Except as stated in this special exception, the provisions of LGPL3 will -continue to comply in full to this Library. If you modify this Library, you -may apply this exception to your version of this Library, but you are not -obliged to do so. If you do not wish to do so, delete this exception -statement from your version. This exception does not (and cannot) modify any -license terms which apply to the Application, with which you must still -comply. - - - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/vendor/github.com/juju/retry/Makefile b/vendor/github.com/juju/retry/Makefile deleted file mode 100644 index 6d36bad0..00000000 --- a/vendor/github.com/juju/retry/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -PROJECT := github.com/juju/retry - -default: check - -check-licence: - @(fgrep -rl "Licensed under the LGPLv3" .;\ - fgrep -rl "MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT" .;\ - find . -name "*.go") | sed -e 's,\./,,' | sort | uniq -u | \ - xargs -I {} echo FAIL: licence missed: {} - -check: check-licence - go test $(PROJECT)/... - -docs: - godoc2md $(PROJECT) > README.md diff --git a/vendor/github.com/juju/retry/README.md b/vendor/github.com/juju/retry/README.md deleted file mode 100644 index 1fbe9a47..00000000 --- a/vendor/github.com/juju/retry/README.md +++ /dev/null @@ -1,277 +0,0 @@ - -# retry - import "github.com/juju/retry" - -The retry package encapsulates the mechanism around retrying commands. - -The simple use is to call retry.Call with a function closure. - -```go - - - err := retry.Call(retry.CallArgs{ - Func: func() error { ... }, - Attempts: 5, - Delay: time.Minute, - Clock: clock.WallClock, - }) - -``` - -The bare minimum arguments that need to be specified are: -* Func - the function to call -* Attempts - the number of times to try Func before giving up, or a negative number for unlimited attempts (`retry.UnlimitedAttempts`) -* Delay - how long to wait between each try that returns an error -* Clock - either the wall clock, or some testing clock - -Any error that is returned from the `Func` is considered transient. -In order to identify some errors as fatal, pass in a function for the -`IsFatalError` CallArgs value. - -In order to have the `Delay` change for each iteration, a `BackoffFunc` -needs to be set on the CallArgs. A simple doubling delay function is -provided by `DoubleDelay`. - -An example of a more complex `BackoffFunc` could be a stepped function such -as: - -```go - - - func StepDelay(last time.Duration, attempt int) time.Duration { - switch attempt{ - case 1: - return time.Second - case 2: - return 5 * time.Second - case 3: - return 20 * time.Second - case 4: - return time.Minute - case 5: - return 5 * time.Minute - default: - return 2 * last - } - } - -``` - -Consider some package `foo` that has a `TryAgainError`, which looks something -like this: -```go - - - type TryAgainError struct { - After time.Duration - } - -``` -and we create something that looks like this: - -```go - - - type TryAgainHelper struct { - next time.Duration - } - - func (h *TryAgainHelper) notify(lastError error, attempt int) { - if tryAgain, ok := lastError.(*foo.TryAgainError); ok { - h.next = tryAgain.After - } else { - h.next = 0 - } - } - - func (h *TryAgainHelper) next(last time.Duration) time.Duration { - if h.next != 0 { - return h.next - } - return last - } - -``` - -Then we could do this: -```go - - - helper := TryAgainHelper{} - retry.Call(retry.CallArgs{ - Func: func() error { - return foo.SomeFunc() - }, - NotifyFunc: helper.notify, - BackoffFunc: helper.next, - Attempts: 20, - Delay: 100 * time.Millisecond, - Clock: clock.WallClock, - }) - -``` - - - - -## Constants -``` go -const ( - // UnlimitedAttempts can be used as a value for `Attempts` to clearly - // show to the reader that there is no limit to the number of attempts. - UnlimitedAttempts = -1 -) -``` - - -## func Call -``` go -func Call(args CallArgs) error -``` -Call will repeatedly execute the Func until either the function returns no -error, the retry count is exceeded or the stop channel is closed. - - -## func DoubleDelay -``` go -func DoubleDelay(delay time.Duration, attempt int) time.Duration -``` -DoubleDelay provides a simple function that doubles the duration passed in. -This can then be easily used as the `BackoffFunc` in the `CallArgs` -structure. - -## func ExpBackoff -``` go -func ExpBackoff(minDelay, maxDelay time.Duration, exp float64, applyJitter bool) func(time.Duration, int) time.Duration { -``` -ExpBackoff returns a function a which generates time.Duration values using an -exponential back-off algorithm with the specified parameters. The returned value -can then be easily used as the `BackoffFunc` in the `CallArgs` structure. - -The next delay value is calculated using the following formula: - `newDelay = min(minDelay * exp^attempt, maxDelay)` - -If `applyJitter` is set to `true`, the function will randomly select and return -back a value in the `[minDelay, newDelay]` range. - -## func IsAttemptsExceeded -``` go -func IsAttemptsExceeded(err error) bool -``` -IsAttemptsExceeded returns true if the error is the result of the `Call` -function finishing due to hitting the requested number of `Attempts`. - - -## func IsDurationExceeded -``` go -func IsDurationExceeded(err error) bool -``` -IsDurationExceeded returns true if the error is the result of the `Call` -function finishing due to the total duration exceeding the specified -`MaxDuration` value. - - -## func IsRetryStopped -``` go -func IsRetryStopped(err error) bool -``` -IsRetryStopped returns true if the error is the result of the `Call` -function finishing due to the stop channel being closed. - - -## func LastError -``` go -func LastError(err error) error -``` -LastError retrieves the last error returned from `Func` before iteration -was terminated due to the attempt count being exceeded, the maximum -duration being exceeded, or the stop channel being closed. - - - -## type CallArgs -``` go -type CallArgs struct { - // Func is the function that will be retried if it returns an error result. - Func func() error - - // IsFatalError is a function that, if set, will be called for every non- - // nil error result from `Func`. If `IsFatalError` returns true, the error - // is immediately returned breaking out from any further retries. - IsFatalError func(error) bool - - // NotifyFunc is a function that is called if Func fails, and the attempt - // number. The first time this function is called attempt is 1, the second - // time, attempt is 2 and so on. - NotifyFunc func(lastError error, attempt int) - - // Attempts specifies the number of times Func should be retried before - // giving up and returning the `AttemptsExceeded` error. If a negative - // value is specified, the `Call` will retry forever. - Attempts int - - // Delay specifies how long to wait between retries. - Delay time.Duration - - // MaxDelay specifies how longest time to wait between retries. If no - // value is specified there is no maximum delay. - MaxDelay time.Duration - - // MaxDuration specifies the maximum time the `Call` function should spend - // iterating over `Func`. The duration is calculated from the start of the - // `Call` function. If the next delay time would take the total duration - // of the call over MaxDuration, then a DurationExceeded error is - // returned. If no value is specified, Call will continue until the number - // of attempts is complete. - MaxDuration time.Duration - - // BackoffFunc allows the caller to provide a function that alters the - // delay each time through the loop. If this function is not provided the - // delay is the same each iteration. Alternatively a function such as - // `retry.DoubleDelay` can be used that will provide an exponential - // backoff. The first time this function is called attempt is 1, the - // second time, attempt is 2 and so on. - BackoffFunc func(delay time.Duration, attempt int) time.Duration - - // Clock provides the mechanism for waiting. Normal program execution is - // expected to use something like clock.WallClock, and tests can override - // this to not actually sleep in tests. - Clock clock.Clock - - // Stop is a channel that can be used to indicate that the waiting should - // be interrupted. If Stop is nil, then the Call function cannot be interrupted. - // If the channel is closed prior to the Call function being executed, the - // Func is still attempted once. - Stop <-chan struct{} -} -``` -CallArgs is a simple structure used to define the behaviour of the Call -function. - - - - - - - - - - - -### func (\*CallArgs) Validate -``` go -func (args *CallArgs) Validate() error -``` -Validate the values are valid. The ensures that the Func, Delay, Attempts -and Clock have been specified. - - - - - - - - - -- - - -Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) diff --git a/vendor/github.com/juju/retry/clock.go b/vendor/github.com/juju/retry/clock.go deleted file mode 100644 index 3451fbf3..00000000 --- a/vendor/github.com/juju/retry/clock.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package retry - -import "time" - -// Clock provides an interface for dealing with clocks. -type Clock interface { - // Now returns the current clock time. - Now() time.Time - - // After waits for the duration to elapse and then sends the - // current time on the returned channel. - After(time.Duration) <-chan time.Time -} diff --git a/vendor/github.com/juju/retry/doc.go b/vendor/github.com/juju/retry/doc.go deleted file mode 100644 index 8a7393e0..00000000 --- a/vendor/github.com/juju/retry/doc.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2015 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -// The retry package encapsulates the mechanism around retrying commands. -// -// The simple use is to call retry.Call with a function closure. -// -// err := retry.Call(retry.CallArgs{ -// Func: func() error { ... }, -// Attempts: 5, -// Delay: time.Minute, -// Clock: clock.WallClock, -// }) -// -// The bare minimum arguments that need to be specified are: -// - Func - the function to call -// - Attempts - the number of times to try Func before giving up, or a negative number for unlimited attempts (`retry.UnlimitedAttempts`) -// - Delay - how long to wait between each try that returns an error -// - Clock - either the wall clock, or some testing clock -// -// Any error that is returned from the Func is considered transient. -// In order to identify some errors as fatal, pass in a function for the -// IsFatalError CallArgs value. -// -// In order to have the Delay change for each iteration, a BackoffFunc -// needs to be set on the CallArgs. A simple doubling delay function is -// provided by DoubleDelay. -// -// An example of a more complex BackoffFunc could be a stepped function such -// as: -// -// func StepDelay(last time.Duration, attempt int) time.Duration { -// switch attempt{ -// case 1: -// return time.Second -// case 2: -// return 5 * time.Second -// case 3: -// return 20 * time.Second -// case 4: -// return time.Minute -// case 5: -// return 5 * time.Minute -// default: -// return 2 * last -// } -// } -// -// Consider some package foo that has a TryAgainError, which looks something -// like this: -// -// type TryAgainError struct { -// After time.Duration -// } -// -// and we create something that looks like this: -// -// type TryAgainHelper struct { -// next time.Duration -// } -// -// func (h *TryAgainHelper) notify(lastError error, attempt int) { -// if tryAgain, ok := lastError.(*foo.TryAgainError); ok { -// h.next = tryAgain.After -// } else { -// h.next = 0 -// } -// } -// -// func (h *TryAgainHelper) next(last time.Duration) time.Duration { -// if h.next != 0 { -// return h.next -// } -// return last -// } -// -// Then we could do this: -// -// helper := TryAgainHelper{} -// retry.Call(retry.CallArgs{ -// Func: func() error { -// return foo.SomeFunc() -// }, -// NotifyFunc: helper.notify, -// BackoffFunc: helper.next, -// Attempts: 20, -// Delay: 100 * time.Millisecond, -// Clock: clock.WallClock, -// }) -package retry diff --git a/vendor/github.com/juju/retry/retry.go b/vendor/github.com/juju/retry/retry.go deleted file mode 100644 index d9964d6d..00000000 --- a/vendor/github.com/juju/retry/retry.go +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright 2015 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package retry - -import ( - "fmt" - "math" - "math/rand" - "time" - - "github.com/juju/errors" -) - -const ( - // UnlimitedAttempts can be used as a value for Attempts to clearly - // show to the reader that there is no limit to the number of attempts. - UnlimitedAttempts = -1 -) - -// retryStopped is the error that is returned from the Call function -// when the stop channel has been closed. -type retryStopped struct { - lastError error -} - -// Error provides the implementation for the error interface method. -func (e *retryStopped) Error() string { - return fmt.Sprintf("retry stopped") -} - -// attemptsExceeded is the error that is returned when the retry count has -// been hit without the function returning a nil error result. The last error -// returned from the function being retried is available as the LastError -// attribute. -type attemptsExceeded struct { - lastError error -} - -// Error provides the implementation for the error interface method. -func (e *attemptsExceeded) Error() string { - return fmt.Sprintf("attempt count exceeded: %s", e.lastError) -} - -// durationExceeded is the error that is returned when the total time that the -// Call function would have executed exceeds the MaxDuration specified. -// The last error returned from the function being retried is available as the -// LastError attribute. -type durationExceeded struct { - lastError error -} - -// Error provides the implementation for the error interface method. -func (e *durationExceeded) Error() string { - return fmt.Sprintf("max duration exceeded: %s", e.lastError) -} - -// LastError retrieves the last error returned from Func before iteration -// was terminated due to the attempt count being exceeded, the maximum -// duration being exceeded, or the stop channel being closed. -func LastError(err error) error { - cause := errors.Cause(err) - switch err := cause.(type) { - case *attemptsExceeded: - return err.lastError - case *retryStopped: - return err.lastError - case *durationExceeded: - return err.lastError - } - return errors.Errorf("unexpected error type: %T, %s", cause, cause) -} - -// IsAttemptsExceeded returns true if the error is the result of the Call -// function finishing due to hitting the requested number of Attempts. -func IsAttemptsExceeded(err error) bool { - cause := errors.Cause(err) - _, ok := cause.(*attemptsExceeded) - return ok -} - -// IsDurationExceeded returns true if the error is the result of the Call -// function finishing due to the total duration exceeding the specified -// MaxDuration value. -func IsDurationExceeded(err error) bool { - cause := errors.Cause(err) - _, ok := cause.(*durationExceeded) - return ok -} - -// IsRetryStopped returns true if the error is the result of the Call -// function finishing due to the stop channel being closed. -func IsRetryStopped(err error) bool { - cause := errors.Cause(err) - _, ok := cause.(*retryStopped) - return ok -} - -// CallArgs is a simple structure used to define the behaviour of the Call -// function. -type CallArgs struct { - // Func is the function that will be retried if it returns an error result. - Func func() error - - // IsFatalError is a function that, if set, will be called for every non- - // nil error result from Func. If IsFatalError returns true, the error - // is immediately returned breaking out from any further retries. - IsFatalError func(error) bool - - // NotifyFunc is a function that is called if Func fails, and the attempt - // number. The first time this function is called attempt is 1, the second - // time, attempt is 2 and so on. - NotifyFunc func(lastError error, attempt int) - - // Attempts specifies the number of times Func should be retried before - // giving up and returning the AttemptsExceeded error. If a negative - // value is specified, the Call will retry forever. - Attempts int - - // Delay specifies how long to wait between retries. - Delay time.Duration - - // MaxDelay specifies how longest time to wait between retries. If no - // value is specified there is no maximum delay. - MaxDelay time.Duration - - // MaxDuration specifies the maximum time the Call function should spend - // iterating over Func. The duration is calculated from the start of the - // Call function. If the next delay time would take the total duration - // of the call over MaxDuration, then a DurationExceeded error is - // returned. If no value is specified, Call will continue until the number - // of attempts is complete. - MaxDuration time.Duration - - // BackoffFunc allows the caller to provide a function that alters the - // delay each time through the loop. If this function is not provided the - // delay is the same each iteration. Alternatively a function such as - // retry.DoubleDelay can be used that will provide an exponential - // backoff. The first time this function is called attempt is 1, the - // second time, attempt is 2 and so on. - BackoffFunc func(delay time.Duration, attempt int) time.Duration - - // Clock provides the mechanism for waiting. Normal program execution is - // expected to use something like clock.WallClock, and tests can override - // this to not actually sleep in tests. - Clock Clock - - // Stop is a channel that can be used to indicate that the waiting should - // be interrupted. If Stop is nil, then the Call function cannot be interrupted. - // If the channel is closed prior to the Call function being executed, the - // Func is still attempted once. - Stop <-chan struct{} -} - -// Validate the values are valid. The ensures that the Func, Delay, Attempts -// and Clock have been specified. -func (args *CallArgs) Validate() error { - if args.Func == nil { - return errors.NotValidf("missing Func") - } - if args.Delay == 0 { - return errors.NotValidf("missing Delay") - } - if args.Clock == nil { - return errors.NotValidf("missing Clock") - } - // One of Attempts or MaxDuration need to be specified - if args.Attempts == 0 && args.MaxDuration == 0 { - return errors.NotValidf("missing Attempts or MaxDuration") - } - return nil -} - -// Call will repeatedly execute the Func until either the function returns no -// error, the retry count is exceeded or the stop channel is closed. -func Call(args CallArgs) error { - err := args.Validate() - if err != nil { - return errors.Trace(err) - } - start := args.Clock.Now() - for i := 1; args.Attempts <= 0 || i <= args.Attempts; i++ { - err = args.Func() - if err == nil { - return nil - } - if args.IsFatalError != nil && args.IsFatalError(err) { - return errors.Trace(err) - } - if args.NotifyFunc != nil { - args.NotifyFunc(err, i) - } - if i == args.Attempts && args.Attempts > 0 { - break // don't wait before returning the error - } - - if args.BackoffFunc != nil { - delay := args.BackoffFunc(args.Delay, i) - if delay > args.MaxDelay && args.MaxDelay > 0 { - delay = args.MaxDelay - } - args.Delay = delay - } - elapsedTime := args.Clock.Now().Sub(start) - if args.MaxDuration > 0 && (elapsedTime+args.Delay) > args.MaxDuration { - return errors.Wrap(err, &durationExceeded{err}) - } - - // Wait for the delay, and retry - select { - case <-args.Clock.After(args.Delay): - case <-args.Stop: - return errors.Wrap(err, &retryStopped{err}) - } - } - return errors.Wrap(err, &attemptsExceeded{err}) -} - -// DoubleDelay provides a simple function that doubles the duration passed in. -// This can then be easily used as the BackoffFunc in the CallArgs -// structure. -func DoubleDelay(delay time.Duration, attempt int) time.Duration { - if attempt == 1 { - return delay - } - return delay * 2 -} - -// ExpBackoff returns a function a which generates time.Duration values using -// an exponential back-off algorithm with the specified parameters. The -// returned value can then be easily used as the BackoffFunc in the CallArgs -// structure. -// -// The next delay value is calculated using the following formula: -// -// newDelay = min(minDelay * exp^attempt, maxDelay) -// -// If applyJitter is set to true, the function will randomly select and return -// back a value in the [minDelay, newDelay] range. -func ExpBackoff(minDelay, maxDelay time.Duration, exp float64, applyJitter bool) func(time.Duration, int) time.Duration { - minDelayF := float64(minDelay) - maxDelayF := float64(maxDelay) - return func(_ time.Duration, attempt int) time.Duration { - newDelay := minDelayF * math.Pow(exp, float64(attempt)) - - // Return a random value in the [minDelay, newDelay) range. - if applyJitter { - // We want to go +/- 20%, which is a 40% swing, and - // Float64 returns in the range 0-1 - newDelay = (1 + rand.Float64()*0.4 - 0.2) * newDelay - } - if newDelay < minDelayF { - newDelay = minDelayF - } - if newDelay > maxDelayF { - newDelay = maxDelayF - } - return time.Duration(newDelay).Round(time.Millisecond) - } -} diff --git a/vendor/modules.txt b/vendor/modules.txt index f090ee01..1222d730 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -131,19 +131,6 @@ github.com/jinzhu/now # github.com/josharian/intern v1.0.0 ## explicit; go 1.5 github.com/josharian/intern -# github.com/juju/clock v1.1.1 -## explicit; go 1.18 -github.com/juju/clock -# github.com/juju/errors v1.0.0 -## explicit; go 1.18 -github.com/juju/errors -# github.com/juju/loggo v1.0.0 -## explicit; go 1.14 -# github.com/juju/retry v1.0.1 -## explicit; go 1.17 -github.com/juju/retry -# github.com/juju/testing v1.0.2 -## explicit; go 1.17 # github.com/mailru/easyjson v0.9.0 ## explicit; go 1.20 github.com/mailru/easyjson/buffer diff --git a/websocket/client.go b/websocket/client.go index 70777265..820e49ce 100644 --- a/websocket/client.go +++ b/websocket/client.go @@ -16,6 +16,7 @@ package websocket import ( "context" + "errors" "fmt" "log/slog" "net" @@ -24,7 +25,6 @@ import ( "github.com/google/uuid" "github.com/gorilla/websocket" - "github.com/pkg/errors" "github.com/cloudbase/garm/auth" "github.com/cloudbase/garm/database/common" @@ -63,7 +63,7 @@ func NewClient(ctx context.Context, conn *websocket.Conn) (*Client, error) { watcher.WithUserIDFilter(user), ) if err != nil { - return nil, errors.Wrap(err, "registering consumer") + return nil, fmt.Errorf("error registering consumer: %w", err) } return &Client{ id: clientID.String(),