pkg/autoupdate: introduce `updater` for shared state

Introduce an `updater` type to allow for sharing state.
This will be more useful for future changes.

[NO NEW TESTS NEEDED] as it does not change behavior.

Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
This commit is contained in:
Valentin Rothberg 2022-07-28 14:20:50 +02:00
parent ccbb8e7444
commit d476097739
1 changed files with 37 additions and 23 deletions

View File

@ -145,9 +145,15 @@ func AutoUpdate(ctx context.Context, runtime *libpod.Runtime, options entities.A
runtime.NewSystemEvent(events.AutoUpdate) runtime.NewSystemEvent(events.AutoUpdate)
auto := updater{
conn: conn,
options: &options,
runtime: runtime,
updatedRawImages: make(map[string]bool),
}
// Update all images/container according to their auto-update policy. // Update all images/container according to their auto-update policy.
var allReports []*entities.AutoUpdateReport var allReports []*entities.AutoUpdateReport
updatedRawImages := make(map[string]bool)
for imageID, policyMapper := range containerMap { for imageID, policyMapper := range containerMap {
image, exists := imageMap[imageID] image, exists := imageMap[imageID]
if !exists { if !exists {
@ -156,7 +162,7 @@ func AutoUpdate(ctx context.Context, runtime *libpod.Runtime, options entities.A
} }
for _, ctr := range policyMapper[PolicyRegistryImage] { for _, ctr := range policyMapper[PolicyRegistryImage] {
report, err := autoUpdateRegistry(ctx, image, ctr, updatedRawImages, &options, conn, runtime) report, err := auto.updateRegistry(ctx, image, ctr)
if err != nil { if err != nil {
errs = append(errs, err) errs = append(errs, err)
} }
@ -166,7 +172,7 @@ func AutoUpdate(ctx context.Context, runtime *libpod.Runtime, options entities.A
} }
for _, ctr := range policyMapper[PolicyLocalImage] { for _, ctr := range policyMapper[PolicyLocalImage] {
report, err := autoUpdateLocally(ctx, image, ctr, &options, conn, runtime) report, err := auto.updateLocally(ctx, image, ctr)
if err != nil { if err != nil {
errs = append(errs, err) errs = append(errs, err)
} }
@ -179,8 +185,16 @@ func AutoUpdate(ctx context.Context, runtime *libpod.Runtime, options entities.A
return allReports, errs return allReports, errs
} }
// autoUpdateRegistry updates the image/container according to the "registry" policy. // updater includes shared state for auto-updating one or more containers.
func autoUpdateRegistry(ctx context.Context, image *libimage.Image, ctr *libpod.Container, updatedRawImages map[string]bool, options *entities.AutoUpdateOptions, conn *dbus.Conn, runtime *libpod.Runtime) (*entities.AutoUpdateReport, error) { type updater struct {
conn *dbus.Conn
options *entities.AutoUpdateOptions
updatedRawImages map[string]bool
runtime *libpod.Runtime
}
// updateRegistry updates the image/container according to the "registry" policy.
func (u *updater) updateRegistry(ctx context.Context, image *libimage.Image, ctr *libpod.Container) (*entities.AutoUpdateReport, error) {
cid := ctr.ID() cid := ctr.ID()
rawImageName := ctr.RawImageName() rawImageName := ctr.RawImageName()
if rawImageName == "" { if rawImageName == "" {
@ -202,16 +216,16 @@ func autoUpdateRegistry(ctx context.Context, image *libimage.Image, ctr *libpod.
Updated: "failed", Updated: "failed",
} }
if _, updated := updatedRawImages[rawImageName]; updated { if _, updated := u.updatedRawImages[rawImageName]; updated {
logrus.Infof("Auto-updating container %q using registry image %q", cid, rawImageName) logrus.Infof("Auto-updating container %q using registry image %q", cid, rawImageName)
if err := restartSystemdUnit(ctx, ctr, unit, conn); err != nil { if err := u.restartSystemdUnit(ctx, ctr, unit); err != nil {
return report, err return report, err
} }
report.Updated = "true" report.Updated = "true"
return report, nil return report, nil
} }
authfile := getAuthfilePath(ctr, options) authfile := getAuthfilePath(ctr, u.options)
needsUpdate, err := newerRemoteImageAvailable(ctx, image, rawImageName, authfile) needsUpdate, err := newerRemoteImageAvailable(ctx, image, rawImageName, authfile)
if err != nil { if err != nil {
return report, fmt.Errorf("registry auto-updating container %q: image check for %q failed: %w", cid, rawImageName, err) return report, fmt.Errorf("registry auto-updating container %q: image check for %q failed: %w", cid, rawImageName, err)
@ -222,24 +236,24 @@ func autoUpdateRegistry(ctx context.Context, image *libimage.Image, ctr *libpod.
return report, nil return report, nil
} }
if options.DryRun { if u.options.DryRun {
report.Updated = "pending" report.Updated = "pending"
return report, nil return report, nil
} }
if _, err := updateImage(ctx, runtime, rawImageName, authfile); err != nil { if _, err := updateImage(ctx, u.runtime, rawImageName, authfile); err != nil {
return report, fmt.Errorf("registry auto-updating container %q: image update for %q failed: %w", cid, rawImageName, err) return report, fmt.Errorf("registry auto-updating container %q: image update for %q failed: %w", cid, rawImageName, err)
} }
updatedRawImages[rawImageName] = true u.updatedRawImages[rawImageName] = true
logrus.Infof("Auto-updating container %q using registry image %q", cid, rawImageName) logrus.Infof("Auto-updating container %q using registry image %q", cid, rawImageName)
updateErr := restartSystemdUnit(ctx, ctr, unit, conn) updateErr := u.restartSystemdUnit(ctx, ctr, unit)
if updateErr == nil { if updateErr == nil {
report.Updated = "true" report.Updated = "true"
return report, nil return report, nil
} }
if !options.Rollback { if !u.options.Rollback {
return report, updateErr return report, updateErr
} }
@ -247,7 +261,7 @@ func autoUpdateRegistry(ctx context.Context, image *libimage.Image, ctr *libpod.
if err := image.Tag(rawImageName); err != nil { if err := image.Tag(rawImageName); err != nil {
return report, fmt.Errorf("falling back to previous image: %w", err) return report, fmt.Errorf("falling back to previous image: %w", err)
} }
if err := restartSystemdUnit(ctx, ctr, unit, conn); err != nil { if err := u.restartSystemdUnit(ctx, ctr, unit); err != nil {
return report, fmt.Errorf("restarting unit with old image during fallback: %w", err) return report, fmt.Errorf("restarting unit with old image during fallback: %w", err)
} }
@ -255,8 +269,8 @@ func autoUpdateRegistry(ctx context.Context, image *libimage.Image, ctr *libpod.
return report, nil return report, nil
} }
// autoUpdateRegistry updates the image/container according to the "local" policy. // updateRegistry updates the image/container according to the "local" policy.
func autoUpdateLocally(ctx context.Context, image *libimage.Image, ctr *libpod.Container, options *entities.AutoUpdateOptions, conn *dbus.Conn, runtime *libpod.Runtime) (*entities.AutoUpdateReport, error) { func (u *updater) updateLocally(ctx context.Context, image *libimage.Image, ctr *libpod.Container) (*entities.AutoUpdateReport, error) {
cid := ctr.ID() cid := ctr.ID()
rawImageName := ctr.RawImageName() rawImageName := ctr.RawImageName()
if rawImageName == "" { if rawImageName == "" {
@ -278,7 +292,7 @@ func autoUpdateLocally(ctx context.Context, image *libimage.Image, ctr *libpod.C
Updated: "failed", Updated: "failed",
} }
needsUpdate, err := newerLocalImageAvailable(runtime, image, rawImageName) needsUpdate, err := newerLocalImageAvailable(u.runtime, image, rawImageName)
if err != nil { if err != nil {
return report, fmt.Errorf("locally auto-updating container %q: image check for %q failed: %w", cid, rawImageName, err) return report, fmt.Errorf("locally auto-updating container %q: image check for %q failed: %w", cid, rawImageName, err)
} }
@ -288,19 +302,19 @@ func autoUpdateLocally(ctx context.Context, image *libimage.Image, ctr *libpod.C
return report, nil return report, nil
} }
if options.DryRun { if u.options.DryRun {
report.Updated = "pending" report.Updated = "pending"
return report, nil return report, nil
} }
logrus.Infof("Auto-updating container %q using local image %q", cid, rawImageName) logrus.Infof("Auto-updating container %q using local image %q", cid, rawImageName)
updateErr := restartSystemdUnit(ctx, ctr, unit, conn) updateErr := u.restartSystemdUnit(ctx, ctr, unit)
if updateErr == nil { if updateErr == nil {
report.Updated = "true" report.Updated = "true"
return report, nil return report, nil
} }
if !options.Rollback { if !u.options.Rollback {
return report, updateErr return report, updateErr
} }
@ -308,7 +322,7 @@ func autoUpdateLocally(ctx context.Context, image *libimage.Image, ctr *libpod.C
if err := image.Tag(rawImageName); err != nil { if err := image.Tag(rawImageName); err != nil {
return report, fmt.Errorf("falling back to previous image: %w", err) return report, fmt.Errorf("falling back to previous image: %w", err)
} }
if err := restartSystemdUnit(ctx, ctr, unit, conn); err != nil { if err := u.restartSystemdUnit(ctx, ctr, unit); err != nil {
return report, fmt.Errorf("restarting unit with old image during fallback: %w", err) return report, fmt.Errorf("restarting unit with old image during fallback: %w", err)
} }
@ -317,9 +331,9 @@ func autoUpdateLocally(ctx context.Context, image *libimage.Image, ctr *libpod.C
} }
// restartSystemdUnit restarts the systemd unit the container is running in. // restartSystemdUnit restarts the systemd unit the container is running in.
func restartSystemdUnit(ctx context.Context, ctr *libpod.Container, unit string, conn *dbus.Conn) error { func (u *updater) restartSystemdUnit(ctx context.Context, ctr *libpod.Container, unit string) error {
restartChan := make(chan string) restartChan := make(chan string)
if _, err := conn.RestartUnitContext(ctx, unit, "replace", restartChan); err != nil { if _, err := u.conn.RestartUnitContext(ctx, unit, "replace", restartChan); err != nil {
return fmt.Errorf("auto-updating container %q: restarting systemd unit %q failed: %w", ctr.ID(), unit, err) return fmt.Errorf("auto-updating container %q: restarting systemd unit %q failed: %w", ctr.ID(), unit, err)
} }