Repository: skupperproject/skupper
Pull request #1361 (2024-01-16 22:17:21)

traverse host map on delete
UpdateHost incorrectly assumed host defined on delete


Patch:
diff --git a/client/container/client.go b/client/container/client.go
index 3dccc3bb..0311d974 100644
--- a/client/container/client.go
+++ b/client/container/client.go
@@ -1,6 +1,7 @@
 package container
 
 import (
+	"context"
 	"errors"
 	"fmt"
 	"os"
@@ -30,7 +31,7 @@ type Client interface {
 	ContainerRestart(id string) error
 	ImageList() ([]*Image, error)
 	ImageInspect(id string) (*Image, error)
-	ImagePull(id string) error
+	ImagePull(ctx context.Context, id string) error
 	NetworkList() ([]*Network, error)
 	NetworkInspect(id string) (*Network, error)
 	NetworkCreate(network *Network) (*Network, error)
diff --git a/client/podman/container.go b/client/podman/container.go
index 5d97bc20..ed2f5f51 100644
--- a/client/podman/container.go
+++ b/client/podman/container.go
@@ -1,6 +1,7 @@
 package podman
 
 import (
+	"context"
 	"fmt"
 	"os/user"
 	"strconv"
@@ -245,8 +246,8 @@ func (p *PodmanRestClient) ContainerUpdate(name string, fn func(newContainer *co
 }
 
 // ContainerUpdateImage updates the image used by the given container (name).
-func (p *PodmanRestClient) ContainerUpdateImage(name string, newImage string) (*container.Container, error) {
-	err := p.ImagePull(newImage)
+func (p *PodmanRestClient) ContainerUpdateImage(ctx context.Context, name string, newImage string) (*container.Container, error) {
+	err := p.ImagePull(ctx, newImage)
 	if err != nil {
 		return nil, fmt.Errorf("error pulling image %q: %s", newImage, err)
 	}
diff --git a/client/podman/image.go b/client/podman/image.go
index 2be5f250..8188f013 100644
--- a/client/podman/image.go
+++ b/client/podman/image.go
@@ -1,6 +1,7 @@
 package podman
 
 import (
+	"context"
 	"encoding/base64"
 	"encoding/json"
 	"fmt"
@@ -71,7 +72,7 @@ func (p *PodmanRestClient) ImageInspect(id string) (*container.Image, error) {
 	return img, nil
 }
 
-func (p *PodmanRestClient) ImagePull(id string) error {
+func (p *PodmanRestClient) ImagePull(ctx context.Context, id string) error {
 	params := images.NewImagePullLibpodParams()
 	params.Reference = &id
 	params.TLSVerify = new(bool)
@@ -94,7 +95,7 @@ func (p *PodmanRestClient) ImagePull(id string) error {
 		Schemes:            []string{"http", "https"},
 		Params:             params,
 		Reader:             reader,
-		Context:            params.Context,
+		Context:            ctx,
 		Client:             params.HTTPClient,
 	}
 	res, err := p.RestClient.Submit(op)
diff --git a/cmd/skupper/skupper_podman_site.go b/cmd/skupper/skupper_podman_site.go
index d4730e5a..d89ab2bd 100644
--- a/cmd/skupper/skupper_podman_site.go
+++ b/cmd/skupper/skupper_podman_site.go
@@ -1,10 +1,12 @@
 package main
 
 import (
+	"context"
 	"fmt"
 	"net"
 	"os"
 	"strings"
+	"time"
 
 	"github.com/google/uuid"
 	"github.com/skupperproject/skupper/api/types"
@@ -32,6 +34,7 @@ type PodmanInitFlags struct {
 	ContainerNetwork             string
 	EnableIPV6                   bool
 	PodmanEndpoint               string
+	Timeout                      time.Duration
 }
 
 func (s *SkupperPodmanSite) Create(cmd *cobra.Command, args []string) error {
@@ -127,7 +130,9 @@ func (s *SkupperPodmanSite) Create(cmd *cobra.Command, args []string) error {
 
 	// Initializing
 	cmd.SilenceUsage = true
-	err = siteHandler.Create(site)
+	ctx, cn := context.WithTimeout(context.Background(), s.flags.Timeout)
+	defer cn()
+	err = siteHandler.Create(ctx, site)
 	if err != nil {
 		return fmt.Errorf("Error initializing Skupper - %w", err)
 	}
@@ -180,6 +185,8 @@ func (s *SkupperPodmanSite) CreateFlags(cmd *cobra.Command) {
 		"ingress host binding port used for flow-collector and console")
 	cmd.Flags().DurationVar(&routerCreateOpts.FlowCollector.FlowRecordTtl, "flow-collector-record-ttl", 0, "Time after which terminated flow records are deleted, i.e. those flow records that have an end time set. Default is 30 minutes.")
 
+	cmd.Flags().DurationVar(&s.flags.Timeout, "timeout", types.DefaultTimeoutDuration, "Configurable timeout for site initialization")
+
 }
 
 func (s *SkupperPodmanSite) Delete(cmd *cobra.Command, args []string) error {
@@ -292,13 +299,16 @@ func (s *SkupperPodmanSite) Update(cmd *cobra.Command, args []string) error {
 	// updates site version number (always the last one)
 	s.up.RegisterTasks(update.NewVersionUpdateTask(s.podman.cli))
 	// process eligible tasks
-	return s.up.Process(s.podman.currentSite.Version)
+	ctx, cn := context.WithTimeout(context.Background(), s.up.Timeout)
+	defer cn()
+	return s.up.Process(ctx, s.podman.currentSite.Version)
 }
 
 func (s *SkupperPodmanSite) UpdateFlags(cmd *cobra.Command) {
 	s.up = &domain.UpdateProcessor{}
 	cmd.Flags().BoolVar(&s.up.DryRun, "dry-run", false, "only prints the tasks to be performed, but does not run any action")
 	cmd.Flags().BoolVar(&s.up.Verbose, "verbose", false, "displays tasks and post tasks being executed")
+	cmd.Flags().DurationVar(&s.up.Timeout, "timeout", types.DefaultTimeoutDuration, "Configurable timeout for site update")
 }
 
 func (s *SkupperPodmanSite) Version(cmd *cobra.Command, args []string) error {
diff --git a/pkg/domain/podman/deployment.go b/pkg/domain/podman/deployment.go
index a8d26b87..2048d5d0 100644
--- a/pkg/domain/podman/deployment.go
+++ b/pkg/domain/podman/deployment.go
@@ -1,6 +1,7 @@
 package podman
 
 import (
+	"context"
 	"fmt"
 	"strconv"
 	"strings"
@@ -35,7 +36,7 @@ func NewSkupperDeploymentHandlerPodman(cli *podman.PodmanRestClient) *SkupperDep
 }
 
 // Deploy deploys each component as a container
-func (s *SkupperDeploymentHandler) Deploy(deployment domain.SkupperDeployment) error {
+func (s *SkupperDeploymentHandler) Deploy(ctx context.Context, deployment domain.SkupperDeployment) error {
 	var err error
 	var cleanupContainers []string
 
@@ -56,7 +57,7 @@ func (s *SkupperDeploymentHandler) Deploy(deployment domain.SkupperDeployment) e
 	for _, component := range deployment.GetComponents() {
 
 		// Pulling image first
-		err = s.cli.ImagePull(component.GetImage())
+		err = s.cli.ImagePull(ctx, component.GetImage())
 		if err != nil {
 			return err
 		}
diff --git a/pkg/domain/podman/site.go b/pkg/domain/podman/site.go
index e4e04faf..a2aa142a 100644
--- a/pkg/domain/podman/site.go
+++ b/pkg/domain/podman/site.go
@@ -1,6 +1,7 @@
 package podman
 
 import (
+	"context"
 	"fmt"
 	"os"
 	"path"
@@ -98,7 +99,7 @@ func NewSitePodmanHandler(endpoint string) (*SiteHandler, error) {
 	}, nil
 }
 
-func (s *SiteHandler) prepare(site domain.Site) (domain.Site, error) {
+func (s *SiteHandler) prepare(ctx context.Context, site domain.Site) (domain.Site, error) {
 	podmanSite, ok := site.(*Site)
 
 	if !ok {
@@ -125,7 +126,7 @@ func (s *SiteHandler) prepare(site domain.Site) (domain.Site, error) {
 	domain.ConfigureSiteCredentials(podmanSite, podmanSite.IngressHosts...)
 	s.ConfigurePodmanDeployments(podmanSite)
 
-	if err := s.canCreate(podmanSite); err != nil {
+	if err := s.canCreate(ctx, podmanSite); err != nil {
 		return nil, err
 	}
 
@@ -209,13 +210,13 @@ func (s *SiteHandler) prepareRouterDeployment(site *Site) *SkupperDeployment {
 	return routerDepl
 }
 
-func (s *SiteHandler) Create(site domain.Site) error {
+func (s *SiteHandler) Create(ctx context.Context, site domain.Site) error {
 	var err error
 	var cleanupFns []func()
 
 	var preparedSite domain.Site
 	podmanSite := site.(*Site)
-	preparedSite, err = s.prepare(podmanSite)
+	preparedSite, err = s.prepare(ctx, podmanSite)
 	if err != nil {
 		return err
 	}
@@ -320,7 +321,7 @@ func (s *SiteHandler) Create(site domain.Site) error {
 	// Deploy container(s)
 	deployHandler := NewSkupperDeploymentHandlerPodman(s.cli)
 	for _, depl := range podmanSite.GetDeployments() {
-		err = deployHandler.Deploy(depl)
+		err = deployHandler.Deploy(ctx, depl)
 		if err != nil {
 			return err
 		}
@@ -351,7 +352,7 @@ func (s *SiteHandler) Create(site domain.Site) error {
 	return nil
 }
 
-func (s *SiteHandler) canCreate(site *Site) error {
+func (s *SiteHandler) canCreate(ctx context.Context, site *Site) error {
 
 	// Validating podman endpoint
 	if s.cli == nil {
@@ -439,7 +440,7 @@ func (s *SiteHandler) canCreate(site *Site) error {
 	}
 
 	// Validating router container runs without errors
-	err = s.runTempContainer()
+	err = s.runTempContainer(ctx)
 	if err != nil {
 		return fmt.Errorf("site cannot be created: %s", err)
 	}
@@ -978,9 +979,9 @@ func (s *SiteHandler) createPrometheusConfigFiles(site *Site) error {
 	return nil
 }
 
-func (s *SiteHandler) runTempContainer() error {
+func (s *SiteHandler) runTempContainer(ctx context.Context) error {
 	cli := s.cli
-	err := cli.ImagePull(images.GetRouterImageName())
+	err := cli.ImagePull(ctx, images.GetRouterImageName())
 	if err != nil {
 		return err
 	}
diff --git a/pkg/domain/podman/update/common.go b/pkg/domain/podman/update/common.go
index ced175d6..d44ee4e0 100644
--- a/pkg/domain/podman/update/common.go
+++ b/pkg/domain/podman/update/common.go
@@ -1,6 +1,7 @@
 package update
 
 import (
+	"context"
 	"fmt"
 
 	"github.com/skupperproject/skupper/api/types"
@@ -41,7 +42,7 @@ func (v *VersionUpdateTask) Priority() domain.UpdatePriority {
 	return domain.PriorityLast
 }
 
-func (v *VersionUpdateTask) Run() *domain.UpdateResult {
+func (v *VersionUpdateTask) Run(context.Context) *domain.UpdateResult {
 	var res = &domain.UpdateResult{}
 	ch := podman.NewRouterConfigHandlerPodman(v.cli)
 	cfg, err := ch.GetRouterConfig()
@@ -89,7 +90,7 @@ func (u *ContainerImagesTask) Priority() domain.UpdatePriority {
 	return domain.PriorityNormal
 }
 
-func (u *ContainerImagesTask) Run() *domain.UpdateResult {
+func (u *ContainerImagesTask) Run(ctx context.Context) *domain.UpdateResult {
 	var result = &domain.UpdateResult{}
 	sh := podman.NewSitePodmanHandlerFromCli(u.cli)
 	site, err := sh.Get()
@@ -112,7 +113,7 @@ func (u *ContainerImagesTask) Run() *domain.UpdateResult {
 				image = images.GetPrometheusServerImageName()
 			}
 			if image != cmp.GetImage() {
-				_, err = u.cli.ContainerUpdateImage(cmp.Name(), image)
+				_, err = u.cli.ContainerUpdateImage(ctx, cmp.Name(), image)
 				if err != nil {
 					result.AddErrors(fmt.Errorf("error updating container: %s - image: %s - %s",
 						cmp.Name(), image, err))
@@ -123,7 +124,7 @@ func (u *ContainerImagesTask) Run() *domain.UpdateResult {
 		}
 	}
 	// updating service containers
-	updSvcResult := u.updateServiceContainers()
+	updSvcResult := u.updateServiceContainers(ctx)
 	if len(updSvcResult.Errors) > 0 {
 		result.AddErrors(updSvcResult.Errors...)
 		return result
@@ -134,7 +135,7 @@ func (u *ContainerImagesTask) Run() *domain.UpdateResult {
 	return result
 }
 
-func (u *ContainerImagesTask) updateServiceContainers() domain.UpdateResult {
+func (u *ContainerImagesTask) updateServiceContainers(ctx context.Context) domain.UpdateResult {
 	var result domain.UpdateResult
 	sh := podman.NewServiceHandlerPodman(u.cli)
 	services, err := sh.List()
@@ -151,7 +152,7 @@ func (u *ContainerImagesTask) updateServiceContainers() domain.UpdateResult {
 			return result
 		}
 		if c.Image != images.GetRouterImageName() {
-			_, err = u.cli.ContainerUpdateImage(svcPodman.ContainerName, images.GetRouterImageName())
+			_, err = u.cli.ContainerUpdateImage(ctx, svcPodman.ContainerName, images.GetRouterImageName())
 			if err != nil {
 				result.AddErrors(fmt.Errorf("error updating service container image for %s: %s",
 					svcPodman.ContainerName, err))
diff --git a/pkg/domain/site.go b/pkg/domain/site.go
index 11539fc0..f61f1222 100644
--- a/pkg/domain/site.go
+++ b/pkg/domain/site.go
@@ -1,6 +1,7 @@
 package domain
 
 import (
+	"context"
 	"fmt"
 
 	"github.com/google/uuid"
@@ -27,7 +28,7 @@ type Site interface {
 }
 
 type SiteHandler interface {
-	Create(s Site) error
+	Create(ctx context.Context, s Site) error
 	Get() (Site, error)
 	Delete() error
 	Update() error
diff --git a/pkg/domain/skupper_deployment.go b/pkg/domain/skupper_deployment.go
index 8ec6c5e9..1730f174 100644
--- a/pkg/domain/skupper_deployment.go
+++ b/pkg/domain/skupper_deployment.go
@@ -1,12 +1,14 @@
 package domain
 
+import "context"
+
 type SkupperDeployment interface {
 	GetName() string
 	GetComponents() []SkupperComponent
 }
 
 type SkupperDeploymentHandler interface {
-	Deploy(deployment SkupperDeployment) error
+	Deploy(ctx context.Context, deployment SkupperDeployment) error
 	List() ([]SkupperDeployment, error)
 	Undeploy(name string) error
 }
diff --git a/pkg/domain/update.go b/pkg/domain/update.go
index d65974c6..2c421bd1 100644
--- a/pkg/domain/update.go
+++ b/pkg/domain/update.go
@@ -1,9 +1,11 @@
 package domain
 
 import (
+	"context"
 	"fmt"
 	"reflect"
 	"sort"
+	"time"
 
 	"github.com/skupperproject/skupper/pkg/utils"
 )
@@ -60,7 +62,7 @@ type UpdateTask interface {
 	// Priority determines how tasks will be sorted by the UpdateProcessor
 	Priority() UpdatePriority
 	// Run method is where the update task is done
-	Run() *UpdateResult
+	Run(ctx context.Context) *UpdateResult
 }
 
 type UpdateProcessor struct {
@@ -69,6 +71,7 @@ type UpdateProcessor struct {
 	changes   []string
 	Verbose   bool
 	DryRun    bool
+	Timeout   time.Duration
 }
 
 func (p *UpdateProcessor) Println(a ...any) {
@@ -106,14 +109,14 @@ func (p *UpdateProcessor) registerPostTasks(tasks ...UpdateTask) {
 	}
 }
 
-func (p *UpdateProcessor) Process(siteVersion string) error {
-	err := p.process(siteVersion, p.tasks)
+func (p *UpdateProcessor) Process(ctx context.Context, siteVersion string) error {
+	err := p.process(ctx, siteVersion, p.tasks)
 	if err != nil {
 		return err
 	}
 	if len(p.postTasks) > 0 {
 		p.Println("Post update tasks")
-		return p.process(siteVersion, p.postTasks)
+		return p.process(ctx, siteVersion, p.postTasks)
 	}
 	if len(p.changes) > 0 {
 		fmt.Println("Skupper is now updated for '" + utils.ReadUsername() + "'.")
@@ -123,7 +126,7 @@ func (p *UpdateProcessor) Process(siteVersion string) error {
 	return nil
 }
 
-func (p *UpdateProcessor) process(siteVersion string, tasks []UpdateTask) error {
+func (p *UpdateProcessor) process(ctx context.Context, siteVersion string, tasks []UpdateTask) error {
 	var validTasks []UpdateTask
 	title := "Task"
 	postTasks := false
@@ -170,7 +173,7 @@ func (p *UpdateProcessor) process(siteVersion string, tasks []UpdateTask) error
 			title, i+1, totalTasks, version, task.Priority(), task.Info())
 		var result *UpdateResult
 		if !p.DryRun {
-			result = task.Run()
+			result = task.Run(ctx)
 			if result == nil {
 				result = &UpdateResult{}
 			}
diff --git a/pkg/flow/controller.go b/pkg/flow/controller.go
index 989647b2..885097b6 100644
--- a/pkg/flow/controller.go
+++ b/pkg/flow/controller.go
@@ -87,19 +87,21 @@ func UpdateProcess(c *FlowController, deleted bool, name string, process *Proces
 }
 
 func UpdateHost(c *FlowController, deleted bool, name string, host *HostRecord) error {
-	if !deleted && host != nil {
+	if deleted {
+		for id, host := range c.hostRecords {
+			if *host.Name == name {
+				host.EndTime = uint64(time.Now().UnixNano()) / uint64(time.Microsecond)
+				delete(c.hostRecords, id)
+				break
+			}
+		}
+	} else if host != nil {
 		host.RecType = recordNames[Host]
 		if _, ok := c.hostRecords[host.Identity]; !ok {
 			c.hostRecords[host.Identity] = host
 		}
 		c.hostOutgoing <- host
-	} else {
-		if existing, ok := c.hostRecords[host.Identity]; ok {
-			existing.EndTime = uint64(time.Now().UnixNano()) / uint64(time.Microsecond)
-		}
-		delete(c.hostRecords, host.Identity)
 	}
-
 	return nil
 }
 


Test patch:
diff --git a/client/podman/container_test.go b/client/podman/container_test.go
index 251c2586..e7829845 100644
--- a/client/podman/container_test.go
+++ b/client/podman/container_test.go
@@ -115,12 +115,19 @@ func TestContainer(t *testing.T) {
 
 	// Pulling image
 	t.Run("image-pull", func(t *testing.T) {
-		assert.Assert(t, cli.ImagePull(image))
+		assert.Assert(t, cli.ImagePull(ctx, image))
 		invalidImage := strings.Replace(images.GetSiteControllerImageName(), ":main", ":invalid", 1)
-		invalidImageErr := cli.ImagePull(invalidImage)
+		invalidImageErr := cli.ImagePull(ctx, invalidImage)
 		assert.Assert(t, invalidImageErr != nil)
 		assert.Assert(t, strings.Contains(invalidImageErr.Error(), "Recommendation:"))
 	})
+	t.Run("image-pull-timeout", func(t *testing.T) {
+		expCtx, expCn := context.WithTimeout(context.Background(), time.Millisecond)
+		time.Sleep(time.Millisecond)
+		defer expCn()
+		expErr := cli.ImagePull(expCtx, image)
+		assert.ErrorContains(t, expErr, "context deadline exceeded")
+	})
 
 	// Creating container
 	t.Run("container-create", func(t *testing.T) {
@@ -205,7 +212,7 @@ func TestContainer(t *testing.T) {
 	// Updating container image
 	image = strings.ReplaceAll(image, ":main", ":latest")
 	t.Run("container-update-image", func(t *testing.T) {
-		c, err := cli.ContainerUpdateImage(name, image)
+		c, err := cli.ContainerUpdateImage(ctx, name, image)
 		assert.Assert(t, err)
 		assert.Equal(t, c.Image, image)
 		containerInspectTest(t)
@@ -214,7 +221,7 @@ func TestContainer(t *testing.T) {
 
 	t.Run("container-logs", func(t *testing.T) {
 		clogsName := RandomName("skupper-test")
-		assert.Assert(t, cli.ImagePull(images.GetRouterImageName()))
+		assert.Assert(t, cli.ImagePull(ctx, images.GetRouterImageName()))
 		err = cli.ContainerCreate(&container.Container{
 			Name:        clogsName,
 			Image:       images.GetRouterImageName(),
@@ -295,7 +302,7 @@ func TestContainerUpdateMock(t *testing.T) {
 	startedAt := cc.StartedAt
 
 	newImage := strings.Replace(image, ":main", ":updated", -1)
-	_, err = cli.ContainerUpdateImage("my-container", newImage)
+	_, err = cli.ContainerUpdateImage(context.Background(), "my-container", newImage)
 	assert.Assert(t, err)
 
 	// validating that the container has the new image and has been restarted
diff --git a/client/podman/informer_test.go b/client/podman/informer_test.go
index 08e57b90..86727499 100644
--- a/client/podman/informer_test.go
+++ b/client/podman/informer_test.go
@@ -67,7 +67,7 @@ func TestContainerInformer(t *testing.T) {
 
 	// Pulling image
 	image := images.GetServiceControllerImageName()
-	assert.Assert(t, cli.ImagePull(image))
+	assert.Assert(t, cli.ImagePull(ctx, image))
 
 	var containersLeft = map[string]bool{}
 	for _, s := range scenarios {
diff --git a/cmd/skupper/skupper_podman_test.go b/cmd/skupper/skupper_podman_test.go
index eeefc078..aa5da321 100644
--- a/cmd/skupper/skupper_podman_test.go
+++ b/cmd/skupper/skupper_podman_test.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"bytes"
+	"context"
 	"fmt"
 	"strings"
 	"testing"
@@ -153,7 +154,7 @@ type siteHandlerMock struct {
 	getHook func() (domain.Site, error)
 }
 
-func (sh *siteHandlerMock) Create(s domain.Site) error {
+func (sh *siteHandlerMock) Create(ctx context.Context, s domain.Site) error {
 	return fmt.Errorf("not implemented")
 }
 
diff --git a/pkg/domain/podman/link_test.go b/pkg/domain/podman/link_test.go
index 4ec1be5d..08ead78c 100644
--- a/pkg/domain/podman/link_test.go
+++ b/pkg/domain/podman/link_test.go
@@ -21,7 +21,7 @@ func TestLinkHandlerPodman(t *testing.T) {
 	// Create a basic podman site
 	siteHandler, err := NewSitePodmanHandler(getEndpoint())
 	assert.Assert(t, err)
-	assert.Assert(t, siteHandler.Create(newBasicSite()))
+	assert.Assert(t, siteHandler.Create(context.Background(), newBasicSite()))
 	defer func() {
 		assert.Assert(t, siteHandler.Delete())
 	}()
diff --git a/pkg/domain/podman/main_test.go b/pkg/domain/podman/main_test.go
index 78abfd00..7ada9a35 100644
--- a/pkg/domain/podman/main_test.go
+++ b/pkg/domain/podman/main_test.go
@@ -52,7 +52,7 @@ func createBasicSite() error {
 	if err != nil {
 		return err
 	}
-	return siteHandler.Create(newBasicSite())
+	return siteHandler.Create(context.Background(), newBasicSite())
 }
 
 func teardownBasicSite() error {
@@ -139,7 +139,7 @@ func configureSiteAndCreateRouter(ctx context.Context, cli *client.VanClient, na
 }
 
 func runNginxContainer() error {
-	if err := cli.ImagePull(NGINX_IMAGE); err != nil {
+	if err := cli.ImagePull(context.Background(), NGINX_IMAGE); err != nil {
 		return err
 	}
 	c := container.Container{
diff --git a/pkg/domain/podman/site_test.go b/pkg/domain/podman/site_test.go
index b278a67f..b274ede2 100644
--- a/pkg/domain/podman/site_test.go
+++ b/pkg/domain/podman/site_test.go
@@ -4,6 +4,7 @@
 package podman
 
 import (
+	"context"
 	_ "embed"
 	"strings"
 	"testing"
@@ -79,7 +80,7 @@ func TestSiteHandler(t *testing.T) {
 	for _, scenario := range scenarios {
 		t.Run(scenario.name, func(t *testing.T) {
 			t.Logf("creating site")
-			err = siteHandler.Create(scenario.site)
+			err = siteHandler.Create(context.Background(), scenario.site)
 			assert.Assert(t, err)
 
 			// remove site
@@ -177,7 +178,7 @@ func TestSiteHandlerDeleteBrokenSite(t *testing.T) {
 	}
 
 	// Create a podman site
-	err = siteHandler.Create(site)
+	err = siteHandler.Create(context.Background(), site)
 	assert.Assert(t, err)
 
 	// remove site
diff --git a/pkg/domain/podman/update/common_test.go b/pkg/domain/podman/update/common_test.go
index 0f81e88d..baf50a89 100644
--- a/pkg/domain/podman/update/common_test.go
+++ b/pkg/domain/podman/update/common_test.go
@@ -4,6 +4,7 @@
 package update
 
 import (
+	"context"
 	_ "embed"
 	"flag"
 	"os"
@@ -74,7 +75,7 @@ func TestContainerImagesTask(t *testing.T) {
 			imagesTask.version = test.version
 			t.Logf("New version: %s - current mock site version: %s", test.version, site.GetVersion())
 			assert.Assert(t, imagesTask.AppliesTo(site.GetVersion()) == test.changed)
-			res := imagesTask.Run()
+			res := imagesTask.Run(context.Background())
 			assert.Assert(t, len(res.Errors) == 0)
 			assert.Assert(t, res.Changed() == test.changed)
 			expectedChanges := 4
@@ -151,7 +152,7 @@ func TestVersionUpdateTask(t *testing.T) {
 
 			// mocking task execution
 			if test.changed {
-				res := versionUpdTask.Run()
+				res := versionUpdTask.Run(context.Background())
 				assert.Assert(t, len(res.Errors) == 0)
 				assert.Assert(t, res.Changed() == test.changed)
 				assert.Assert(t, 1 == len(res.GetChanges()))
diff --git a/pkg/domain/update_test.go b/pkg/domain/update_test.go
index 0a7f5dbf..0765dba0 100644
--- a/pkg/domain/update_test.go
+++ b/pkg/domain/update_test.go
@@ -1,6 +1,7 @@
 package domain
 
 import (
+	"context"
 	"fmt"
 	"testing"
 
@@ -406,7 +407,7 @@ func TestUpdateProcessor(t *testing.T) {
 				Verbose: true,
 			}
 			up.RegisterTasks(scenario.tasks...)
-			err := up.Process(scenario.curVersion)
+			err := up.Process(context.Background(), scenario.curVersion)
 			assert.Equal(t, err != nil, scenario.expectError, fmt.Sprintf("error expected == %v but got err == %v", scenario.expectError, err))
 			assert.DeepEqual(t, scenario.expectedChanges, up.changes)
 		})
@@ -447,6 +448,6 @@ func (u *mockUpdateTask) Priority() UpdatePriority {
 	return u.priority
 }
 
-func (u *mockUpdateTask) Run() *UpdateResult {
+func (u *mockUpdateTask) Run(context.Context) *UpdateResult {
 	return u.result
 }
diff --git a/pkg/flow/controller_test.go b/pkg/flow/controller_test.go
index 27adcbaf..f10c66cb 100644
--- a/pkg/flow/controller_test.go
+++ b/pkg/flow/controller_test.go
@@ -55,7 +55,7 @@ func TestUpdateHost(t *testing.T) {
 	hostUpdate := <-fc.hostOutgoing
 	assert.Assert(t, hostUpdate != nil)
 	assert.Equal(t, hostUpdate.Parent, "mysite")
-	err = UpdateHost(fc, true, "bastion-server", host)
+	err = UpdateHost(fc, true, "bastion-server", nil)
 	assert.Assert(t, err)
 	assert.Equal(t, len(fc.hostRecords), 0)
 }
diff --git a/test/integration/examples/custom/helloworld/helloworld_podman_test.go b/test/integration/examples/custom/helloworld/helloworld_podman_test.go
index 2615d7c6..10292883 100644
--- a/test/integration/examples/custom/helloworld/helloworld_podman_test.go
+++ b/test/integration/examples/custom/helloworld/helloworld_podman_test.go
@@ -4,6 +4,7 @@ package helloworld
 
 import (
 	"bytes"
+	"context"
 	"fmt"
 	"log"
 	"os"
@@ -702,7 +703,7 @@ func deployPodmanResources() error {
 		// podman network exists, but DNS is not enabled
 		return fmt.Errorf("podman network %s already exists, but DNS is not enabled", PodmanNetwork)
 	}
-	err = podmanCli.ImagePull("quay.io/skupper/hello-world-backend")
+	err = podmanCli.ImagePull(context.Background(), "quay.io/skupper/hello-world-backend")
 	if err != nil {
 		return err
 	}