Merge "Import changes for goma server" into main
diff --git a/cipd_manifest.txt b/cipd_manifest.txt
index c14d055..bbe5d6a 100644
--- a/cipd_manifest.txt
+++ b/cipd_manifest.txt
@@ -13,7 +13,7 @@
 # https://chrome-infra-packages.appspot.com/
 
 # go
-infra/3pp/tools/go/${platform} version:2@1.17.2
+infra/3pp/tools/go/${platform} version:2@1.17.7
 
 # protoc
-infra/3pp/tools/protoc/${platform} version:2@3.19.0
+infra/3pp/tools/protoc/${platform} version:2@3.19.4
diff --git a/cipd_manifest.versions b/cipd_manifest.versions
index 844694b..681fd65 100644
--- a/cipd_manifest.versions
+++ b/cipd_manifest.versions
@@ -2,9 +2,9 @@
 # Do not modify manually. All changes will be overwritten.
 
 infra/3pp/tools/go/linux-amd64
-	version:2@1.17.2
-	-xKRu10txxPJsPJD1jyJi-kISvT6ZvAnXLKqmKPt-ZsC
+	version:2@1.17.7
+	IW5qSWS42VJGJItDwDBpnYO5ztmvNUAhmclpt4MKCeIC
 
 infra/3pp/tools/protoc/linux-amd64
-	version:2@3.19.0
-	PtB-djyyxXTZKvTxPCUnm8csA4AGysPN5ME5CN8XadoC
+	version:2@3.19.4
+	PXupdd2Pp_925ne_qf0ExEukmvjnoHgmxRpMFFN7IdEC
diff --git a/cmd/exec_server/main.go b/cmd/exec_server/main.go
index fc38165..634499f 100644
--- a/cmd/exec_server/main.go
+++ b/cmd/exec_server/main.go
@@ -74,6 +74,7 @@
 
 	// http://b/141901653
 	execMaxRetryCount = flag.Int("exec-max-retry-count", 5, "max retry count for exec call. 0 is unlimited count, but bound to ctx timtout. Use small number for powerful clients to run local fallback quickly. Use large number for powerless clients to use remote more than local.")
+	execActionTimeout = flag.Duration("exec-action-timeout", 15*time.Minute, "action timeout after which the execution should be killed.")
 
 	cmdFilesBucket      = flag.String("cmd-files-bucket", "", "cloud storage bucket for command binary files")
 	fetchConfigParallel = flag.Bool("fetch-config-parallel", true, "fetch toolchain configs in parallel")
