diff --git a/cmd/cli.go b/cmd/cli.go
index 16e60a2a..874a1f6d 100644
--- a/cmd/cli.go
+++ b/cmd/cli.go
@@ -24,7 +24,7 @@ type CliGlobals struct {
// BeforeApply is a hook that run cli cmd are executed.
func (s *CliGlobals) BeforeApply() (err error) {
- s.conn, err = grpc.Dial(s.GRPCAuthority, grpc.WithTransportCredentials(insecure.NewCredentials()))
+ s.conn, err = grpc.NewClient(s.GRPCAuthority, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return err
}
diff --git a/cmd/image.go b/cmd/image.go
index da7c91ee..7d608d7b 100644
--- a/cmd/image.go
+++ b/cmd/image.go
@@ -9,9 +9,9 @@ import (
"time"
"unicode"
- "github.com/AlecAivazis/survey/v2"
+ survey "github.com/AlecAivazis/survey/v2"
"github.com/crazy-max/diun/v4/pb"
- "github.com/docker/go-units"
+ units "github.com/docker/go-units"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/tidwall/pretty"
"google.golang.org/protobuf/encoding/protojson"
@@ -138,8 +138,8 @@ func (s *ImageRemoveCmd) Run(_ *Context) error {
// ImagePruneCmd holds image prune command
type ImagePruneCmd struct {
CliGlobals
- //All bool `kong:"name='all',default='false',help='Remove all manifests from the database.'"`
- //Filter string `kong:"name='filter',help='Provide filter values (e.g., until=24h).'"`
+ // All bool `kong:"name='all',default='false',help='Remove all manifests from the database.'"`
+ // Filter string `kong:"name='filter',help='Provide filter values (e.g., until=24h).'"`
Force bool `kong:"name='force',default='false',help='Do not prompt for confirmation.'"`
}
diff --git a/cmd/main.go b/cmd/main.go
index 6e59a76d..43c65ad6 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -39,7 +39,7 @@ func main() {
Author: "CrazyMax",
Version: version,
}
- meta.UserAgent = fmt.Sprintf("%s/%s go/%s %s", meta.ID, meta.Version, runtime.Version()[2:], strings.Title(runtime.GOOS))
+ meta.UserAgent = fmt.Sprintf("%s/%s go/%s %s", meta.ID, meta.Version, runtime.Version()[2:], strings.Title(runtime.GOOS)) //nolint:staticcheck // ignoring "SA1019: strings.Title is deprecated", as for our use we don't need full unicode support
if meta.Hostname, err = os.Hostname(); err != nil {
log.Fatal().Err(err).Msg("Cannot resolve hostname")
}
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index 5b70440f..0c0b7add 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -189,7 +189,7 @@ for {{ .Entry.Manifest.Platform }} platform.
},
},
RegOpts: model.RegOpts{
- {
+ model.RegOpt{
Name: "myregistry",
Selector: model.RegOptSelectorName,
Username: "fii",
@@ -197,7 +197,7 @@ for {{ .Entry.Manifest.Platform }} platform.
InsecureTLS: utl.NewFalse(),
Timeout: utl.NewDuration(5 * time.Second),
},
- {
+ model.RegOpt{
Name: "docker.io",
Selector: model.RegOptSelectorImage,
Username: "foo",
@@ -205,7 +205,7 @@ for {{ .Entry.Manifest.Platform }} platform.
InsecureTLS: utl.NewFalse(),
Timeout: utl.NewDuration(0),
},
- {
+ model.RegOpt{
Name: "docker.io/crazymax",
Selector: model.RegOptSelectorImage,
UsernameFile: "./fixtures/run_secrets_username",
@@ -301,7 +301,7 @@ func TestLoadEnv(t *testing.T) {
Watch: (&model.Watch{}).GetDefaults(),
Defaults: (&model.Defaults{}).GetDefaults(),
RegOpts: model.RegOpts{
- {
+ model.RegOpt{
Name: "docker.io",
Selector: model.RegOptSelectorImage,
UsernameFile: "./fixtures/run_secrets_username",
diff --git a/internal/notif/client.go b/internal/notif/client.go
index 4ddc915e..f18622b9 100644
--- a/internal/notif/client.go
+++ b/internal/notif/client.go
@@ -99,7 +99,7 @@ func (c *Client) Send(entry model.NotifEntry) {
for _, n := range c.notifiers {
log.Debug().Str("image", entry.Image.String()).Msgf("Sending %s notification...", n.Name())
if err := n.Send(entry); err != nil {
- log.Error().Err(err).Str("image", entry.Image.String()).Msgf("%s notification failed", strings.Title(n.Name()))
+ log.Error().Err(err).Str("image", entry.Image.String()).Msgf("%s notification failed", strings.Title(n.Name())) //nolint:staticcheck // ignoring "SA1019: strings.Title is deprecated", as for our use we don't need full unicode support
}
}
}
diff --git a/internal/notif/discord/client.go b/internal/notif/discord/client.go
index 20966d82..bb07b5a8 100644
--- a/internal/notif/discord/client.go
+++ b/internal/notif/discord/client.go
@@ -2,6 +2,7 @@ package discord
import (
"bytes"
+ "context"
"encoding/json"
"fmt"
"net/http"
@@ -41,10 +42,6 @@ func (c *Client) Name() string {
func (c *Client) Send(entry model.NotifEntry) error {
var content bytes.Buffer
- hc := http.Client{
- Timeout: *c.cfg.Timeout,
- }
-
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
@@ -125,7 +122,11 @@ func (c *Client) Send(entry model.NotifEntry) error {
return err
}
- req, err := http.NewRequest("POST", u.String(), dataBuf)
+ hc := http.Client{}
+ ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
+ defer cancel()
+
+ req, err := http.NewRequestWithContext(ctx, "POST", u.String(), dataBuf)
if err != nil {
return err
}
@@ -137,6 +138,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
if err != nil {
return err
}
+ defer resp.Body.Close()
if resp.StatusCode != http.StatusNoContent {
return errors.Errorf("unexpected HTTP status %d: %s", resp.StatusCode, resp.Body)
diff --git a/internal/notif/gotify/client.go b/internal/notif/gotify/client.go
index 94222c5c..094ebe7f 100644
--- a/internal/notif/gotify/client.go
+++ b/internal/notif/gotify/client.go
@@ -2,6 +2,7 @@ package gotify
import (
"bytes"
+ "context"
"encoding/json"
"net/http"
"net/url"
@@ -44,10 +45,6 @@ func (c *Client) Send(entry model.NotifEntry) error {
return errors.Wrap(err, "cannot retrieve token secret for Gotify notifier")
}
- hc := http.Client{
- Timeout: *c.cfg.Timeout,
- }
-
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
@@ -92,7 +89,11 @@ func (c *Client) Send(entry model.NotifEntry) error {
q.Set("token", token)
u.RawQuery = q.Encode()
- req, err := http.NewRequest("POST", u.String(), bytes.NewBuffer(jsonBody))
+ hc := http.Client{}
+ ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
+ defer cancel()
+
+ req, err := http.NewRequestWithContext(ctx, "POST", u.String(), bytes.NewBuffer(jsonBody))
if err != nil {
return err
}
@@ -105,6 +106,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
if err != nil {
return err
}
+ defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
var errBody struct {
diff --git a/internal/notif/ntfy/client.go b/internal/notif/ntfy/client.go
index 0884484c..c664f0de 100644
--- a/internal/notif/ntfy/client.go
+++ b/internal/notif/ntfy/client.go
@@ -2,6 +2,7 @@ package ntfy
import (
"bytes"
+ "context"
"encoding/json"
"fmt"
"net/http"
@@ -38,10 +39,6 @@ func (c *Client) Name() string {
// Send creates and sends a ntfy notification with an entry
func (c *Client) Send(entry model.NotifEntry) error {
- hc := http.Client{
- Timeout: *c.cfg.Timeout,
- }
-
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
@@ -84,7 +81,11 @@ func (c *Client) Send(entry model.NotifEntry) error {
q := u.Query()
u.RawQuery = q.Encode()
- req, err := http.NewRequest("POST", u.String(), dataBuf)
+ hc := http.Client{}
+ ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
+ defer cancel()
+
+ req, err := http.NewRequestWithContext(ctx, "POST", u.String(), dataBuf)
if err != nil {
return err
}
@@ -99,6 +100,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
if err != nil {
return err
}
+ defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
var errBody struct {
diff --git a/internal/notif/rocketchat/client.go b/internal/notif/rocketchat/client.go
index 4db4aaf3..40d65fc2 100644
--- a/internal/notif/rocketchat/client.go
+++ b/internal/notif/rocketchat/client.go
@@ -2,6 +2,7 @@ package rocketchat
import (
"bytes"
+ "context"
"encoding/json"
"net/http"
"net/url"
@@ -46,10 +47,6 @@ func (c *Client) Send(entry model.NotifEntry) error {
return errors.Wrap(err, "cannot retrieve token secret for RocketChat notifier")
}
- hc := http.Client{
- Timeout: *c.cfg.Timeout,
- }
-
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
@@ -125,7 +122,11 @@ func (c *Client) Send(entry model.NotifEntry) error {
}
u.Path = path.Join(u.Path, "api/v1/chat.postMessage")
- req, err := http.NewRequest("POST", u.String(), dataBuf)
+ hc := http.Client{}
+ ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
+ defer cancel()
+
+ req, err := http.NewRequestWithContext(ctx, "POST", u.String(), dataBuf)
if err != nil {
return err
}
@@ -139,6 +140,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
if err != nil {
return err
}
+ defer resp.Body.Close()
var respBody struct {
Success bool `json:"success"`
diff --git a/internal/notif/script/client.go b/internal/notif/script/client.go
index bbdd1ccb..32094f2b 100644
--- a/internal/notif/script/client.go
+++ b/internal/notif/script/client.go
@@ -66,6 +66,6 @@ func (c *Client) Send(entry model.NotifEntry) error {
return errors.Wrap(err, strings.TrimSpace(stderr.String()))
}
- log.Debug().Msgf(strings.TrimSpace(stdout.String()))
+ log.Debug().Msg(strings.TrimSpace(stdout.String()))
return nil
}
diff --git a/internal/notif/signalrest/client.go b/internal/notif/signalrest/client.go
index 405a0d41..c1b37f74 100644
--- a/internal/notif/signalrest/client.go
+++ b/internal/notif/signalrest/client.go
@@ -2,6 +2,7 @@ package signalrest
import (
"bytes"
+ "context"
"encoding/json"
"net/http"
@@ -34,10 +35,6 @@ func (c *Client) Name() string {
// Send creates and sends a signalrest notification with an entry
func (c *Client) Send(entry model.NotifEntry) error {
- hc := http.Client{
- Timeout: *c.cfg.Timeout,
- }
-
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
@@ -65,7 +62,11 @@ func (c *Client) Send(entry model.NotifEntry) error {
return err
}
- req, err := http.NewRequest("POST", c.cfg.Endpoint, bytes.NewBuffer(body))
+ hc := http.Client{}
+ ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
+ defer cancel()
+
+ req, err := http.NewRequestWithContext(ctx, "POST", c.cfg.Endpoint, bytes.NewBuffer(body))
if err != nil {
return err
}
@@ -79,6 +80,11 @@ func (c *Client) Send(entry model.NotifEntry) error {
req.Header.Set("Content-Type", "application/json")
req.Header.Set("User-Agent", c.meta.UserAgent)
- _, err = hc.Do(req)
- return err
+ resp, err := hc.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ return nil
}
diff --git a/internal/notif/teams/client.go b/internal/notif/teams/client.go
index 1efbd60b..bbaa5470 100644
--- a/internal/notif/teams/client.go
+++ b/internal/notif/teams/client.go
@@ -2,6 +2,7 @@ package teams
import (
"bytes"
+ "context"
"encoding/json"
"fmt"
"net/http"
@@ -49,10 +50,6 @@ type Fact struct {
// Send creates and sends a webhook notification with an entry
func (c *Client) Send(entry model.NotifEntry) error {
- hc := http.Client{
- Timeout: time.Duration(10) * time.Second,
- }
-
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
@@ -106,7 +103,11 @@ func (c *Client) Send(entry model.NotifEntry) error {
return err
}
- req, err := http.NewRequest("POST", c.cfg.WebhookURL, bytes.NewBuffer(jsonBody))
+ hc := http.Client{}
+ ctx, cancel := context.WithTimeout(context.Background(), time.Duration(10)*time.Second)
+ defer cancel()
+
+ req, err := http.NewRequestWithContext(ctx, "POST", c.cfg.WebhookURL, bytes.NewBuffer(jsonBody))
if err != nil {
return err
}
@@ -114,6 +115,11 @@ func (c *Client) Send(entry model.NotifEntry) error {
req.Header.Add("Content-Type", "application/json")
req.Header.Set("User-Agent", c.meta.UserAgent)
- _, err = hc.Do(req)
- return err
+ resp, err := hc.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ return nil
}
diff --git a/internal/notif/webhook/client.go b/internal/notif/webhook/client.go
index e73d37c1..c6b4de13 100644
--- a/internal/notif/webhook/client.go
+++ b/internal/notif/webhook/client.go
@@ -2,6 +2,7 @@ package webhook
import (
"bytes"
+ "context"
"net/http"
"github.com/crazy-max/diun/v4/internal/model"
@@ -33,10 +34,6 @@ func (c *Client) Name() string {
// Send creates and sends a webhook notification with an entry
func (c *Client) Send(entry model.NotifEntry) error {
- hc := http.Client{
- Timeout: *c.cfg.Timeout,
- }
-
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
@@ -50,7 +47,11 @@ func (c *Client) Send(entry model.NotifEntry) error {
return err
}
- req, err := http.NewRequest(c.cfg.Method, c.cfg.Endpoint, bytes.NewBuffer(body))
+ hc := http.Client{}
+ ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
+ defer cancel()
+
+ req, err := http.NewRequestWithContext(ctx, "POST", c.cfg.Endpoint, bytes.NewBuffer(body))
if err != nil {
return err
}
@@ -63,6 +64,11 @@ func (c *Client) Send(entry model.NotifEntry) error {
req.Header.Set("User-Agent", c.meta.UserAgent)
- _, err = hc.Do(req)
- return err
+ resp, err := hc.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ return nil
}
diff --git a/internal/provider/common_test.go b/internal/provider/common_test.go
index 72a9abe3..0982d69c 100644
--- a/internal/provider/common_test.go
+++ b/internal/provider/common_test.go
@@ -7,7 +7,7 @@ import (
"github.com/crazy-max/diun/v4/pkg/registry"
"github.com/crazy-max/diun/v4/pkg/utl"
"github.com/pkg/errors"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestValidateImage(t *testing.T) {
@@ -693,10 +693,10 @@ func TestValidateImage(t *testing.T) {
tt.defaults,
)
if tt.expectedErr == nil {
- assert.NoError(t, err)
- assert.Equal(t, tt.expectedImage, img)
+ require.NoError(t, err)
+ require.Equal(t, tt.expectedImage, img)
} else {
- assert.ErrorContains(t, err, tt.expectedErr.Error())
+ require.ErrorContains(t, err, tt.expectedErr.Error())
}
})
}
diff --git a/pkg/registry/image.go b/pkg/registry/image.go
index e8dd9f76..a44e1eb8 100644
--- a/pkg/registry/image.go
+++ b/pkg/registry/image.go
@@ -85,13 +85,6 @@ func (i Image) Reference() string {
return i.Tag
}
-// WithDigest sets the digest for an image.
-func (i Image) WithDigest(digest digest.Digest) (err error) {
- i.Digest = digest
- i.named, err = reference.WithDigest(i.named, digest)
- return err
-}
-
func (i Image) hubLink() (string, error) {
if i.opts.HubTpl != "" {
var out bytes.Buffer
diff --git a/pkg/registry/manifest_test.go b/pkg/registry/manifest_test.go
index b3f2574b..7274ee83 100644
--- a/pkg/registry/manifest_test.go
+++ b/pkg/registry/manifest_test.go
@@ -4,6 +4,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCompareDigest(t *testing.T) {
@@ -26,7 +27,7 @@ func TestCompareDigest(t *testing.T) {
// download manifest
_, _, err = rc.Manifest(img, Manifest{})
- assert.NoError(t, err)
+ require.NoError(t, err)
// check manifest
manifest, _, err := rc.Manifest(img, Manifest{
@@ -36,7 +37,7 @@ func TestCompareDigest(t *testing.T) {
Digest: "sha256:db618981ef3d07699ff6cd8b9d2a81f51a021747bc08c85c1b0e8d11130c2be5",
Platform: "linux/amd64",
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "docker.io/crazymax/diun", manifest.Name)
assert.Equal(t, "2.5.0", manifest.Tag)
assert.Equal(t, "application/vnd.docker.distribution.manifest.list.v2+json", manifest.MIMEType)
@@ -64,7 +65,7 @@ func TestManifest(t *testing.T) {
// download manifest
_, _, err = rc.Manifest(img, Manifest{})
- assert.NoError(t, err)
+ require.NoError(t, err)
// check manifest
manifest, updated, err := rc.Manifest(img, Manifest{
@@ -101,7 +102,7 @@ func TestManifest(t *testing.T) {
}`),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, false, updated)
assert.Equal(t, "docker.io/portainer/portainer-ce", manifest.Name)
assert.Equal(t, "linux-amd64-2.5.1", manifest.Tag)
@@ -130,7 +131,7 @@ func TestManifestMultiUpdatedPlatform(t *testing.T) {
// download manifest
_, _, err = rc.Manifest(img, Manifest{})
- assert.NoError(t, err)
+ require.NoError(t, err)
// check manifest
manifest, updated, err := rc.Manifest(img, Manifest{
@@ -186,7 +187,7 @@ func TestManifestMultiUpdatedPlatform(t *testing.T) {
}`),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, true, updated)
assert.Equal(t, "docker.io/library/mongo", manifest.Name)
assert.Equal(t, "3.6.21", manifest.Tag)
@@ -215,7 +216,7 @@ func TestManifestMultiNotUpdatedPlatform(t *testing.T) {
// download manifest
_, _, err = rc.Manifest(img, Manifest{})
- assert.NoError(t, err)
+ require.NoError(t, err)
// check manifest
manifest, updated, err := rc.Manifest(img, Manifest{
@@ -271,7 +272,7 @@ func TestManifestMultiNotUpdatedPlatform(t *testing.T) {
}`),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, false, updated)
assert.Equal(t, "docker.io/library/mongo", manifest.Name)
assert.Equal(t, "3.6.21", manifest.Tag)
@@ -299,7 +300,7 @@ func TestManifestVariant(t *testing.T) {
}
manifest, _, err := rc.Manifest(img, Manifest{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "docker.io/crazymax/diun", manifest.Name)
assert.Equal(t, "2.5.0", manifest.Tag)
assert.Equal(t, "application/vnd.docker.distribution.manifest.list.v2+json", manifest.MIMEType)
@@ -327,11 +328,11 @@ func TestManifestTaggedDigest(t *testing.T) {
// download manifest
_, _, err = rc.Manifest(img, Manifest{})
- assert.NoError(t, err)
+ require.NoError(t, err)
// check manifest
manifest, updated, err := rc.Manifest(img, manifestCrazymaxDiun4250)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, false, updated)
assert.Equal(t, "docker.io/crazymax/diun", manifest.Name)
assert.Equal(t, "4.25.0", manifest.Tag)
@@ -359,7 +360,7 @@ func TestManifestTaggedDigestUnknownTag(t *testing.T) {
}
_, _, err = rc.Manifest(img, Manifest{})
- assert.Error(t, err)
+ require.Error(t, err)
}
var manifestCrazymaxDiun4250 = Manifest{
diff --git a/pkg/registry/ref.go b/pkg/registry/ref.go
index 49330f5b..f6286074 100644
--- a/pkg/registry/ref.go
+++ b/pkg/registry/ref.go
@@ -28,9 +28,7 @@ func namedReference(name string) (reference.Named, error) {
ref, err := reference.ParseNormalizedNamed(name)
if err != nil {
return nil, errors.Wrapf(err, "parsing normalized named %q", name)
- }
-
- if _, ok := ref.(reference.Named); !ok {
+ } else if ref == nil {
return nil, errors.Errorf("%q is not a named reference", name)
}
diff --git a/pkg/registry/tags_test.go b/pkg/registry/tags_test.go
index 9174a879..ecd452be 100644
--- a/pkg/registry/tags_test.go
+++ b/pkg/registry/tags_test.go
@@ -23,8 +23,8 @@ func TestTags(t *testing.T) {
t.Error(err)
}
- assert.True(t, tags.Total > 0)
- assert.True(t, len(tags.List) > 0)
+ assert.Greater(t, tags.Total, 0)
+ assert.Greater(t, len(tags.List), 0)
}
func TestTagsWithDigest(t *testing.T) {
@@ -46,8 +46,8 @@ func TestTagsWithDigest(t *testing.T) {
t.Error(err)
}
- assert.True(t, tags.Total > 0)
- assert.True(t, len(tags.List) > 0)
+ assert.Greater(t, tags.Total, 0)
+ assert.Greater(t, len(tags.List), 0)
}
func TestTagsSort(t *testing.T) {