mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 09:01:31 +00:00
chore: enable errorlint
This commit is contained in:
@@ -20,6 +20,7 @@ linters:
|
||||
- errcheck # checks for unchecked errors in type assertions and I/O
|
||||
- errchkjson # checks types passed to json encoding functions, flags omittable error checks
|
||||
- errname # checks that sentinel errors are prefixed with Err, error types suffixed with Error
|
||||
- errorlint # catches ==/!= on errors, type assertions on errors, and %v instead of %w — all break on wrapped errors
|
||||
- exptostd # detects golang.org/x/exp/ functions replaceable by stdlib
|
||||
- fatcontext # detects nested contexts in loops
|
||||
- forcetypeassert # flags unchecked type assertions that can panic
|
||||
|
||||
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
@@ -143,7 +144,7 @@ func (c *credEndpoint) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
creds, roleARN, err := c.fetch(r.Context(), credID)
|
||||
if err != nil {
|
||||
if err == errUnknownCredID {
|
||||
if errors.Is(err, errUnknownCredID) {
|
||||
http.Error(w, "not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -539,7 +539,7 @@ func installBootloader(disk string) error {
|
||||
); biosErr != nil {
|
||||
if efiErr != nil {
|
||||
// Both targets failed — the system will not boot.
|
||||
return fmt.Errorf("both bootloader targets failed (EFI: %v; BIOS: %w)", efiErr, biosErr)
|
||||
return fmt.Errorf("both bootloader targets failed (EFI: %w; BIOS: %w)", efiErr, biosErr)
|
||||
}
|
||||
return biosErr
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ type ConfigFile struct {
|
||||
func GenerateConfigFiles(configs []ConfigFile, configSettings ConfigSettings) error {
|
||||
for _, cfg := range configs {
|
||||
if err := GenerateConfigFile(cfg.Path, cfg.Template, configSettings); err != nil {
|
||||
return fmt.Errorf("error creating %s: %v", cfg.Name, err)
|
||||
return fmt.Errorf("error creating %s: %w", cfg.Name, err)
|
||||
}
|
||||
fmt.Printf("✅ Created: %s\n", cfg.Name)
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ func readAMIConfig(store objectstore.ObjectStore, bucket, imageID string) (viper
|
||||
|
||||
var state viperblock.VBState
|
||||
if err := json.Unmarshal(viperblock.StateBody(body), &state); err != nil {
|
||||
return viperblock.AMIMetadata{}, fmt.Errorf("%w: %s: %v", handlers_ec2_image.ErrCorruptAMIConfig, key, err)
|
||||
return viperblock.AMIMetadata{}, fmt.Errorf("%w: %s: %w", handlers_ec2_image.ErrCorruptAMIConfig, key, err)
|
||||
}
|
||||
return state.VolumeConfig.AMIMetadata, nil
|
||||
}
|
||||
@@ -352,7 +352,7 @@ func readVolumeConfig(store objectstore.ObjectStore, bucket, volumeID string) (*
|
||||
|
||||
var w volumeConfigWrapper
|
||||
if err := json.Unmarshal(viperblock.StateBody(body), &w); err != nil {
|
||||
return nil, fmt.Errorf("%w: %s: %v", errCorruptVolumeConfig, key, err)
|
||||
return nil, fmt.Errorf("%w: %s: %w", errCorruptVolumeConfig, key, err)
|
||||
}
|
||||
return &w.VolumeConfig, nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package gateway_bedrock
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
@@ -88,7 +89,7 @@ func (s *CredentialStore) Resolve(_ context.Context, accountID, vendor string) (
|
||||
return "", false, fmt.Errorf("decrypt credential for %s/%s: %w", accountID, vendor, err)
|
||||
}
|
||||
return plaintext, true, nil
|
||||
case err != nats.ErrKeyNotFound:
|
||||
case !errors.Is(err, nats.ErrKeyNotFound):
|
||||
return "", false, fmt.Errorf("kv get credential for %s/%s: %w", accountID, vendor, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -709,11 +709,11 @@ func (s *ImageServiceImpl) GetAMIConfig(ctx context.Context, imageID string) (vi
|
||||
|
||||
body, err := io.ReadAll(result.Body)
|
||||
if err != nil {
|
||||
return viperblock.AMIMetadata{}, fmt.Errorf("%w: %s: %v", ErrCorruptAMIConfig, configKey, err)
|
||||
return viperblock.AMIMetadata{}, fmt.Errorf("%w: %s: %w", ErrCorruptAMIConfig, configKey, err)
|
||||
}
|
||||
var vbState viperblock.VBState
|
||||
if err := json.Unmarshal(viperblock.StateBody(body), &vbState); err != nil {
|
||||
return viperblock.AMIMetadata{}, fmt.Errorf("%w: %s: %v", ErrCorruptAMIConfig, configKey, err)
|
||||
return viperblock.AMIMetadata{}, fmt.Errorf("%w: %s: %w", ErrCorruptAMIConfig, configKey, err)
|
||||
}
|
||||
return vbState.VolumeConfig.AMIMetadata, nil
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ func ReadSnapshotConfig(store objectstore.ObjectStore, bucket, snapshotID string
|
||||
|
||||
var cfg SnapshotConfig
|
||||
if err := json.NewDecoder(result.Body).Decode(&cfg); err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", ErrCorruptSnapshotMetadata, err)
|
||||
return nil, fmt.Errorf("%w: %w", ErrCorruptSnapshotMetadata, err)
|
||||
}
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ func (b *NATSBootstrap) persistCA(data []byte) error {
|
||||
return fmt.Errorf("%w: CA envelope empty", errBootstrapPermanent)
|
||||
}
|
||||
if _, err := base64.StdEncoding.DecodeString(env.CertificateAuthority); err != nil {
|
||||
return fmt.Errorf("%w: CA not base64: %v", errBootstrapPermanent, err)
|
||||
return fmt.Errorf("%w: CA not base64: %w", errBootstrapPermanent, err)
|
||||
}
|
||||
return SetClusterCertificateAuthority(b.kv, b.clusterName, env.CertificateAuthority)
|
||||
}
|
||||
@@ -310,7 +310,7 @@ func (b *NATSBootstrap) persistCA(data []byte) error {
|
||||
func unmarshalBootstrapEnvelope(data []byte) (BootstrapEnvelope, error) {
|
||||
var env BootstrapEnvelope
|
||||
if err := json.Unmarshal(data, &env); err != nil {
|
||||
return env, fmt.Errorf("%w: unmarshal envelope: %v", errBootstrapPermanent, err)
|
||||
return env, fmt.Errorf("%w: unmarshal envelope: %w", errBootstrapPermanent, err)
|
||||
}
|
||||
return env, nil
|
||||
}
|
||||
@@ -323,7 +323,7 @@ func assertJWKSMatch(existing, incoming []byte) error {
|
||||
return fmt.Errorf("unmarshal existing JWKS: %w", err)
|
||||
}
|
||||
if err := json.Unmarshal(incoming, &in); err != nil {
|
||||
return fmt.Errorf("%w: unmarshal incoming JWKS: %v", errBootstrapPermanent, err)
|
||||
return fmt.Errorf("%w: unmarshal incoming JWKS: %w", errBootstrapPermanent, err)
|
||||
}
|
||||
if len(in.Keys) == 0 {
|
||||
return fmt.Errorf("%w: incoming JWKS has no keys", errBootstrapPermanent)
|
||||
|
||||
@@ -92,7 +92,8 @@ func NewS3ObjectStore(client *s3.S3) *S3ObjectStore {
|
||||
func (s *S3ObjectStore) GetObject(ctx context.Context, input *s3.GetObjectInput) (*s3.GetObjectOutput, error) {
|
||||
out, err := s.client.GetObjectWithContext(ctx, input)
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok &&
|
||||
var aerr awserr.Error
|
||||
if errors.As(err, &aerr) &&
|
||||
(aerr.Code() == s3.ErrCodeNoSuchKey || aerr.Code() == "NotFound") {
|
||||
return nil, &NoSuchKeyError{Key: aws.StringValue(input.Key)}
|
||||
}
|
||||
@@ -104,7 +105,8 @@ func (s *S3ObjectStore) GetObject(ctx context.Context, input *s3.GetObjectInput)
|
||||
func (s *S3ObjectStore) HeadObject(ctx context.Context, input *s3.HeadObjectInput) (*s3.HeadObjectOutput, error) {
|
||||
out, err := s.client.HeadObjectWithContext(ctx, input)
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok &&
|
||||
var aerr awserr.Error
|
||||
if errors.As(err, &aerr) &&
|
||||
(aerr.Code() == s3.ErrCodeNoSuchKey || aerr.Code() == "NotFound") {
|
||||
return nil, &NoSuchKeyError{Key: aws.StringValue(input.Key)}
|
||||
}
|
||||
@@ -134,7 +136,8 @@ func (s *S3ObjectStore) EnsureBucket(ctx context.Context, bucket string) error {
|
||||
}
|
||||
_, err := s.client.CreateBucketWithContext(ctx, &s3.CreateBucketInput{Bucket: aws.String(bucket)})
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
var aerr awserr.Error
|
||||
if errors.As(err, &aerr) {
|
||||
switch aerr.Code() {
|
||||
case s3.ErrCodeBucketAlreadyOwnedByYou, s3.ErrCodeBucketAlreadyExists:
|
||||
return nil
|
||||
|
||||
@@ -99,7 +99,7 @@ func newHasher(checksumType string) (hash.Hash, error) {
|
||||
func fetchExpectedDigest(checksumURL, filename string) (string, error) {
|
||||
parsed, err := url.Parse(checksumURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%w: parse url: %v", ErrChecksumFetchFailed, err)
|
||||
return "", fmt.Errorf("%w: parse url: %w", ErrChecksumFetchFailed, err)
|
||||
}
|
||||
if parsed.Scheme != "https" {
|
||||
return "", fmt.Errorf("%w: non-https checksum url scheme %q", ErrChecksumFetchFailed, parsed.Scheme)
|
||||
@@ -138,12 +138,12 @@ func fetchExpectedDigest(checksumURL, filename string) (string, error) {
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, checksumURL, nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%w: build request: %v", ErrChecksumFetchFailed, err)
|
||||
return "", fmt.Errorf("%w: build request: %w", ErrChecksumFetchFailed, err)
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%w: %v", ErrChecksumFetchFailed, err)
|
||||
return "", fmt.Errorf("%w: %w", ErrChecksumFetchFailed, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
@@ -153,7 +153,7 @@ func fetchExpectedDigest(checksumURL, filename string) (string, error) {
|
||||
|
||||
body, err := io.ReadAll(io.LimitReader(resp.Body, sumsFileMaxSize+1))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%w: read body: %v", ErrChecksumFetchFailed, err)
|
||||
return "", fmt.Errorf("%w: read body: %w", ErrChecksumFetchFailed, err)
|
||||
}
|
||||
if len(body) > sumsFileMaxSize {
|
||||
return "", fmt.Errorf("%w: sums file exceeds %d byte limit", ErrChecksumFetchFailed, sumsFileMaxSize)
|
||||
@@ -203,7 +203,7 @@ func parseSumsFile(body []byte, filename string) (string, error) {
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return "", fmt.Errorf("%w: scan sums file: %v", ErrChecksumFetchFailed, err)
|
||||
return "", fmt.Errorf("%w: scan sums file: %w", ErrChecksumFetchFailed, err)
|
||||
}
|
||||
|
||||
// Alpine single-file fallback: accept only if exactly one bare-digest line in the file.
|
||||
|
||||
@@ -61,7 +61,7 @@ func ConnectNATS(host, token, caCertPath string, opts ...RetryOption) (*nats.Con
|
||||
if caCertPath != "" {
|
||||
caCert, err := os.ReadFile(caCertPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w %s: %v", ErrCACertRead, caCertPath, err)
|
||||
return nil, fmt.Errorf("%w %s: %w", ErrCACertRead, caCertPath, err)
|
||||
}
|
||||
pool := x509.NewCertPool()
|
||||
if !pool.AppendCertsFromPEM(caCert) {
|
||||
|
||||
@@ -182,12 +182,12 @@ func DownloadFileWithProgress(url string, name string, filename string, timeout
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("request error: %v", err)
|
||||
return fmt.Errorf("request error: %w", err)
|
||||
}
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("http error: %v", err)
|
||||
return fmt.Errorf("http error: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||||
@@ -196,7 +196,7 @@ func DownloadFileWithProgress(url string, name string, filename string, timeout
|
||||
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("file create error: %v", err)
|
||||
return fmt.Errorf("file create error: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
@@ -215,7 +215,7 @@ func DownloadFileWithProgress(url string, name string, filename string, timeout
|
||||
_, err = io.Copy(f, reader)
|
||||
_, _ = bar.Stop()
|
||||
if err != nil {
|
||||
return fmt.Errorf("copy error: %v", err)
|
||||
return fmt.Errorf("copy error: %w", err)
|
||||
}
|
||||
return err
|
||||
} else {
|
||||
@@ -231,7 +231,7 @@ func DownloadFileWithProgress(url string, name string, filename string, timeout
|
||||
_ = spin.Stop()
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("copy error: %v", err)
|
||||
return fmt.Errorf("copy error: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -212,7 +212,8 @@ var localSystemID = func() (string, error) {
|
||||
out, err := sudoCommand("ovs-vsctl", "get", "open_vswitch", ".", "external-ids:system-id").Output()
|
||||
if err != nil {
|
||||
var stderr string
|
||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
stderr = strings.TrimSpace(string(exitErr.Stderr))
|
||||
}
|
||||
return "", fmt.Errorf("ovs-vsctl get system-id: %s: %w", stderr, err)
|
||||
@@ -239,7 +240,8 @@ var discoverChassis = func(sbAddr string) ([]string, error) {
|
||||
out, err := sudoCommand("ovn-sbctl", args...).Output()
|
||||
if err != nil {
|
||||
var stderr string
|
||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
stderr = strings.TrimSpace(string(exitErr.Stderr))
|
||||
}
|
||||
return nil, fmt.Errorf("ovn-sbctl list Chassis: %s: %w", stderr, err)
|
||||
@@ -843,7 +845,8 @@ var portToBr = func(port string) (string, error) {
|
||||
out, err := sudoCommand("ovs-vsctl", "port-to-br", port).Output()
|
||||
if err != nil {
|
||||
var stderr string
|
||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
stderr = strings.TrimSpace(string(exitErr.Stderr))
|
||||
}
|
||||
return "", fmt.Errorf("ovs-vsctl port-to-br %s: %s: %w", port, stderr, err)
|
||||
|
||||
Reference in New Issue
Block a user