@@ -460,7 +461,7 @@
 	re := &remoteexec.Adapter{
 		InstancePrefix:   *remoteInstancePrefix,
 		InstanceBaseName: *remoteInstanceBaseName,
-		ExecTimeout:      15 * time.Minute,
+		ExecTimeout:      *execActionTimeout,
 		SpanTimeout:      spanTimeout,
 		Client: remoteexec.Client{
 			ClientConn: reConn,
diff --git a/go.mod b/go.mod
index 17ff1f4..6f6fd6b 100644
--- a/go.mod
+++ b/go.mod
@@ -1,34 +1,33 @@
 module go.chromium.org/goma/server
 
-go 1.12
+go 1.16
 
 require (
-	cloud.google.com/go v0.97.0
-	cloud.google.com/go/errorreporting v0.1.0
-	cloud.google.com/go/monitoring v1.1.0
-	cloud.google.com/go/profiler v0.1.1
-	cloud.google.com/go/pubsub v1.17.1
-	cloud.google.com/go/storage v1.18.2
-	cloud.google.com/go/trace v1.0.0 // indirect
-	contrib.go.opencensus.io/exporter/stackdriver v0.13.8
+	cloud.google.com/go/compute v1.5.0
+	cloud.google.com/go/errorreporting v0.2.0
+	cloud.google.com/go/monitoring v1.3.0
+	cloud.google.com/go/profiler v0.2.0
+	cloud.google.com/go/pubsub v1.18.0
+	cloud.google.com/go/storage v1.21.0
+	contrib.go.opencensus.io/exporter/stackdriver v0.13.10
 	github.com/bazelbuild/remote-apis v0.0.0-20210520160108-3e385366f152
 	github.com/bazelbuild/remote-apis-sdks v0.0.0-20201118210229-b732553f9d45
 	github.com/fsnotify/fsnotify v1.5.1
 	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e
-	github.com/gomodule/redigo v1.8.5
-	github.com/google/go-cmp v0.5.6
+	github.com/gomodule/redigo v1.8.8
+	github.com/google/go-cmp v0.5.7
 	github.com/google/uuid v1.3.0
 	github.com/googleapis/gax-go/v2 v2.1.1
 	github.com/googleapis/google-cloud-go-testing v0.0.0-20190904031503-2d24dde44ba5
 	github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
 	go.opencensus.io v0.23.0
-	go.uber.org/zap v1.19.1
+	go.uber.org/zap v1.21.0
 	golang.org/x/build v0.0.0-20191031202223-0706ea4fce0c
-	golang.org/x/net v0.0.0-20210505214959-0714010a04ed
-	golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1
+	golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
+	golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
 	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
-	google.golang.org/api v0.59.0
-	google.golang.org/genproto v0.0.0-20211019152133-63b7e35f4404
-	google.golang.org/grpc v1.41.0
+	google.golang.org/api v0.70.0
+	google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf
+	google.golang.org/grpc v1.44.0
 	google.golang.org/protobuf v1.27.1
 )
diff --git a/go.sum b/go.sum
index 485e8bc..526bf81 100644
--- a/go.sum
+++ b/go.sum
@@ -16,7 +16,6 @@
 cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
 cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
 cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
-cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
 cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
 cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
 cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
@@ -24,44 +23,56 @@
 cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
 cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
 cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
-cloud.google.com/go v0.92.2/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
 cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
 cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
-cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8=
 cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
+cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
+cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U=
+cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=
+cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
 cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
 cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
 cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
 cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
 cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
 cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
+cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC29qE3Xmw=
+cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
+cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM=
+cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/errorreporting v0.1.0 h1:z40EhrjRspplwbpO+9DSnC4kgDokBi94T/gYwtdKL5Q=
-cloud.google.com/go/errorreporting v0.1.0/go.mod h1:cZSiBMvrnl0X13pD9DwKf9sQ8Eqy3EzHqkyKBZxiIrM=
-cloud.google.com/go/kms v1.0.0 h1:YkIeqPXqTAlwXk3Z2/WG0d6h1tqJQjU354WftjEoP9E=
-cloud.google.com/go/kms v1.0.0/go.mod h1:nhUehi+w7zht2XrUfvTRNpxrfayBHqP4lu2NSywui/0=
-cloud.google.com/go/monitoring v1.1.0 h1:ZnyNdf/XRcynMmKzRSNTOdOyYPs6G7do1l2D2hIvIKo=
+cloud.google.com/go/errorreporting v0.2.0 h1:b2QhVcl+43FS3qAYuoafNVvqYIc8uDUFeEB7mvFt9C8=
+cloud.google.com/go/errorreporting v0.2.0/go.mod h1:QkYzg92wgpJ0ChLdcO5LhtCEyYwq0tIa+jLrj6Nh5ME=
+cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c=
+cloud.google.com/go/iam v0.1.1 h1:4CapQyNFjiksks1/x7jsvsygFPhihslYk5GptIrlX68=
+cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw=
+cloud.google.com/go/kms v1.1.0 h1:1yc4rLqCkVDS9Zvc7m+3mJ47kw0Uo5Q5+sMjcmUVUeM=
+cloud.google.com/go/kms v1.1.0/go.mod h1:WdbppnCDMDpOvoYBMn1+gNmOeEoZYqAv+HeuKARGCXI=
 cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4=
-cloud.google.com/go/profiler v0.1.1 h1:seMHZtcgOwZXAOKDZuW2sN3u1yKjYG19dUkElb4mbcQ=
-cloud.google.com/go/profiler v0.1.1/go.mod h1:zG22vSCuJKJMvIlLpX3FhNjOsifaoLdPAYc4yLw5Iw4=
+cloud.google.com/go/monitoring v1.3.0 h1:hsJjohhLscxGKXFFUj2AdH+m/jkZ3PyDcprmJ7udj2I=
+cloud.google.com/go/monitoring v1.3.0/go.mod h1:rJAj7Dv+RCZInqdbE9qo32ZEaXgnumNQ1Yx8dXx8Yhg=
+cloud.google.com/go/profiler v0.2.0 h1:TZEKR39niWTuvpak6VNg+D8J5qTzJnyaD1Yl4BOU+d8=
+cloud.google.com/go/profiler v0.2.0/go.mod h1:Rn0g4ZAbYR1sLVP7GAmCZxid4dmtD/nURxcaxf6pngI=
 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
 cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
 cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
 cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
-cloud.google.com/go/pubsub v1.17.1 h1:s2UGTTphpnUQ0Wppkp2OprR4pS3nlBpPvyL2GV9cqdc=
-cloud.google.com/go/pubsub v1.17.1/go.mod h1:4qDxMr1WsM9+aQAz36ltDwCIM+R0QdlseyFjBuNvnss=
+cloud.google.com/go/pubsub v1.18.0 h1:f5HKj3RCujL2zm2cT/Op1mHG1bIDj2fYQ2NDbiAuNAU=
+cloud.google.com/go/pubsub v1.18.0/go.mod h1:Vg6zS1lnXBFiQuHMntX4Id4mKIdsVRjKED4nCVMdMJ8=
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
 cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
 cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
-cloud.google.com/go/storage v1.18.2 h1:5NQw6tOn3eMm0oE8vTkfjau18kjL79FlMjy/CHTpmoY=
 cloud.google.com/go/storage v1.18.2/go.mod h1:AiIj7BWXyhO5gGVmYJ+S8tbkCx3yb0IMjua8Aw4naVM=
+cloud.google.com/go/storage v1.21.0 h1:HwnT2u2D309SFDHQII6m18HlrCi3jAXhUMTLOWXYH14=
+cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKuqnZI01LAA=
 cloud.google.com/go/trace v1.0.0 h1:laKx2y7IWMjguCe5zZx6n7qLtREk4kyE69SXVC0VSN8=
 cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A=
-contrib.go.opencensus.io/exporter/stackdriver v0.13.8 h1:lIFYmQsqejvlq+GobFUbC5F0prD5gvhP6r0gWLZRDq4=
-contrib.go.opencensus.io/exporter/stackdriver v0.13.8/go.mod h1:huNtlWx75MwO7qMs0KrMxPZXzNNWebav1Sq/pm02JdQ=
+contrib.go.opencensus.io/exporter/stackdriver v0.13.10 h1:a9+GZPUe+ONKUwULjlEOucMMG0qfSCCenlji0Nhqbys=
+contrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@@ -96,8 +107,11 @@
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
 github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/cznic/cc v0.0.0-20181122101902-d673e9b70d4d/go.mod h1:m3fD/V+XTB35Kh9zw6dzjMY+We0Q7PMf6LLIC4vuG9k=
@@ -178,10 +192,9 @@
 github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
 github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/gomodule/redigo v1.8.5 h1:nRAxCa+SVsyjSBrtZmG/cqb6VbTmuRzpg/PoTFlpumc=
-github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
+github.com/gomodule/redigo v1.8.8 h1:f6cXq6RRfiyrOJEV7p3JhLDlmawGBVBBP1MggY8Mo4E=
+github.com/gomodule/redigo v1.8.8/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
 github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc=
 github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg=
 github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks=
@@ -201,8 +214,9 @@
 github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
 github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
 github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
 github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
@@ -220,14 +234,13 @@
 github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
 github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0 h1:zHs+jv3LO743/zFGcByu2KmpbliCU2AhjcGgrdTwSG4=
-github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
+github.com/google/pprof v0.0.0-20220113144219-d25a53d42d00 h1:hQb7P4XOakoaN+LET7TJ7PNoBsGm8Tf4lNtAdNwkxDE=
+github.com/google/pprof v0.0.0-20220113144219-d25a53d42d00/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -265,11 +278,9 @@
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
 github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
@@ -318,21 +329,20 @@
 go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
-go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
 go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
 go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
-go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
+go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
+go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
 go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI=
-go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
+go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
+go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
 go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
 golang.org/x/build v0.0.0-20191031202223-0706ea4fce0c h1:jjNoDZTS0vmbqBhqD5MPXauZW+kcGyflfDDFBNCPSVI=
 golang.org/x/build v0.0.0-20191031202223-0706ea4fce0c/go.mod h1:Nl5grlQor/lxfX9FfGLe+g2cVSCiURG36KQgsg/ODs4=
@@ -368,7 +378,6 @@
 golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
 golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
@@ -381,7 +390,6 @@
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -416,14 +424,14 @@
 golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210505214959-0714010a04ed h1:V9kAVxLvz1lkufatrpHuUVyJ/5tR3Ms7rk951P4mI98=
 golang.org/x/net v0.0.0-20210505214959-0714010a04ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
+golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -433,7 +441,6 @@
 golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
@@ -441,8 +448,9 @@
 golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 h1:B333XXssMuKQeBwiNODx4TupZy7bf4sxFZnN2ZOcvUE=
 golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
+golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -490,7 +498,6 @@
 golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -501,15 +508,23 @@
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac h1:oN6lz7iLW/YC7un8pq+9bOLyXrprv2+DKfkJY+2LJJw=
 golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
+golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -517,12 +532,13 @@
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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=
@@ -571,13 +587,11 @@
 golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -602,7 +616,6 @@
 google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
 google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
-google.golang.org/api v0.37.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
 google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
 google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
 google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
@@ -615,8 +628,16 @@
 google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
 google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
 google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E=
-google.golang.org/api v0.59.0 h1:fPfFO7gttlXYo2ALuD3HxJzh8vaF++4youI0BkFL6GE=
 google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
+google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
+google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
+google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSimebM=
+google.golang.org/api v0.65.0/go.mod h1:ArYhxgGadlWmqO1IqVujw6Cs8IdD33bTmzKo2Sh+cbg=
+google.golang.org/api v0.66.0/go.mod h1:I1dmXYpX7HGwz/ejRxwQp2qj5bFAz93HiCU1C1oYd9M=
+google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=
+google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7C80=
+google.golang.org/api v0.70.0 h1:67zQnAE0T2rB0A3CwLSas0K+SbVzSxP+zTLkQLexeiw=
+google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -661,8 +682,6 @@
 google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
@@ -690,8 +709,22 @@
 google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
 google.golang.org/genproto v0.0.0-20211016002631-37fc39342514/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
 google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211019152133-63b7e35f4404 h1:ZB48alYoIN+Soc1OcXirVKYOhOOf6Pek+iN+L+pzQI4=
-google.golang.org/genproto v0.0.0-20211019152133-63b7e35f4404/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220114231437-d2e6a121cae0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220201184016-50beb8ab5c44/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220216160803-4663080d8bc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf h1:SVYXkUz2yZS9FWb2Gm8ivSlbNQzL2Z/NpPKE3RG2jWk=
+google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
 google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -717,8 +750,9 @@
 google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
 google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
 google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
-google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E=
-google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
+google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
+google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg=
+google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@@ -735,7 +769,6 @@
 google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
diff --git a/proto/api/goma_data.pb.go b/proto/api/goma_data.pb.go
index 3483e54..5e6b76a 100644
--- a/proto/api/goma_data.pb.go
+++ b/proto/api/goma_data.pb.go
@@ -7,7 +7,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: api/goma_data.proto
 
 package api
diff --git a/proto/api/goma_log.pb.go b/proto/api/goma_log.pb.go
index 05bc12b..af63833 100644
--- a/proto/api/goma_log.pb.go
+++ b/proto/api/goma_log.pb.go
@@ -6,7 +6,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: api/goma_log.proto
 
 package api
diff --git a/proto/auth/acl.pb.go b/proto/auth/acl.pb.go
index 0a52c08..41180a4 100644
--- a/proto/auth/acl.pb.go
+++ b/proto/auth/acl.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: auth/acl.proto
 
 package auth
diff --git a/proto/auth/auth.pb.go b/proto/auth/auth.pb.go
index e65234e..5194c8f 100644
--- a/proto/auth/auth.pb.go
+++ b/proto/auth/auth.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: auth/auth.proto
 
 package auth
diff --git a/proto/auth/auth_service.pb.go b/proto/auth/auth_service.pb.go
index 6321f14..7f2d823 100644
--- a/proto/auth/auth_service.pb.go
+++ b/proto/auth/auth_service.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: auth/auth_service.proto
 
 package auth
diff --git a/proto/auth/authdb.pb.go b/proto/auth/authdb.pb.go
index 0cad264..6a51a54 100644
--- a/proto/auth/authdb.pb.go
+++ b/proto/auth/authdb.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: auth/authdb.proto
 
 package auth
diff --git a/proto/auth/authdb_service.pb.go b/proto/auth/authdb_service.pb.go
index 652d407..a7b4fd6 100644
--- a/proto/auth/authdb_service.pb.go
+++ b/proto/auth/authdb_service.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: auth/authdb_service.proto
 
 package auth
diff --git a/proto/backend/backend.pb.go b/proto/backend/backend.pb.go
index 7476eb3..f4959bc 100644
--- a/proto/backend/backend.pb.go
+++ b/proto/backend/backend.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: backend/backend.proto
 
 package backend
diff --git a/proto/cache/cache.pb.go b/proto/cache/cache.pb.go
index bc85fd0..f3e0517 100644
--- a/proto/cache/cache.pb.go
+++ b/proto/cache/cache.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: cache/cache.proto
 
 package cache
diff --git a/proto/cache/cache_service.pb.go b/proto/cache/cache_service.pb.go
index 8b96a6c..aa0f0c1 100644
--- a/proto/cache/cache_service.pb.go
+++ b/proto/cache/cache_service.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: cache/cache_service.proto
 
 package cache
diff --git a/proto/command/command.pb.go b/proto/command/command.pb.go
index 7871e62..2d912fa 100644
--- a/proto/command/command.pb.go
+++ b/proto/command/command.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: command/command.proto
 
 package command
diff --git a/proto/command/command_service.pb.go b/proto/command/command_service.pb.go
index c3e8595..32d7f87 100644
--- a/proto/command/command_service.pb.go
+++ b/proto/command/command_service.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: command/command_service.proto
 
 package command
diff --git a/proto/command/package_opts.pb.go b/proto/command/package_opts.pb.go
index 37fab1c..b020710 100644
--- a/proto/command/package_opts.pb.go
+++ b/proto/command/package_opts.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: command/package_opts.proto
 
 package command
diff --git a/proto/command/setup.pb.go b/proto/command/setup.pb.go
index 112d99b..22573a0 100644
--- a/proto/command/setup.pb.go
+++ b/proto/command/setup.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: command/setup.proto
 
 package command
diff --git a/proto/exec/exec_service.pb.go b/proto/exec/exec_service.pb.go
index 5d950ee..6fa07c1 100644
--- a/proto/exec/exec_service.pb.go
+++ b/proto/exec/exec_service.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: exec/exec_service.proto
 
 package exec
diff --git a/proto/execlog/log_service.pb.go b/proto/execlog/log_service.pb.go
index d50edb4..d469cf7 100644
--- a/proto/execlog/log_service.pb.go
+++ b/proto/execlog/log_service.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: execlog/log_service.proto
 
 package execlog
diff --git a/proto/file/file_service.pb.go b/proto/file/file_service.pb.go
index 84fd608..fd5ab5a 100644
--- a/proto/file/file_service.pb.go
+++ b/proto/file/file_service.pb.go
@@ -8,7 +8,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: file/file_service.proto
 
 package file
diff --git a/proto/nsjail/config.pb.go b/proto/nsjail/config.pb.go
index b2812f8..3eaf940 100644
--- a/proto/nsjail/config.pb.go
+++ b/proto/nsjail/config.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: nsjail/config.proto
 
 package nsjail
diff --git a/proto/settings/settings.pb.go b/proto/settings/settings.pb.go
index 70fe00d..0d113c7 100644
--- a/proto/settings/settings.pb.go
+++ b/proto/settings/settings.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: settings/settings.proto
 
 package settings
diff --git a/proto/settings/settings_service.pb.go b/proto/settings/settings_service.pb.go
index 49bbd5e..f27d789 100644
--- a/proto/settings/settings_service.pb.go
+++ b/proto/settings/settings_service.pb.go
@@ -5,7 +5,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.0
+// 	protoc        v3.19.4
 // source: settings/settings_service.proto
 
 package settings
diff --git a/remoteexec/adapter_test.go b/remoteexec/adapter_test.go
index 06b4bb7..8c360ef 100644
--- a/remoteexec/adapter_test.go
+++ b/remoteexec/adapter_test.go
@@ -1273,13 +1273,13 @@
 		t.Errorf("out/Release/run.sh doesn't exist")
 	} else if !runsh.isExecutable {
 		t.Errorf("out/Release/run.sh is not executable")
-	} else if want := digest.Bytes("run.sh", []byte(nsjailHardeningWrapperScript)).Digest(); !proto.Equal(runsh.digest, want) {
+	} else if want := digest.Bytes("run.sh", nsjailHardeningWrapperScript).Digest(); !proto.Equal(runsh.digest, want) {
 		t.Errorf("out/Release/run.sh digest=%s; want=%s", runsh.digest, want)
 	}
 	nsjailCfg, exists := files["out/Release/nsjail.cfg"]
 	if !exists {
 		t.Errorf("out/Release/nsjail.cfg doesn't exist")
-	} else if want := digest.Bytes("nsjail.cfg", []byte(nsjailHardeningConfig)).Digest(); !proto.Equal(nsjailCfg.digest, want) {
+	} else if want := digest.Bytes("nsjail.cfg", nsjailHardeningConfig).Digest(); !proto.Equal(nsjailCfg.digest, want) {
 		t.Errorf("out/Release/nsjail.cfg digest=%s; want=%s", nsjailCfg.digest, want)
 	}
 
diff --git a/remoteexec/exec.go b/remoteexec/exec.go
index 17806e0..ff10af5 100644
--- a/remoteexec/exec.go
+++ b/remoteexec/exec.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"context"
+	_ "embed"
 	"errors"
 	"fmt"
 	"math/rand"
@@ -57,7 +58,8 @@
 	tree        *merkletree.MerkleTree
 	input       gomaInputInterface
 
-	filepath clientFilePath
+	filepath    clientFilePath
+	cmdFilepath clientFilePath
 
 	args         []string
 	envs         []string
@@ -208,9 +210,12 @@
 	}
 	if cmdConfig.GetCmdDescriptor().GetCross().GetWindowsCross() {
 		r.filepath = winpath.FilePath{}
+		r.cmdFilepath = posixpath.FilePath{}
 		// drop .bat suffix
 		// http://b/185210502#comment12
 		cmdFiles[0].Path = strings.TrimSuffix(cmdFiles[0].Path, ".bat")
+	} else {
+		r.cmdFilepath = r.filepath
 	}
 
 	r.cmdConfig = cmdConfig
