Repository: replicatedhq/kots
Pull request #296 (2020-01-31 01:00:44)

add scope test instrumentation


Patch:
diff --git a/.gitignore b/.gitignore
index e7c5a94ee..65d1cb5f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,4 +12,7 @@
 *.out
 
 bin/
-vendor
\ No newline at end of file
+vendor
+
+# scope test logs
+scope-go-*.log
\ No newline at end of file
diff --git a/cmd/kots/cli/upstream-upgrade.go b/cmd/kots/cli/upstream-upgrade.go
index a0a909336..df5e2f09a 100644
--- a/cmd/kots/cli/upstream-upgrade.go
+++ b/cmd/kots/cli/upstream-upgrade.go
@@ -71,11 +71,7 @@ func UpstreamUpgradeCmd() *cobra.Command {
 			authSlug, err := auth.GetOrCreateAuthSlug(v.GetString("namespace"))
 			if err != nil {
 				log.FinishSpinnerWithError()
-				log.Info("Unable to authenticate to the Admin Console running in the %s namespace. Ensure you have read access to secrets in this namespace and try again.", v.GetString("namespace"))
-				if v.GetBool("debug") {
-					return errors.Wrap(err, "failed to get kotsadm auth slug")
-				}
-				os.Exit(2) // not returning error here as we don't want to show the entire stack trace to normal users
+				return errors.Wrap(err, "failed to get kotsadm auth slug")
 			}
 
 			newReq, err := http.NewRequest("POST", updateCheckURI, strings.NewReader("{}"))
@@ -151,8 +147,5 @@ func UpstreamUpgradeCmd() *cobra.Command {
 	cmd.Flags().StringP("namespace", "n", "default", "the namespace where the admin console is running")
 	cmd.Flags().Bool("deploy", false, "when set, automatically deploy the latest version downloads")
 
-	cmd.Flags().Bool("debug", false, "when set, log full error traces in some cases where we provide a pretty message")
-	cmd.Flags().MarkHidden("debug")
-
 	return cmd
 }
diff --git a/ffi/online.go b/ffi/online.go
index fa4780a43..1a92cfe90 100644
--- a/ffi/online.go
+++ b/ffi/online.go
@@ -64,7 +64,6 @@ func PullFromLicense(socket string, licenseData string, downstream string, names
 			RootDir:             tmpRoot,
 			ExcludeAdminConsole: true,
 			CreateAppDir:        false,
-			ReportWriter:        statusClient.getOutputWriter(),
 		}
 
 		if _, err := pull.Pull(fmt.Sprintf("replicated://%s", license.Spec.AppSlug), pullOptions); err != nil {
diff --git a/go.mod b/go.mod
index 4a6af17af..bfdd81118 100644
--- a/go.mod
+++ b/go.mod
@@ -32,7 +32,6 @@ require (
 	github.com/fatih/color v1.7.0
 	github.com/frankban/quicktest v1.4.1 // indirect
 	github.com/ghodss/yaml v1.0.0
-	github.com/golang/protobuf v1.3.2 // indirect
 	github.com/golang/snappy v0.0.1 // indirect
 	github.com/google/gofuzz v1.0.0
 	github.com/google/uuid v1.1.1
@@ -73,11 +72,12 @@ require (
 	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
 	github.com/xeipuuv/gojsonschema v1.1.0 // indirect
 	github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
+	go.undefinedlabs.com/scopeagent v0.1.6
 	golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7
-	golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 // indirect
 	gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20180810215634-df19058c872c // indirect
 	gopkg.in/yaml.v2 v2.2.2
 	gotest.tools v0.0.0-20190624233834-05ebafbffc79 // indirect
+	honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc // indirect
 	k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b
 	k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d
 	k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
diff --git a/go.sum b/go.sum
index 0437b8dd5..a29c2fb03 100644
--- a/go.sum
+++ b/go.sum
@@ -91,6 +91,8 @@ github.com/aws/aws-sdk-go v1.25.18 h1:fMEkpli4r+FS4xZRqjgjYHP+uKaSwfk2MOcDUpLYwI
 github.com/aws/aws-sdk-go v1.25.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
 github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
 github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
+github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
+github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -100,6 +102,7 @@ github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb
 github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
 github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
 github.com/bsm/go-vlq v0.0.0-20150828105119-ec6e8d4f5f4e/go.mod h1:N+BjUcTjSxc2mtRGSCPsat1kze3CUtvJN3/jTXlp29k=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
 github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
@@ -169,6 +172,8 @@ github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8
 github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 github.com/emicklei/go-restful v2.9.6+incompatible h1:tfrHha8zJ01ywiOEC1miGY8st1/igzWB8OmvPgoYX7w=
 github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM=
 github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
 github.com/evanphx/json-patch v4.0.0+incompatible h1:xregGRMLBeuRcwiOTHRCsPPuzCQlqhxUPbqdw+zNkLc=
@@ -191,6 +196,8 @@ github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NB
 github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
 github.com/gizak/termui/v3 v3.1.0/go.mod h1:bXQEBkJpzxUAKf0+xq9MSWAvWZlE7c+aidmyFlkYTrY=
 github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
+github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
+github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
 github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
@@ -224,6 +231,8 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
 github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
+github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
@@ -371,6 +380,7 @@ github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALr
 github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
 github.com/keybase/go-crypto v0.0.0-20161004153544-93f5b35093ba/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/klauspost/compress v1.4.1 h1:8VMb5+0wMgdBykOV96DwNwKFQ+WTI4pzYURP99CcB9E=
 github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
@@ -500,6 +510,9 @@ github.com/opencontainers/runc v1.0.0-rc8 h1:dDCFes8Hj1r/i5qnypONo5jdOme/8HWZC/a
 github.com/opencontainers/runc v1.0.0-rc8/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
 github.com/opencontainers/selinux v1.2.2 h1:Kx9J6eDG5/24A6DtUquGSpJQ+m2MUTahn4FtGEe8bFg=
 github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
+github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
+github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
 github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
 github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 h1:TnbXhKzrTOyuvWrjI8W6pcoI9XPbLHFXCdN2dtUw7Rw=
@@ -543,6 +556,7 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
 github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
@@ -662,12 +676,16 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT
 github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
 github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8=
 github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
+github.com/undefinedlabs/go-mpatch v0.0.0-20200122175732-0044123dbb98 h1:Z/megzdoMbuZ0H/oLmfTw92PAEfyTi1DkvAr8AUzFgw=
+github.com/undefinedlabs/go-mpatch v0.0.0-20200122175732-0044123dbb98/go.mod h1:TyJZDQ/5AgyN7FSLiBJ8RO9u2c6wbtRvK827b6AVqY4=
 github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE=
 github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g=
 github.com/vbauerster/mpb v3.4.0+incompatible h1:mfiiYw87ARaeRW6x5gWwYRUawxaW1tLAD8IceomUCNw=
 github.com/vbauerster/mpb v3.4.0+incompatible/go.mod h1:zAHG26FUhVKETRu+MWqYXcI70POlC6N8up9p1dID7SU=
 github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
 github.com/vmihailenco/msgpack v4.0.1+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
+github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
+github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
 github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k=
 github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
 github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
@@ -703,6 +721,8 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
 go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.undefinedlabs.com/scopeagent v0.1.6 h1:AEUAbwBh7g0XXFVMHyTJqrJOTNjKehcNBL+qWAbth70=
+go.undefinedlabs.com/scopeagent v0.1.6/go.mod h1:4QeO91RRdKn2G+KyTqou6dZTWkUS+L0tnJIk0cbrQjM=
 go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
 golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
 golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
@@ -749,12 +769,15 @@ golang.org/x/net v0.0.0-20190502183928-7f726cade0ab/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68=
 golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -795,6 +818,8 @@ golang.org/x/sys v0.0.0-20190621203818-d432491b9138 h1:t8BZD9RDjkm9/h7yYN6kE8oae
 golang.org/x/sys v0.0.0-20190621203818-d432491b9138/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0=
 golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -811,6 +836,7 @@ golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGm
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181122213734-04b5d21e00f1/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -820,6 +846,7 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3
 golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190501045030-23463209683d/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 h1:QjA/9ArTfVTLfEhClDCG7SGrZkZixxWpwNCDiwJfh88=
 golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
@@ -832,6 +859,7 @@ google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@@ -839,6 +867,7 @@ google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoA
 google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
 google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922/go.mod h1:L3J43x8/uS+qIUoksaLKe6OS3nUKxOKuIFz1sl2/jx4=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
@@ -846,12 +875,15 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
 google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0=
 google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20180810215634-df19058c872c h1:vTxShRUnK60yd8DZU+f95p1zSLj814+5CuEh7NjF2/Y=
 gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20180810215634-df19058c872c/go.mod h1:3HH7i1SgMqlzxCcBmUHW657sD4Kvv9sC3HpL3YukzwA=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
@@ -865,6 +897,8 @@ gopkg.in/laverya/yaml.v3 v3.0.0-beta3/go.mod h1:b5w3YJ/R5MxUkx01JYEDFaW9XiYHxEm6
 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs=
+gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk=
 gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
@@ -876,6 +910,7 @@ grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJd
 honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
 k8s.io/api v0.0.0-20190313235455-40a48860b5ab/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
 k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b h1:aBGgKJUM9Hk/3AE8WaZIApnTxG35kbuQba2w+SXqezo=
diff --git a/pkg/kotsadm/api.go b/pkg/kotsadm/api.go
index 785dbcfa0..d6f2c66eb 100644
--- a/pkg/kotsadm/api.go
+++ b/pkg/kotsadm/api.go
@@ -125,7 +125,6 @@ func ensureApiRole(namespace string, clientset *kubernetes.Clientset) error {
 		if err != nil {
 			return errors.Wrap(err, "failed to create role")
 		}
-		return nil
 	}
 
 	// we have now changed the role, so an upgrade is required
diff --git a/pkg/kotsadm/kotsadm.go b/pkg/kotsadm/kotsadm.go
index 74d3c107a..55c647f05 100644
--- a/pkg/kotsadm/kotsadm.go
+++ b/pkg/kotsadm/kotsadm.go
@@ -125,7 +125,6 @@ func ensureKotsadmRole(namespace string, clientset *kubernetes.Clientset) error
 		if err != nil {
 			return errors.Wrap(err, "failed to create role")
 		}
-		return nil
 	}
 
 	// we have now changed the role, so an upgrade is required
diff --git a/pkg/pull/pull.go b/pkg/pull/pull.go
index 8c45345e8..72731987c 100644
--- a/pkg/pull/pull.go
+++ b/pkg/pull/pull.go
@@ -1,7 +1,6 @@
 package pull
 
 import (
-	"fmt"
 	"io"
 	"io/ioutil"
 	"net/url"
@@ -102,10 +101,6 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) {
 
 	log.Initialize()
 
-	if pullOptions.ReportWriter == nil {
-		pullOptions.ReportWriter = ioutil.Discard
-	}
-
 	uri, err := url.ParseRequestURI(upstreamURI)
 	if err != nil {
 		return "", errors.Wrap(err, "failed to parse uri")
@@ -163,7 +158,6 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) {
 	}
 
 	log.ActionWithSpinner("Pulling upstream")
-	io.WriteString(pullOptions.ReportWriter, "Pulling upstream\n")
 	u, err := upstream.FetchUpstream(upstreamURI, &fetchOptions)
 	if err != nil {
 		log.FinishSpinnerWithError()
@@ -193,7 +187,6 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) {
 		Log:               log,
 	}
 	log.ActionWithSpinner("Creating base")
-	io.WriteString(pullOptions.ReportWriter, "Creating base\n")
 
 	b, err := base.RenderUpstream(u, &renderOptions)
 	if err != nil {
@@ -217,7 +210,6 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) {
 	if pullOptions.RewriteImages {
 
 		log.ActionWithSpinner("Copying private images")
-		io.WriteString(pullOptions.ReportWriter, "Copying private images\n")
 
 		// Rewrite all images
 		if pullOptions.RewriteImageOptions.ImageFiles == "" {
@@ -352,7 +344,6 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) {
 	}
 
 	log.ActionWithSpinner("Creating midstream")
-	io.WriteString(pullOptions.ReportWriter, "Creating midstream\n")
 
 	m, err := midstream.CreateMidstream(b, images, objects, pullSecret)
 	if err != nil {
@@ -370,7 +361,6 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) {
 
 	for _, downstreamName := range pullOptions.Downstreams {
 		log.ActionWithSpinner("Creating downstream %q", downstreamName)
-		io.WriteString(pullOptions.ReportWriter, fmt.Sprintf("Creating downstream %q\n", downstreamName))
 		d, err := downstream.CreateDownstream(m, downstreamName)
 		if err != nil {
 			return "", errors.Wrap(err, "failed to create downstream")
diff --git a/pkg/rewrite/rewrite.go b/pkg/rewrite/rewrite.go
index 73ca5ea79..4ed27a82d 100644
--- a/pkg/rewrite/rewrite.go
+++ b/pkg/rewrite/rewrite.go
@@ -1,9 +1,7 @@
 package rewrite
 
 import (
-	"fmt"
 	"io"
-	"io/ioutil"
 	"path/filepath"
 
 	"github.com/pkg/errors"
@@ -50,10 +48,6 @@ func Rewrite(rewriteOptions RewriteOptions) error {
 
 	log.Initialize()
 
-	if rewriteOptions.ReportWriter == nil {
-		rewriteOptions.ReportWriter = ioutil.Discard
-	}
-
 	fetchOptions := &upstream.FetchOptions{
 		RootDir:             rewriteOptions.RootDir,
 		LocalPath:           rewriteOptions.UpstreamPath,
@@ -64,7 +58,6 @@ func Rewrite(rewriteOptions RewriteOptions) error {
 	}
 
 	log.ActionWithSpinner("Pulling upstream")
-	io.WriteString(rewriteOptions.ReportWriter, "Pulling upstream\n")
 	u, err := upstream.FetchUpstream(rewriteOptions.UpstreamURI, fetchOptions)
 	if err != nil {
 		log.FinishSpinnerWithError()
@@ -92,7 +85,6 @@ func Rewrite(rewriteOptions RewriteOptions) error {
 		Log:               log,
 	}
 	log.ActionWithSpinner("Creating base")
-	io.WriteString(rewriteOptions.ReportWriter, "Creating base\n")
 	b, err := base.RenderUpstream(u, &renderOptions)
 	if err != nil {
 		return errors.Wrap(err, "failed to render upstream")
@@ -208,7 +200,6 @@ func Rewrite(rewriteOptions RewriteOptions) error {
 	}
 
 	log.ActionWithSpinner("Creating midstream")
-	io.WriteString(rewriteOptions.ReportWriter, "Creating midstream\n")
 
 	m, err := midstream.CreateMidstream(b, images, objects, pullSecret)
 	if err != nil {
@@ -226,7 +217,6 @@ func Rewrite(rewriteOptions RewriteOptions) error {
 
 	for _, downstreamName := range rewriteOptions.Downstreams {
 		log.ActionWithSpinner("Creating downstream %q", downstreamName)
-		io.WriteString(rewriteOptions.ReportWriter, fmt.Sprintf("Creating downstream %q\n", downstreamName))
 		d, err := downstream.CreateDownstream(m, downstreamName)
 		if err != nil {
 			return errors.Wrap(err, "failed to create downstream")
diff --git a/support-bundle.yaml b/support-bundle.yaml
index caef1d65c..58854035b 100644
--- a/support-bundle.yaml
+++ b/support-bundle.yaml
@@ -6,39 +6,29 @@ spec:
   collectors:
     - clusterInfo: {}
     - clusterResources: {}
-    - exec:
-        args:
+    - exec: 
+        args: 
           - "-U"
           - kotsadm
         collectorName: kotsadm-postgres-db
-        command:
+        command: 
           - pg_dump
         containerName: kotsadm-postgres
         name: kots/admin_console
-        selector:
+        selector: 
           - app=kotsadm-postgres
         timeout: 10s
-    - logs:
-        collectorName: kotsadm-postgres-db
-        name: kots/admin_console
-        selector:
-          - app=kotsadm-postgres 
-    - logs:
+    - logs: 
         collectorName: kotsadm-api
         name: kots/admin_console
-        selector:
+        selector: 
           - app=kotsadm-api
-    - logs:
+    - logs: 
         collectorName: kotsadm-operator
         name: kots/admin_console
-        selector:
+        selector: 
           - app=kotsadm-operator
-    - logs:
-        collectorName: kotsadm
-        name: kots/admin_console
-        selector:
-          - app=kotsadm
-    - secret:
+    - secret: 
         collectorName: kotsadm-replicated-registry
         includeValue: false
         key: .dockerconfigjson


Test patch:
diff --git a/pkg/base/base_test.go b/pkg/base/base_test.go
index 9ce7a9ebc..a472821eb 100644
--- a/pkg/base/base_test.go
+++ b/pkg/base/base_test.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_transpileHelmHooksToKotsHooks(t *testing.T) {
@@ -108,6 +109,8 @@ spec:
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			b := BaseFile{
@@ -120,7 +123,6 @@ spec:
 			assert.Equal(t, test.expected, string(b.Content))
 		})
 	}
-
 }
 
 func Test_ShouldBeIncludedInBaseKustomization(t *testing.T) {
@@ -398,6 +400,8 @@ spec:
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			b := BaseFile{
diff --git a/pkg/base/main_test.go b/pkg/base/main_test.go
new file mode 100644
index 000000000..1752f6e2b
--- /dev/null
+++ b/pkg/base/main_test.go
@@ -0,0 +1,12 @@
+package base
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/base/write_test.go b/pkg/base/write_test.go
index 3e6131a63..e2d78f3ec 100644
--- a/pkg/base/write_test.go
+++ b/pkg/base/write_test.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 var (
@@ -133,6 +134,8 @@ func Test_DeduplicateOnContent(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			actualResources, actualPatches, err := deduplicateOnContent(test.files, test.excludeKotsKinds)
diff --git a/pkg/cursor/cursor_test.go b/pkg/cursor/cursor_test.go
index 2aeed7f8b..ac85cb467 100644
--- a/pkg/cursor/cursor_test.go
+++ b/pkg/cursor/cursor_test.go
@@ -4,6 +4,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_Comparable(t *testing.T) {
@@ -50,6 +51,8 @@ func Test_Comparable(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			c1, err := NewCursor(test.c1)
 			if test.c1Error {
 				assert.Error(t, err)
diff --git a/pkg/cursor/main_test.go b/pkg/cursor/main_test.go
new file mode 100644
index 000000000..7c42f42d6
--- /dev/null
+++ b/pkg/cursor/main_test.go
@@ -0,0 +1,12 @@
+package cursor
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/image/builder_test.go b/pkg/image/builder_test.go
index f6c9f8b46..50c3958cf 100644
--- a/pkg/image/builder_test.go
+++ b/pkg/image/builder_test.go
@@ -4,9 +4,12 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func TestReleaseStartNum(t *testing.T) {
+	test := scopeagent.StartTest(t)
+	defer test.End()
 	var err error
 	var ref *ImageRef
 
diff --git a/pkg/image/image_test.go b/pkg/image/image_test.go
index 23b965efb..d3060b58a 100644
--- a/pkg/image/image_test.go
+++ b/pkg/image/image_test.go
@@ -7,6 +7,7 @@ import (
 	"github.com/replicatedhq/kots/pkg/docker/registry"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 	"sigs.k8s.io/kustomize/v3/pkg/image"
 	kustomizeimage "sigs.k8s.io/kustomize/v3/pkg/image"
 )
@@ -66,6 +67,8 @@ func Test_ImageNameFromNameParts(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			image, err := ImageInfoFromFile(registryOps, test.parts)
 			if test.isError {
 				assert.Error(t, err)
@@ -119,6 +122,8 @@ func TestDestRef(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			if got := DestRef(tt.args.registry, tt.args.srcImage); got != tt.want {
 				t.Errorf("DestImageName() = %v, want %v", got, tt.want)
 			}
@@ -248,6 +253,8 @@ func Test_buildImageAlts(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 			got, err := buildImageAlts(tt.destRegistry, tt.image)
 			req.NoError(err)
@@ -295,6 +302,8 @@ func Test_stripImageTag(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			if got := stripImageTag(tt.image); got != tt.want {
 				t.Errorf("stripImageTag() = %v, want %v", got, tt.want)
 			}
diff --git a/pkg/image/main_test.go b/pkg/image/main_test.go
new file mode 100644
index 000000000..1ea35b3c7
--- /dev/null
+++ b/pkg/image/main_test.go
@@ -0,0 +1,12 @@
+package image
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/k8sutil/main_test.go b/pkg/k8sutil/main_test.go
new file mode 100644
index 000000000..2087f7470
--- /dev/null
+++ b/pkg/k8sutil/main_test.go
@@ -0,0 +1,12 @@
+package k8sutil
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/k8sutil/updaterole_test.go b/pkg/k8sutil/updaterole_test.go
index 0ed064be4..f67b216b9 100644
--- a/pkg/k8sutil/updaterole_test.go
+++ b/pkg/k8sutil/updaterole_test.go
@@ -4,6 +4,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 	rbacv1 "k8s.io/api/rbac/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
@@ -144,6 +145,8 @@ func TestUpdateRole(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 			UpdateRole(tt.existingRole, tt.desiredRole)
 			req.ElementsMatch(tt.existingRole.Rules, tt.expectedRules)
diff --git a/pkg/kotsadm/kotsad_version_test.go b/pkg/kotsadm/kotsad_version_test.go
index de3dec6e4..c1e6bba14 100644
--- a/pkg/kotsadm/kotsad_version_test.go
+++ b/pkg/kotsadm/kotsad_version_test.go
@@ -4,6 +4,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_kotsadmRegistry(t *testing.T) {
@@ -33,6 +34,8 @@ func Test_kotsadmRegistry(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			OverrideVersion = test.overrideVersion
 			OverrideRegistry = test.overrideRegistry
 			OverrideNamespace = test.overrideNamespace
diff --git a/pkg/kotsadm/main_test.go b/pkg/kotsadm/main_test.go
new file mode 100644
index 000000000..708b56399
--- /dev/null
+++ b/pkg/kotsadm/main_test.go
@@ -0,0 +1,12 @@
+package kotsadm
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/midstream/lists_test.go b/pkg/midstream/lists_test.go
index 74f3d933a..c2569576c 100644
--- a/pkg/midstream/lists_test.go
+++ b/pkg/midstream/lists_test.go
@@ -4,6 +4,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_findNewStrings(t *testing.T) {
@@ -30,6 +31,8 @@ func Test_findNewStrings(t *testing.T) {
 	}
 
 	for _, test := range tests {
+		scopetest := scopeagent.StartTest(t)
+		defer scopetest.End()
 		diff := findNewStrings(test.newList, test.existingList)
 		assert.Equal(t, test.expected, diff)
 	}
diff --git a/pkg/midstream/main_test.go b/pkg/midstream/main_test.go
new file mode 100644
index 000000000..3a6724c5c
--- /dev/null
+++ b/pkg/midstream/main_test.go
@@ -0,0 +1,12 @@
+package midstream
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/pull/main_test.go b/pkg/pull/main_test.go
new file mode 100644
index 000000000..2c4ae1104
--- /dev/null
+++ b/pkg/pull/main_test.go
@@ -0,0 +1,12 @@
+package pull
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/pull/upstream_test.go b/pkg/pull/upstream_test.go
index 6e2168f9c..97e2af2f3 100644
--- a/pkg/pull/upstream_test.go
+++ b/pkg/pull/upstream_test.go
@@ -4,6 +4,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func TestRewriteUpstream(t *testing.T) {
@@ -26,6 +27,8 @@ func TestRewriteUpstream(t *testing.T) {
 	}
 	for _, test := range tests {
 		t.Run(test.upstreamURI, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			actual := RewriteUpstream(test.upstreamURI)
 			assert.Equal(t, actual, test.expected)
 		})
diff --git a/pkg/template/builder_test.go b/pkg/template/builder_test.go
index 7200517a8..8ae5964f9 100644
--- a/pkg/template/builder_test.go
+++ b/pkg/template/builder_test.go
@@ -5,6 +5,7 @@ import (
 	"text/template"
 
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 type testContext struct {
@@ -211,17 +212,23 @@ func TestBuildStrings(t *testing.T) {
 
 	for _, test := range cases {
 		t.Run(test.name(), func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			test.runTest(t, builder)
 		})
 	}
 
 	t.Run("Test bad values", func(t *testing.T) {
+		scopetest := scopeagent.StartTest(t)
+		defer scopetest.End()
 		built, err := builder.String("{{repl ParseBool True}}")
 		require.New(t).Error(err)
 		require.New(t).Equal("", built)
 	})
 
 	t.Run("Test broken template syntax", func(t *testing.T) {
+		scopetest := scopeagent.StartTest(t)
+		defer scopetest.End()
 		built, err := builder.String("{{repl SomeFunc")
 		require.New(t).Error(err)
 		require.New(t).Equal("", built)
diff --git a/pkg/template/license_context_test.go b/pkg/template/license_context_test.go
index fa6439b90..7a31f476e 100644
--- a/pkg/template/license_context_test.go
+++ b/pkg/template/license_context_test.go
@@ -5,9 +5,12 @@ import (
 
 	kotsv1beta1 "github.com/replicatedhq/kots/kotskinds/apis/kots/v1beta1"
 	"github.com/stretchr/testify/assert"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func TestLicenseContext_dockercfg(t *testing.T) {
+	test := scopeagent.StartTest(t)
+	defer test.End()
 	ctx := LicenseCtx{
 		License: &kotsv1beta1.License{
 			Spec: kotsv1beta1.LicenseSpec{
diff --git a/pkg/template/main_test.go b/pkg/template/main_test.go
new file mode 100644
index 000000000..f8c8204a5
--- /dev/null
+++ b/pkg/template/main_test.go
@@ -0,0 +1,12 @@
+package template
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/template/random_test.go b/pkg/template/random_test.go
index 59a1430ea..3386d2987 100644
--- a/pkg/template/random_test.go
+++ b/pkg/template/random_test.go
@@ -8,9 +8,12 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	_ "github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func TestGenerateRandomString(t *testing.T) {
+	test := scopeagent.StartTest(t)
+	defer test.End()
 	ctx := &StaticCtx{}
 	str := ctx.RandomString(100)
 	assert.Len(t, str, 100)
@@ -64,6 +67,8 @@ func TestGenerateRandomStringTemplates(t *testing.T) {
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			// TODO
 
 			// req := require.New(t)
diff --git a/pkg/template/static_context_test.go b/pkg/template/static_context_test.go
index 15bc5c584..0732c1f04 100644
--- a/pkg/template/static_context_test.go
+++ b/pkg/template/static_context_test.go
@@ -4,9 +4,12 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func TestStaticContext_kubeSeal_badCert(t *testing.T) {
+	test := scopeagent.StartTest(t)
+	defer test.End()
 	req := require.New(t)
 
 	ctx := StaticCtx{}
@@ -21,6 +24,8 @@ SPA=
 }
 
 func TestStaticContext_kubeSeal_goodCert(t *testing.T) {
+	test := scopeagent.StartTest(t)
+	defer test.End()
 	req := require.New(t)
 
 	ctx := StaticCtx{}
@@ -60,6 +65,8 @@ yw==
 }
 
 func TestSprigRandom(t *testing.T) {
+	test := scopeagent.StartTest(t)
+	defer test.End()
 	req := require.New(t)
 
 	builder := Builder{}
diff --git a/pkg/upstream/fetch_test.go b/pkg/upstream/fetch_test.go
index 39d053299..30bc51db1 100644
--- a/pkg/upstream/fetch_test.go
+++ b/pkg/upstream/fetch_test.go
@@ -10,10 +10,13 @@ import (
 	kotsv1beta1 "github.com/replicatedhq/kots/kotskinds/apis/kots/v1beta1"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
 func Test_downloadUpstream(t *testing.T) {
+	test := scopeagent.StartTest(t)
+	defer test.End()
 	req := require.New(t)
 
 	srcDir, err := ioutil.TempDir("", "downloadUpstream")
diff --git a/pkg/upstream/helm_test.go b/pkg/upstream/helm_test.go
index 1df80d9c2..bb626005b 100644
--- a/pkg/upstream/helm_test.go
+++ b/pkg/upstream/helm_test.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_parseHelmURL(t *testing.T) {
@@ -34,6 +35,8 @@ func Test_parseHelmURL(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			u, err := url.ParseRequestURI(test.uri)
diff --git a/pkg/upstream/main_test.go b/pkg/upstream/main_test.go
new file mode 100644
index 000000000..ea25579b3
--- /dev/null
+++ b/pkg/upstream/main_test.go
@@ -0,0 +1,12 @@
+package upstream
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/upstream/replicated_test.go b/pkg/upstream/replicated_test.go
index 5fa408d8f..7ee297e52 100644
--- a/pkg/upstream/replicated_test.go
+++ b/pkg/upstream/replicated_test.go
@@ -9,6 +9,7 @@ import (
 	"github.com/replicatedhq/kots/pkg/upstream/types"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -54,6 +55,8 @@ func Test_parseReplicatedURL(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			u, err := url.ParseRequestURI(test.uri)
@@ -142,6 +145,8 @@ func Test_releaseToFiles(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			actual, err := releaseToFiles(test.release)
@@ -153,6 +158,8 @@ func Test_releaseToFiles(t *testing.T) {
 }
 
 func Test_createConfigValues(t *testing.T) {
+	test := scopeagent.StartTest(t)
+	defer test.End()
 	applicationName := "Test App"
 
 	config := &kotsv1beta1.Config{
@@ -282,6 +289,8 @@ func Test_createConfigValues(t *testing.T) {
 }
 
 func Test_getRequest(t *testing.T) {
+	test := scopeagent.StartTest(t)
+	defer test.End()
 	beta := "beta"
 	unstable := "unstable"
 	tests := []struct {
diff --git a/pkg/util/main_test.go b/pkg/util/main_test.go
new file mode 100644
index 000000000..bf388a081
--- /dev/null
+++ b/pkg/util/main_test.go
@@ -0,0 +1,12 @@
+package util
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go
index 660b7764b..891c51480 100644
--- a/pkg/util/util_test.go
+++ b/pkg/util/util_test.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_CommonSlicePrefix(t *testing.T) {
@@ -36,6 +37,8 @@ func Test_CommonSlicePrefix(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			common := CommonSlicePrefix(test.first, test.second)
 			assert.Equal(t, test.expected, common)
 		})
@@ -71,6 +74,8 @@ func Test_SplitStringOnLen(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			parts, err := SplitStringOnLen(test.in, test.max)
@@ -110,6 +115,8 @@ func TestIntPointer(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 			got := IntPointer(tt.x)
 			req.Equal(tt.want, *got)
@@ -137,6 +144,8 @@ func TestGenPassword(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 			got := GenPassword(tt.length)
 			req.Len(got, tt.length)
@@ -178,6 +187,8 @@ func TestCompareStringArrays(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 			req.Equal(CompareStringArrays(tt.arr1, tt.arr2), tt.want)
 		})
diff --git a/pkg/version/main_test.go b/pkg/version/main_test.go
new file mode 100644
index 000000000..e92254507
--- /dev/null
+++ b/pkg/version/main_test.go
@@ -0,0 +1,12 @@
+package version
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/version/version_test.go b/pkg/version/version_test.go
index 7cf50c059..7e49d7bdf 100644
--- a/pkg/version/version_test.go
+++ b/pkg/version/version_test.go
@@ -7,6 +7,7 @@ import (
 	"time"
 
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func TestVersion(t *testing.T) {
@@ -25,6 +26,8 @@ func TestVersion(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			version = tt.want
@@ -65,6 +68,8 @@ func TestGitSHA(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			gitSHA = tt.sha
@@ -99,6 +104,8 @@ func TestBuildTime(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			buildTime = tt.timestring
@@ -129,6 +136,8 @@ func TestGetBuild(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			version = tt.version
@@ -177,6 +186,8 @@ func TestIsLatestRelease(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {