Parcourir la source

add telemetry to all helm agent.go methods (#3045)

Co-authored-by: David Townley <davidtownley@Davids-MacBook-Air.local>
dt3-5 il y a 3 ans
Parent
commit
5799985122

+ 1 - 1
api/server/authz/release.go

@@ -50,7 +50,7 @@ func (p *ReleaseScopedMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Reque
 	// get the version for the application
 	version, _ := requestutils.GetURLParamUint(r, types.URLParamReleaseVersion)
 
-	release, err := helmAgent.GetRelease(name, int(version), false)
+	release, err := helmAgent.GetRelease(context.Background(), name, int(version), false)
 	if err != nil {
 		// ugly casing since at the time of this commit Helm doesn't have an errors package.
 		// so we rely on the Helm error containing "not found"

+ 4 - 4
api/server/handlers/cluster/install_agent.go

@@ -65,7 +65,7 @@ func (c *InstallAgentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 		return
 	}
 
-	chart, err := loader.LoadChartPublic(c.Config().ServerConf.DefaultAddonHelmRepoURL, "porter-agent", "")
+	chart, err := loader.LoadChartPublic(context.Background(), c.Config().ServerConf.DefaultAddonHelmRepoURL, "porter-agent", "")
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
@@ -139,7 +139,7 @@ func (c *InstallAgentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 		Values:    porterAgentValues,
 	}
 
-	_, err = helmAgent.InstallChart(conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
+	_, err = helmAgent.InstallChart(context.Background(), conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
 
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(
@@ -172,13 +172,13 @@ func checkAndDeleteOlderAgent(k8sAgent *kubernetes.Agent, helmAgent *helm.Agent)
 	}
 
 	// detect if the `porter-agent` release is installed
-	helmRelease, err := helmAgent.GetRelease("porter-agent", 0, false)
+	helmRelease, err := helmAgent.GetRelease(context.Background(), "porter-agent", 0, false)
 
 	if err != nil || helmRelease == nil {
 		return nil
 	}
 
-	_, err = helmAgent.UninstallChart("porter-agent")
+	_, err = helmAgent.UninstallChart(context.Background(), "porter-agent")
 
 	if err != nil {
 		return err

+ 4 - 3
api/server/handlers/cluster/upgrade_agent.go

@@ -1,6 +1,7 @@
 package cluster
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 
@@ -39,13 +40,13 @@ func (c *UpgradeAgentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 		return
 	}
 
-	currRelease, err := helmAgent.GetRelease("porter-agent", 0, false)
+	currRelease, err := helmAgent.GetRelease(context.Background(), "porter-agent", 0, false)
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
 	}
 
-	chart, err := loader.LoadChartPublic(c.Config().ServerConf.DefaultAddonHelmRepoURL, "porter-agent", "")
+	chart, err := loader.LoadChartPublic(context.Background(), c.Config().ServerConf.DefaultAddonHelmRepoURL, "porter-agent", "")
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
@@ -56,7 +57,7 @@ func (c *UpgradeAgentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 	// TODO: update values
 	// newValues["redis"] =
 
-	_, err = helmAgent.UpgradeReleaseByValues(&helm.UpgradeReleaseConfig{
+	_, err = helmAgent.UpgradeReleaseByValues(context.Background(), &helm.UpgradeReleaseConfig{
 		Chart:      chart,
 		Name:       "porter-agent",
 		Values:     newValues,

+ 2 - 1
api/server/handlers/namespace/create_env_group.go

@@ -1,6 +1,7 @@
 package namespace
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 	"strings"
@@ -185,7 +186,7 @@ func rolloutApplications(
 				Values:     newConfig,
 			}
 
-			_, err = helmAgent.UpgradeReleaseByValues(conf, config.DOConf, config.ServerConf.DisablePullSecretsInjection, false)
+			_, err = helmAgent.UpgradeReleaseByValues(context.Background(), conf, config.DOConf, config.ServerConf.DisablePullSecretsInjection, false)
 
 			if err != nil {
 				mu.Lock()

+ 2 - 1
api/server/handlers/namespace/list_releases.go

@@ -1,6 +1,7 @@
 package namespace
 
 import (
+	"context"
 	"net/http"
 
 	"github.com/porter-dev/porter/api/server/authz"
@@ -48,7 +49,7 @@ func (c *ListReleasesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 		return
 	}
 
-	releases, err := helmAgent.ListReleases(namespace, request.ReleaseListFilter)
+	releases, err := helmAgent.ListReleases(context.Background(), namespace, request.ReleaseListFilter)
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return

+ 2 - 2
api/server/handlers/release/create.go

@@ -119,7 +119,7 @@ func (c *CreateReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 		request.TemplateVersion = ""
 	}
 
-	chart, err := loader.LoadChartPublic(request.RepoURL, request.TemplateName, request.TemplateVersion)
+	chart, err := loader.LoadChartPublic(ctx, request.RepoURL, request.TemplateName, request.TemplateVersion)
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(telemetry.Error(ctx, span, err, "error loading public chart")))
 		return
@@ -154,7 +154,7 @@ func (c *CreateReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 		Registries: registries,
 	}
 
-	helmRelease, err := helmAgent.InstallChart(conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
+	helmRelease, err := helmAgent.InstallChart(ctx, conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(
 			telemetry.Error(ctx, span, err, "error installing a new chart"),

+ 9 - 7
api/server/handlers/release/create_addon.go

@@ -1,6 +1,7 @@
 package release
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 
@@ -91,7 +92,7 @@ func (c *CreateAddonHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		Registries: registries,
 	}
 
-	helmRelease, err := helmAgent.InstallChart(conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
+	helmRelease, err := helmAgent.InstallChart(context.Background(), conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(
 			fmt.Errorf("error installing a new chart: %s", err.Error()),
@@ -124,7 +125,7 @@ type LoadAddonChartOpts struct {
 func LoadChart(config *config.Config, opts *LoadAddonChartOpts) (*chart.Chart, error) {
 	// if the chart repo url is one of the specified application/addon charts, just load public
 	if opts.RepoURL == config.ServerConf.DefaultAddonHelmRepoURL || opts.RepoURL == config.ServerConf.DefaultApplicationHelmRepoURL {
-		return loader.LoadChartPublic(opts.RepoURL, opts.TemplateName, opts.TemplateVersion)
+		return loader.LoadChartPublic(context.Background(), opts.RepoURL, opts.TemplateName, opts.TemplateVersion)
 	} else {
 		// load the helm repos in the project
 		hrs, err := config.Repo.HelmRepo().ListHelmReposByProjectID(opts.ProjectID)
@@ -141,12 +142,13 @@ func LoadChart(config *config.Config, opts *LoadAddonChartOpts) (*chart.Chart, e
 						return nil, err
 					}
 
-					return loader.LoadChart(&loader.BasicAuthClient{
-						Username: string(basic.Username),
-						Password: string(basic.Password),
-					}, hr.RepoURL, opts.TemplateName, opts.TemplateVersion)
+					return loader.LoadChart(context.Background(),
+						&loader.BasicAuthClient{
+							Username: string(basic.Username),
+							Password: string(basic.Password),
+						}, hr.RepoURL, opts.TemplateName, opts.TemplateVersion)
 				} else {
-					return loader.LoadChartPublic(hr.RepoURL, opts.TemplateName, opts.TemplateVersion)
+					return loader.LoadChartPublic(context.Background(), hr.RepoURL, opts.TemplateName, opts.TemplateVersion)
 				}
 			}
 		}

+ 2 - 1
api/server/handlers/release/delete.go

@@ -1,6 +1,7 @@
 package release
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 	"strings"
@@ -43,7 +44,7 @@ func (c *DeleteReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 		return
 	}
 
-	_, err = helmAgent.UninstallChart(helmRelease.Name)
+	_, err = helmAgent.UninstallChart(context.Background(), helmRelease.Name)
 
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))

+ 2 - 1
api/server/handlers/release/get_history.go

@@ -1,6 +1,7 @@
 package release
 
 import (
+	"context"
 	"net/http"
 
 	"github.com/porter-dev/porter/api/server/authz"
@@ -40,7 +41,7 @@ func (c *GetReleaseHistoryHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ
 
 	// get the name of the application
 	name, _ := requestutils.GetURLParamString(r, types.URLParamReleaseName)
-	history, err := helmAgent.GetReleaseHistory(name)
+	history, err := helmAgent.GetReleaseHistory(context.Background(), name)
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return

+ 3 - 2
api/server/handlers/release/update_image_batch.go

@@ -1,6 +1,7 @@
 package release
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 	"strings"
@@ -75,7 +76,7 @@ func (c *UpdateImageBatchHandler) ServeHTTP(w http.ResponseWriter, r *http.Reque
 		go func() {
 			defer wg.Done()
 			// read release via agent
-			rel, err := helmAgent.GetRelease(releases[index].Name, 0, false)
+			rel, err := helmAgent.GetRelease(context.Background(), releases[index].Name, 0, false)
 			if err != nil {
 				// if this is a release not found error, just return - the release has likely been deleted from the underlying
 				// cluster but has not been deleted from the Porter database yet
@@ -104,7 +105,7 @@ func (c *UpdateImageBatchHandler) ServeHTTP(w http.ResponseWriter, r *http.Reque
 					Values:     rel.Config,
 				}
 
-				_, err = helmAgent.UpgradeReleaseByValues(conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection, false)
+				_, err = helmAgent.UpgradeReleaseByValues(context.Background(), conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection, false)
 
 				if err != nil {
 					// if this is a release not found error, just return - the release has likely been deleted from the underlying

+ 2 - 1
api/server/handlers/release/update_rollback.go

@@ -1,6 +1,7 @@
 package release
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 
@@ -48,7 +49,7 @@ func (c *RollbackReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 		return
 	}
 
-	err = helmAgent.RollbackRelease(helmRelease.Name, request.Revision)
+	err = helmAgent.RollbackRelease(context.Background(), helmRelease.Name, request.Revision)
 
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(

+ 3 - 2
api/server/handlers/release/upgrade.go

@@ -1,6 +1,7 @@
 package release
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 	"net/url"
@@ -116,7 +117,7 @@ func (c *UpgradeReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 
 	// if LatestRevision is set, check that the revision matches the latest revision in the database
 	if request.LatestRevision != 0 {
-		currHelmRelease, err := helmAgent.GetRelease(helmRelease.Name, 0, false)
+		currHelmRelease, err := helmAgent.GetRelease(context.Background(), helmRelease.Name, 0, false)
 		if err != nil {
 			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(
 				fmt.Errorf("could not retrieve latest revision"),
@@ -153,7 +154,7 @@ func (c *UpgradeReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 		}
 	}
 
-	newHelmRelease, upgradeErr := helmAgent.UpgradeRelease(conf, request.Values, c.Config().DOConf,
+	newHelmRelease, upgradeErr := helmAgent.UpgradeRelease(context.Background(), conf, request.Values, c.Config().DOConf,
 		c.Config().ServerConf.DisablePullSecretsInjection, request.IgnoreDependencies)
 
 	if upgradeErr == nil && newHelmRelease != nil {

+ 3 - 2
api/server/handlers/release/upgrade_webhook.go

@@ -1,6 +1,7 @@
 package release
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 	"net/url"
@@ -84,7 +85,7 @@ func (c *WebhookHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	rel, err := helmAgent.GetRelease(release.Name, 0, true)
+	rel, err := helmAgent.GetRelease(context.Background(), release.Name, 0, true)
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
@@ -168,7 +169,7 @@ func (c *WebhookHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		),
 	}
 
-	rel, err = helmAgent.UpgradeReleaseByValues(conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection, false)
+	rel, err = helmAgent.UpgradeReleaseByValues(context.Background(), conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection, false)
 
 	if err != nil {
 		notifyOpts.Status = notifier.StatusHelmFailed

+ 8 - 6
api/server/handlers/stack/helpers.go

@@ -1,6 +1,8 @@
 package stack
 
 import (
+	"context"
+
 	"github.com/porter-dev/porter/api/server/shared/config"
 	"github.com/porter-dev/porter/api/types"
 	"github.com/porter-dev/porter/internal/helm"
@@ -28,7 +30,7 @@ func applyAppResource(opts *applyAppResourceOpts) (*release.Release, error) {
 		opts.request.TemplateVersion = ""
 	}
 
-	chart, err := loader.LoadChartPublic(opts.request.TemplateRepoURL, opts.request.TemplateName, opts.request.TemplateVersion)
+	chart, err := loader.LoadChartPublic(context.Background(), opts.request.TemplateRepoURL, opts.request.TemplateName, opts.request.TemplateVersion)
 	if err != nil {
 		return nil, err
 	}
@@ -53,7 +55,7 @@ func applyAppResource(opts *applyAppResourceOpts) (*release.Release, error) {
 		"revision": opts.stackRevision,
 	}
 
-	return opts.helmAgent.InstallChart(conf, opts.config.DOConf, opts.config.ServerConf.DisablePullSecretsInjection)
+	return opts.helmAgent.InstallChart(context.Background(), conf, opts.config.DOConf, opts.config.ServerConf.DisablePullSecretsInjection)
 }
 
 type rollbackAppResourceOpts struct {
@@ -63,7 +65,7 @@ type rollbackAppResourceOpts struct {
 }
 
 func rollbackAppResource(opts *rollbackAppResourceOpts) error {
-	return opts.helmAgent.RollbackRelease(opts.name, int(opts.helmRevisionID))
+	return opts.helmAgent.RollbackRelease(context.Background(), opts.name, int(opts.helmRevisionID))
 }
 
 type updateAppResourceTagOpts struct {
@@ -82,7 +84,7 @@ type updateAppResourceTagOpts struct {
 
 func updateAppResourceTag(opts *updateAppResourceTagOpts) error {
 	// read the current release to get the current values
-	rel, err := opts.helmAgent.GetRelease(opts.name, 0, true)
+	rel, err := opts.helmAgent.GetRelease(context.Background(), opts.name, 0, true)
 	if err != nil {
 		return err
 	}
@@ -104,7 +106,7 @@ func updateAppResourceTag(opts *updateAppResourceTagOpts) error {
 		StackRevision: opts.stackRevision,
 	}
 
-	_, err = opts.helmAgent.UpgradeReleaseByValues(conf, opts.config.DOConf,
+	_, err = opts.helmAgent.UpgradeReleaseByValues(context.Background(), conf, opts.config.DOConf,
 		opts.config.ServerConf.DisablePullSecretsInjection, false)
 
 	return err
@@ -116,7 +118,7 @@ type deleteAppResourceOpts struct {
 }
 
 func deleteAppResource(opts *deleteAppResourceOpts) error {
-	_, err := opts.helmAgent.UninstallChart(opts.name)
+	_, err := opts.helmAgent.UninstallChart(context.Background(), opts.name)
 
 	return err
 }

+ 15 - 11
api/server/handlers/stacks/create_porter_app.go

@@ -1,6 +1,7 @@
 package stacks
 
 import (
+	"context"
 	"encoding/base64"
 	"fmt"
 	"net/http"
@@ -74,7 +75,7 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 		return
 	}
 
-	helmRelease, err := helmAgent.GetRelease(stackName, 0, false)
+	helmRelease, err := helmAgent.GetRelease(ctx, stackName, 0, false)
 	shouldCreate := err != nil
 
 	porterYamlBase64 := request.PorterYAMLBase64
@@ -149,6 +150,7 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 		// create the release job chart if it does not exist (only done by front-end currently, where we set overrideRelease=true)
 		if request.OverrideRelease && releaseJobValues != nil {
 			conf, err := createReleaseJobChart(
+				ctx,
 				stackName,
 				releaseJobValues,
 				c.Config().ServerConf.DefaultApplicationHelmRepoURL,
@@ -160,10 +162,10 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 				c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error making config for release job chart: %w", err)))
 				return
 			}
-			_, err = helmAgent.InstallChart(conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
+			_, err = helmAgent.InstallChart(ctx, conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
 			if err != nil {
 				c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error creating release job chart: %w", err)))
-				_, err = helmAgent.UninstallChart(fmt.Sprintf("%s-r", stackName))
+				_, err = helmAgent.UninstallChart(ctx, fmt.Sprintf("%s-r", stackName))
 				if err != nil {
 					c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error uninstalling release job chart: %w", err)))
 				}
@@ -182,11 +184,11 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 		}
 
 		// create the app chart
-		_, err = helmAgent.InstallChart(conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
+		_, err = helmAgent.InstallChart(ctx, conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
 		if err != nil {
 			c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error deploying app: %s", err.Error())))
 
-			_, err = helmAgent.UninstallChart(stackName)
+			_, err = helmAgent.UninstallChart(ctx, stackName)
 			if err != nil {
 				c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error uninstalling chart: %w", err)))
 			}
@@ -233,10 +235,11 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 		// create/update the release job chart
 		if request.OverrideRelease && releaseJobValues != nil {
 			releaseJobName := fmt.Sprintf("%s-r", stackName)
-			helmRelease, err := helmAgent.GetRelease(releaseJobName, 0, false)
+			helmRelease, err := helmAgent.GetRelease(ctx, releaseJobName, 0, false)
 			if err != nil {
 				// here the user has created a release job for an already created app, so we need to create and install  the release job chart
 				conf, err := createReleaseJobChart(
+					ctx,
 					stackName,
 					releaseJobValues,
 					c.Config().ServerConf.DefaultApplicationHelmRepoURL,
@@ -248,10 +251,10 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 					c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error making config for release job chart: %w", err)))
 					return
 				}
-				_, err = helmAgent.InstallChart(conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
+				_, err = helmAgent.InstallChart(ctx, conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
 				if err != nil {
 					c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error creating release job chart: %w", err)))
-					_, err = helmAgent.UninstallChart(fmt.Sprintf("%s-r", stackName))
+					_, err = helmAgent.UninstallChart(ctx, fmt.Sprintf("%s-r", stackName))
 					if err != nil {
 						c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error uninstalling release job chart: %w", err)))
 					}
@@ -265,7 +268,7 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 					Registries: registries,
 					Values:     releaseJobValues,
 				}
-				_, err = helmAgent.UpgradeReleaseByValues(conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection, false)
+				_, err = helmAgent.UpgradeReleaseByValues(ctx, conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection, false)
 				if err != nil {
 					c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error upgrading release job chart: %w", err)))
 					return
@@ -285,7 +288,7 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 		}
 
 		// update the chart
-		_, err = helmAgent.UpgradeInstallChart(conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
+		_, err = helmAgent.UpgradeInstallChart(ctx, conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
 		if err != nil {
 			c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error deploying app: %s", err.Error())))
 			return
@@ -346,6 +349,7 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 }
 
 func createReleaseJobChart(
+	ctx context.Context,
 	stackName string,
 	values map[string]interface{},
 	repoUrl string,
@@ -353,7 +357,7 @@ func createReleaseJobChart(
 	cluster *models.Cluster,
 	repo repository.Repository,
 ) (*helm.InstallChartConfig, error) {
-	chart, err := loader.LoadChartPublic(repoUrl, "job", "")
+	chart, err := loader.LoadChartPublic(ctx, repoUrl, "job", "")
 	if err != nil {
 		return nil, err
 	}

+ 2 - 1
api/server/handlers/template/get.go

@@ -1,6 +1,7 @@
 package template
 
 import (
+	"context"
 	"net/http"
 	"strings"
 
@@ -49,7 +50,7 @@ func (t *TemplateGetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		request.RepoURL = t.Config().ServerConf.DefaultApplicationHelmRepoURL
 	}
 
-	chart, err := loader.LoadChartPublic(request.RepoURL, name, version)
+	chart, err := loader.LoadChartPublic(context.Background(), request.RepoURL, name, version)
 	if err != nil {
 		t.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return

+ 2 - 1
api/server/handlers/template/get_upgrade_notes.go

@@ -1,6 +1,7 @@
 package template
 
 import (
+	"context"
 	"net/http"
 	"strings"
 
@@ -51,7 +52,7 @@ func (t *TemplateGetUpgradeNotesHandler) ServeHTTP(w http.ResponseWriter, r *htt
 		prevVersion = "v0.0.0"
 	}
 
-	chart, err := loader.LoadChartPublic(request.RepoURL, name, version)
+	chart, err := loader.LoadChartPublic(context.Background(), request.RepoURL, name, version)
 	if err != nil {
 		t.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return

+ 2 - 1
api/server/handlers/v1/env_group/create.go

@@ -1,6 +1,7 @@
 package env_group
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 	"strings"
@@ -201,7 +202,7 @@ func rolloutApplications(
 				Values:     newConfig,
 			}
 
-			_, err = helmAgent.UpgradeReleaseByValues(conf, config.DOConf, config.ServerConf.DisablePullSecretsInjection, false)
+			_, err = helmAgent.UpgradeReleaseByValues(context.Background(), conf, config.DOConf, config.ServerConf.DisablePullSecretsInjection, false)
 
 			if err != nil {
 				mu.Lock()

+ 3 - 2
api/server/handlers/v1/release/upgrade.go

@@ -1,6 +1,7 @@
 package release
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 	"net/url"
@@ -118,7 +119,7 @@ func (c *UpgradeReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 
 	// if LatestRevision is set, check that the revision matches the latest revision in the database
 	if request.LatestRevision != 0 {
-		currHelmRelease, err := helmAgent.GetRelease(helmRelease.Name, 0, false)
+		currHelmRelease, err := helmAgent.GetRelease(context.Background(), helmRelease.Name, 0, false)
 		if err != nil {
 			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(
 				fmt.Errorf("could not retrieve latest revision"),
@@ -138,7 +139,7 @@ func (c *UpgradeReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 		}
 	}
 
-	newHelmRelease, upgradeErr := helmAgent.UpgradeReleaseByValues(conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection, false)
+	newHelmRelease, upgradeErr := helmAgent.UpgradeReleaseByValues(context.Background(), conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection, false)
 
 	if upgradeErr == nil && newHelmRelease != nil {
 		helmRelease = newHelmRelease

+ 2 - 1
api/server/handlers/v1/template/get.go

@@ -1,6 +1,7 @@
 package template
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 	"strings"
@@ -81,7 +82,7 @@ func (t *TemplateGetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		version = ""
 	}
 
-	chart, err := loader.LoadChartPublic(request.RepoURL, name, version)
+	chart, err := loader.LoadChartPublic(context.Background(), request.RepoURL, name, version)
 	if err != nil {
 		t.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return

+ 2 - 1
api/server/handlers/v1/template/get_upgrade_notes.go

@@ -1,6 +1,7 @@
 package template
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 	"strings"
@@ -83,7 +84,7 @@ func (t *TemplateGetUpgradeNotesHandler) ServeHTTP(w http.ResponseWriter, r *htt
 		prevVersion = "v0.0.0"
 	}
 
-	chart, err := loader.LoadChartPublic(request.RepoURL, name, version)
+	chart, err := loader.LoadChartPublic(context.Background(), request.RepoURL, name, version)
 	if err != nil {
 		t.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return

+ 138 - 29
internal/helm/agent.go

@@ -9,6 +9,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/porter-dev/porter/internal/telemetry"
+
 	"github.com/pkg/errors"
 	"github.com/porter-dev/porter/internal/helm/loader"
 	"github.com/stefanmcshane/helm/pkg/action"
@@ -34,9 +36,17 @@ type Agent struct {
 
 // ListReleases lists releases based on a ListFilter
 func (a *Agent) ListReleases(
+	ctx context.Context,
 	namespace string,
 	filter *types.ReleaseListFilter,
 ) ([]*release.Release, error) {
+	ctx, span := telemetry.NewSpan(ctx, "helm-list-releases")
+	defer span.End()
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "namespace", Value: namespace},
+	)
+
 	lsel := fmt.Sprintf("owner=helm,status in (%s)", strings.Join(filter.StatusFilter, ","))
 
 	// list secrets
@@ -47,7 +57,7 @@ func (a *Agent) ListReleases(
 		},
 	)
 	if err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error getting secret list")
 	}
 
 	// before decoding to helm release, only keep the latest releases for each chart
@@ -95,10 +105,20 @@ func (a *Agent) ListReleases(
 
 // GetRelease returns the info of a release.
 func (a *Agent) GetRelease(
+	ctx context.Context,
 	name string,
 	version int,
 	getDeps bool,
 ) (*release.Release, error) {
+	ctx, span := telemetry.NewSpan(ctx, "helm-get-release")
+	defer span.End()
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "name", Value: name},
+		telemetry.AttributeKV{Key: "version", Value: version},
+		telemetry.AttributeKV{Key: "getDeps", Value: getDeps},
+	)
+
 	// Namespace is already known by the RESTClientGetter.
 	cmd := action.NewGet(a.ActionConfig)
 
@@ -106,7 +126,7 @@ func (a *Agent) GetRelease(
 
 	release, err := cmd.Run(name)
 	if err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error running get release")
 	}
 
 	if getDeps && release.Chart != nil && release.Chart.Metadata != nil {
@@ -125,9 +145,9 @@ func (a *Agent) GetRelease(
 				}
 
 				if !depExists {
-					depChart, err := loader.LoadChartPublic(dep.Repository, dep.Name, dep.Version)
+					depChart, err := loader.LoadChartPublic(ctx, dep.Repository, dep.Name, dep.Version)
 					if err != nil {
-						return nil, fmt.Errorf("Error retrieving chart dependency %s/%s-%s: %s", dep.Repository, dep.Name, dep.Version, err.Error())
+						return nil, telemetry.Error(ctx, span, err, fmt.Sprintf("Error retrieving chart dependency %s/%s-%s", dep.Repository, dep.Name, dep.Version))
 					}
 
 					release.Chart.AddDependency(depChart)
@@ -141,9 +161,18 @@ func (a *Agent) GetRelease(
 
 // DeleteReleaseRevision deletes a specific revision of a release
 func (a *Agent) DeleteReleaseRevision(
+	ctx context.Context,
 	name string,
 	version int,
 ) error {
+	ctx, span := telemetry.NewSpan(ctx, "helm-delete-release-history")
+	defer span.End()
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "name", Value: name},
+		telemetry.AttributeKV{Key: "version", Value: version},
+	)
+
 	_, err := a.ActionConfig.Releases.Delete(name, version)
 
 	return err
@@ -151,8 +180,16 @@ func (a *Agent) DeleteReleaseRevision(
 
 // GetReleaseHistory returns a list of charts for a specific release
 func (a *Agent) GetReleaseHistory(
+	ctx context.Context,
 	name string,
 ) ([]*release.Release, error) {
+	ctx, span := telemetry.NewSpan(ctx, "helm-get-release-history")
+	defer span.End()
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "name", Value: name},
+	)
+
 	cmd := action.NewHistory(a.ActionConfig)
 
 	return cmd.Run(name)
@@ -175,33 +212,57 @@ type UpgradeReleaseConfig struct {
 
 // UpgradeRelease upgrades a specific release with new values.yaml
 func (a *Agent) UpgradeRelease(
+	ctx context.Context,
 	conf *UpgradeReleaseConfig,
 	values string,
 	doAuth *oauth2.Config,
 	disablePullSecretsInjection bool,
 	ignoreDependencies bool,
 ) (*release.Release, error) {
+	ctx, span := telemetry.NewSpan(ctx, "helm-upgrade-release")
+	defer span.End()
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "project-id", Value: conf.Cluster.ProjectID},
+		telemetry.AttributeKV{Key: "cluster-id", Value: conf.Cluster.ID},
+		telemetry.AttributeKV{Key: "name", Value: conf.Name},
+		telemetry.AttributeKV{Key: "stack-name", Value: conf.StackName},
+		telemetry.AttributeKV{Key: "stack-revision", Value: conf.StackRevision},
+	)
+
 	valuesYaml, err := chartutil.ReadValues([]byte(values))
 	if err != nil {
-		return nil, fmt.Errorf("Values could not be parsed: %v", err)
+		return nil, telemetry.Error(ctx, span, err, "Values could not be parsed")
 	}
 
 	conf.Values = valuesYaml
 
-	return a.UpgradeReleaseByValues(conf, doAuth, disablePullSecretsInjection, ignoreDependencies)
+	return a.UpgradeReleaseByValues(ctx, conf, doAuth, disablePullSecretsInjection, ignoreDependencies)
 }
 
 // UpgradeReleaseByValues upgrades a release by unmarshaled yaml values
 func (a *Agent) UpgradeReleaseByValues(
+	ctx context.Context,
 	conf *UpgradeReleaseConfig,
 	doAuth *oauth2.Config,
 	disablePullSecretsInjection bool,
 	ignoreDependencies bool,
 ) (*release.Release, error) {
+	ctx, span := telemetry.NewSpan(ctx, "helm-upgrade-release-by-values")
+	defer span.End()
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "project-id", Value: conf.Cluster.ProjectID},
+		telemetry.AttributeKV{Key: "cluster-id", Value: conf.Cluster.ID},
+		telemetry.AttributeKV{Key: "name", Value: conf.Name},
+		telemetry.AttributeKV{Key: "stack-name", Value: conf.StackName},
+		telemetry.AttributeKV{Key: "stack-revision", Value: conf.StackRevision},
+	)
+
 	// grab the latest release
-	rel, err := a.GetRelease(conf.Name, 0, !ignoreDependencies)
+	rel, err := a.GetRelease(ctx, conf.Name, 0, !ignoreDependencies)
 	if err != nil {
-		return nil, fmt.Errorf("Could not get release to be upgraded: %v", err)
+		return nil, telemetry.Error(ctx, span, err, "Could not get release to be upgraded")
 	}
 
 	ch := rel.Chart
@@ -224,7 +285,7 @@ func (a *Agent) UpgradeReleaseByValues(
 	)
 
 	if err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error getting porter postrenderer")
 	}
 
 	if conf.StackName != "" && conf.StackRevision > 0 {
@@ -247,7 +308,7 @@ func (a *Agent) UpgradeReleaseByValues(
 				},
 			)
 			if err != nil {
-				return nil, fmt.Errorf("Upgrade failed: %w", err)
+				return nil, telemetry.Error(ctx, span, err, "error getting secret list")
 			}
 
 			if len(secretList.Items) > 0 {
@@ -270,20 +331,20 @@ func (a *Agent) UpgradeReleaseByValues(
 					err = helmSecrets.Update(mostRecentSecret.GetName(), rel)
 
 					if err != nil {
-						return nil, fmt.Errorf("Upgrade failed: %w", err)
+						return nil, telemetry.Error(ctx, span, err, "error updating helm secrets")
 					}
 
 					// retry upgrade
 					res, err = cmd.Run(conf.Name, ch, conf.Values)
 
 					if err != nil {
-						return nil, fmt.Errorf("Upgrade failed: %w", err)
+						return nil, telemetry.Error(ctx, span, err, "error running upgrade after updating helm secrets")
 					}
 
 					return res, nil
 				} else {
 					// ask the user to wait for about a minute before retrying for the above fix to kick in
-					return nil, fmt.Errorf("another operation (install/upgrade/rollback) is in progress. If this error persists, please wait for 60 seconds to force an upgrade")
+					return nil, telemetry.Error(ctx, span, err, "another operation (install/upgrade/rollback) is in progress. If this error persists, please wait for 60 seconds to force an upgrade")
 				}
 			}
 		} else if strings.Contains(err.Error(), "current release manifest contains removed kubernetes api(s)") || strings.Contains(err.Error(), "resource mapping not found for name") {
@@ -296,7 +357,7 @@ func (a *Agent) UpgradeReleaseByValues(
 				},
 			)
 			if err != nil {
-				return nil, fmt.Errorf("Upgrade failed: %w", err)
+				return nil, telemetry.Error(ctx, span, err, "error getting secret list")
 			}
 
 			if len(secretList.Items) > 0 {
@@ -324,7 +385,7 @@ func (a *Agent) UpgradeReleaseByValues(
 
 				newRelDryRun, err := installCmd.Run(ch, conf.Values)
 				if err != nil {
-					return nil, err
+					return nil, telemetry.Error(ctx, span, err, "error running install cmd")
 				}
 
 				oldManifestBuffer := bytes.NewBufferString(rel.Manifest)
@@ -334,7 +395,7 @@ func (a *Agent) UpgradeReleaseByValues(
 
 				updatedManifestBuffer, err := versionMapper.Run(oldManifestBuffer, newManifestBuffer)
 				if err != nil {
-					return nil, err
+					return nil, telemetry.Error(ctx, span, err, "error running version mapper")
 				}
 
 				rel.Manifest = updatedManifestBuffer.String()
@@ -344,19 +405,19 @@ func (a *Agent) UpgradeReleaseByValues(
 				err = helmSecrets.Update(mostRecentSecret.GetName(), rel)
 
 				if err != nil {
-					return nil, fmt.Errorf("Upgrade failed: %w", err)
+					return nil, telemetry.Error(ctx, span, err, "error updating helm secret")
 				}
 
 				res, err := cmd.Run(conf.Name, ch, conf.Values)
 				if err != nil {
-					return nil, fmt.Errorf("Upgrade failed: %w", err)
+					return nil, telemetry.Error(ctx, span, err, "error running upgrade after updating helm secrets")
 				}
 
 				return res, nil
 			}
 		}
 
-		return nil, fmt.Errorf("Upgrade failed: %w", err)
+		return nil, telemetry.Error(ctx, span, err, "error running upgrade")
 	}
 
 	return res, nil
@@ -375,23 +436,35 @@ type InstallChartConfig struct {
 
 // InstallChartFromValuesBytes reads the raw values and calls Agent.InstallChart
 func (a *Agent) InstallChartFromValuesBytes(
+	ctx context.Context,
 	conf *InstallChartConfig,
 	values []byte,
 	doAuth *oauth2.Config,
 	disablePullSecretsInjection bool,
 ) (*release.Release, error) {
+	ctx, span := telemetry.NewSpan(ctx, "helm-install-chart-from-values-bytes")
+	defer span.End()
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "project-id", Value: conf.Cluster.ProjectID},
+		telemetry.AttributeKV{Key: "cluster-id", Value: conf.Cluster.ID},
+		telemetry.AttributeKV{Key: "chart-name", Value: conf.Name},
+		telemetry.AttributeKV{Key: "chart-namespace", Value: conf.Namespace},
+	)
+
 	valuesYaml, err := chartutil.ReadValues(values)
 	if err != nil {
-		return nil, fmt.Errorf("Values could not be parsed: %v", err)
+		return nil, telemetry.Error(ctx, span, err, "Values could not be parsed")
 	}
 
 	conf.Values = valuesYaml
 
-	return a.InstallChart(conf, doAuth, disablePullSecretsInjection)
+	return a.InstallChart(ctx, conf, doAuth, disablePullSecretsInjection)
 }
 
 // InstallChart installs a new chart
 func (a *Agent) InstallChart(
+	ctx context.Context,
 	conf *InstallChartConfig,
 	doAuth *oauth2.Config,
 	disablePullSecretsInjection bool,
@@ -402,6 +475,16 @@ func (a *Agent) InstallChart(
 		}
 	}()
 
+	ctx, span := telemetry.NewSpan(ctx, "helm-install-chart")
+	defer span.End()
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "project-id", Value: conf.Cluster.ProjectID},
+		telemetry.AttributeKV{Key: "cluster-id", Value: conf.Cluster.ID},
+		telemetry.AttributeKV{Key: "chart-name", Value: conf.Name},
+		telemetry.AttributeKV{Key: "chart-namespace", Value: conf.Namespace},
+	)
+
 	cmd := action.NewInstall(a.ActionConfig)
 
 	if cmd.Version == "" && cmd.Devel {
@@ -413,7 +496,7 @@ func (a *Agent) InstallChart(
 	cmd.Timeout = 300 * time.Second
 
 	if err := checkIfInstallable(conf.Chart); err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error checking if installable")
 	}
 
 	var err error
@@ -429,14 +512,14 @@ func (a *Agent) InstallChart(
 	)
 
 	if err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error getting post renderer")
 	}
 
 	if req := conf.Chart.Metadata.Dependencies; req != nil {
 		for _, dep := range req {
-			depChart, err := loader.LoadChartPublic(dep.Repository, dep.Name, dep.Version)
+			depChart, err := loader.LoadChartPublic(ctx, dep.Repository, dep.Name, dep.Version)
 			if err != nil {
-				return nil, fmt.Errorf("error retrieving chart dependency %s/%s-%s: %s", dep.Repository, dep.Name, dep.Version, err.Error())
+				return nil, telemetry.Error(ctx, span, err, fmt.Sprintf("error retrieving chart dependency %s/%s-%s", dep.Repository, dep.Name, dep.Version))
 			}
 
 			conf.Chart.AddDependency(depChart)
@@ -448,6 +531,7 @@ func (a *Agent) InstallChart(
 
 // UpgradeInstallChart installs a new chart if it doesn't exist, otherwise it upgrades it
 func (a *Agent) UpgradeInstallChart(
+	ctx context.Context,
 	conf *InstallChartConfig,
 	doAuth *oauth2.Config,
 	disablePullSecretsInjection bool,
@@ -458,6 +542,16 @@ func (a *Agent) UpgradeInstallChart(
 		}
 	}()
 
+	ctx, span := telemetry.NewSpan(ctx, "helm-upgrade-install-chart")
+	defer span.End()
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "project-id", Value: conf.Cluster.ProjectID},
+		telemetry.AttributeKV{Key: "cluster-id", Value: conf.Cluster.ID},
+		telemetry.AttributeKV{Key: "chart-name", Value: conf.Name},
+		telemetry.AttributeKV{Key: "chart-namespace", Value: conf.Namespace},
+	)
+
 	cmd := action.NewUpgrade(a.ActionConfig)
 	cmd.Install = true
 
@@ -469,7 +563,7 @@ func (a *Agent) UpgradeInstallChart(
 	cmd.Timeout = 300 * time.Second
 
 	if err := checkIfInstallable(conf.Chart); err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error checking if installable")
 	}
 
 	var err error
@@ -485,14 +579,14 @@ func (a *Agent) UpgradeInstallChart(
 	)
 
 	if err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error getting post renderer")
 	}
 
 	if req := conf.Chart.Metadata.Dependencies; req != nil {
 		for _, dep := range req {
-			depChart, err := loader.LoadChartPublic(dep.Repository, dep.Name, dep.Version)
+			depChart, err := loader.LoadChartPublic(ctx, dep.Repository, dep.Name, dep.Version)
 			if err != nil {
-				return nil, fmt.Errorf("error retrieving chart dependency %s/%s-%s: %s", dep.Repository, dep.Name, dep.Version, err.Error())
+				return nil, telemetry.Error(ctx, span, err, fmt.Sprintf("error retrieving chart dependency %s/%s-%s", dep.Repository, dep.Name, dep.Version))
 			}
 
 			conf.Chart.AddDependency(depChart)
@@ -504,17 +598,32 @@ func (a *Agent) UpgradeInstallChart(
 
 // UninstallChart uninstalls a chart
 func (a *Agent) UninstallChart(
+	ctx context.Context,
 	name string,
 ) (*release.UninstallReleaseResponse, error) {
+	ctx, span := telemetry.NewSpan(ctx, "helm-uninstall-chart")
+	defer span.End()
+
+	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "chart-name", Value: name})
+
 	cmd := action.NewUninstall(a.ActionConfig)
 	return cmd.Run(name)
 }
 
 // RollbackRelease rolls a release back to a specified revision/version
 func (a *Agent) RollbackRelease(
+	ctx context.Context,
 	name string,
 	version int,
 ) error {
+	ctx, span := telemetry.NewSpan(ctx, "helm-rollback-release")
+	defer span.End()
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "name", Value: name},
+		telemetry.AttributeKV{Key: "version", Value: version},
+	)
+
 	cmd := action.NewRollback(a.ActionConfig)
 	cmd.Version = version
 	return cmd.Run(name)

+ 5 - 4
internal/helm/agent_test.go

@@ -1,6 +1,7 @@
 package helm_test
 
 import (
+	"context"
 	"testing"
 
 	"github.com/stefanmcshane/helm/pkg/storage/driver"
@@ -223,7 +224,7 @@ func TestGetReleases(t *testing.T) {
 		// namespace, so we have to reset the namespace of the storage driver
 		agent.ActionConfig.Releases.Driver.(*driver.Memory).SetNamespace(tc.namespace)
 
-		rel, err := agent.GetRelease(tc.getName, tc.getVersion, false)
+		rel, err := agent.GetRelease(context.Background(), tc.getName, tc.getVersion, false)
 		if err != nil {
 			t.Errorf("%v", err)
 		}
@@ -256,7 +257,7 @@ func TestListReleaseHistory(t *testing.T) {
 		// namespace, so we have to reset the namespace of the storage driver
 		agent.ActionConfig.Releases.Driver.(*driver.Memory).SetNamespace(tc.namespace)
 
-		releases, err := agent.GetReleaseHistory("wordpress")
+		releases, err := agent.GetReleaseHistory(context.Background(), "wordpress")
 		if err != nil {
 			t.Errorf("%v", err)
 		}
@@ -325,12 +326,12 @@ func TestRollbackRelease(t *testing.T) {
 		// namespace, so we have to reset the namespace of the storage driver
 		agent.ActionConfig.Releases.Driver.(*driver.Memory).SetNamespace(tc.namespace)
 
-		err := agent.RollbackRelease("wordpress", 1)
+		err := agent.RollbackRelease(context.Background(), "wordpress", 1)
 		if err != nil {
 			t.Errorf("%v", err)
 		}
 
-		rel, err := agent.GetRelease(tc.getName, tc.getVersion, false)
+		rel, err := agent.GetRelease(context.Background(), tc.getName, tc.getVersion, false)
 		if err != nil {
 			t.Errorf("%v", err)
 		}

+ 21 - 9
internal/helm/loader/loader.go

@@ -2,12 +2,15 @@ package loader
 
 import (
 	"bytes"
+	"context"
 	"fmt"
 	"io/ioutil"
 	"net/http"
 	"net/url"
 	"strings"
 
+	"github.com/porter-dev/porter/internal/telemetry"
+
 	"k8s.io/helm/pkg/repo"
 	"sigs.k8s.io/yaml"
 
@@ -123,18 +126,27 @@ func LoadRepoIndexPublic(repoURL string) (*repo.IndexFile, error) {
 }
 
 // LoadChart uses an http request to fetch a chart from a remote Helm repo
-func LoadChart(client *BasicAuthClient, repoURL, chartName, chartVersion string) (*chart.Chart, error) {
+func LoadChart(ctx context.Context, client *BasicAuthClient, repoURL, chartName, chartVersion string) (*chart.Chart, error) {
+	ctx, span := telemetry.NewSpan(ctx, "load-chart")
+	defer span.End()
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "repo-url", Value: repoURL},
+		telemetry.AttributeKV{Key: "chart-name", Value: chartName},
+		telemetry.AttributeKV{Key: "chart-version", Value: chartVersion},
+	)
+
 	repoIndex, err := LoadRepoIndex(client, repoURL)
 	if err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error loading repo index")
 	}
 
 	cv, err := repoIndex.Get(chartName, chartVersion)
 
 	if err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error getting repo index")
 	} else if len(cv.URLs) == 0 {
-		return nil, fmt.Errorf("%s:%s no valid download urls", chartName, chartVersion)
+		return nil, telemetry.Error(ctx, span, nil, fmt.Sprintf("%s:%s no valid download urls", chartName, chartVersion))
 	}
 
 	trimmedRepoURL := strings.TrimSuffix(strings.TrimSpace(repoURL), "/")
@@ -147,7 +159,7 @@ func LoadChart(client *BasicAuthClient, repoURL, chartName, chartVersion string)
 	// download tgz
 	req, err := http.NewRequest("GET", chartURL, nil)
 	if err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error creating request")
 	}
 
 	if client.Username != "" {
@@ -156,14 +168,14 @@ func LoadChart(client *BasicAuthClient, repoURL, chartName, chartVersion string)
 
 	resp, err := http.DefaultClient.Do(req)
 	if err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error executing request")
 	}
 
 	defer resp.Body.Close()
 
 	data, err := ioutil.ReadAll(resp.Body)
 	if err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error reading response body")
 	}
 
 	return chartloader.LoadArchive(bytes.NewReader(data))
@@ -174,8 +186,8 @@ func LoadChart(client *BasicAuthClient, repoURL, chartName, chartVersion string)
 //
 // TODO: this is an expensive operation, so after retrieving the digest from the
 // repo index, this should check the digest in the cache
-func LoadChartPublic(repoURL, chartName, chartVersion string) (*chart.Chart, error) {
-	return LoadChart(&BasicAuthClient{}, repoURL, chartName, chartVersion)
+func LoadChartPublic(ctx context.Context, repoURL, chartName, chartVersion string) (*chart.Chart, error) {
+	return LoadChart(ctx, &BasicAuthClient{}, repoURL, chartName, chartVersion)
 }
 
 // Helper method to test if chart repo URL is valid, or is a path. Chartmuseum saves URLs

+ 2 - 1
internal/helm/repo/repo.go

@@ -1,6 +1,7 @@
 package repo
 
 import (
+	"context"
 	"fmt"
 
 	"github.com/porter-dev/porter/api/types"
@@ -78,7 +79,7 @@ func (hr *HelmRepo) getChartBasic(
 		Password: string(basic.Password),
 	}
 
-	return loader.LoadChart(client, hr.RepoURL, chartName, chartVersion)
+	return loader.LoadChart(context.Background(), client, hr.RepoURL, chartName, chartVersion)
 }
 
 func ValidateRepoURL(

+ 2 - 1
internal/kubernetes/envgroup/create.go

@@ -1,6 +1,7 @@
 package envgroup
 
 import (
+	"context"
 	"errors"
 	"fmt"
 	"strconv"
@@ -190,7 +191,7 @@ func GetSyncedReleases(helmAgent *helm.Agent, configMap *v1.ConfigMap) ([]*relea
 	appStrArr := strings.Split(appStr, ",")
 
 	// list all latest helm releases and check them against app string
-	releases, err := helmAgent.ListReleases(configMap.Namespace, &types.ReleaseListFilter{
+	releases, err := helmAgent.ListReleases(context.Background(), configMap.Namespace, &types.ReleaseListFilter{
 		StatusFilter: []string{
 			"deployed",
 			"uninstalled",

+ 2 - 2
internal/opa/opa.go

@@ -172,7 +172,7 @@ func (runner *KubernetesOPARunner) runHelmReleaseQueries(name string, collection
 	var helmReleases []*release.Release
 
 	if collection.Match.Name != "" {
-		helmRelease, err := helmAgent.GetRelease(collection.Match.Name, 0, false)
+		helmRelease, err := helmAgent.GetRelease(context.Background(), collection.Match.Name, 0, false)
 
 		if err != nil {
 			if collection.MustExist && strings.Contains(err.Error(), "not found") {
@@ -204,7 +204,7 @@ func (runner *KubernetesOPARunner) runHelmReleaseQueries(name string, collection
 
 		helmReleases = append(helmReleases, helmRelease)
 	} else if collection.Match.ChartName != "" {
-		prefilterReleases, err := helmAgent.ListReleases(collection.Match.Namespace, &types.ReleaseListFilter{
+		prefilterReleases, err := helmAgent.ListReleases(context.Background(), collection.Match.Namespace, &types.ReleaseListFilter{
 			ByDate: true,
 			StatusFilter: []string{
 				"deployed",

+ 3 - 2
internal/templater/helm/values/writer.go

@@ -1,6 +1,7 @@
 package helm
 
 import (
+	"context"
 	"fmt"
 
 	"github.com/porter-dev/porter/internal/helm"
@@ -42,7 +43,7 @@ func (w *TemplateWriter) Create(
 		Values:    vals,
 	}
 
-	_, err := w.Agent.InstallChart(conf, nil, false)
+	_, err := w.Agent.InstallChart(context.Background(), conf, nil, false)
 	if err != nil {
 		return nil, err
 	}
@@ -63,7 +64,7 @@ func (w *TemplateWriter) Update(
 		Values: vals,
 	}
 
-	_, err := w.Agent.UpgradeReleaseByValues(conf, nil, false, false)
+	_, err := w.Agent.UpgradeReleaseByValues(context.Background(), conf, nil, false, false)
 	if err != nil {
 		return nil, err
 	}