@@ -600,6 +605,13 @@
 
 	symAbsOk := r.f.capabilities.GetCacheCapabilities().GetSymlinkAbsolutePathStrategy() == rpb.SymlinkAbsolutePathStrategy_ALLOWED
 
+	cmdCleanCWD := cleanCWD
+	cmdCleanRootDir := cleanRootDir
+	if (r.filepath == winpath.FilePath{}) && (r.cmdFilepath == posixpath.FilePath{}) {
+		cmdCleanCWD = winpath.ToPosix(cleanCWD)
+		cmdCleanRootDir = winpath.ToPosix(cleanRootDir)
+	}
+
 	for _, f := range r.cmdFiles {
 		if _, found := toolchainInputs[f.Path]; found {
 			// Must be processed in r.gomaReq.Input. So, skip this.
@@ -619,7 +631,7 @@
 				return nil
 			}
 		}
-		fname, err := rootRel(r.filepath, e.Name, cleanCWD, cleanRootDir)
+		fname, err := rootRel(r.cmdFilepath, e.Name, cmdCleanCWD, cmdCleanRootDir)
 		if err != nil {
 			if err == errOutOfRoot {
 				logger.Warnf("cmd files: out of root: %s", e.Name)
@@ -726,17 +738,12 @@
 	}
 }
 
