Skip to content

Commit

Permalink
feat: replace jq with gojq (#10469)
Browse files Browse the repository at this point in the history
  • Loading branch information
johejo committed Feb 11, 2023
1 parent b444440 commit 9cb3fc6
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 14 deletions.
4 changes: 0 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ RUN --mount=type=cache,target=/root/.yarn \

FROM builder as argoexec-build

RUN curl -L -o /usr/local/bin/jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 && \
chmod +x /usr/local/bin/jq

# Tell git to forget about all of the files that were not included because of .dockerignore in order to ensure that
# the git state is "clean" even though said .dockerignore files are not present
RUN cat .dockerignore >> .gitignore
Expand Down Expand Up @@ -87,7 +84,6 @@ FROM bitnami/kubectl:1.24.8 as kubectl
FROM gcr.io/distroless/static as argoexec

COPY --from=kubectl /opt/bitnami/kubectl/bin/kubectl /bin/
COPY --from=argoexec-build /usr/local/bin/jq /bin/
COPY --from=argoexec-build /go/src/github.com/argoproj/argo-workflows/dist/argoexec /bin/
COPY --from=argoexec-build /etc/mime.types /etc/mime.types
COPY hack/ssh_known_hosts /etc/ssh/
Expand Down
4 changes: 1 addition & 3 deletions Dockerfile.windows
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,9 @@ COPY --from=builder /windows/system32/netapi32.dll /windows/system32/netapi32.dl

# NOTE: kubectl version should be one minor version less than https://storage.googleapis.com/kubernetes-release/release/stable.txt
ENV KUBECTL_VERSION=1.24.8
ENV JQ_VERSION=1.6

RUN mkdir C:\app && \
curl -L -o C:\app\kubectl.exe "https://storage.googleapis.com/kubernetes-release/release/v%KUBECTL_VERSION%/bin/windows/amd64/kubectl.exe" && \
curl -L -o C:\app\jq.exe "https://github.com/stedolan/jq/releases/download/jq-%JQ_VERSION%/jq-win64.exe"
curl -L -o C:\app\kubectl.exe "https://storage.googleapis.com/kubernetes-release/release/v%KUBECTL_VERSION%/bin/windows/amd64/kubectl.exe"

COPY --from=builder C:/ProgramData/chocolatey/lib/7zip.portable/tools/7z-extra/x64/7za.exe C:/app/7za.exe

Expand Down
1 change: 0 additions & 1 deletion docs/running-locally.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ Note:
* [Yarn](https://classic.yarnpkg.com/en/docs/install/#mac-stable)
* [Docker](https://docs.docker.com/get-docker/)
* [`protoc`](http:https://google.github.io/proto-lens/installing-protoc.html)
* [`jq`](https://stedolan.github.io/jq/download/)
* [`node` >= 16.15.0](https://nodejs.org/download/release/latest-v16.x/) for running the UI
* A local Kubernetes cluster ([`k3d`](https://k3d.io/), [`kind`](https://kind.sigs.k8s.io/docs/user/quick-start/#installation), or [`minikube`](https://minikube.sigs.k8s.io/docs/start/))

Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/itchyny/gojq v0.12.11
github.com/klauspost/pgzip v1.2.5
github.com/minio/minio-go/v7 v7.0.47
github.com/pkg/errors v0.9.1
Expand Down Expand Up @@ -149,6 +150,7 @@ require (
github.com/imdario/mergo v0.3.13 // indirect
github.com/imkira/go-interpol v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/itchyny/timefmt-go v0.1.5 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jcmturner/gofork v1.0.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,10 @@ github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/itchyny/gojq v0.12.11 h1:YhLueoHhHiN4mkfM+3AyJV6EPcCxKZsOnYf+aVSwaQw=
github.com/itchyny/gojq v0.12.11/go.mod h1:o3FT8Gkbg/geT4pLI0tF3hvip5F3Y/uskjRz9OYa38g=
github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE=
github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jcmturner/gofork v0.0.0-20180107083740-2aebee971930/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
Expand Down
42 changes: 36 additions & 6 deletions workflow/executor/resource.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package executor

import (
"bytes"
"context"
"encoding/json"
"fmt"
Expand All @@ -11,6 +10,7 @@ import (
"strings"
"time"

"github.com/itchyny/gojq"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
apierr "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -311,14 +311,11 @@ func (we *WorkflowExecutor) SaveResourceParameters(ctx context.Context, resource
}
output := string(out)
if param.ValueFrom.JQFilter != "" {
jq := exec.Command("jq", "-rc", param.ValueFrom.JQFilter)
jq.Stdin = bytes.NewBuffer(out)
out, err := jq.Output()
log.WithError(err).WithField("out", string(out)).WithField("args", jq.Args).Info("jq")
output, err = jqFilter(ctx, out, param.ValueFrom.JQFilter)
log.WithError(err).WithField("out", string(out)).WithField("filter", param.ValueFrom.JQFilter).Info("gojq")
if err != nil {
return err
}
output = strings.TrimSpace(string(out))
}

we.Template.Outputs.Parameters[i].Value = wfv1.AnyStringPtr(output)
Expand All @@ -327,3 +324,36 @@ func (we *WorkflowExecutor) SaveResourceParameters(ctx context.Context, resource
err := we.reportOutputs(ctx, nil)
return err
}

func jqFilter(ctx context.Context, input []byte, filter string) (string, error) {
var v interface{}
if err := json.Unmarshal(input, &v); err != nil {
return "", err
}
q, err := gojq.Parse(filter)
if err != nil {
return "", err
}
iter := q.RunWithContext(ctx, v)
var buf strings.Builder
for {
v, ok := iter.Next()
if !ok {
break
}
if err, ok := v.(error); ok {
return "", err
}
if s, ok := v.(string); ok {
buf.WriteString(s)
} else {
b, err := json.Marshal(v)
if err != nil {
return "", err
}
buf.Write(b)
}
buf.WriteString("\n")
}
return strings.TrimSpace(buf.String()), nil
}
19 changes: 19 additions & 0 deletions workflow/executor/resource_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package executor

import (
"context"
"io/ioutil"
"os"
"path"
Expand Down Expand Up @@ -217,3 +218,21 @@ func TestResourceExecRetry(t *testing.T) {
assert.Error(t, err)
assert.Equal(t, "no more retries i/o timeout", err.Error())
}

func Test_jqFilter(t *testing.T) {
for _, testCase := range []struct {
input []byte
filter string
want string
}{
{[]byte(`{"metadata": {"name": "foo"}}`), ".metadata.name", "foo"},
{[]byte(`{"items": [{"key": "foo"}, {"key": "bar"}]}`), ".items.[].key", "foo\nbar"},
} {
t.Run(string(testCase.input), func(t *testing.T) {
ctx := context.Background()
got, err := jqFilter(ctx, testCase.input, testCase.filter)
assert.NoError(t, err)
assert.Equal(t, testCase.want, got)
})
}
}

0 comments on commit 9cb3fc6

Please sign in to comment.