...

Text file src/github.com/linkerd/linkerd2/justfile

Documentation: github.com/linkerd/linkerd2

     1# See https://just.systems/man/en
     2
     3lint: action-lint action-dev-check md-lint sh-lint rs-fetch rs-clippy rs-check-fmt go-lint
     4
     5##
     6## Go
     7##
     8
     9export GO111MODULE := "on"
    10
    11go-fetch:
    12    go mod download
    13
    14go-fmt *flags:
    15    bin/fmt {{ flags }}
    16
    17go-lint *flags:
    18    golangci-lint run {{ flags }}
    19
    20go-test:
    21    LINKERD_TEST_PRETTY_DIFF=1 gotestsum -- -race -v -mod=readonly ./...
    22
    23##
    24## Rust
    25##
    26
    27# By default we compile in development mode mode because it's faster.
    28rs-build-type := if env_var_or_default("RELEASE", "") == "" { "debug" } else { "release" }
    29
    30# Overriddes the default Rust toolchain version.
    31rs-toolchain := ""
    32
    33rs-features := 'all'
    34
    35_cargo := "cargo" + if rs-toolchain != "" { " +" + rs-toolchain } else { "" }
    36
    37# Fetch Rust dependencies.
    38rs-fetch:
    39    {{ _cargo }} fetch --locked
    40
    41# Format Rust code.
    42rs-fmt:
    43    {{ _cargo }} fmt --all
    44
    45# Check that the Rust code is formatted correctly.
    46rs-check-fmt:
    47    {{ _cargo }} fmt --all -- --check
    48
    49# Lint Rust code.
    50rs-clippy:
    51    {{ _cargo }} clippy --frozen --workspace --all-targets --no-deps {{ _features }} {{ _fmt }}
    52
    53alias clippy := rs-clippy
    54
    55# Audit Rust dependencies.
    56rs-audit-deps:
    57    {{ _cargo }} deny {{ _features }} check
    58
    59# Generate Rust documentation.
    60rs-doc *flags:
    61    {{ _cargo }} doc --frozen \
    62        {{ if rs-build-type == "release" { "--release" } else { "" } }} \
    63        {{ _features }} \
    64        {{ flags }}
    65
    66rs-test-build:
    67    {{ _cargo-test }} --no-run --frozen \
    68        --workspace --exclude=linkerd-policy-test \
    69        {{ _features }}
    70
    71# Run Rust unit tests
    72rs-test *flags:
    73    {{ _cargo-test }} --frozen \
    74        --workspace --exclude=linkerd-policy-test \
    75        {{ if rs-build-type == "release" { "--release" } else { "" } }} \
    76        {{ _features }} \
    77        {{ flags }}
    78
    79# Check each crate independently to ensure its Cargo.toml is sufficient.
    80rs-check-dirs:
    81    #!/usr/bin/env bash
    82    set -euo pipefail
    83    while IFS= read -r toml ; do
    84        {{ just_executable() }} \
    85            rs-build-type='{{ rs-build-type }}' \
    86            rs-features='{{ rs-features }}' \
    87            rs-toolchain='{{ rs-toolchain }}' \
    88            _rs-check-dir "${toml%/*}"
    89        {{ just_executable() }} \
    90            rs-build-type='{{ rs-build-type }}' \
    91            rs-features='{{ rs-features }}' \
    92            rs-toolchain='{{ rs-toolchain }}' \
    93            _rs-check-dir "${toml%/*}" --tests
    94    done < <(find . -mindepth 2 -name Cargo.toml | sort -r)
    95
    96_rs-check-dir dir *flags:
    97    cd {{ dir }} \
    98        && {{ _cargo }} check --frozen \
    99                {{ if rs-build-type == "release" { "--release" } else { "" } }} \
   100                {{ _features }} \
   101                {{ flags }} \
   102                {{ _fmt }}
   103
   104# If we're running in github actions and cargo-action-fmt is installed, then add
   105# a command suffix that formats errors.
   106_fmt := if env_var_or_default("GITHUB_ACTIONS", "") != "true" { "" } else {
   107    ```
   108    if command -v cargo-action-fmt >/dev/null 2>&1; then
   109        echo "--message-format=json | cargo-action-fmt"
   110    fi
   111    ```
   112}
   113
   114# Configures which features to enable when invoking cargo commands.
   115_features := if rs-features == "all" {
   116        "--all-features"
   117    } else if rs-features != "" {
   118        "--no-default-features --features=" + rs-features
   119    } else { "" }
   120
   121# Use cargo-nextest if it is available. It may not be available when running
   122# outside of the devcontainer.
   123_cargo-test := _cargo + ```
   124    if command -v cargo-nextest >/dev/null 2>&1 ; then
   125        echo " nextest run"
   126    else
   127        echo " test"
   128    fi
   129    ```
   130
   131##
   132## Policy integration tests
   133##
   134
   135export POLICY_TEST_CONTEXT := env_var_or_default("POLICY_TEST_CONTEXT", "k3d-" + k3d-name)
   136
   137# Install linkerd in the test cluster and run the policy tests.
   138policy-test: linkerd-install policy-test-deps-load policy-test-run && policy-test-cleanup linkerd-uninstall
   139
   140# Run the policy tests without installing linkerd.
   141policy-test-run *flags:
   142    cd policy-test && {{ _cargo-test }} {{ flags }}
   143
   144# Build the policy tests without running them.
   145policy-test-build:
   146    cd policy-test && {{ _cargo-test }} --no-run
   147
   148# Delete all test namespaces and remove linkerd from the cluster.
   149policy-test-cleanup:
   150    {{ _kubectl }} delete ns --selector='linkerd-policy-test'
   151    @while [ $({{ _kubectl }} get ns --selector='linkerd-policy-test' -o json |jq '.items | length') != "0" ]; do sleep 1 ; done
   152
   153policy-test-deps-pull:
   154    docker pull -q docker.io/bitnami/kubectl:latest
   155    docker pull -q docker.io/curlimages/curl:latest
   156    docker pull -q ghcr.io/olix0r/hokay:latest
   157
   158# Load all images into the test cluster.
   159policy-test-deps-load: _k3d-init policy-test-deps-pull
   160    for i in {1..3} ; do {{ _k3d-load }} \
   161        bitnami/kubectl:latest \
   162        curlimages/curl:latest \
   163        ghcr.io/olix0r/hokay:latest && exit ; sleep 1 ; done
   164
   165##
   166## Test cluster
   167##
   168
   169# The name of the k3d cluster to use.
   170k3d-name := "l5d-test"
   171
   172# The name of the docker network to use (i.e., for multicluster testing).
   173k3d-network := "k3d-name"
   174
   175# The kubernetes version to use for the test cluster. e.g. 'v1.24', 'latest', etc
   176k3d-k8s := "latest"
   177
   178k3d-agents := "0"
   179k3d-servers := "1"
   180
   181_k3d-flags := "--no-lb --k3s-arg --disable='local-storage,traefik,servicelb,metrics-server@server:*'"
   182
   183_context := "--context=k3d-" + k3d-name
   184_kubectl := "kubectl " + _context
   185
   186_k3d-load := "k3d image import --mode=direct --cluster=" + k3d-name
   187
   188# Run kubectl with the test cluster context.
   189k *flags:
   190    {{ _kubectl }} {{ flags }}
   191
   192# Creates a k3d cluster that can be used for testing.
   193k3d-create: && _k3d-ready
   194    k3d cluster create {{ k3d-name }} \
   195        --image='+{{ k3d-k8s }}' \
   196        --agents='{{ k3d-agents }}' \
   197        --servers='{{ k3d-servers }}' \
   198        --network='{{ k3d-network }}' \
   199        {{ _k3d-flags }} \
   200        --kubeconfig-update-default \
   201        --kubeconfig-switch-context=false
   202
   203# Deletes the test cluster.
   204k3d-delete:
   205    k3d cluster delete {{ k3d-name }}
   206
   207# Print information the test cluster's detailed status.
   208k3d-info:
   209    k3d cluster list {{ k3d-name }} -o json | jq .
   210
   211# Set the default kubectl context to the test cluster.
   212k3d-use:
   213    k3d kubeconfig merge {{ k3d-name }} \
   214        --kubeconfig-merge-default \
   215        --kubeconfig-switch-context=true \
   216        >/dev/null
   217
   218# Ensures the test cluster has been initialized.
   219_k3d-init: && _k3d-ready
   220    #!/usr/bin/env bash
   221    set -euo pipefail
   222    if ! k3d cluster list {{ k3d-name }} >/dev/null 2>/dev/null; then
   223        {{ just_executable() }} \
   224            k3d-k8s='{{ k3d-k8s }}' \
   225            k3d-name='{{ k3d-name }}' \
   226            k3d-network='{{ k3d-network }}' \
   227            _k3d-flags='{{ _k3d-flags }}' \
   228            k3d-create
   229    fi
   230    k3d kubeconfig merge {{ k3d-name }} \
   231        --kubeconfig-merge-default \
   232        --kubeconfig-switch-context=false \
   233        >/dev/null
   234
   235_k3d-ready: _k3d-api-ready _k3d-dns-ready
   236
   237# Wait for the cluster's API server to be accessible
   238_k3d-api-ready:
   239    #!/usr/bin/env bash
   240    set -euo pipefail
   241    for i in {1..6} ; do
   242        if {{ _kubectl }} cluster-info >/dev/null ; then exit 0 ; fi
   243        sleep 10
   244    done
   245    exit 1
   246
   247# Wait for the cluster's DNS pods to be ready.
   248_k3d-dns-ready:
   249    while [ $({{ _kubectl }} get po -n kube-system -l k8s-app=kube-dns -o json |jq '.items | length') = "0" ]; do sleep 1 ; done
   250    {{ _kubectl }} wait pod --for=condition=ready \
   251        --namespace=kube-system --selector=k8s-app=kube-dns \
   252        --timeout=1m
   253
   254##
   255## Docker images
   256##
   257
   258# If DOCKER_REGISTRY is not already set, use a bogus registry with a unique
   259# name so that it's virtually impossible to accidentally use an incorrect image.
   260export DOCKER_REGISTRY := env_var_or_default("DOCKER_REGISTRY", "test.l5d.io/" + _test-id )
   261_test-id := `tr -dc 'a-z0-9' </dev/urandom | fold -w 5 | head -n 1`
   262
   263# The docker image tag.
   264linkerd-tag := `bin/root-tag`
   265
   266docker-arch := ''
   267
   268_pause-load: _k3d-init
   269    #!/usr/bin/env bash
   270    set -euo pipefail
   271    img="$(yq .gateway.pauseImage multicluster/charts/linkerd-multicluster/values.yaml)"
   272    if [ -z "$(docker image ls -q "$img")" ]; then
   273       docker pull -q "$img"
   274    fi
   275    k3d image import --mode=direct --cluster='{{ k3d-name }}' "$img"
   276
   277##
   278## Linkerd CLI
   279##
   280
   281# The Linkerd CLI binary.
   282linkerd-exec := "bin/linkerd"
   283_linkerd := linkerd-exec + " " + _context
   284
   285controller-image := DOCKER_REGISTRY + "/controller"
   286proxy-image := DOCKER_REGISTRY + "/proxy"
   287policy-controller-image := DOCKER_REGISTRY + "/policy-controller"
   288
   289# External dependencies
   290#
   291# We execute these commands lazily in case `yq` isn't present (so that other
   292# just recipes can succeed).
   293_proxy-init-image-cmd := "yq '.proxyInit.image | \"ghcr.io/linkerd/proxy-init:\" + .version' charts/linkerd-control-plane/values.yaml"
   294_cni-plugin-image-cmd := "yq '.image | \"ghcr.io/linkerd/cni-plugin:\" + .version' charts/linkerd2-cni/values.yaml"
   295_prometheus-image-cmd := "yq '.prometheus.image | .registry + \"/\" + .name + \":\" + .tag'  viz/charts/linkerd-viz/values.yaml"
   296
   297linkerd *flags:
   298    {{ _linkerd }} {{ flags }}
   299
   300# Install crds on the test cluster.
   301linkerd-crds-install: _k3d-init
   302    {{ _linkerd }} install --crds \
   303        | {{ _kubectl }} apply -f -
   304    {{ _kubectl }} wait crd --for condition=established \
   305        --selector='linkerd.io/control-plane-ns' \
   306        --timeout=1m
   307
   308# Install linkerd on the test cluster using test images.
   309linkerd-install *args='': linkerd-load linkerd-crds-install && _linkerd-ready
   310    {{ _linkerd }} install \
   311            --set='imagePullPolicy=Never' \
   312            --set='controllerImage={{ controller-image }}' \
   313            --set='linkerdVersion={{ linkerd-tag }}' \
   314            --set='policyController.image.name={{ policy-controller-image }}' \
   315            --set='policyController.image.version={{ linkerd-tag }}' \
   316            --set='policyController.loglevel=info\,linkerd=trace\,kubert=trace' \
   317            --set='proxy.image.name={{ proxy-image }}' \
   318            --set='proxy.image.version={{ linkerd-tag }}' \
   319            --set='proxyInit.image.name=ghcr.io/linkerd/proxy-init' \
   320            {{ args }} \
   321        | {{ _kubectl }} apply -f -
   322
   323# Wait for all test namespaces to be removed before uninstalling linkerd from the cluster.
   324linkerd-uninstall:
   325    {{ _linkerd }} uninstall \
   326        | {{ _kubectl }} delete -f -
   327
   328linkerd-load: _linkerd-images _k3d-init
   329    for i in {1..3} ; do {{ _k3d-load }} \
   330        '{{ controller-image }}:{{ linkerd-tag }}' \
   331        '{{ policy-controller-image }}:{{ linkerd-tag }}' \
   332        '{{ proxy-image }}:{{ linkerd-tag }}' \
   333        $({{ _proxy-init-image-cmd }}) && exit ; sleep 1 ; done
   334
   335linkerd-load-cni:
   336    docker pull -q $({{ _cni-plugin-image-cmd }})
   337    {{ _k3d-load }} $({{ _cni-plugin-image-cmd }})
   338
   339linkerd-build: _policy-controller-build
   340    TAG={{ linkerd-tag }} bin/docker-build-controller
   341    TAG={{ linkerd-tag }} bin/docker-build-proxy
   342
   343_linkerd-images:
   344    #!/usr/bin/env bash
   345    set -xeuo pipefail
   346    docker pull -q $({{ _proxy-init-image-cmd }})
   347    for img in \
   348        '{{ controller-image }}:{{ linkerd-tag }}' \
   349        '{{ policy-controller-image }}:{{ linkerd-tag }}' \
   350        '{{ proxy-image }}:{{ linkerd-tag }}'
   351    do
   352        if [ -z $(docker image ls -q "$img") ]; then
   353            # Build images if any one of the images is missing.
   354            exec {{ just_executable() }} \
   355                controller-image='{{ controller-image }}' \
   356                policy-controller-image='{{ policy-controller-image }}' \
   357                linkerd-tag='{{ linkerd-tag }}' \
   358                linkerd-build
   359        fi
   360    done
   361
   362# Build the policy controller docker image for testing (on amd64).
   363_policy-controller-build:
   364    docker buildx build . \
   365        --file='policy-controller/Dockerfile' \
   366        --platform={{ if docker-arch == '' { "amd64" } else { docker-arch} }} \
   367        --build-arg='build_type={{ rs-build-type }}' \
   368        --tag='{{ policy-controller-image }}:{{ linkerd-tag }}' \
   369        --progress=plain \
   370        --load
   371
   372_linkerd-ready:
   373    if ! {{ _kubectl }} wait pod --for=condition=ready \
   374            --namespace=linkerd --selector='linkerd.io/control-plane-component' \
   375            --timeout=1m ; then \
   376        {{ _kubectl }} describe pods --namespace=linkerd ; \
   377    fi
   378
   379# Ensure that a linkerd control plane is installed
   380_linkerd-init: && _linkerd-ready
   381    #!/usr/bin/env bash
   382    set -euo pipefail
   383    if ! {{ _kubectl }} get ns linkerd >/dev/null 2>&1 ; then
   384        {{ just_executable() }} \
   385            k3d-name='{{ k3d-name }}' \
   386            k3d-k8s='{{ k3d-k8s }}' \
   387            k3d-agents='{{ k3d-agents }}' \
   388            k3d-servers='{{ k3d-servers }}' \
   389            k3d-network='{{ k3d-network }}' \
   390            _k3d-flags='{{ _k3d-flags }}' \
   391            linkerd-tag='{{ linkerd-tag }}' \
   392            controller-image='{{ controller-image }}' \
   393            proxy-image='{{ proxy-image }}' \
   394            linkerd-exec='{{ linkerd-exec }}' \
   395            linkerd-install
   396    fi
   397
   398##
   399## linkerd viz
   400##
   401
   402linkerd-viz *flags: _k3d-init
   403    {{ _linkerd }} viz {{ flags }}
   404
   405linkerd-viz-install: _linkerd-init linkerd-viz-load && _linkerd-viz-ready
   406    {{ _linkerd }} viz install \
   407            --set='defaultRegistry={{ DOCKER_REGISTRY }}' \
   408            --set='linkerdVersion={{ linkerd-tag }}' \
   409            --set='defaultImagePullPolicy=Never' \
   410        | {{ _kubectl }} apply -f -
   411
   412# Wait for all test namespaces to be removed before uninstalling linkerd from the cluster.
   413linkerd-viz-uninstall:
   414    {{ _linkerd }} viz uninstall \
   415        | {{ _kubectl }} delete -f -
   416
   417_linkerd-viz-images:
   418    #!/usr/bin/env bash
   419    set -euo pipefail
   420    docker pull -q $({{ _prometheus-image-cmd }})
   421    for img in \
   422        '{{ DOCKER_REGISTRY }}/metrics-api:{{ linkerd-tag }}' \
   423        '{{ DOCKER_REGISTRY }}/tap:{{ linkerd-tag }}' \
   424        '{{ DOCKER_REGISTRY }}/web:{{ linkerd-tag }}'
   425    do
   426        if [ -z $(docker image ls -q "$img") ]; then
   427            echo "Missing image: $img" >&2
   428            exec {{ just_executable() }} \
   429                linkerd-tag='{{ linkerd-tag }}' \
   430                linkerd-viz-build
   431        fi
   432    done
   433
   434linkerd-viz-load: _linkerd-viz-images _k3d-init
   435    for i in {1..3} ; do {{ _k3d-load }} \
   436        {{ DOCKER_REGISTRY }}/metrics-api:{{ linkerd-tag }} \
   437        {{ DOCKER_REGISTRY }}/tap:{{ linkerd-tag }} \
   438        {{ DOCKER_REGISTRY }}/web:{{ linkerd-tag }} \
   439        $({{ _prometheus-image-cmd }}) && exit ; sleep 1 ; done
   440
   441linkerd-viz-build:
   442    TAG={{ linkerd-tag }} bin/docker-build-metrics-api
   443    TAG={{ linkerd-tag }} bin/docker-build-tap
   444    TAG={{ linkerd-tag }} bin/docker-build-web
   445
   446_linkerd-viz-ready:
   447    {{ _kubectl }} wait pod --for=condition=ready \
   448        --namespace=linkerd-viz --selector='linkerd.io/extension=viz' \
   449        --timeout=1m
   450
   451# Ensure that a linkerd control plane is installed
   452_linkerd-viz-uninit:
   453    #!/usr/bin/env bash
   454    set -euo pipefail
   455    if {{ _kubectl }} get ns linkerd-viz >/dev/null 2>&1 ; then
   456        {{ just_executable() }} \
   457            k3d-name='{{ k3d-name }}' \
   458            linkerd-exec='{{ linkerd-exec }}' \
   459            linkerd-viz-uninstall
   460    fi
   461
   462# TODO linkerd-jaeger-install
   463
   464##
   465## linkerd multicluster
   466##
   467
   468_mc-target-k3d-flags := "--k3s-arg --disable='local-storage,metrics-server@server:*' --k3s-arg '--cluster-cidr=10.23.0.0/24@server:*'"
   469
   470linkerd-mc-install: _linkerd-init
   471    {{ _linkerd }} mc install --set='linkerdVersion={{ linkerd-tag }}' \
   472        | {{ _kubectl }} apply -f -
   473
   474# Wait for all test namespaces to be removed before uninstalling linkerd-multicluster.
   475linkerd-mc-uninstall:
   476    {{ _linkerd }} mc uninstall \
   477        | {{ _kubectl }} delete -f -
   478
   479mc-target-k3d-delete:
   480    #!/usr/bin/env bash
   481    set -euo pipefail
   482    if k3d cluster list '{{ k3d-name }}-target' >/dev/null 2>/dev/null; then
   483        {{ just_executable() }} \
   484            k3d-name='{{ k3d-name }}-target' \
   485            k3d-delete
   486    fi
   487
   488_mc-load: _k3d-init linkerd-load
   489
   490_mc-target-load:
   491    @{{ just_executable() }} \
   492        k3d-name='{{ k3d-name }}-target' \
   493        k3d-k8s='{{ k3d-k8s }}' \
   494        k3d-agents='{{ k3d-agents }}' \
   495        k3d-servers='{{ k3d-servers }}' \
   496        k3d-network='{{ k3d-network }}' \
   497        _k3d-flags='{{ _mc-target-k3d-flags }}' \
   498        controller-image='{{ controller-image }}' \
   499        proxy-image='{{ proxy-image }}' \
   500        linkerd-exec='{{ linkerd-exec }}' \
   501        linkerd-tag='{{ linkerd-tag }}' \
   502        _pause-load \
   503        _mc-load
   504
   505# Run the multicluster tests with cluster setup
   506mc-test: mc-test-load mc-test-run
   507
   508mc-test-build:
   509    go build --mod=readonly \
   510        ./test/integration/multicluster/...
   511
   512mc-test-load: _mc-load _mc-target-load mc-flat-network-init
   513
   514k3d-source-server := "k3d-" + k3d-name + "-server-0"
   515k3d-target-server := "k3d-" + k3d-name + "-target-server-0"
   516
   517_mc-route-output-fmt := "-o jsonpath='ip route add {.spec.podCIDR} via {.status.addresses[?(.type==\"InternalIP\")].address}'"
   518_mc-print-source-route := _kubectl + " " + "get node " + k3d-source-server + " " + _mc-route-output-fmt
   519_mc-print-target-route := "kubectl --context=k3d-" + k3d-name + "-target "+ "get node " + k3d-target-server + " " + _mc-route-output-fmt
   520
   521# Allow two k3d server nodes to participate in a flat network
   522mc-flat-network-init:
   523	@docker exec k3d-{{k3d-name}}-server-0 `{{_mc-print-target-route}}`
   524	@docker exec k3d-{{k3d-name}}-target-server-0 `{{_mc-print-source-route}}`
   525
   526
   527# Run the multicluster tests without any setup
   528mc-test-run:
   529    LINKERD_DOCKER_REGISTRY='{{ DOCKER_REGISTRY }}' \
   530        go test -v -test.timeout=15m --failfast --mod=readonly \
   531            ./test/integration/multicluster/... \
   532                -integration-tests \
   533                -linkerd='{{ justfile_directory() }}/bin/linkerd' \
   534                -multicluster-source-context='k3d-{{ k3d-name }}' \
   535                -multicluster-target-context='k3d-{{ k3d-name }}-target'
   536
   537##
   538## GitHub Actions
   539##
   540
   541# Format actionlint output for Github Actions if running in CI.
   542_actionlint-fmt := if env_var_or_default("GITHUB_ACTIONS", "") != "true" { "" } else {
   543  '{{range $err := .}}::error file={{$err.Filepath}},line={{$err.Line}},col={{$err.Column}}::{{$err.Message}}%0A```%0A{{replace $err.Snippet "\\n" "%0A"}}%0A```\n{{end}}'
   544}
   545
   546# Lints all GitHub Actions workflows
   547action-lint:
   548    actionlint {{ if _actionlint-fmt != '' { "-format '" + _actionlint-fmt + "'" } else { "" } }} .github/workflows/*
   549
   550# Ensure all devcontainer versions are in sync
   551action-dev-check:
   552    just-dev check-action-images
   553
   554##
   555## Other tools...
   556##
   557
   558md-lint:
   559    markdownlint-cli2 '**/*.md' '!**/node_modules' '!target'
   560
   561sh-lint:
   562    bin/shellcheck-all
   563
   564##
   565## Git
   566##
   567
   568# Display the git history minus Dependabot updates
   569history *paths='.':
   570    @git log --oneline --graph --invert-grep --author="dependabot" -- {{ paths }}
   571
   572# Display the history of Dependabot changes
   573history-dependabot *paths='.':
   574    @git log --oneline --graph --author="dependabot" -- {{ paths }}
   575
   576# vim: set ft=make :

View as plain text