-const (
+var (
 	// TODO: use working_directory in action.
 	// need to fix output path to be relative to working_directory.
 	// http://b/113370588
-	wrapperScript = `#!/bin/bash
-set -e
-if [[ "$WORK_DIR" != "" ]]; then
-  cd "${WORK_DIR}"
-fi
-exec "$@"
-`
+	//go:embed run.sh
+	wrapperScript []byte
 )
 
 type badRequestError struct {
@@ -828,7 +835,7 @@
 		files = []merkletree.Entry{
 			{
 				Name:         posixWrapperName,
-				Data:         digest.Bytes("nsjail-chroot-run-wrapper-script", []byte(nsjailChrootRunWrapperScript)),
+				Data:         digest.Bytes("nsjail-chroot-run-wrapper-script", nsjailChrootRunWrapperScript),
 				IsExecutable: true,
 			},
 			{
@@ -837,7 +844,7 @@
 			},
 		}
 	case wrapperInputRootAbsolutePath:
-		wrapperData := digest.Bytes("wrapper-script", []byte(wrapperScript))
+		wrapperData := digest.Bytes("wrapper-script", wrapperScript)
 		files, wrapperData = r.maybeApplyHardening(ctx, "InputRootAbsolutePath", files, wrapperData)
 		// https://cloud.google.com/remote-build-execution/docs/remote-execution-properties#container_properties
 		rootDir := r.tree.RootDir()
@@ -862,7 +869,7 @@
 			},
 		}, files...)
 	case wrapperRelocatable:
