fix: retry image pulling, stop on 404, no duplicate pulls

This uses go-retry feature
(https://github.com/talos-systems/go-retry/pull/3) to print errors being
retried.

If image is not found in the index, abort retries immediately.

Don't pull installer image twice (if already pulled by the validation
code before).

Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
This commit is contained in:
Andrey Smirnov 2020-09-21 17:08:37 +03:00 committed by talos-bot
parent c6a35ba0ed
commit 8236822c90
4 changed files with 28 additions and 13 deletions

2
go.mod
View File

@ -60,7 +60,7 @@ require (
github.com/talos-systems/crypto v0.2.0
github.com/talos-systems/go-loadbalancer v0.1.0
github.com/talos-systems/go-procfs v0.0.0-20200219015357-57c7311fdd45
github.com/talos-systems/go-retry v0.1.0
github.com/talos-systems/go-retry v0.1.1-0.20200922131245-752f081252cf
github.com/talos-systems/go-smbios v0.0.0-20200219201045-94b8c4e489ee
github.com/talos-systems/grpc-proxy v0.2.0
github.com/talos-systems/net v0.2.0

2
go.sum
View File

@ -760,6 +760,8 @@ github.com/talos-systems/go-procfs v0.0.0-20200219015357-57c7311fdd45 h1:FND/Lgz
github.com/talos-systems/go-procfs v0.0.0-20200219015357-57c7311fdd45/go.mod h1:ATyUGFQIW8OnbnmvqefZWVPgL9g+CAmXHfkgny21xX8=
github.com/talos-systems/go-retry v0.1.0 h1:O+OeZR54CQ1+ch99p/81Pqi5GqJH6LIu1MTN/N0vd78=
github.com/talos-systems/go-retry v0.1.0/go.mod h1:HiXQqyVStZ35uSY/MTLWVvQVmC3lIW2MS5VdDaMtoKM=
github.com/talos-systems/go-retry v0.1.1-0.20200922131245-752f081252cf h1:JzyT28FxRDndO59tFKA1IyGb9uWpJX429PPAfjc0dVQ=
github.com/talos-systems/go-retry v0.1.1-0.20200922131245-752f081252cf/go.mod h1:HiXQqyVStZ35uSY/MTLWVvQVmC3lIW2MS5VdDaMtoKM=
github.com/talos-systems/go-smbios v0.0.0-20200219201045-94b8c4e489ee h1:9i0ZFsjZ0wY8UUn/tk2MQshLBC0PNFJe3+84AUqzzyw=
github.com/talos-systems/go-smbios v0.0.0-20200219201045-94b8c4e489ee/go.mod h1:HxhrzAoTZ7ed5Z5VvtCvnCIrOxyXDS7V2B5hCetAMW8=
github.com/talos-systems/grpc-proxy v0.2.0 h1:DN75bLfaW4xfhq0r0mwFRnfGhSB+HPhK1LNzuMEs9Pw=

View File

@ -13,6 +13,7 @@ import (
"github.com/containerd/containerd"
"github.com/containerd/containerd/cio"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/oci"
"github.com/opencontainers/runtime-spec/specs-go"
@ -47,20 +48,19 @@ func RunInstallerContainer(disk, platform, ref string, reg config.Registries, op
var img containerd.Image
if options.Pull {
log.Printf("pulling %q", ref)
img, err = client.GetImage(ctx, ref)
if err != nil {
if errdefs.IsNotFound(err) && options.Pull {
log.Printf("pulling %q", ref)
img, err = image.Pull(ctx, reg, client, ref)
if err != nil {
return err
}
} else {
img, err = client.GetImage(ctx, ref)
if err != nil {
return err
img, err = image.Pull(ctx, reg, client, ref)
}
}
if err != nil {
return err
}
mounts := []specs.Mount{
{Type: "bind", Destination: "/dev", Source: "/dev", Options: []string{"rbind", "rshared", "rw"}},
}

View File

@ -10,19 +10,32 @@ import (
"time"
"github.com/containerd/containerd"
"github.com/containerd/containerd/errdefs"
"github.com/talos-systems/go-retry/retry"
"github.com/talos-systems/talos/pkg/machinery/config"
)
// Image pull retry settings.
const (
PullTimeout = 20 * time.Minute
PullRetryInterval = 5 * time.Second
)
// Pull is a convenience function that wraps the containerd image pull func with
// retry functionality.
func Pull(ctx context.Context, reg config.Registries, client *containerd.Client, ref string) (img containerd.Image, err error) {
resolver := NewResolver(reg)
err = retry.Exponential(1*time.Minute, retry.WithUnits(1*time.Second)).Retry(func() error {
err = retry.Exponential(PullTimeout, retry.WithUnits(PullRetryInterval), retry.WithErrorLogging(true)).Retry(func() error {
if img, err = client.Pull(ctx, ref, containerd.WithPullUnpack, containerd.WithResolver(resolver)); err != nil {
return retry.ExpectedError(fmt.Errorf("failed to pull image %q: %w", ref, err))
err = fmt.Errorf("failed to pull image %q: %w", ref, err)
if errdefs.IsNotFound(err) {
return retry.UnexpectedError(err)
}
return retry.ExpectedError(err)
}
return nil