-		wrapperData := digest.Bytes("wrapper-script", []byte(wrapperScript))
+		wrapperData := digest.Bytes("wrapper-script", wrapperScript)
 		files, wrapperData = r.maybeApplyHardening(ctx, "chdir: relocatble", files, wrapperData)
 		for _, e := range r.gomaReq.Env {
 			if strings.HasPrefix(e, "PWD=") {
@@ -975,12 +982,12 @@
 	} else if rand.Float64() < r.f.HardeningRatio {
 		if rand.Float64() < r.f.NsjailRatio {
 			logger.Infof("run with %s + nsjail", wt)
-			wrapperData = digest.Bytes("nsjail-hardening-wrapper-scrpt", []byte(nsjailHardeningWrapperScript))
+			wrapperData = digest.Bytes("nsjail-hardening-wrapper-scrpt", nsjailHardeningWrapperScript)
 			// needed for nsjail
 			r.addPlatformProperty(ctx, "dockerPrivileged", "true")
 			files = append(files, merkletree.Entry{
 				Name: "nsjail.cfg",
-				Data: digest.Bytes("nsjail.cfg", []byte(nsjailHardeningConfig)),
+				Data: digest.Bytes("nsjail.cfg", nsjailHardeningConfig),
 			})
 		} else {
 			logger.Infof("run with %s + runsc", wt)
diff --git a/remoteexec/fake_cluster_for_test.go b/remoteexec/fake_cluster_for_test.go
index 6a21944..f4126b6 100644
--- a/remoteexec/fake_cluster_for_test.go
+++ b/remoteexec/fake_cluster_for_test.go
@@ -348,6 +348,7 @@
 
 // mustFileHash returns SHA256 hash of file content.
 func (f *fakeLocalFiles) mustFileHash(ctx context.Context, t *testing.T, fname string) string {
+	t.Helper()
 	data, ok := f.m[fname]
 	if !ok {
 		t.Fatalf("%s not found", fname)
diff --git a/remoteexec/nsjail.cfg b/remoteexec/nsjail.cfg
new file mode 100644
index 0000000..eeb5de9
--- /dev/null
+++ b/remoteexec/nsjail.cfg
@@ -0,0 +1,108 @@
+name: "hardening by nsjail (seccomp-bpf)"
+mode: ONCE
+# keep_env = true
+mount_proc: true
+# it runs in docker container, so ok to mount / as RO.
+mount <
+ src: "/"
+ dst: "/"
+ is_bind: true
+ rw: false
+ is_dir: true
+>
+mount <
+ dst: "/tmp"
+ fstype: "tmpfs"
+ options: "size=5000000"
+ rw: true
+ is_dir: true
+>
+# input root is per request, so ok to mount it as RW.
+# (does not affect to other requests).
+mount <
+ prefix_src_env: "INPUT_ROOT"
+ src: ""
+ prefix_dst_env: "INPUT_ROOT"
+ dst: ""
+ is_bind: true
+ rw: true
+ is_dir: true
+>
+# default may fail with "File too large"
+rlimit_fsize_type: INF
+rlimit_as_type: INF
+# syscalls used by clang.
+seccomp_string: "ALLOW {"
+seccomp_string: "  access,"
+seccomp_string: "  alarm,"
+seccomp_string: "  arch_prctl,"
+seccomp_string: "  brk,"
+seccomp_string: "  chdir,"
+seccomp_string: "  clone,"
+seccomp_string: "  close,"
+seccomp_string: "  connect,"
+seccomp_string: "  dup,"
+seccomp_string: "  dup2,"
+seccomp_string: "  epoll_create1,"
+seccomp_string: "  execve,"
+seccomp_string: "  exit_group,"
+seccomp_string: "  fcntl,"
+seccomp_string: "  fstatfs,"
+seccomp_string: "  futex,"
+seccomp_string: "  getcwd,"
+seccomp_string: "  getdents,"
+seccomp_string: "  getdents64,"
+seccomp_string: "  getegid,"
+seccomp_string: "  geteuid,"
+seccomp_string: "  getgid,"
+seccomp_string: "  getpeername,"
+seccomp_string: "  getpgrp,"
+seccomp_string: "  getpid,"
+seccomp_string: "  getppid,"
+seccomp_string: "  getrandom,"
+seccomp_string: "  getrlimit,"
+seccomp_string: "  gettid,"
+seccomp_string: "  getuid,"
+seccomp_string: "  ioctl,"
+seccomp_string: "  lseek,"
+seccomp_string: "  mkdir,"
+seccomp_string: "  mmap,"
+seccomp_string: "  mprotect,"
+seccomp_string: "  mremap,"
+seccomp_string: "  munmap,"
+seccomp_string: "  nanosleep,"
+seccomp_string: "  newfstat,"
+seccomp_string: "  newfstatat,"
+seccomp_string: "  newlstat,"
+seccomp_string: "  newstat,"
+seccomp_string: "  newuname,"
+seccomp_string: "  open,"
+seccomp_string: "  openat,"
+seccomp_string: "  pipe,"
+seccomp_string: "  pipe2,"
+seccomp_string: "  pread64,"
+seccomp_string: "  prlimit64,"
+seccomp_string: "  read,"
+seccomp_string: "  readlink,"
+seccomp_string: "  readlinkat,"
+seccomp_string: "  rename,"
+seccomp_string: "  rt_sigaction,"
+seccomp_string: "  rt_sigprocmask,"
+seccomp_string: "  rt_sigreturn,"
+seccomp_string: "  sched_getaffinity,"
+seccomp_string: "  sched_yield,"
+seccomp_string: "  set_robust_list,"
+seccomp_string: "  set_tid_address,"
+seccomp_string: "  sigaltstack,"
+seccomp_string: "  socket,"
+seccomp_string: "  sysinfo,"
+seccomp_string: "  tgkill,"
+seccomp_string: "  unlink,"
+seccomp_string: "  vfork,"
+seccomp_string: "  wait4,"
+seccomp_string: "  write,"
+seccomp_string: "  writev"
+seccomp_string: "}"
+seccomp_string: "DEFAULT KILL_PROCESS"
+#seccomp_log: true
+iface_no_lo: true
diff --git a/remoteexec/nsjail.go b/remoteexec/nsjail.go
index 9431851..4a1206d 100644
--- a/remoteexec/nsjail.go
+++ b/remoteexec/nsjail.go
@@ -5,6 +5,7 @@
 package remoteexec
 
 import (
+	_ "embed"
 	"fmt"
 	"sort"
 	"strings"
@@ -16,170 +17,22 @@
 	nsjailpb "go.chromium.org/goma/server/proto/nsjail"
 )
 
-const (
-	nsjailHardeningConfig = `
-name: "hardening by nsjail (seccomp-bpf)"
-mode: ONCE
-# keep_env = true
-mount_proc: true
-# it runs in docker container, so ok to mount / as RO.
-mount <
- src: "/"
- dst: "/"
- is_bind: true
- rw: false
- is_dir: true
->
-mount <
- dst: "/tmp"
- fstype: "tmpfs"
- options: "size=5000000"
- rw: true
- is_dir: true
->
-# input root is per request, so ok to mount it as RW.
-# (does not affect to other requests).
-mount <
- prefix_src_env: "INPUT_ROOT"
- src: ""
- prefix_dst_env: "INPUT_ROOT"
- dst: ""
- is_bind: true
- rw: true
- is_dir: true
->
-# default may fail with "File too large"
-rlimit_fsize_type: INF
-rlimit_as_type: INF
-# syscalls used by clang.
-seccomp_string: "ALLOW {"
-seccomp_string: "  access,"
-seccomp_string: "  alarm,"
-seccomp_string: "  arch_prctl,"
-seccomp_string: "  brk,"
-seccomp_string: "  clone,"
-seccomp_string: "  close,"
-seccomp_string: "  connect,"
-seccomp_string: "  dup2,"
-seccomp_string: "  execve,"
-seccomp_string: "  exit_group,"
-seccomp_string: "  fcntl,"
-seccomp_string: "  fstatfs,"
-seccomp_string: "  futex,"
-seccomp_string: "  getcwd,"
-seccomp_string: "  getdents,"
-seccomp_string: "  getdents64,"
-seccomp_string: "  getegid,"
-seccomp_string: "  geteuid,"
-seccomp_string: "  getgid,"
-seccomp_string: "  getpgrp,"
-seccomp_string: "  getpid,"
-seccomp_string: "  getppid,"
-seccomp_string: "  getrlimit,"
-seccomp_string: "  gettid,"
-seccomp_string: "  getuid,"
-seccomp_string: "  ioctl,"
-seccomp_string: "  lseek,"
-seccomp_string: "  mmap,"
-seccomp_string: "  mprotect,"
-seccomp_string: "  mremap,"
-seccomp_string: "  munmap,"
-seccomp_string: "  newfstat,"
-seccomp_string: "  newlstat,"
-seccomp_string: "  newstat,"
-seccomp_string: "  newuname,"
-seccomp_string: "  open,"
-seccomp_string: "  openat,"
-seccomp_string: "  pipe,"
-seccomp_string: "  pipe2,"
-seccomp_string: "  pread64,"
-seccomp_string: "  prlimit64,"
-seccomp_string: "  read,"
-seccomp_string: "  readlink,"
-seccomp_string: "  rename,"
-seccomp_string: "  rt_sigaction,"
-seccomp_string: "  rt_sigprocmask,"
-seccomp_string: "  rt_sigreturn, "
-seccomp_string: "  set_robust_list,"
-seccomp_string: "  set_tid_address,"
-seccomp_string: "  sigaltstack,"
-seccomp_string: "  socket,"
-seccomp_string: "  sysinfo,"
-seccomp_string: "  unlink,"
-seccomp_string: "  vfork,"
-seccomp_string: "  wait4,"
-seccomp_string: "  write,"
-seccomp_string: "  writev"
-seccomp_string: "}"
-seccomp_string: "DEFAULT KILL"
-#seccomp_log: true
-iface_no_lo: true
-`
-	nsjailHardeningWrapperScript = `#!/bin/bash
-export INPUT_ROOT="$(pwd)"
-if [[ "$WORK_DIR" != "" ]]; then
-  cd "${WORK_DIR}"
-fi
-export PWD="$(pwd)"
-# exit 159 -> seccomp violation
-nsjail -q -C "./nsjail.cfg" --cwd "$PWD" \
-       --  \
-       "$@"
-`
+var (
+	//go:embed nsjail.cfg
+	nsjailHardeningConfig []byte
 
-	nsjailChrootRunWrapperScript = `#!/bin/bash
-set -e
+	//go:embed nsjail_run.sh
+	nsjailHardeningWrapperScript []byte
 
-if [[ "$WORK_DIR" == "" ]]; then
-  echo "ERROR: WORK_DIR is not set" >&2
-  exit 1
-fi
-
-rundir="$(pwd)"
-chroot_workdir="/tmp/goma_chroot"
-
-#
-# mount directories under $chroot_workdir and execute.
-#
-run_dirs=($(ls -1 "$rundir"))
-sys_dirs=(dev proc)
-
-# RBE server generates __action_home__XXXXXXXXXX directory in $rundir
-# (note: XXXXXXXXXX is a random).  Let's skip it because we do not use that.
-# mount directories in the request.
-for d in "${run_dirs[@]}"; do
-  if [[ "$d" == __action_home__* ]]; then
-    continue
-  fi
-  mkdir -p "$chroot_workdir/$d"
-  mount --bind "$rundir/$d" "$chroot_workdir/$d"
-done
-
-# mount directories not included in the request.
-for d in "${sys_dirs[@]}"; do
-  # avoid to mount system directories if that exist in the user's request.
-  if [[ -d "$rundir/$d" ]]; then
-    continue
-  fi
-  # directory will be mounted by nsjail later.
-  mkdir -p "$chroot_workdir/$d"
-done
-# needed to make nsjail bind device files.
-touch "$chroot_workdir/dev/urandom"
-touch "$chroot_workdir/dev/null"
-
-# currently running with root. run the command with nobody:nogroup with chroot.
-# We use nsjail to chdir without running bash script inside chroot, and
-# libc inside chroot can be different from libc outside.
-nsjail --quiet --config "$WORK_DIR/nsjail.cfg" -- "$@"
-`
+	//go:embed nsjail_chroot_run.sh
+	nsjailChrootRunWrapperScript []byte
 )
 
 var seccompString []string
 
 func init() {
 	m := &nsjailpb.NsJailConfig{}
-	err := prototext.Unmarshal([]byte(nsjailHardeningConfig), m)
+	err := prototext.Unmarshal(nsjailHardeningConfig, m)
 	if err != nil {
 		panic(fmt.Errorf("bad nsjailHardeningConfig: %v", err))
 	}
diff --git a/remoteexec/nsjail_chroot_run.sh b/remoteexec/nsjail_chroot_run.sh
new file mode 100755
index 0000000..218975b
--- /dev/null
+++ b/remoteexec/nsjail_chroot_run.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+set -e
+
+if [[ "$WORK_DIR" == "" ]]; then
+  echo "ERROR: WORK_DIR is not set" >&2
+  exit 1
+fi
+
+rundir="$(pwd)"
+chroot_workdir="/tmp/goma_chroot"
+
+#
+# mount directories under $chroot_workdir and execute.
+#
+run_dirs=($(ls -1 "$rundir"))
+sys_dirs=(dev proc)
+
+# RBE server generates __action_home__XXXXXXXXXX directory in $rundir
+# (note: XXXXXXXXXX is a random).  Let's skip it because we do not use that.
+# mount directories in the request.
+for d in "${run_dirs[@]}"; do
+  if [[ "$d" == __action_home__* ]]; then
+    continue
+  fi
+  mkdir -p "$chroot_workdir/$d"
+  mount --bind "$rundir/$d" "$chroot_workdir/$d"
+done
+
+# mount directories not included in the request.
+for d in "${sys_dirs[@]}"; do
+  # avoid to mount system directories if that exist in the user's request.
+  if [[ -d "$rundir/$d" ]]; then
+    continue
+  fi
+  # directory will be mounted by nsjail later.
+  mkdir -p "$chroot_workdir/$d"
+done
+# needed to make nsjail bind device files.
+touch "$chroot_workdir/dev/urandom"
+touch "$chroot_workdir/dev/null"
+
+# currently running with root. run the command with nobody:nogroup with chroot.
+# We use nsjail to chdir without running bash script inside chroot, and
+# libc inside chroot can be different from libc outside.
+nsjail --quiet --config "$WORK_DIR/nsjail.cfg" -- "$@"
diff --git a/remoteexec/nsjail_run.sh b/remoteexec/nsjail_run.sh
new file mode 100755
index 0000000..283a55d
--- /dev/null
+++ b/remoteexec/nsjail_run.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+export INPUT_ROOT="$(pwd)"
+if [[ "$WORK_DIR" != "" ]]; then
+  cd "${WORK_DIR}"
+fi
+export PWD="$(pwd)"
+# exit 159 -> seccomp violation
+nsjail -q -C "./nsjail.cfg" --cwd "$PWD" \
+       --  \
+       "$@"
diff --git a/remoteexec/nsjail_test.go b/remoteexec/nsjail_test.go
index 5caa88a..891635f 100644
--- a/remoteexec/nsjail_test.go
+++ b/remoteexec/nsjail_test.go
@@ -136,7 +136,7 @@
 
 func TestNsjailHardeningConfig(t *testing.T) {
 	cfg := &nsjailpb.NsJailConfig{}
-	err := prototext.Unmarshal([]byte(nsjailHardeningConfig), cfg)
+	err := prototext.Unmarshal(nsjailHardeningConfig, cfg)
 	if err != nil {
 		t.Errorf("unmarshal\n%s\n => %v", nsjailHardeningConfig, err)
 	}
diff --git a/remoteexec/run.sh b/remoteexec/run.sh
new file mode 100755
index 0000000..3f2e8e3
--- /dev/null
+++ b/remoteexec/run.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -e
+if [[ "$WORK_DIR" != "" ]]; then
+  cd "${WORK_DIR}"
+fi
+exec "$@"