diff --git a/.github/report-release-vulnerabilities.sh b/.github/report-release-vulnerabilities.sh
index b583bac859..ee1386c034 100755
--- a/.github/report-release-vulnerabilities.sh
+++ b/.github/report-release-vulnerabilities.sh
@@ -1,4 +1,7 @@
#!/usr/bin/env bash
+# Copyright The Shipwright Contributors
+#
+# SPDX-License-Identifier: Apache-2.0
set -euo pipefail
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 14fa032396..2e3ffc550e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -63,13 +63,13 @@ jobs:
fail-fast: false
matrix:
kubernetes:
- - v1.28.13
+ - v1.29.8
- v1.31.0
tekton:
# oldest LTS that exists at the time of our planned next release
- v0.56.8
# newest LTS that exists at the time of our planned next release
- - v0.65.0 # RETAIN-COMMENT: TEKTON_NEWEST_LTS
+ - v0.65.1 # RETAIN-COMMENT: TEKTON_NEWEST_LTS
max-parallel: 4
runs-on: ubuntu-latest
steps:
@@ -84,7 +84,7 @@ jobs:
- name: Install Ko
uses: ko-build/setup-ko@v0.7
with:
- version: v0.15.2
+ version: v0.17.1
- name: Install kubectl
uses: azure/setup-kubectl@v4
with:
@@ -92,7 +92,7 @@ jobs:
- name: Create kind cluster
uses: helm/kind-action@v1
with:
- version: v0.22.0
+ version: v0.24.0
node_image: kindest/node:${{ matrix.kubernetes }}
cluster_name: kind
wait: 120s
@@ -143,13 +143,13 @@ jobs:
fail-fast: false
matrix:
kubernetes:
- - v1.28.13
+ - v1.29.8
- v1.31.0
tekton:
# oldest LTS that exists at the time of our planned next release
- v0.56.8
# newest LTS that exists at the time of our planned next release
- - v0.65.0 # RETAIN-COMMENT: TEKTON_NEWEST_LTS
+ - v0.65.1 # RETAIN-COMMENT: TEKTON_NEWEST_LTS
max-parallel: 4
runs-on: ubuntu-latest
steps:
@@ -178,7 +178,7 @@ jobs:
- name: Create kind cluster
uses: helm/kind-action@v1
with:
- version: v0.22.0
+ version: v0.24.0
node_image: kindest/node:${{ matrix.kubernetes }}
cluster_name: kind
config: test/kind/config.yaml
@@ -220,7 +220,7 @@ jobs:
- name: Install Ko
uses: ko-build/setup-ko@v0.7
with:
- version: v0.15.2
+ version: v0.17.1
- name: Install Shipwright Build
run: |
make install-controller-kind
diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml
index 5fd3ca54e3..59dccb116d 100644
--- a/.github/workflows/nightly.yaml
+++ b/.github/workflows/nightly.yaml
@@ -29,7 +29,7 @@ jobs:
# Install tools
- uses: ko-build/setup-ko@v0.7
with:
- version: v0.15.2
+ version: v0.17.1
- uses: imjasonh/setup-crane@31b88efe9de28ae0ffa220711af4b60be9435f6e
- uses: sigstore/cosign-installer@v3
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 2cb61d1942..c43b5bcbcc 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -44,7 +44,7 @@ jobs:
# Install tools
- uses: ko-build/setup-ko@v0.7
with:
- version: v0.15.2
+ version: v0.17.1
- uses: sigstore/cosign-installer@v3
- name: Build Release Changelog
diff --git a/HACK.md b/HACK.md
index 9b9b3309b1..88062cedd6 100644
--- a/HACK.md
+++ b/HACK.md
@@ -41,7 +41,7 @@ In the near future, the above would be setup by the controller.
make clean && make build
```
-* This project uses Golang 1.22 and controller-gen v0.14.0.
+* This project uses Golang 1.22 and controller-gen v0.15.0.
* The controllers create/watch Tekton objects.
# Testing
diff --git a/Makefile b/Makefile
index 7a61f10c8e..f51f2bbfaa 100644
--- a/Makefile
+++ b/Makefile
@@ -36,7 +36,7 @@ ZAP_FLAGS ?= --zap-log-level=debug --zap-encoder=console
TEST_NAMESPACE ?= default
# CI: tekton pipelines controller version
-TEKTON_VERSION ?= v0.65.0
+TEKTON_VERSION ?= v0.65.1
# E2E test flags
TEST_E2E_FLAGS ?= -r -p --randomize-all --timeout=1h --trace --vv
diff --git a/README.md b/README.md
index 12e7b16d46..81705ece7f 100644
--- a/README.md
+++ b/README.md
@@ -34,12 +34,12 @@ Shipwright supports any tool that can build container images in Kubernetes clust
## Try It!
-- We assume you already have a Kubernetes cluster (v1.27+). If you don't, you can use [KinD](https://kind.sigs.k8s.io), which you can install by running [`./hack/install-kind.sh`](./hack/install-kind.sh).
+- We assume you already have a Kubernetes cluster (v1.29+). If you don't, you can use [KinD](https://kind.sigs.k8s.io), which you can install by running [`./hack/install-kind.sh`](./hack/install-kind.sh).
-- We also require a Tekton installation (v0.50.+). To install the latest LTS release, run:
+- We also require a Tekton installation (v0.56.+). To install the latest LTS release, run:
```bash
- kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.65.0/release.yaml
+ kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.65.1/release.yaml
```
If you are using OpenShift cluster refer [Running on OpenShift](#running-on-openshift) for some more configurations.
@@ -191,7 +191,7 @@ To find out more on what's the best strategy or what else can Shipwright do for
| Dependency | Supported versions |
|--------------------------------------|------------------------------|
-| [Kubernetes](https://kubernetes.io/) | v1.27.\*, v1.28.\*, v1.29.\* |
+| [Kubernetes](https://kubernetes.io/) | v1.29.\*, v1.30.\*, v1.31.\* |
| [Tekton](https://tekton.dev) | v0.56.\*, v0.59.\*, v0.62.\*, v0.65.\* |
### Platform support
@@ -238,4 +238,4 @@ We are so excited to have you!
---
-Shipwright is a [Cloud Native Computing Foundation (CNCF) Sandbox project](https://www.cncf.io/sandbox-projects/).
\ No newline at end of file
+Shipwright is a [Cloud Native Computing Foundation (CNCF) Sandbox project](https://www.cncf.io/sandbox-projects/).
diff --git a/deploy/crds/shipwright.io_buildruns.yaml b/deploy/crds/shipwright.io_buildruns.yaml
index 3efbe7c6fc..d2f00f59cd 100644
--- a/deploy/crds/shipwright.io_buildruns.yaml
+++ b/deploy/crds/shipwright.io_buildruns.yaml
@@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.14.0
+ controller-gen.kubebuilder.io/version: v0.15.0
name: buildruns.shipwright.io
spec:
conversion:
@@ -104,10 +104,15 @@ spec:
the image registry.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -180,10 +185,15 @@ spec:
description: The key to select.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or its
@@ -243,10 +253,15 @@ spec:
be a valid secret key.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its key
@@ -277,10 +292,15 @@ spec:
the image registry.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -471,10 +491,15 @@ spec:
the repository.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -552,10 +577,15 @@ spec:
secret token to validate webhook request.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -739,6 +769,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
path:
description: 'path is Optional: Used as the mounted
root, rather than the full Ceph tree, default is /'
@@ -760,10 +791,15 @@ spec:
More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -799,10 +835,15 @@ spec:
to OpenStack.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -867,11 +908,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap
@@ -904,10 +951,15 @@ spec:
secret object contains more than one secret, all secret references are passed.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -958,8 +1010,8 @@ spec:
properties:
fieldRef:
description: 'Required: Selects a field of the
- pod: only annotations, labels, name and namespace
- are supported.'
+ pod: only annotations, labels, name, namespace
+ and uid are supported.'
properties:
apiVersion:
description: Version of the schema the FieldPath
@@ -1018,6 +1070,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
emptyDir:
description: |-
@@ -1123,6 +1176,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
dataSource:
description: |-
dataSource field can be used to specify either:
@@ -1267,11 +1321,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -1299,7 +1355,7 @@ spec:
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
- More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
(Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
type: string
volumeMode:
@@ -1343,6 +1399,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
wwids:
description: |-
wwids Optional: FC volume world wide identifiers (wwids)
@@ -1350,6 +1407,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
flexVolume:
description: |-
@@ -1386,10 +1444,15 @@ spec:
scripts.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -1570,6 +1633,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
readOnly:
description: |-
readOnly here will force the ReadOnly setting in VolumeMounts.
@@ -1580,10 +1644,15 @@ spec:
target and initiator authentication
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -1757,11 +1826,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -1840,11 +1911,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the
@@ -1867,7 +1944,7 @@ spec:
fieldRef:
description: 'Required: Selects a field
of the pod: only annotations, labels,
- name and namespace are supported.'
+ name, namespace and uid are supported.'
properties:
apiVersion:
description: Version of the schema
@@ -1931,6 +2008,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
secret:
description: secret information about the secret
@@ -1974,11 +2052,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify whether
@@ -2017,6 +2101,7 @@ spec:
type: object
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
quobyte:
description: quobyte represents a Quobyte mount on the host
@@ -2087,6 +2172,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
pool:
description: |-
pool is the rados pool name.
@@ -2107,10 +2193,15 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2154,10 +2245,15 @@ spec:
sensitive information. If this is not provided, Login operation will fail.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2242,6 +2338,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
optional:
description: optional field specify whether the Secret
or its keys must be defined
@@ -2273,10 +2370,15 @@ spec:
credentials. If not specified, default values will be attempted.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2362,10 +2464,15 @@ spec:
description: The key to select.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or its key
@@ -2424,10 +2531,15 @@ spec:
be a valid secret key.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its key must
@@ -2459,10 +2571,15 @@ spec:
the image registry.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2770,6 +2887,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
path:
description: 'path is Optional: Used as the mounted root,
rather than the full Ceph tree, default is /'
@@ -2791,10 +2909,15 @@ spec:
More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2830,10 +2953,15 @@ spec:
to OpenStack.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2897,11 +3025,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap or its
@@ -2934,10 +3068,15 @@ spec:
secret object contains more than one secret, all secret references are passed.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2987,8 +3126,8 @@ spec:
properties:
fieldRef:
description: 'Required: Selects a field of the pod:
- only annotations, labels, name and namespace are
- supported.'
+ only annotations, labels, name, namespace and uid
+ are supported.'
properties:
apiVersion:
description: Version of the schema the FieldPath
@@ -3047,6 +3186,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
emptyDir:
description: |-
@@ -3152,6 +3292,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
dataSource:
description: |-
dataSource field can be used to specify either:
@@ -3296,11 +3437,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -3328,7 +3471,7 @@ spec:
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
- More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
(Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
type: string
volumeMode:
@@ -3372,6 +3515,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
wwids:
description: |-
wwids Optional: FC volume world wide identifiers (wwids)
@@ -3379,6 +3523,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
flexVolume:
description: |-
@@ -3415,10 +3560,15 @@ spec:
scripts.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3599,6 +3749,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
readOnly:
description: |-
readOnly here will force the ReadOnly setting in VolumeMounts.
@@ -3609,10 +3760,15 @@ spec:
and initiator authentication
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3784,11 +3940,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -3867,11 +4025,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap
@@ -3894,7 +4058,7 @@ spec:
fieldRef:
description: 'Required: Selects a field
of the pod: only annotations, labels,
- name and namespace are supported.'
+ name, namespace and uid are supported.'
properties:
apiVersion:
description: Version of the schema the
@@ -3957,6 +4121,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
secret:
description: secret information about the secret data
@@ -4000,11 +4165,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify whether the
@@ -4043,6 +4214,7 @@ spec:
type: object
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
quobyte:
description: quobyte represents a Quobyte mount on the host
@@ -4113,6 +4285,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
pool:
description: |-
pool is the rados pool name.
@@ -4133,10 +4306,15 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4180,10 +4358,15 @@ spec:
sensitive information. If this is not provided, Login operation will fail.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4267,6 +4450,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
optional:
description: optional field specify whether the Secret or
its keys must be defined
@@ -4298,10 +4482,15 @@ spec:
credentials. If not specified, default values will be attempted.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4377,10 +4566,15 @@ spec:
the image registry.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4453,10 +4647,15 @@ spec:
description: The key to select.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or its
@@ -4516,10 +4715,15 @@ spec:
be a valid secret key.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its key
@@ -4550,10 +4754,15 @@ spec:
the image registry.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4744,10 +4953,15 @@ spec:
the repository.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4825,10 +5039,15 @@ spec:
secret token to validate webhook request.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -5012,6 +5231,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
path:
description: 'path is Optional: Used as the mounted
root, rather than the full Ceph tree, default is /'
@@ -5033,10 +5253,15 @@ spec:
More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -5072,10 +5297,15 @@ spec:
to OpenStack.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -5140,11 +5370,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap
@@ -5177,10 +5413,15 @@ spec:
secret object contains more than one secret, all secret references are passed.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -5231,8 +5472,8 @@ spec:
properties:
fieldRef:
description: 'Required: Selects a field of the
- pod: only annotations, labels, name and namespace
- are supported.'
+ pod: only annotations, labels, name, namespace
+ and uid are supported.'
properties:
apiVersion:
description: Version of the schema the FieldPath
@@ -5291,6 +5532,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
emptyDir:
description: |-
@@ -5396,6 +5638,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
dataSource:
description: |-
dataSource field can be used to specify either:
@@ -5540,11 +5783,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -5572,7 +5817,7 @@ spec:
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
- More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
(Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
type: string
volumeMode:
@@ -5616,6 +5861,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
wwids:
description: |-
wwids Optional: FC volume world wide identifiers (wwids)
@@ -5623,6 +5869,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
flexVolume:
description: |-
@@ -5659,10 +5906,15 @@ spec:
scripts.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -5843,6 +6095,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
readOnly:
description: |-
readOnly here will force the ReadOnly setting in VolumeMounts.
@@ -5853,10 +6106,15 @@ spec:
target and initiator authentication
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -6030,11 +6288,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -6113,11 +6373,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the
@@ -6140,7 +6406,7 @@ spec:
fieldRef:
description: 'Required: Selects a field
of the pod: only annotations, labels,
- name and namespace are supported.'
+ name, namespace and uid are supported.'
properties:
apiVersion:
description: Version of the schema
@@ -6204,6 +6470,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
secret:
description: secret information about the secret
@@ -6247,11 +6514,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify whether
@@ -6290,6 +6563,7 @@ spec:
type: object
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
quobyte:
description: quobyte represents a Quobyte mount on the host
@@ -6360,6 +6634,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
pool:
description: |-
pool is the rados pool name.
@@ -6380,10 +6655,15 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -6427,10 +6707,15 @@ spec:
sensitive information. If this is not provided, Login operation will fail.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -6515,6 +6800,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
optional:
description: optional field specify whether the Secret
or its keys must be defined
@@ -6546,10 +6832,15 @@ spec:
credentials. If not specified, default values will be attempted.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -6835,10 +7126,15 @@ spec:
description: The key to select.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or
@@ -6898,10 +7194,15 @@ spec:
from. Must be a valid secret key.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its
@@ -7422,6 +7723,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
path:
description: 'path is Optional: Used as the mounted
root, rather than the full Ceph tree, default
@@ -7444,10 +7746,15 @@ spec:
More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -7483,10 +7790,15 @@ spec:
to OpenStack.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -7551,11 +7863,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap
@@ -7588,10 +7906,15 @@ spec:
secret object contains more than one secret, all secret references are passed.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -7636,8 +7959,8 @@ spec:
properties:
fieldRef:
description: 'Required: Selects a field of
- the pod: only annotations, labels, name
- and namespace are supported.'
+ the pod: only annotations, labels, name,
+ namespace and uid are supported.'
properties:
apiVersion:
description: Version of the schema the
@@ -7698,6 +8021,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
emptyDir:
description: |-
@@ -7803,6 +8127,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
dataSource:
description: |-
dataSource field can be used to specify either:
@@ -7948,11 +8273,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -7980,7 +8307,7 @@ spec:
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
- More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
(Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
type: string
volumeMode:
@@ -8024,6 +8351,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
wwids:
description: |-
wwids Optional: FC volume world wide identifiers (wwids)
@@ -8031,6 +8359,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
flexVolume:
description: |-
@@ -8067,10 +8396,15 @@ spec:
scripts.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -8251,6 +8585,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
readOnly:
description: |-
readOnly here will force the ReadOnly setting in VolumeMounts.
@@ -8261,10 +8596,15 @@ spec:
target and initiator authentication
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -8439,11 +8779,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -8522,11 +8864,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether
@@ -8549,8 +8897,8 @@ spec:
fieldRef:
description: 'Required: Selects
a field of the pod: only annotations,
- labels, name and namespace are
- supported.'
+ labels, name, namespace and uid
+ are supported.'
properties:
apiVersion:
description: Version of the
@@ -8616,6 +8964,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
secret:
description: secret information about the
@@ -8659,11 +9008,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify whether
@@ -8702,6 +9057,7 @@ spec:
type: object
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
quobyte:
description: quobyte represents a Quobyte mount on the
@@ -8772,6 +9128,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
pool:
description: |-
pool is the rados pool name.
@@ -8792,10 +9149,15 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -8839,10 +9201,15 @@ spec:
sensitive information. If this is not provided, Login operation will fail.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -8927,6 +9294,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
optional:
description: optional field specify whether the
Secret or its keys must be defined
@@ -8958,10 +9326,15 @@ spec:
credentials. If not specified, default values will be attempted.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -9048,10 +9421,15 @@ spec:
description: The key to select.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or its key
@@ -9110,10 +9488,15 @@ spec:
be a valid secret key.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its key must
@@ -9481,6 +9864,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
path:
description: 'path is Optional: Used as the mounted root,
rather than the full Ceph tree, default is /'
@@ -9502,10 +9886,15 @@ spec:
More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -9541,10 +9930,15 @@ spec:
to OpenStack.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -9608,11 +10002,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap or its
@@ -9645,10 +10045,15 @@ spec:
secret object contains more than one secret, all secret references are passed.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -9691,8 +10096,8 @@ spec:
properties:
fieldRef:
description: 'Required: Selects a field of the pod:
- only annotations, labels, name and namespace are
- supported.'
+ only annotations, labels, name, namespace and uid
+ are supported.'
properties:
apiVersion:
description: Version of the schema the FieldPath
@@ -9751,6 +10156,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
emptyDir:
description: |-
@@ -9856,6 +10262,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
dataSource:
description: |-
dataSource field can be used to specify either:
@@ -10000,11 +10407,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -10032,7 +10441,7 @@ spec:
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
- More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
(Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
type: string
volumeMode:
@@ -10076,6 +10485,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
wwids:
description: |-
wwids Optional: FC volume world wide identifiers (wwids)
@@ -10083,6 +10493,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
flexVolume:
description: |-
@@ -10119,10 +10530,15 @@ spec:
scripts.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -10303,6 +10719,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
readOnly:
description: |-
readOnly here will force the ReadOnly setting in VolumeMounts.
@@ -10313,10 +10730,15 @@ spec:
and initiator authentication
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -10488,11 +10910,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -10571,11 +10995,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap
@@ -10598,7 +11028,7 @@ spec:
fieldRef:
description: 'Required: Selects a field
of the pod: only annotations, labels,
- name and namespace are supported.'
+ name, namespace and uid are supported.'
properties:
apiVersion:
description: Version of the schema the
@@ -10661,6 +11091,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
secret:
description: secret information about the secret data
@@ -10704,11 +11135,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify whether the
@@ -10747,6 +11184,7 @@ spec:
type: object
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
quobyte:
description: quobyte represents a Quobyte mount on the host
@@ -10817,6 +11255,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
pool:
description: |-
pool is the rados pool name.
@@ -10837,10 +11276,15 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -10884,10 +11328,15 @@ spec:
sensitive information. If this is not provided, Login operation will fail.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -10971,6 +11420,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
optional:
description: optional field specify whether the Secret or
its keys must be defined
@@ -11002,10 +11452,15 @@ spec:
credentials. If not specified, default values will be attempted.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -11096,10 +11551,15 @@ spec:
description: The key to select.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or its
@@ -11159,10 +11619,15 @@ spec:
be a valid secret key.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its key
@@ -11682,6 +12147,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
path:
description: 'path is Optional: Used as the mounted
root, rather than the full Ceph tree, default is /'
@@ -11703,10 +12169,15 @@ spec:
More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -11742,10 +12213,15 @@ spec:
to OpenStack.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -11810,11 +12286,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap
@@ -11847,10 +12329,15 @@ spec:
secret object contains more than one secret, all secret references are passed.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -11894,8 +12381,8 @@ spec:
properties:
fieldRef:
description: 'Required: Selects a field of the
- pod: only annotations, labels, name and namespace
- are supported.'
+ pod: only annotations, labels, name, namespace
+ and uid are supported.'
properties:
apiVersion:
description: Version of the schema the FieldPath
@@ -11954,6 +12441,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
emptyDir:
description: |-
@@ -12059,6 +12547,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
dataSource:
description: |-
dataSource field can be used to specify either:
@@ -12203,11 +12692,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -12235,7 +12726,7 @@ spec:
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
- More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
(Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
type: string
volumeMode:
@@ -12279,6 +12770,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
wwids:
description: |-
wwids Optional: FC volume world wide identifiers (wwids)
@@ -12286,6 +12778,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
flexVolume:
description: |-
@@ -12322,10 +12815,15 @@ spec:
scripts.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -12506,6 +13004,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
readOnly:
description: |-
readOnly here will force the ReadOnly setting in VolumeMounts.
@@ -12516,10 +13015,15 @@ spec:
target and initiator authentication
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -12693,11 +13197,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -12776,11 +13282,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the
@@ -12803,7 +13315,7 @@ spec:
fieldRef:
description: 'Required: Selects a field
of the pod: only annotations, labels,
- name and namespace are supported.'
+ name, namespace and uid are supported.'
properties:
apiVersion:
description: Version of the schema
@@ -12867,6 +13379,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
secret:
description: secret information about the secret
@@ -12910,11 +13423,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify whether
@@ -12953,6 +13472,7 @@ spec:
type: object
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
quobyte:
description: quobyte represents a Quobyte mount on the host
@@ -13023,6 +13543,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
pool:
description: |-
pool is the rados pool name.
@@ -13043,10 +13564,15 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -13090,10 +13616,15 @@ spec:
sensitive information. If this is not provided, Login operation will fail.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -13178,6 +13709,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
optional:
description: optional field specify whether the Secret
or its keys must be defined
@@ -13209,10 +13741,15 @@ spec:
credentials. If not specified, default values will be attempted.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
diff --git a/deploy/crds/shipwright.io_builds.yaml b/deploy/crds/shipwright.io_builds.yaml
index 4d06c45769..ca02694d9f 100644
--- a/deploy/crds/shipwright.io_builds.yaml
+++ b/deploy/crds/shipwright.io_builds.yaml
@@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.14.0
+ controller-gen.kubebuilder.io/version: v0.15.0
name: builds.shipwright.io
spec:
conversion:
@@ -91,10 +91,15 @@ spec:
the image registry.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -165,10 +170,15 @@ spec:
description: The key to select.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or its key
@@ -227,10 +237,15 @@ spec:
be a valid secret key.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its key must
@@ -261,10 +276,15 @@ spec:
the image registry.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -451,10 +471,15 @@ spec:
the repository.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -532,10 +557,15 @@ spec:
token to validate webhook request.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -718,6 +748,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
path:
description: 'path is Optional: Used as the mounted root,
rather than the full Ceph tree, default is /'
@@ -739,10 +770,15 @@ spec:
More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -778,10 +814,15 @@ spec:
to OpenStack.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -845,11 +886,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap or its
@@ -882,10 +929,15 @@ spec:
secret object contains more than one secret, all secret references are passed.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -935,8 +987,8 @@ spec:
properties:
fieldRef:
description: 'Required: Selects a field of the pod:
- only annotations, labels, name and namespace are
- supported.'
+ only annotations, labels, name, namespace and uid
+ are supported.'
properties:
apiVersion:
description: Version of the schema the FieldPath
@@ -995,6 +1047,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
emptyDir:
description: |-
@@ -1100,6 +1153,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
dataSource:
description: |-
dataSource field can be used to specify either:
@@ -1244,11 +1298,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -1276,7 +1332,7 @@ spec:
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
- More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
(Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
type: string
volumeMode:
@@ -1320,6 +1376,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
wwids:
description: |-
wwids Optional: FC volume world wide identifiers (wwids)
@@ -1327,6 +1384,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
flexVolume:
description: |-
@@ -1363,10 +1421,15 @@ spec:
scripts.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -1547,6 +1610,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
readOnly:
description: |-
readOnly here will force the ReadOnly setting in VolumeMounts.
@@ -1557,10 +1621,15 @@ spec:
and initiator authentication
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -1732,11 +1801,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -1815,11 +1886,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap
@@ -1842,7 +1919,7 @@ spec:
fieldRef:
description: 'Required: Selects a field
of the pod: only annotations, labels,
- name and namespace are supported.'
+ name, namespace and uid are supported.'
properties:
apiVersion:
description: Version of the schema the
@@ -1905,6 +1982,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
secret:
description: secret information about the secret data
@@ -1948,11 +2026,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify whether the
@@ -1991,6 +2075,7 @@ spec:
type: object
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
quobyte:
description: quobyte represents a Quobyte mount on the host
@@ -2061,6 +2146,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
pool:
description: |-
pool is the rados pool name.
@@ -2081,10 +2167,15 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2128,10 +2219,15 @@ spec:
sensitive information. If this is not provided, Login operation will fail.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2215,6 +2311,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
optional:
description: optional field specify whether the Secret or
its keys must be defined
@@ -2246,10 +2343,15 @@ spec:
credentials. If not specified, default values will be attempted.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2408,10 +2510,15 @@ spec:
description: The key to select.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or its key
@@ -2470,10 +2577,15 @@ spec:
be a valid secret key.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its key must
@@ -2987,6 +3099,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
path:
description: 'path is Optional: Used as the mounted root,
rather than the full Ceph tree, default is /'
@@ -3008,10 +3121,15 @@ spec:
More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3047,10 +3165,15 @@ spec:
to OpenStack.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3114,11 +3237,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap or its
@@ -3151,10 +3280,15 @@ spec:
secret object contains more than one secret, all secret references are passed.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3197,8 +3331,8 @@ spec:
properties:
fieldRef:
description: 'Required: Selects a field of the pod:
- only annotations, labels, name and namespace are
- supported.'
+ only annotations, labels, name, namespace and uid
+ are supported.'
properties:
apiVersion:
description: Version of the schema the FieldPath
@@ -3257,6 +3391,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
emptyDir:
description: |-
@@ -3362,6 +3497,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
dataSource:
description: |-
dataSource field can be used to specify either:
@@ -3506,11 +3642,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -3538,7 +3676,7 @@ spec:
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
- More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
(Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
type: string
volumeMode:
@@ -3582,6 +3720,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
wwids:
description: |-
wwids Optional: FC volume world wide identifiers (wwids)
@@ -3589,6 +3728,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
flexVolume:
description: |-
@@ -3625,10 +3765,15 @@ spec:
scripts.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3809,6 +3954,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
readOnly:
description: |-
readOnly here will force the ReadOnly setting in VolumeMounts.
@@ -3819,10 +3965,15 @@ spec:
and initiator authentication
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3994,11 +4145,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -4077,11 +4230,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap
@@ -4104,7 +4263,7 @@ spec:
fieldRef:
description: 'Required: Selects a field
of the pod: only annotations, labels,
- name and namespace are supported.'
+ name, namespace and uid are supported.'
properties:
apiVersion:
description: Version of the schema the
@@ -4167,6 +4326,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
secret:
description: secret information about the secret data
@@ -4210,11 +4370,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify whether the
@@ -4253,6 +4419,7 @@ spec:
type: object
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
quobyte:
description: quobyte represents a Quobyte mount on the host
@@ -4323,6 +4490,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
pool:
description: |-
pool is the rados pool name.
@@ -4343,10 +4511,15 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4390,10 +4563,15 @@ spec:
sensitive information. If this is not provided, Login operation will fail.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4477,6 +4655,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
optional:
description: optional field specify whether the Secret or
its keys must be defined
@@ -4508,10 +4687,15 @@ spec:
credentials. If not specified, default values will be attempted.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
diff --git a/deploy/crds/shipwright.io_buildstrategies.yaml b/deploy/crds/shipwright.io_buildstrategies.yaml
index 2e8768b31a..c1dffd9a1e 100644
--- a/deploy/crds/shipwright.io_buildstrategies.yaml
+++ b/deploy/crds/shipwright.io_buildstrategies.yaml
@@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.14.0
+ controller-gen.kubebuilder.io/version: v0.15.0
name: buildstrategies.shipwright.io
spec:
conversion:
@@ -74,6 +74,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
command:
description: |-
Entrypoint array. Not executed within a shell.
@@ -87,6 +88,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
env:
description: |-
List of environment variables to set in the container.
@@ -122,10 +124,15 @@ spec:
description: The key to select.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or
@@ -185,10 +192,15 @@ spec:
be a valid secret key.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its
@@ -203,6 +215,9 @@ spec:
- name
type: object
type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
envFrom:
description: |-
List of sources to populate environment variables in the container.
@@ -219,10 +234,15 @@ spec:
description: The ConfigMap to select from
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap must be
@@ -238,10 +258,15 @@ spec:
description: The Secret to select from
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret must be defined
@@ -250,6 +275,7 @@ spec:
x-kubernetes-map-type: atomic
type: object
type: array
+ x-kubernetes-list-type: atomic
image:
description: |-
Container image name.
@@ -290,6 +316,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
httpGet:
description: HTTPGet specifies the http request to perform.
@@ -319,6 +346,7 @@ spec:
- value
type: object
type: array
+ x-kubernetes-list-type: atomic
path:
description: Path to access on the HTTP server.
type: string
@@ -399,6 +427,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
httpGet:
description: HTTPGet specifies the http request to perform.
@@ -428,6 +457,7 @@ spec:
- value
type: object
type: array
+ x-kubernetes-list-type: atomic
path:
description: Path to access on the HTTP server.
type: string
@@ -504,6 +534,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
failureThreshold:
description: |-
@@ -558,6 +589,7 @@ spec:
- value
type: object
type: array
+ x-kubernetes-list-type: atomic
path:
description: Path to access on the HTTP server.
type: string
@@ -714,6 +746,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
failureThreshold:
description: |-
@@ -768,6 +801,7 @@ spec:
- value
type: object
type: array
+ x-kubernetes-list-type: atomic
path:
description: Path to access on the HTTP server.
type: string
@@ -962,6 +996,30 @@ spec:
2) has CAP_SYS_ADMIN
Note that this field cannot be set when spec.os.name is windows.
type: boolean
+ appArmorProfile:
+ description: |-
+ appArmorProfile is the AppArmor options to use by this container. If set, this profile
+ overrides the pod's appArmorProfile.
+ Note that this field cannot be set when spec.os.name is windows.
+ properties:
+ localhostProfile:
+ description: |-
+ localhostProfile indicates a profile loaded on the node that should be used.
+ The profile must be preconfigured on the node to work.
+ Must match the loaded name of the profile.
+ Must be set if and only if type is "Localhost".
+ type: string
+ type:
+ description: |-
+ type indicates which kind of AppArmor profile will be applied.
+ Valid options are:
+ Localhost - a profile pre-loaded on the node.
+ RuntimeDefault - the container runtime's default profile.
+ Unconfined - no AppArmor enforcement.
+ type: string
+ required:
+ - type
+ type: object
capabilities:
description: |-
The capabilities to add/drop when running containers.
@@ -975,6 +1033,7 @@ spec:
type
type: string
type: array
+ x-kubernetes-list-type: atomic
drop:
description: Removed capabilities
items:
@@ -982,6 +1041,7 @@ spec:
type
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
privileged:
description: |-
@@ -1139,6 +1199,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
failureThreshold:
description: |-
@@ -1193,6 +1254,7 @@ spec:
- value
type: object
type: array
+ x-kubernetes-list-type: atomic
path:
description: Path to access on the HTTP server.
type: string
@@ -1334,6 +1396,9 @@ spec:
- name
type: object
type: array
+ x-kubernetes-list-map-keys:
+ - devicePath
+ x-kubernetes-list-type: map
volumeMounts:
description: |-
Pod volumes to mount into the container's filesystem.
@@ -1353,6 +1418,8 @@ spec:
to container and the other way around.
When not set, MountPropagationNone is used.
This field is beta in 1.10.
+ When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified
+ (which defaults to None).
type: string
name:
description: This must match the Name of a Volume.
@@ -1362,6 +1429,29 @@ spec:
Mounted read-only if true, read-write otherwise (false or unspecified).
Defaults to false.
type: boolean
+ recursiveReadOnly:
+ description: |-
+ RecursiveReadOnly specifies whether read-only mounts should be handled
+ recursively.
+
+
+ If ReadOnly is false, this field has no meaning and must be unspecified.
+
+
+ If ReadOnly is true, and this field is set to Disabled, the mount is not made
+ recursively read-only. If this field is set to IfPossible, the mount is made
+ recursively read-only, if it is supported by the container runtime. If this
+ field is set to Enabled, the mount is made recursively read-only if it is
+ supported by the container runtime, otherwise the pod will not be started and
+ an error will be generated to indicate the reason.
+
+
+ If this field is set to IfPossible or Enabled, MountPropagation must be set to
+ None (or be unspecified, which defaults to None).
+
+
+ If this field is not specified, it is treated as an equivalent of Disabled.
+ type: string
subPath:
description: |-
Path within the volume from which the container's volume should be mounted.
@@ -1379,6 +1469,9 @@ spec:
- name
type: object
type: array
+ x-kubernetes-list-map-keys:
+ - mountPath
+ x-kubernetes-list-type: map
workingDir:
description: |-
Container's working directory.
@@ -1556,6 +1649,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
path:
description: 'path is Optional: Used as the mounted root,
rather than the full Ceph tree, default is /'
@@ -1577,10 +1671,15 @@ spec:
More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -1616,10 +1715,15 @@ spec:
to OpenStack.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -1683,11 +1787,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap or its
@@ -1720,10 +1830,15 @@ spec:
secret object contains more than one secret, all secret references are passed.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -1769,8 +1884,8 @@ spec:
properties:
fieldRef:
description: 'Required: Selects a field of the pod:
- only annotations, labels, name and namespace are
- supported.'
+ only annotations, labels, name, namespace and uid
+ are supported.'
properties:
apiVersion:
description: Version of the schema the FieldPath
@@ -1829,6 +1944,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
emptyDir:
description: |-
@@ -1934,6 +2050,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
dataSource:
description: |-
dataSource field can be used to specify either:
@@ -2078,11 +2195,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -2110,7 +2229,7 @@ spec:
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
- More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
(Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
type: string
volumeMode:
@@ -2154,6 +2273,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
wwids:
description: |-
wwids Optional: FC volume world wide identifiers (wwids)
@@ -2161,6 +2281,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
flexVolume:
description: |-
@@ -2197,10 +2318,15 @@ spec:
scripts.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2381,6 +2507,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
readOnly:
description: |-
readOnly here will force the ReadOnly setting in VolumeMounts.
@@ -2391,10 +2518,15 @@ spec:
and initiator authentication
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2571,11 +2703,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -2654,11 +2788,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap
@@ -2681,7 +2821,7 @@ spec:
fieldRef:
description: 'Required: Selects a field
of the pod: only annotations, labels,
- name and namespace are supported.'
+ name, namespace and uid are supported.'
properties:
apiVersion:
description: Version of the schema the
@@ -2744,6 +2884,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
secret:
description: secret information about the secret data
@@ -2787,11 +2928,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify whether the
@@ -2830,6 +2977,7 @@ spec:
type: object
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
quobyte:
description: quobyte represents a Quobyte mount on the host
@@ -2900,6 +3048,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
pool:
description: |-
pool is the rados pool name.
@@ -2920,10 +3069,15 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2967,10 +3121,15 @@ spec:
sensitive information. If this is not provided, Login operation will fail.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3054,6 +3213,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
optional:
description: optional field specify whether the Secret or
its keys must be defined
@@ -3085,10 +3245,15 @@ spec:
credentials. If not specified, default values will be attempted.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3298,10 +3463,15 @@ spec:
description: The key to select.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or
@@ -3361,10 +3531,15 @@ spec:
be a valid secret key.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its
@@ -3474,6 +3649,30 @@ spec:
2) has CAP_SYS_ADMIN
Note that this field cannot be set when spec.os.name is windows.
type: boolean
+ appArmorProfile:
+ description: |-
+ appArmorProfile is the AppArmor options to use by this container. If set, this profile
+ overrides the pod's appArmorProfile.
+ Note that this field cannot be set when spec.os.name is windows.
+ properties:
+ localhostProfile:
+ description: |-
+ localhostProfile indicates a profile loaded on the node that should be used.
+ The profile must be preconfigured on the node to work.
+ Must match the loaded name of the profile.
+ Must be set if and only if type is "Localhost".
+ type: string
+ type:
+ description: |-
+ type indicates which kind of AppArmor profile will be applied.
+ Valid options are:
+ Localhost - a profile pre-loaded on the node.
+ RuntimeDefault - the container runtime's default profile.
+ Unconfined - no AppArmor enforcement.
+ type: string
+ required:
+ - type
+ type: object
capabilities:
description: |-
The capabilities to add/drop when running containers.
@@ -3487,6 +3686,7 @@ spec:
type
type: string
type: array
+ x-kubernetes-list-type: atomic
drop:
description: Removed capabilities
items:
@@ -3494,6 +3694,7 @@ spec:
type
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
privileged:
description: |-
@@ -3647,6 +3848,8 @@ spec:
to container and the other way around.
When not set, MountPropagationNone is used.
This field is beta in 1.10.
+ When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified
+ (which defaults to None).
type: string
name:
description: This must match the Name of a Volume.
@@ -3656,6 +3859,29 @@ spec:
Mounted read-only if true, read-write otherwise (false or unspecified).
Defaults to false.
type: boolean
+ recursiveReadOnly:
+ description: |-
+ RecursiveReadOnly specifies whether read-only mounts should be handled
+ recursively.
+
+
+ If ReadOnly is false, this field has no meaning and must be unspecified.
+
+
+ If ReadOnly is true, and this field is set to Disabled, the mount is not made
+ recursively read-only. If this field is set to IfPossible, the mount is made
+ recursively read-only, if it is supported by the container runtime. If this
+ field is set to Enabled, the mount is made recursively read-only if it is
+ supported by the container runtime, otherwise the pod will not be started and
+ an error will be generated to indicate the reason.
+
+
+ If this field is set to IfPossible or Enabled, MountPropagation must be set to
+ None (or be unspecified, which defaults to None).
+
+
+ If this field is not specified, it is treated as an equivalent of Disabled.
+ type: string
subPath:
description: |-
Path within the volume from which the container's volume should be mounted.
@@ -3793,6 +4019,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
path:
description: 'path is Optional: Used as the mounted root,
rather than the full Ceph tree, default is /'
@@ -3814,10 +4041,15 @@ spec:
More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3853,10 +4085,15 @@ spec:
to OpenStack.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3920,11 +4157,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap or its
@@ -3957,10 +4200,15 @@ spec:
secret object contains more than one secret, all secret references are passed.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4006,8 +4254,8 @@ spec:
properties:
fieldRef:
description: 'Required: Selects a field of the pod:
- only annotations, labels, name and namespace are
- supported.'
+ only annotations, labels, name, namespace and uid
+ are supported.'
properties:
apiVersion:
description: Version of the schema the FieldPath
@@ -4066,6 +4314,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
emptyDir:
description: |-
@@ -4171,6 +4420,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
dataSource:
description: |-
dataSource field can be used to specify either:
@@ -4315,11 +4565,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -4347,7 +4599,7 @@ spec:
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
- More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
(Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
type: string
volumeMode:
@@ -4391,6 +4643,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
wwids:
description: |-
wwids Optional: FC volume world wide identifiers (wwids)
@@ -4398,6 +4651,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
flexVolume:
description: |-
@@ -4434,10 +4688,15 @@ spec:
scripts.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4618,6 +4877,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
readOnly:
description: |-
readOnly here will force the ReadOnly setting in VolumeMounts.
@@ -4628,10 +4888,15 @@ spec:
and initiator authentication
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4808,11 +5073,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -4891,11 +5158,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap
@@ -4918,7 +5191,7 @@ spec:
fieldRef:
description: 'Required: Selects a field
of the pod: only annotations, labels,
- name and namespace are supported.'
+ name, namespace and uid are supported.'
properties:
apiVersion:
description: Version of the schema the
@@ -4981,6 +5254,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
secret:
description: secret information about the secret data
@@ -5024,11 +5298,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify whether the
@@ -5067,6 +5347,7 @@ spec:
type: object
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
quobyte:
description: quobyte represents a Quobyte mount on the host
@@ -5137,6 +5418,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
pool:
description: |-
pool is the rados pool name.
@@ -5157,10 +5439,15 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -5204,10 +5491,15 @@ spec:
sensitive information. If this is not provided, Login operation will fail.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -5291,6 +5583,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
optional:
description: optional field specify whether the Secret or
its keys must be defined
@@ -5322,10 +5615,15 @@ spec:
credentials. If not specified, default values will be attempted.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
diff --git a/deploy/crds/shipwright.io_clusterbuildstrategies.yaml b/deploy/crds/shipwright.io_clusterbuildstrategies.yaml
index 220baf9309..546aaea788 100644
--- a/deploy/crds/shipwright.io_clusterbuildstrategies.yaml
+++ b/deploy/crds/shipwright.io_clusterbuildstrategies.yaml
@@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.14.0
+ controller-gen.kubebuilder.io/version: v0.15.0
name: clusterbuildstrategies.shipwright.io
spec:
conversion:
@@ -74,6 +74,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
command:
description: |-
Entrypoint array. Not executed within a shell.
@@ -87,6 +88,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
env:
description: |-
List of environment variables to set in the container.
@@ -122,10 +124,15 @@ spec:
description: The key to select.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or
@@ -185,10 +192,15 @@ spec:
be a valid secret key.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its
@@ -203,6 +215,9 @@ spec:
- name
type: object
type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
envFrom:
description: |-
List of sources to populate environment variables in the container.
@@ -219,10 +234,15 @@ spec:
description: The ConfigMap to select from
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap must be
@@ -238,10 +258,15 @@ spec:
description: The Secret to select from
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret must be defined
@@ -250,6 +275,7 @@ spec:
x-kubernetes-map-type: atomic
type: object
type: array
+ x-kubernetes-list-type: atomic
image:
description: |-
Container image name.
@@ -290,6 +316,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
httpGet:
description: HTTPGet specifies the http request to perform.
@@ -319,6 +346,7 @@ spec:
- value
type: object
type: array
+ x-kubernetes-list-type: atomic
path:
description: Path to access on the HTTP server.
type: string
@@ -399,6 +427,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
httpGet:
description: HTTPGet specifies the http request to perform.
@@ -428,6 +457,7 @@ spec:
- value
type: object
type: array
+ x-kubernetes-list-type: atomic
path:
description: Path to access on the HTTP server.
type: string
@@ -504,6 +534,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
failureThreshold:
description: |-
@@ -558,6 +589,7 @@ spec:
- value
type: object
type: array
+ x-kubernetes-list-type: atomic
path:
description: Path to access on the HTTP server.
type: string
@@ -714,6 +746,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
failureThreshold:
description: |-
@@ -768,6 +801,7 @@ spec:
- value
type: object
type: array
+ x-kubernetes-list-type: atomic
path:
description: Path to access on the HTTP server.
type: string
@@ -962,6 +996,30 @@ spec:
2) has CAP_SYS_ADMIN
Note that this field cannot be set when spec.os.name is windows.
type: boolean
+ appArmorProfile:
+ description: |-
+ appArmorProfile is the AppArmor options to use by this container. If set, this profile
+ overrides the pod's appArmorProfile.
+ Note that this field cannot be set when spec.os.name is windows.
+ properties:
+ localhostProfile:
+ description: |-
+ localhostProfile indicates a profile loaded on the node that should be used.
+ The profile must be preconfigured on the node to work.
+ Must match the loaded name of the profile.
+ Must be set if and only if type is "Localhost".
+ type: string
+ type:
+ description: |-
+ type indicates which kind of AppArmor profile will be applied.
+ Valid options are:
+ Localhost - a profile pre-loaded on the node.
+ RuntimeDefault - the container runtime's default profile.
+ Unconfined - no AppArmor enforcement.
+ type: string
+ required:
+ - type
+ type: object
capabilities:
description: |-
The capabilities to add/drop when running containers.
@@ -975,6 +1033,7 @@ spec:
type
type: string
type: array
+ x-kubernetes-list-type: atomic
drop:
description: Removed capabilities
items:
@@ -982,6 +1041,7 @@ spec:
type
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
privileged:
description: |-
@@ -1139,6 +1199,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
failureThreshold:
description: |-
@@ -1193,6 +1254,7 @@ spec:
- value
type: object
type: array
+ x-kubernetes-list-type: atomic
path:
description: Path to access on the HTTP server.
type: string
@@ -1334,6 +1396,9 @@ spec:
- name
type: object
type: array
+ x-kubernetes-list-map-keys:
+ - devicePath
+ x-kubernetes-list-type: map
volumeMounts:
description: |-
Pod volumes to mount into the container's filesystem.
@@ -1353,6 +1418,8 @@ spec:
to container and the other way around.
When not set, MountPropagationNone is used.
This field is beta in 1.10.
+ When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified
+ (which defaults to None).
type: string
name:
description: This must match the Name of a Volume.
@@ -1362,6 +1429,29 @@ spec:
Mounted read-only if true, read-write otherwise (false or unspecified).
Defaults to false.
type: boolean
+ recursiveReadOnly:
+ description: |-
+ RecursiveReadOnly specifies whether read-only mounts should be handled
+ recursively.
+
+
+ If ReadOnly is false, this field has no meaning and must be unspecified.
+
+
+ If ReadOnly is true, and this field is set to Disabled, the mount is not made
+ recursively read-only. If this field is set to IfPossible, the mount is made
+ recursively read-only, if it is supported by the container runtime. If this
+ field is set to Enabled, the mount is made recursively read-only if it is
+ supported by the container runtime, otherwise the pod will not be started and
+ an error will be generated to indicate the reason.
+
+
+ If this field is set to IfPossible or Enabled, MountPropagation must be set to
+ None (or be unspecified, which defaults to None).
+
+
+ If this field is not specified, it is treated as an equivalent of Disabled.
+ type: string
subPath:
description: |-
Path within the volume from which the container's volume should be mounted.
@@ -1379,6 +1469,9 @@ spec:
- name
type: object
type: array
+ x-kubernetes-list-map-keys:
+ - mountPath
+ x-kubernetes-list-type: map
workingDir:
description: |-
Container's working directory.
@@ -1556,6 +1649,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
path:
description: 'path is Optional: Used as the mounted root,
rather than the full Ceph tree, default is /'
@@ -1577,10 +1671,15 @@ spec:
More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -1616,10 +1715,15 @@ spec:
to OpenStack.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -1683,11 +1787,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap or its
@@ -1720,10 +1830,15 @@ spec:
secret object contains more than one secret, all secret references are passed.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -1769,8 +1884,8 @@ spec:
properties:
fieldRef:
description: 'Required: Selects a field of the pod:
- only annotations, labels, name and namespace are
- supported.'
+ only annotations, labels, name, namespace and uid
+ are supported.'
properties:
apiVersion:
description: Version of the schema the FieldPath
@@ -1829,6 +1944,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
emptyDir:
description: |-
@@ -1934,6 +2050,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
dataSource:
description: |-
dataSource field can be used to specify either:
@@ -2078,11 +2195,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -2110,7 +2229,7 @@ spec:
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
- More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
(Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
type: string
volumeMode:
@@ -2154,6 +2273,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
wwids:
description: |-
wwids Optional: FC volume world wide identifiers (wwids)
@@ -2161,6 +2281,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
flexVolume:
description: |-
@@ -2197,10 +2318,15 @@ spec:
scripts.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2381,6 +2507,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
readOnly:
description: |-
readOnly here will force the ReadOnly setting in VolumeMounts.
@@ -2391,10 +2518,15 @@ spec:
and initiator authentication
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2571,11 +2703,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -2654,11 +2788,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap
@@ -2681,7 +2821,7 @@ spec:
fieldRef:
description: 'Required: Selects a field
of the pod: only annotations, labels,
- name and namespace are supported.'
+ name, namespace and uid are supported.'
properties:
apiVersion:
description: Version of the schema the
@@ -2744,6 +2884,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
secret:
description: secret information about the secret data
@@ -2787,11 +2928,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify whether the
@@ -2830,6 +2977,7 @@ spec:
type: object
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
quobyte:
description: quobyte represents a Quobyte mount on the host
@@ -2900,6 +3048,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
pool:
description: |-
pool is the rados pool name.
@@ -2920,10 +3069,15 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2967,10 +3121,15 @@ spec:
sensitive information. If this is not provided, Login operation will fail.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3054,6 +3213,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
optional:
description: optional field specify whether the Secret or
its keys must be defined
@@ -3085,10 +3245,15 @@ spec:
credentials. If not specified, default values will be attempted.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3298,10 +3463,15 @@ spec:
description: The key to select.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or
@@ -3361,10 +3531,15 @@ spec:
be a valid secret key.
type: string
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its
@@ -3474,6 +3649,30 @@ spec:
2) has CAP_SYS_ADMIN
Note that this field cannot be set when spec.os.name is windows.
type: boolean
+ appArmorProfile:
+ description: |-
+ appArmorProfile is the AppArmor options to use by this container. If set, this profile
+ overrides the pod's appArmorProfile.
+ Note that this field cannot be set when spec.os.name is windows.
+ properties:
+ localhostProfile:
+ description: |-
+ localhostProfile indicates a profile loaded on the node that should be used.
+ The profile must be preconfigured on the node to work.
+ Must match the loaded name of the profile.
+ Must be set if and only if type is "Localhost".
+ type: string
+ type:
+ description: |-
+ type indicates which kind of AppArmor profile will be applied.
+ Valid options are:
+ Localhost - a profile pre-loaded on the node.
+ RuntimeDefault - the container runtime's default profile.
+ Unconfined - no AppArmor enforcement.
+ type: string
+ required:
+ - type
+ type: object
capabilities:
description: |-
The capabilities to add/drop when running containers.
@@ -3487,6 +3686,7 @@ spec:
type
type: string
type: array
+ x-kubernetes-list-type: atomic
drop:
description: Removed capabilities
items:
@@ -3494,6 +3694,7 @@ spec:
type
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
privileged:
description: |-
@@ -3647,6 +3848,8 @@ spec:
to container and the other way around.
When not set, MountPropagationNone is used.
This field is beta in 1.10.
+ When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified
+ (which defaults to None).
type: string
name:
description: This must match the Name of a Volume.
@@ -3656,6 +3859,29 @@ spec:
Mounted read-only if true, read-write otherwise (false or unspecified).
Defaults to false.
type: boolean
+ recursiveReadOnly:
+ description: |-
+ RecursiveReadOnly specifies whether read-only mounts should be handled
+ recursively.
+
+
+ If ReadOnly is false, this field has no meaning and must be unspecified.
+
+
+ If ReadOnly is true, and this field is set to Disabled, the mount is not made
+ recursively read-only. If this field is set to IfPossible, the mount is made
+ recursively read-only, if it is supported by the container runtime. If this
+ field is set to Enabled, the mount is made recursively read-only if it is
+ supported by the container runtime, otherwise the pod will not be started and
+ an error will be generated to indicate the reason.
+
+
+ If this field is set to IfPossible or Enabled, MountPropagation must be set to
+ None (or be unspecified, which defaults to None).
+
+
+ If this field is not specified, it is treated as an equivalent of Disabled.
+ type: string
subPath:
description: |-
Path within the volume from which the container's volume should be mounted.
@@ -3793,6 +4019,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
path:
description: 'path is Optional: Used as the mounted root,
rather than the full Ceph tree, default is /'
@@ -3814,10 +4041,15 @@ spec:
More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3853,10 +4085,15 @@ spec:
to OpenStack.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3920,11 +4157,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap or its
@@ -3957,10 +4200,15 @@ spec:
secret object contains more than one secret, all secret references are passed.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4006,8 +4254,8 @@ spec:
properties:
fieldRef:
description: 'Required: Selects a field of the pod:
- only annotations, labels, name and namespace are
- supported.'
+ only annotations, labels, name, namespace and uid
+ are supported.'
properties:
apiVersion:
description: Version of the schema the FieldPath
@@ -4066,6 +4314,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
emptyDir:
description: |-
@@ -4171,6 +4420,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
dataSource:
description: |-
dataSource field can be used to specify either:
@@ -4315,11 +4565,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -4347,7 +4599,7 @@ spec:
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
- More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
(Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
type: string
volumeMode:
@@ -4391,6 +4643,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
wwids:
description: |-
wwids Optional: FC volume world wide identifiers (wwids)
@@ -4398,6 +4651,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
type: object
flexVolume:
description: |-
@@ -4434,10 +4688,15 @@ spec:
scripts.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4618,6 +4877,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
readOnly:
description: |-
readOnly here will force the ReadOnly setting in VolumeMounts.
@@ -4628,10 +4888,15 @@ spec:
and initiator authentication
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4808,11 +5073,13 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
+ x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
@@ -4891,11 +5158,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the ConfigMap
@@ -4918,7 +5191,7 @@ spec:
fieldRef:
description: 'Required: Selects a field
of the pod: only annotations, labels,
- name and namespace are supported.'
+ name, namespace and uid are supported.'
properties:
apiVersion:
description: Version of the schema the
@@ -4981,6 +5254,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
secret:
description: secret information about the secret data
@@ -5024,11 +5298,17 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify whether the
@@ -5067,6 +5347,7 @@ spec:
type: object
type: object
type: array
+ x-kubernetes-list-type: atomic
type: object
quobyte:
description: quobyte represents a Quobyte mount on the host
@@ -5137,6 +5418,7 @@ spec:
items:
type: string
type: array
+ x-kubernetes-list-type: atomic
pool:
description: |-
pool is the rados pool name.
@@ -5157,10 +5439,15 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -5204,10 +5491,15 @@ spec:
sensitive information. If this is not provided, Login operation will fail.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -5291,6 +5583,7 @@ spec:
- path
type: object
type: array
+ x-kubernetes-list-type: atomic
optional:
description: optional field specify whether the Secret or
its keys must be defined
@@ -5322,10 +5615,15 @@ spec:
credentials. If not specified, default values will be attempted.
properties:
name:
+ default: ""
description: |-
Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
diff --git a/go.mod b/go.mod
index def14f4de6..51b773dc7b 100644
--- a/go.mod
+++ b/go.mod
@@ -16,61 +16,59 @@ require (
github.com/prometheus/client_model v0.6.1
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
- github.com/tektoncd/pipeline v0.65.0
+ github.com/tektoncd/pipeline v0.65.1
go.uber.org/zap v1.27.0
- k8s.io/api v0.29.9
- k8s.io/apiextensions-apiserver v0.29.9
- k8s.io/apimachinery v0.29.9
- k8s.io/client-go v0.29.9
- k8s.io/code-generator v0.29.9
- k8s.io/kubectl v0.29.9
+ k8s.io/api v0.30.6
+ k8s.io/apiextensions-apiserver v0.30.6
+ k8s.io/apimachinery v0.30.6
+ k8s.io/client-go v0.30.6
+ k8s.io/code-generator v0.30.6
+ k8s.io/kubectl v0.30.6
k8s.io/utils v0.0.0-20240102154912-e7106e64919e
knative.dev/pkg v0.0.0-20240416145024-0f34a8815650
- sigs.k8s.io/controller-runtime v0.17.6
+ sigs.k8s.io/controller-runtime v0.18.5
sigs.k8s.io/yaml v1.4.0
)
require (
contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect
contrib.go.opencensus.io/exporter/prometheus v0.4.2 // indirect
- dario.cat/mergo v1.0.0 // indirect
+ dario.cat/mergo v1.0.1 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.0.0 // indirect
- github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
+ github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blendle/zapdriver v1.3.1 // indirect
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
- github.com/cloudflare/circl v1.3.7 // indirect
- github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
- github.com/cyphar/filepath-securejoin v0.2.4 // indirect
+ github.com/cloudflare/circl v1.5.0 // indirect
+ github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
+ github.com/cyphar/filepath-securejoin v0.3.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
- github.com/docker/distribution v2.8.2+incompatible // indirect
- github.com/docker/docker-credential-helpers v0.7.0 // indirect
- github.com/emicklei/go-restful/v3 v3.11.0 // indirect
+ github.com/docker/distribution v2.8.3+incompatible // indirect
+ github.com/docker/docker-credential-helpers v0.8.2 // indirect
+ github.com/emicklei/go-restful/v3 v3.12.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
- github.com/evanphx/json-patch v5.6.0+incompatible // indirect
+ github.com/evanphx/json-patch v5.9.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
- github.com/fsnotify/fsnotify v1.7.0 // indirect
+ github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
- github.com/go-git/go-billy/v5 v5.5.0 // indirect
- github.com/go-kit/log v0.2.1 // indirect
- github.com/go-logfmt/logfmt v0.5.1 // indirect
+ github.com/go-git/go-billy/v5 v5.6.0 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
- github.com/go-openapi/jsonpointer v0.19.6 // indirect
- github.com/go-openapi/jsonreference v0.20.2 // indirect
- github.com/go-openapi/swag v0.22.3 // indirect
+ github.com/go-openapi/jsonpointer v0.21.0 // indirect
+ github.com/go-openapi/jsonreference v0.21.0 // indirect
+ github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
- github.com/google/cel-go v0.20.1 // indirect
+ github.com/google/cel-go v0.21.0 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect
github.com/google/uuid v1.6.0 // indirect
- github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
+ github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/imdario/mergo v0.3.15 // indirect
@@ -79,9 +77,9 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
- github.com/klauspost/compress v1.17.9 // indirect
+ github.com/klauspost/compress v1.17.11 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
- github.com/mattn/go-runewidth v0.0.15 // indirect
+ github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
@@ -90,16 +88,16 @@ require (
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
- github.com/prometheus/common v0.55.0 // indirect
+ github.com/prometheus/common v0.60.1 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
- github.com/prometheus/statsd_exporter v0.22.7 // indirect
- github.com/rivo/uniseg v0.2.0 // indirect
- github.com/rogpeppe/go-internal v1.12.0 // indirect
+ github.com/prometheus/statsd_exporter v0.28.0 // indirect
+ github.com/rivo/uniseg v0.4.7 // indirect
+ github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
- github.com/skeema/knownhosts v1.2.2 // indirect
- github.com/stoewer/go-strcase v1.2.0 // indirect
- github.com/vbatts/tar-split v0.11.3 // indirect
+ github.com/skeema/knownhosts v1.3.0 // indirect
+ github.com/stoewer/go-strcase v1.3.0 // indirect
+ github.com/vbatts/tar-split v0.11.6 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
@@ -107,27 +105,26 @@ require (
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.30.0 // indirect
- golang.org/x/oauth2 v0.22.0 // indirect
+ golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/term v0.25.0 // indirect
golang.org/x/text v0.19.0 // indirect
- golang.org/x/time v0.5.0 // indirect
+ golang.org/x/time v0.7.0 // indirect
golang.org/x/tools v0.26.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
- google.golang.org/api v0.181.0 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
- google.golang.org/grpc v1.67.0 // indirect
+ google.golang.org/api v0.204.0 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
+ google.golang.org/grpc v1.67.1 // indirect
google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- k8s.io/component-base v0.29.9 // indirect
- k8s.io/gengo v0.0.0-20240129211411-f967bbeff4b4 // indirect
+ k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
- k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
+ k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
)
diff --git a/go.sum b/go.sum
index ef81901007..fc61ded451 100644
--- a/go.sum
+++ b/go.sum
@@ -34,11 +34,10 @@ contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d h
contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d/go.mod h1:IshRmMJBhDfFj5Y67nVhMYTTIze91RUeT73ipWKs/GY=
contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg=
contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9fpw1KeYcjrnC1J8B+JKjsZyRQ=
-dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
-dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
+dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
+dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
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/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
@@ -54,8 +53,8 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8V
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
-github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
-github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
+github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
+github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -79,49 +78,47 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cloudevents/sdk-go/v2 v2.15.2 h1:54+I5xQEnI73RBhWHxbI1XJcqOFOVJN85vb41+8mHUc=
github.com/cloudevents/sdk-go/v2 v2.15.2/go.mod h1:lL7kSWAE/V8VI4Wh0jbL2v/jvqsm6tjmaQBSvxcv4uE=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
-github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
-github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
+github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys=
+github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
-github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
-github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU=
+github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
-github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
-github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
+github.com/cyphar/filepath-securejoin v0.3.4 h1:VBWugsJh2ZxJmLFSM06/0qzQyiQX2Qs0ViKrUAcqdZ8=
+github.com/cyphar/filepath-securejoin v0.3.4/go.mod h1:8s/MCNJREmFK0H02MF6Ihv1nakJe4L/w3WZLHNkvlYM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ=
github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
-github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
-github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
-github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
+github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
+github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
+github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
-github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
-github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
+github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU=
+github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
-github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls=
+github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg=
github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
-github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
-github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
+github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
-github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
-github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
+github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8=
+github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys=
@@ -133,24 +130,21 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
-github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
-github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
-github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
-github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
-github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
-github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
-github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
-github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
+github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
+github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
+github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
+github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
+github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
+github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
@@ -192,8 +186,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84=
-github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg=
+github.com/google/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI=
+github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -213,7 +207,6 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo=
github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
@@ -234,8 +227,8 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -272,14 +265,12 @@ github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
+github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/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/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -290,8 +281,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
-github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
-github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
+github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@@ -344,8 +335,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
-github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
-github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
+github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc=
+github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
@@ -354,14 +345,16 @@ github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
-github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0=
github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI=
-github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
+github.com/prometheus/statsd_exporter v0.28.0 h1:S3ZLyLm/hOKHYZFOF0h4zYmd0EeKyPF9R1pFBYXUgYY=
+github.com/prometheus/statsd_exporter v0.28.0/go.mod h1:Lq41vNkMLfiPANmI+uHb5/rpFFUTxPXiiNpmsAYLvDI=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
-github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
+github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
@@ -369,17 +362,16 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A=
-github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
+github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
+github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
-github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
+github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
+github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@@ -387,7 +379,6 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -396,11 +387,10 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
-github.com/tektoncd/pipeline v0.65.0 h1:MIXXt/OeV/SLQ0KYXXBzPHBwXe2iIhgZcJBHkkgzaYY=
-github.com/tektoncd/pipeline v0.65.0/go.mod h1:V3cyfxxc7b3GLT2a13GX2mWA86qmxWhh4mOp4gfFQwQ=
-github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
-github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=
-github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=
+github.com/tektoncd/pipeline v0.65.1 h1:7Ee/nqG+QWE25NGzwKZdFE0p5COb/aljfDysUFv8+0o=
+github.com/tektoncd/pipeline v0.65.1/go.mod h1:V3cyfxxc7b3GLT2a13GX2mWA86qmxWhh4mOp4gfFQwQ=
+github.com/vbatts/tar-split v0.11.6 h1:4SjTW5+PU11n6fZenf2IPoV8/tz3AaYHMWjf23envGs=
+github.com/vbatts/tar-split v0.11.6/go.mod h1:dqKNtesIOr2j2Qv3W/cHjnvk9I8+G7oAkFDFN6TCBEI=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -522,8 +512,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
-golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
+golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
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=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -583,7 +573,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -612,8 +601,8 @@ golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
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.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
-golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
+golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
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=
@@ -648,7 +637,6 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -684,8 +672,8 @@ google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
-google.golang.org/api v0.181.0 h1:rPdjwnWgiPPOJx3IcSAQ2III5aX5tCer6wMpa/xmZi4=
-google.golang.org/api v0.181.0/go.mod h1:MnQ+M0CFsfUwA5beZ+g/vCBCPXvtmZwRz2qzZk8ih1k=
+google.golang.org/api v0.204.0 h1:3PjmQQEDkR/ENVZZwIYB4W/KzYtN8OrqnNcHWpeR8E4=
+google.golang.org/api v0.204.0/go.mod h1:69y8QSoKIbL9F94bWgWAq6wGqGwyjBgi2y8rAK8zLag=
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=
@@ -723,10 +711,10 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8=
-google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
+google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38 h1:2oV8dfuIkM1Ti7DwXc0BJfnwr9csz4TDXI9EmiI+Rbw=
+google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38/go.mod h1:vuAjtvlwkDKF6L1GQ0SokiRLCGFfeBUXWr/aFFkHACc=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
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=
@@ -740,8 +728,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
-google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
-google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
+google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
+google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
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=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -790,27 +778,24 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-k8s.io/api v0.29.9 h1:FwdflpNsfMUYUOblMZNWJ4K/q0OSL5A4jGa0iOgcJco=
-k8s.io/api v0.29.9/go.mod h1:fNhmzRfKaSEHCmczA/jRx6CiDKhYOnFLJBERMJAXEk8=
-k8s.io/apiextensions-apiserver v0.29.9 h1:EB6RK06kFJjbzBwU1YiVznxrcgBE0hhDWt6EQQIcOy4=
-k8s.io/apiextensions-apiserver v0.29.9/go.mod h1:jcaHG6R/bB1iU6XzC1DMhB1x2ktTJLt2KKpg6B65Z2c=
-k8s.io/apimachinery v0.29.9 h1:YZ8HUid1TzQVz94cnNlsQjLdH0VoAhWSqz7t0q6B12A=
-k8s.io/apimachinery v0.29.9/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y=
-k8s.io/client-go v0.29.9 h1:4f/Wz6li3rEyIPFj32XAQMtOGMM1tg7KQi1oeS6ibPg=
-k8s.io/client-go v0.29.9/go.mod h1:2N1drQEZ5yiYrWVaE2Un8JiISUhl47D8pyZlYLszke4=
-k8s.io/code-generator v0.29.9 h1:57k53ZbD4W4NFlTV2iH7nKfmoLP4Q6yW2o2H2nyZpF0=
-k8s.io/code-generator v0.29.9/go.mod h1:7TYnI0dYItL2cKuhhgPSuF3WED9uMdELgbVXFfn/joE=
-k8s.io/component-base v0.29.9 h1:lPENvp3CCwdeMEWGjiTfn5b287qQYuK7gX32OBOovmA=
-k8s.io/component-base v0.29.9/go.mod h1:NGDa6Ih0EdcLA2G4K2ZYySoiB+2Tn+rmSqPyudCPgDY=
-k8s.io/gengo v0.0.0-20240129211411-f967bbeff4b4 h1:izq7u3SJBdOAuA5YYe1/PIp9jczrih/jGlKRRt0G7bQ=
-k8s.io/gengo v0.0.0-20240129211411-f967bbeff4b4/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
-k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
+k8s.io/api v0.30.6 h1:uqRDLnFkmPLorI9D0x1dGXdYeRQMhQHlrHDgZ3/45RE=
+k8s.io/api v0.30.6/go.mod h1:6x759Hj7155pXRKStxzM7TMN9hW0x7WrBr51kuDMSHo=
+k8s.io/apiextensions-apiserver v0.30.6 h1:eXmd0cki9xjpUguN7zaWI8I6wo1utHQj6RWqeBaVmew=
+k8s.io/apiextensions-apiserver v0.30.6/go.mod h1:va7pN44YJJDHrShKhPSL9S5CyTJ8idAmqIARt5wY4j8=
+k8s.io/apimachinery v0.30.6 h1:dlplzGrUL/DiPOVVVjDcT9ZoQBOwYeB6hcFy90veggs=
+k8s.io/apimachinery v0.30.6/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
+k8s.io/client-go v0.30.6 h1:hMo7AUkHy/UqnwPMH+oJvFR9gpvXVfQnsiO+G2fdE30=
+k8s.io/client-go v0.30.6/go.mod h1:DDN89/30A1DfatO+c3ksYMM12kL7a/CZvsBaVjwh33g=
+k8s.io/code-generator v0.30.6 h1:P0pDCNLfT5lxrY6kZ07WtdIHc7a5cZCiJYz1B3MRbu8=
+k8s.io/code-generator v0.30.6/go.mod h1:Sg5PSxoHkTD7iFp+gM4d1XvCFCvrMkEa9uoHnCbyfwE=
+k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 h1:NGrVE502P0s0/1hudf8zjgwki1X/TByhmAoILTarmzo=
+k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70/go.mod h1:VH3AT8AaQOqiGjMF9p0/IM1Dj+82ZwjfxUP1IxaHE+8=
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
-k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
-k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
-k8s.io/kubectl v0.29.9 h1:8DJIPkRk5a6WonxRAbicJIn0DNwacOxaLxO4EDwf/hc=
-k8s.io/kubectl v0.29.9/go.mod h1:ylJbHUuPTYiwxAKx97nAyU3TKh3vHlEW+Pp44Usolvw=
+k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
+k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
+k8s.io/kubectl v0.30.6 h1:yPBMSJJxJk3ZHbiSAZreptXp0CiDVFLeLDXDGH7TyM0=
+k8s.io/kubectl v0.30.6/go.mod h1:MHos6OafyfyoFaoSawxQh1uPVc3xXs+v98FGF8Mz0/0=
k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ=
k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
knative.dev/pkg v0.0.0-20240416145024-0f34a8815650 h1:m2ahFUO0L2VrgGDYdyOUFdE6xBd3pLXAJozLJwqLRQM=
@@ -818,12 +803,11 @@ knative.dev/pkg v0.0.0-20240416145024-0f34a8815650/go.mod h1:soFw5ss08G4PU3JiFDK
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
-sigs.k8s.io/controller-runtime v0.17.6 h1:12IXsozEsIXWAMRpgRlYS1jjAHQXHtWEOMdULh3DbEw=
-sigs.k8s.io/controller-runtime v0.17.6/go.mod h1:N0jpP5Lo7lMTF9aL56Z/B2oWBJjey6StQM0jRbKQXtY=
+sigs.k8s.io/controller-runtime v0.18.5 h1:nTHio/W+Q4aBlQMgbnC5hZb4IjIidyrizMai9P6n4Rk=
+sigs.k8s.io/controller-runtime v0.18.5/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
-sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
diff --git a/hack/install-controller-gen.sh b/hack/install-controller-gen.sh
index 4b1a86a5bd..fecbf71ae7 100755
--- a/hack/install-controller-gen.sh
+++ b/hack/install-controller-gen.sh
@@ -11,7 +11,7 @@
set -eu
# controller-gen version
-CONTROLLER_GEN_VERSION="${CONTROLLER_GEN_VERSION:-v0.14.0}"
+CONTROLLER_GEN_VERSION="${CONTROLLER_GEN_VERSION:-v0.15.0}"
if [ ! -f "${GOPATH}/bin/controller-gen" ]; then
echo "# Installing controller-gen..."
diff --git a/hack/install-kind.sh b/hack/install-kind.sh
index 41961e0a81..a63a5eaed9 100755
--- a/hack/install-kind.sh
+++ b/hack/install-kind.sh
@@ -13,7 +13,7 @@ set -eu
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"
# kind version
-KIND_VERSION="${KIND_VERSION:-v0.22.0}"
+KIND_VERSION="${KIND_VERSION:-v0.24.0}"
if ! hash kind > /dev/null 2>&1 ; then
echo "# Installing KinD..."
@@ -27,7 +27,7 @@ kind --version
KIND_CLUSTER_NAME="${KIND_CLUSTER_NAME:-kind}"
# kind cluster version
-KIND_CLUSTER_VERSION="${KIND_CLUSTER_VERSION:-v1.27.11}"
+KIND_CLUSTER_VERSION="${KIND_CLUSTER_VERSION:-v1.29.8}"
echo "# Creating a new Kubernetes cluster..."
kind delete cluster --name="${KIND_CLUSTER_NAME}"
diff --git a/hack/install-tekton.sh b/hack/install-tekton.sh
index 9953ebc416..56b8fc7c10 100755
--- a/hack/install-tekton.sh
+++ b/hack/install-tekton.sh
@@ -9,7 +9,7 @@
set -eu
-TEKTON_VERSION="${TEKTON_VERSION:-v0.65.0}"
+TEKTON_VERSION="${TEKTON_VERSION:-v0.65.1}"
TEKTON_HOST="github.com"
TEKTON_HOST_PATH="tektoncd/pipeline/releases/download"
diff --git a/pkg/reconciler/build/controller.go b/pkg/reconciler/build/controller.go
index fc04a2af28..08f15d9963 100644
--- a/pkg/reconciler/build/controller.go
+++ b/pkg/reconciler/build/controller.go
@@ -33,7 +33,7 @@ const (
name string = "name"
)
-type setOwnerReferenceFunc func(owner, object metav1.Object, scheme *runtime.Scheme) error
+type setOwnerReferenceFunc func(owner, object metav1.Object, scheme *runtime.Scheme, opts ...controllerutil.OwnerReferenceOption) error
// Add creates a new Build Controller and adds it to the Manager. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
@@ -58,10 +58,10 @@ func add(ctx context.Context, mgr manager.Manager, r reconcile.Reconciler, maxCo
return err
}
- pred := predicate.Funcs{
- UpdateFunc: func(e event.UpdateEvent) bool {
- o := e.ObjectOld.(*build.Build)
- n := e.ObjectNew.(*build.Build)
+ pred := predicate.TypedFuncs[*build.Build]{
+ UpdateFunc: func(e event.TypedUpdateEvent[*build.Build]) bool {
+ o := e.ObjectOld
+ n := e.ObjectNew
buildAtBuildDeletion := false
@@ -112,20 +112,20 @@ func add(ctx context.Context, mgr manager.Manager, r reconcile.Reconciler, maxCo
// or BuildRunDeletion annotation does not change
return o.GetGeneration() != n.GetGeneration() || buildAtBuildDeletion
},
- DeleteFunc: func(_ event.DeleteEvent) bool {
+ DeleteFunc: func(_ event.TypedDeleteEvent[*build.Build]) bool {
// Never reconcile on deletion, there is nothing we have to do
return false
},
}
// Watch for changes to primary resource Build
- if err = c.Watch(source.Kind(mgr.GetCache(), &build.Build{}), &handler.EnqueueRequestForObject{}, pred); err != nil {
+ if err = c.Watch(source.Kind(mgr.GetCache(), &build.Build{}, &handler.TypedEnqueueRequestForObject[*build.Build]{}, pred)); err != nil {
return err
}
- preSecret := predicate.Funcs{
+ preSecret := predicate.TypedFuncs[*corev1.Secret]{
// Only filter events where the secret have the Build specific annotation
- CreateFunc: func(e event.CreateEvent) bool {
+ CreateFunc: func(e event.TypedCreateEvent[*corev1.Secret]) bool {
objectAnnotations := e.Object.GetAnnotations()
if _, ok := buildCredentialsAnnotationExist(objectAnnotations); ok {
return true
@@ -135,7 +135,7 @@ func add(ctx context.Context, mgr manager.Manager, r reconcile.Reconciler, maxCo
// Only filter events where the secret have the Build specific annotation,
// but only if the Build specific annotation changed
- UpdateFunc: func(e event.UpdateEvent) bool {
+ UpdateFunc: func(e event.TypedUpdateEvent[*corev1.Secret]) bool {
oldAnnotations := e.ObjectOld.GetAnnotations()
newAnnotations := e.ObjectNew.GetAnnotations()
@@ -148,7 +148,7 @@ func add(ctx context.Context, mgr manager.Manager, r reconcile.Reconciler, maxCo
},
// Only filter events where the secret have the Build specific annotation
- DeleteFunc: func(e event.DeleteEvent) bool {
+ DeleteFunc: func(e event.TypedDeleteEvent[*corev1.Secret]) bool {
objectAnnotations := e.Object.GetAnnotations()
if _, ok := buildCredentialsAnnotationExist(objectAnnotations); ok {
return true
@@ -157,9 +157,7 @@ func add(ctx context.Context, mgr manager.Manager, r reconcile.Reconciler, maxCo
},
}
- return c.Watch(source.Kind(mgr.GetCache(), &corev1.Secret{}), handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, o client.Object) []reconcile.Request {
- secret := o.(*corev1.Secret)
-
+ return c.Watch(source.Kind(mgr.GetCache(), &corev1.Secret{}, handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, secret *corev1.Secret) []reconcile.Request {
buildList := &build.BuildList{}
// List all builds in the namespace of the current secret
@@ -201,7 +199,7 @@ func add(ctx context.Context, mgr manager.Manager, r reconcile.Reconciler, maxCo
}
}
return reconcileList
- }), preSecret)
+ }), preSecret))
}
func buildCredentialsAnnotationExist(annotation map[string]string) (string, bool) {
diff --git a/pkg/reconciler/buildlimitcleanup/controller.go b/pkg/reconciler/buildlimitcleanup/controller.go
index 805b96dd2d..4d09f0eaa6 100644
--- a/pkg/reconciler/buildlimitcleanup/controller.go
+++ b/pkg/reconciler/buildlimitcleanup/controller.go
@@ -11,7 +11,6 @@ import (
"github.com/shipwright-io/build/pkg/config"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
- "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
@@ -47,14 +46,14 @@ func add(mgr manager.Manager, r reconcile.Reconciler, maxConcurrentReconciles in
return err
}
- pred := predicate.Funcs{
- CreateFunc: func(e event.CreateEvent) bool {
- o := e.Object.(*buildv1beta1.Build)
+ pred := predicate.TypedFuncs[*buildv1beta1.Build]{
+ CreateFunc: func(e event.TypedCreateEvent[*buildv1beta1.Build]) bool {
+ o := e.Object
return o.Spec.Retention != nil && (o.Spec.Retention.FailedLimit != nil || o.Spec.Retention.SucceededLimit != nil)
},
- UpdateFunc: func(e event.UpdateEvent) bool {
- n := e.ObjectNew.(*buildv1beta1.Build)
- o := e.ObjectOld.(*buildv1beta1.Build)
+ UpdateFunc: func(e event.TypedUpdateEvent[*buildv1beta1.Build]) bool {
+ n := e.ObjectNew
+ o := e.ObjectOld
// Check to see if there are new retention parameters or whether the
// limit values have decreased
@@ -77,27 +76,27 @@ func add(mgr manager.Manager, r reconcile.Reconciler, maxConcurrentReconciles in
}
return false
},
- DeleteFunc: func(_ event.DeleteEvent) bool {
+ DeleteFunc: func(_ event.TypedDeleteEvent[*buildv1beta1.Build]) bool {
// Never reconcile on deletion, there is nothing we have to do
return false
},
}
- predBuildRun := predicate.Funcs{
- CreateFunc: func(_ event.CreateEvent) bool {
+ predBuildRun := predicate.TypedFuncs[*buildv1beta1.BuildRun]{
+ CreateFunc: func(_ event.TypedCreateEvent[*buildv1beta1.BuildRun]) bool {
// Never reconcile in case of create buildrun event
return false
},
// Reconcile the build the related buildrun has just completed
- UpdateFunc: func(e event.UpdateEvent) bool {
- n := e.ObjectNew.(*buildv1beta1.BuildRun)
+ UpdateFunc: func(e event.TypedUpdateEvent[*buildv1beta1.BuildRun]) bool {
+ n := e.ObjectNew
// check if Buildrun is related to a build
if n.Spec.Build.Name == nil {
return false
}
- o := e.ObjectOld.(*buildv1beta1.BuildRun)
+ o := e.ObjectOld
oldCondition := o.Status.GetCondition(buildv1beta1.Succeeded)
newCondition := n.Status.GetCondition(buildv1beta1.Succeeded)
if newCondition != nil {
@@ -108,21 +107,19 @@ func add(mgr manager.Manager, r reconcile.Reconciler, maxConcurrentReconciles in
}
return false
},
- DeleteFunc: func(_ event.DeleteEvent) bool {
+ DeleteFunc: func(_ event.TypedDeleteEvent[*buildv1beta1.BuildRun]) bool {
// Never reconcile on deletion, there is nothing we have to do
return false
},
}
// Watch for changes to primary resource Build
- if err = c.Watch(source.Kind(mgr.GetCache(), &buildv1beta1.Build{}), &handler.EnqueueRequestForObject{}, pred); err != nil {
+ if err = c.Watch(source.Kind(mgr.GetCache(), &buildv1beta1.Build{}, &handler.TypedEnqueueRequestForObject[*buildv1beta1.Build]{}, pred)); err != nil {
return err
}
// Watch for changes to resource BuildRun
- return c.Watch(source.Kind(mgr.GetCache(), &buildv1beta1.BuildRun{}), handler.EnqueueRequestsFromMapFunc(func(_ context.Context, o client.Object) []reconcile.Request {
- buildRun := o.(*buildv1beta1.BuildRun)
-
+ return c.Watch(source.Kind(mgr.GetCache(), &buildv1beta1.BuildRun{}, handler.TypedEnqueueRequestsFromMapFunc(func(_ context.Context, buildRun *buildv1beta1.BuildRun) []reconcile.Request {
return []reconcile.Request{
{
NamespacedName: types.NamespacedName{
@@ -131,5 +128,5 @@ func add(mgr manager.Manager, r reconcile.Reconciler, maxConcurrentReconciles in
},
},
}
- }), predBuildRun)
+ }), predBuildRun))
}
diff --git a/pkg/reconciler/buildrun/buildrun_test.go b/pkg/reconciler/buildrun/buildrun_test.go
index 3fd6d765e9..ae3ef627b5 100644
--- a/pkg/reconciler/buildrun/buildrun_test.go
+++ b/pkg/reconciler/buildrun/buildrun_test.go
@@ -946,7 +946,7 @@ var _ = Describe("Reconcile BuildRun", func() {
statusWriter.UpdateCalls(statusCall)
reconciler = buildrunctl.NewReconciler(config.NewDefaultConfig(), manager,
- func(owner, object metav1.Object, scheme *runtime.Scheme) error {
+ func(owner, object metav1.Object, scheme *runtime.Scheme, _ ...controllerutil.OwnerReferenceOption) error {
return fmt.Errorf("foobar error")
})
diff --git a/pkg/reconciler/buildrun/controller.go b/pkg/reconciler/buildrun/controller.go
index f6c0974868..a725d282ea 100644
--- a/pkg/reconciler/buildrun/controller.go
+++ b/pkg/reconciler/buildrun/controller.go
@@ -13,7 +13,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
- "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/event"
@@ -27,7 +26,7 @@ import (
"github.com/shipwright-io/build/pkg/config"
)
-type setOwnerReferenceFunc func(owner, object metav1.Object, scheme *runtime.Scheme) error
+type setOwnerReferenceFunc func(owner, object metav1.Object, scheme *runtime.Scheme, opts ...controllerutil.OwnerReferenceOption) error
// Add creates a new BuildRun Controller and adds it to the Manager. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
@@ -51,38 +50,32 @@ func add(mgr manager.Manager, r reconcile.Reconciler, maxConcurrentReconciles in
return err
}
- predBuildRun := predicate.Funcs{
- CreateFunc: func(e event.CreateEvent) bool {
- o := e.Object.(*buildv1beta1.BuildRun)
-
+ predBuildRun := predicate.TypedFuncs[*buildv1beta1.BuildRun]{
+ CreateFunc: func(e event.TypedCreateEvent[*buildv1beta1.BuildRun]) bool {
// The CreateFunc is also called when the controller is started and iterates over all objects. For those BuildRuns that have a TaskRun referenced already,
// we do not need to do a further reconciliation. BuildRun updates then only happen from the TaskRun.
- return o.Status.TaskRunName == nil && o.Status.CompletionTime == nil
+ return e.Object.Status.TaskRunName == nil && e.Object.Status.CompletionTime == nil
},
- UpdateFunc: func(e event.UpdateEvent) bool {
- // Ignore updates to CR status in which case metadata.Generation does not change
- o := e.ObjectOld.(*buildv1beta1.BuildRun)
- n := e.ObjectNew.(*buildv1beta1.BuildRun)
-
+ UpdateFunc: func(e event.TypedUpdateEvent[*buildv1beta1.BuildRun]) bool {
// Only reconcile a BuildRun update when
// - it is set to canceled
switch {
- case !o.IsCanceled() && n.IsCanceled():
+ case !e.ObjectOld.IsCanceled() && e.ObjectNew.IsCanceled():
return true
}
return false
},
- DeleteFunc: func(_ event.DeleteEvent) bool {
+ DeleteFunc: func(_ event.TypedDeleteEvent[*buildv1beta1.BuildRun]) bool {
// Never reconcile on deletion, there is nothing we have to do
return false
},
}
- predTaskRun := predicate.Funcs{
- UpdateFunc: func(e event.UpdateEvent) bool {
- o := e.ObjectOld.(*pipelineapi.TaskRun)
- n := e.ObjectNew.(*pipelineapi.TaskRun)
+ predTaskRun := predicate.TypedFuncs[*pipelineapi.TaskRun]{
+ UpdateFunc: func(e event.TypedUpdateEvent[*pipelineapi.TaskRun]) bool {
+ o := e.ObjectOld
+ n := e.ObjectNew
// Process an update event when the old TR resource is not yet started and the new TR resource got a
// condition of the type Succeeded
@@ -98,24 +91,20 @@ func add(mgr manager.Manager, r reconcile.Reconciler, maxConcurrentReconciles in
}
return false
},
- DeleteFunc: func(e event.DeleteEvent) bool {
- o := e.Object.(*pipelineapi.TaskRun)
-
+ DeleteFunc: func(e event.TypedDeleteEvent[*pipelineapi.TaskRun]) bool {
// If the TaskRun was deleted before completion, then we reconcile to update the BuildRun to a Failed status
- return o.Status.CompletionTime == nil
+ return e.Object.Status.CompletionTime == nil
},
}
// Watch for changes to primary resource BuildRun
- if err = c.Watch(source.Kind(mgr.GetCache(), &buildv1beta1.BuildRun{}), &handler.EnqueueRequestForObject{}, predBuildRun); err != nil {
+ if err = c.Watch(source.Kind[*buildv1beta1.BuildRun](mgr.GetCache(), &buildv1beta1.BuildRun{}, &handler.TypedEnqueueRequestForObject[*buildv1beta1.BuildRun]{}, predBuildRun)); err != nil {
return err
}
// enqueue Reconciles requests only for events where a TaskRun already exists and that is related
// to a BuildRun
- return c.Watch(source.Kind(mgr.GetCache(), &pipelineapi.TaskRun{}), handler.EnqueueRequestsFromMapFunc(func(_ context.Context, o client.Object) []reconcile.Request {
- taskRun := o.(*pipelineapi.TaskRun)
-
+ return c.Watch(source.Kind(mgr.GetCache(), &pipelineapi.TaskRun{}, handler.TypedEnqueueRequestsFromMapFunc(func(_ context.Context, taskRun *pipelineapi.TaskRun) []reconcile.Request {
// check if TaskRun is related to BuildRun
if taskRun.GetLabels() == nil || taskRun.GetLabels()[buildv1beta1.LabelBuildRun] == "" {
return []reconcile.Request{}
@@ -129,5 +118,5 @@ func add(mgr manager.Manager, r reconcile.Reconciler, maxConcurrentReconciles in
},
},
}
- }), predTaskRun)
+ }), predTaskRun))
}
diff --git a/pkg/reconciler/buildrunttlcleanup/controller.go b/pkg/reconciler/buildrunttlcleanup/controller.go
index d21f0857e9..e4ea0700f9 100644
--- a/pkg/reconciler/buildrunttlcleanup/controller.go
+++ b/pkg/reconciler/buildrunttlcleanup/controller.go
@@ -95,47 +95,42 @@ func add(mgr manager.Manager, r reconcile.Reconciler, maxConcurrentReconciles in
return err
}
- predBuildRun := predicate.Funcs{
- CreateFunc: func(e event.CreateEvent) bool {
- // Reconcile if TTL values are set
- o := e.Object.(*buildv1beta1.BuildRun)
-
+ predBuildRun := predicate.TypedFuncs[*buildv1beta1.BuildRun]{
+ CreateFunc: func(e event.TypedCreateEvent[*buildv1beta1.BuildRun]) bool {
// ignore a running BuildRun
- condition := o.Status.GetCondition(buildv1beta1.Succeeded)
+ condition := e.Object.Status.GetCondition(buildv1beta1.Succeeded)
if condition == nil || condition.Status == corev1.ConditionUnknown {
return false
}
- return reconcileCompletedBuildRun(condition, o)
+ return reconcileCompletedBuildRun(condition, e.Object)
},
- UpdateFunc: func(e event.UpdateEvent) bool {
+ UpdateFunc: func(e event.TypedUpdateEvent[*buildv1beta1.BuildRun]) bool {
// check if the updated object is completed
- n := e.ObjectNew.(*buildv1beta1.BuildRun)
- newCondition := n.Status.GetCondition(buildv1beta1.Succeeded)
+ newCondition := e.ObjectNew.Status.GetCondition(buildv1beta1.Succeeded)
if newCondition == nil || newCondition.Status == corev1.ConditionUnknown {
return false
}
- o := e.ObjectOld.(*buildv1beta1.BuildRun)
- oldCondition := o.Status.GetCondition(buildv1beta1.Succeeded)
+ oldCondition := e.ObjectOld.Status.GetCondition(buildv1beta1.Succeeded)
// for objects that failed or just completed, check if a matching TTL is set
if oldCondition == nil || oldCondition.Status == corev1.ConditionUnknown {
- return reconcileCompletedBuildRun(newCondition, n)
+ return reconcileCompletedBuildRun(newCondition, e.ObjectNew)
}
// for objects that were already complete, check if the TTL was lowered or introduced
if oldCondition != nil && oldCondition.Status != corev1.ConditionUnknown {
- return reconcileAlreadyCompletedBuildRun(newCondition, n, o)
+ return reconcileAlreadyCompletedBuildRun(newCondition, e.ObjectNew, e.ObjectOld)
}
return false
},
- DeleteFunc: func(_ event.DeleteEvent) bool {
+ DeleteFunc: func(_ event.TypedDeleteEvent[*buildv1beta1.BuildRun]) bool {
// Never reconcile on deletion, there is nothing we have to do
return false
},
}
// Watch for changes to primary resource BuildRun
- return c.Watch(source.Kind(mgr.GetCache(), &buildv1beta1.BuildRun{}), &handler.EnqueueRequestForObject{}, predBuildRun)
+ return c.Watch(source.Kind(mgr.GetCache(), &buildv1beta1.BuildRun{}, &handler.TypedEnqueueRequestForObject[*buildv1beta1.BuildRun]{}, predBuildRun))
}
diff --git a/pkg/reconciler/buildstrategy/controller.go b/pkg/reconciler/buildstrategy/controller.go
index fc7d31363c..403036753d 100644
--- a/pkg/reconciler/buildstrategy/controller.go
+++ b/pkg/reconciler/buildstrategy/controller.go
@@ -40,5 +40,5 @@ func add(mgr manager.Manager, r reconcile.Reconciler, maxConcurrentReconciles in
}
// Watch for changes to primary resource BuildStrategy
- return c.Watch(source.Kind(mgr.GetCache(), &buildv1beta1.BuildStrategy{}), &handler.EnqueueRequestForObject{})
+ return c.Watch(source.Kind(mgr.GetCache(), &buildv1beta1.BuildStrategy{}, &handler.TypedEnqueueRequestForObject[*buildv1beta1.BuildStrategy]{}))
}
diff --git a/pkg/reconciler/clusterbuildstrategy/controller.go b/pkg/reconciler/clusterbuildstrategy/controller.go
index 789bd26778..614aad25f7 100644
--- a/pkg/reconciler/clusterbuildstrategy/controller.go
+++ b/pkg/reconciler/clusterbuildstrategy/controller.go
@@ -40,5 +40,5 @@ func add(mgr manager.Manager, r reconcile.Reconciler, maxConcurrentReconciles in
}
// Watch for changes to primary resource ClusterBuildStrategy
- return c.Watch(source.Kind(mgr.GetCache(), &buildv1beta1.ClusterBuildStrategy{}), &handler.EnqueueRequestForObject{})
+ return c.Watch(source.Kind(mgr.GetCache(), &buildv1beta1.ClusterBuildStrategy{}, &handler.TypedEnqueueRequestForObject[*buildv1beta1.ClusterBuildStrategy]{}))
}
diff --git a/vendor/dario.cat/mergo/.gitignore b/vendor/dario.cat/mergo/.gitignore
index 529c3412ba..45ad0f1ae3 100644
--- a/vendor/dario.cat/mergo/.gitignore
+++ b/vendor/dario.cat/mergo/.gitignore
@@ -13,6 +13,9 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
+# Golang/Intellij
+.idea
+
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/
diff --git a/vendor/dario.cat/mergo/README.md b/vendor/dario.cat/mergo/README.md
index 7d0cf9f32a..0b3c488893 100644
--- a/vendor/dario.cat/mergo/README.md
+++ b/vendor/dario.cat/mergo/README.md
@@ -44,13 +44,21 @@ Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the
## Status
-It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, Microsoft, etc](https://github.com/imdario/mergo#mergo-in-the-wild).
+Mergo is stable and frozen, ready for production. Check a short list of the projects using at large scale it [here](https://github.com/imdario/mergo#mergo-in-the-wild).
+
+No new features are accepted. They will be considered for a future v2 that improves the implementation and fixes bugs for corner cases.
### Important notes
#### 1.0.0
-In [1.0.0](//github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL `dario.cat/mergo`.
+In [1.0.0](//github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL `dario.cat/mergo`. No more v1 versions will be released.
+
+If the vanity URL is causing issues in your project due to a dependency pulling Mergo - it isn't a direct dependency in your project - it is recommended to use [replace](https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive) to pin the version to the last one with the old import URL:
+
+```
+replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.16
+```
#### 0.3.9
@@ -64,55 +72,24 @@ If you were using Mergo before April 6th, 2015, please check your project works
If Mergo is useful to you, consider buying me a coffee, a beer, or making a monthly donation to allow me to keep building great free software. :heart_eyes:
-
### Mergo in the wild
-- [moby/moby](https://github.com/moby/moby)
-- [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)
-- [vmware/dispatch](https://github.com/vmware/dispatch)
-- [Shopify/themekit](https://github.com/Shopify/themekit)
-- [imdario/zas](https://github.com/imdario/zas)
-- [matcornic/hermes](https://github.com/matcornic/hermes)
-- [OpenBazaar/openbazaar-go](https://github.com/OpenBazaar/openbazaar-go)
-- [kataras/iris](https://github.com/kataras/iris)
-- [michaelsauter/crane](https://github.com/michaelsauter/crane)
-- [go-task/task](https://github.com/go-task/task)
-- [sensu/uchiwa](https://github.com/sensu/uchiwa)
-- [ory/hydra](https://github.com/ory/hydra)
-- [sisatech/vcli](https://github.com/sisatech/vcli)
-- [dairycart/dairycart](https://github.com/dairycart/dairycart)
-- [projectcalico/felix](https://github.com/projectcalico/felix)
-- [resin-os/balena](https://github.com/resin-os/balena)
-- [go-kivik/kivik](https://github.com/go-kivik/kivik)
-- [Telefonica/govice](https://github.com/Telefonica/govice)
-- [supergiant/supergiant](supergiant/supergiant)
-- [SergeyTsalkov/brooce](https://github.com/SergeyTsalkov/brooce)
-- [soniah/dnsmadeeasy](https://github.com/soniah/dnsmadeeasy)
-- [ohsu-comp-bio/funnel](https://github.com/ohsu-comp-bio/funnel)
-- [EagerIO/Stout](https://github.com/EagerIO/Stout)
-- [lynndylanhurley/defsynth-api](https://github.com/lynndylanhurley/defsynth-api)
-- [russross/canvasassignments](https://github.com/russross/canvasassignments)
-- [rdegges/cryptly-api](https://github.com/rdegges/cryptly-api)
-- [casualjim/exeggutor](https://github.com/casualjim/exeggutor)
-- [divshot/gitling](https://github.com/divshot/gitling)
-- [RWJMurphy/gorl](https://github.com/RWJMurphy/gorl)
-- [andrerocker/deploy42](https://github.com/andrerocker/deploy42)
-- [elwinar/rambler](https://github.com/elwinar/rambler)
-- [tmaiaroto/gopartman](https://github.com/tmaiaroto/gopartman)
-- [jfbus/impressionist](https://github.com/jfbus/impressionist)
-- [Jmeyering/zealot](https://github.com/Jmeyering/zealot)
-- [godep-migrator/rigger-host](https://github.com/godep-migrator/rigger-host)
-- [Dronevery/MultiwaySwitch-Go](https://github.com/Dronevery/MultiwaySwitch-Go)
-- [thoas/picfit](https://github.com/thoas/picfit)
-- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server)
-- [jnuthong/item_search](https://github.com/jnuthong/item_search)
-- [bukalapak/snowboard](https://github.com/bukalapak/snowboard)
-- [containerssh/containerssh](https://github.com/containerssh/containerssh)
-- [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
-- [tjpnz/structbot](https://github.com/tjpnz/structbot)
+Mergo is used by [thousands](https://deps.dev/go/dario.cat%2Fmergo/v1.0.0/dependents) [of](https://deps.dev/go/github.com%2Fimdario%2Fmergo/v0.3.16/dependents) [projects](https://deps.dev/go/github.com%2Fimdario%2Fmergo/v0.3.12), including:
+
+* [containerd/containerd](https://github.com/containerd/containerd)
+* [datadog/datadog-agent](https://github.com/datadog/datadog-agent)
+* [docker/cli/](https://github.com/docker/cli/)
+* [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
+* [go-micro/go-micro](https://github.com/go-micro/go-micro)
+* [grafana/loki](https://github.com/grafana/loki)
+* [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)
+* [masterminds/sprig](github.com/Masterminds/sprig)
+* [moby/moby](https://github.com/moby/moby)
+* [slackhq/nebula](https://github.com/slackhq/nebula)
+* [volcano-sh/volcano](https://github.com/volcano-sh/volcano)
## Install
@@ -141,6 +118,39 @@ if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
}
```
+If you need to override pointers, so the source pointer's value is assigned to the destination's pointer, you must use `WithoutDereference`:
+
+```go
+package main
+
+import (
+ "fmt"
+
+ "dario.cat/mergo"
+)
+
+type Foo struct {
+ A *string
+ B int64
+}
+
+func main() {
+ first := "first"
+ second := "second"
+ src := Foo{
+ A: &first,
+ B: 2,
+ }
+
+ dest := Foo{
+ A: &second,
+ B: 1,
+ }
+
+ mergo.Merge(&dest, src, mergo.WithOverride, mergo.WithoutDereference)
+}
+```
+
Additionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field.
```go
diff --git a/vendor/dario.cat/mergo/map.go b/vendor/dario.cat/mergo/map.go
index b50d5c2a4e..759b4f74fd 100644
--- a/vendor/dario.cat/mergo/map.go
+++ b/vendor/dario.cat/mergo/map.go
@@ -58,7 +58,7 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, conf
}
fieldName := field.Name
fieldName = changeInitialCase(fieldName, unicode.ToLower)
- if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v), !config.ShouldNotDereference) || overwrite) {
+ if _, ok := dstMap[fieldName]; !ok || (!isEmptyValue(reflect.ValueOf(src.Field(i).Interface()), !config.ShouldNotDereference) && overwrite) || config.overwriteWithEmptyValue {
dstMap[fieldName] = src.Field(i).Interface()
}
}
diff --git a/vendor/dario.cat/mergo/merge.go b/vendor/dario.cat/mergo/merge.go
index 0ef9b2138c..fd47c95b2b 100644
--- a/vendor/dario.cat/mergo/merge.go
+++ b/vendor/dario.cat/mergo/merge.go
@@ -269,7 +269,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
return
}
- } else {
+ } else if src.Elem().Kind() != reflect.Struct {
if overwriteWithEmptySrc || (overwrite && !src.IsNil()) || dst.IsNil() {
dst.Set(src)
}
diff --git a/vendor/github.com/antlr4-go/antlr/v4/antlrdoc.go b/vendor/github.com/antlr4-go/antlr/v4/antlrdoc.go
index 3bb4fd7c4e..48bd362bf5 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/antlrdoc.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/antlrdoc.go
@@ -17,9 +17,9 @@ ANTLR4 that it is compatible with (I.E. uses the /v4 path).
However, this was found to be problematic, as it meant that with the runtime embedded so far underneath the root
of the repo, the `go get` and related commands could not properly resolve the location of the go runtime source code.
This meant that the reference to the runtime in your `go.mod` file would refer to the correct source code, but would not
-list the release tag such as @4.12.0 - this was confusing, to say the least.
+list the release tag such as @4.13.1 - this was confusing, to say the least.
-As of 4.12.1, the runtime is now available as a go module in its own repo, and can be imported as `github.com/antlr4-go/antlr`
+As of 4.13.0, the runtime is now available as a go module in its own repo, and can be imported as `github.com/antlr4-go/antlr`
(the go get command should also be used with this path). See the main documentation for the ANTLR4 project for more information,
which is available at [ANTLR docs]. The documentation for using the Go runtime is available at [Go runtime docs].
@@ -49,7 +49,7 @@ Here is a general/recommended template for an ANTLR based recognizer in Go:
.
├── parser
│ ├── mygrammar.g4
- │ ├── antlr-4.12.1-complete.jar
+ │ ├── antlr-4.13.1-complete.jar
│ ├── generate.go
│ └── generate.sh
├── parsing - generated code goes here
@@ -71,7 +71,7 @@ And the generate.sh file will look similar to this:
#!/bin/sh
- alias antlr4='java -Xmx500M -cp "./antlr4-4.12.1-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
+ alias antlr4='java -Xmx500M -cp "./antlr4-4.13.1-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
antlr4 -Dlanguage=Go -no-visitor -package parsing *.g4
depending on whether you want visitors or listeners or any other ANTLR options. Not that another option here
diff --git a/vendor/github.com/antlr4-go/antlr/v4/atn.go b/vendor/github.com/antlr4-go/antlr/v4/atn.go
index cdeefed247..e749ebd0cf 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/atn.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/atn.go
@@ -4,8 +4,6 @@
package antlr
-import "sync"
-
// ATNInvalidAltNumber is used to represent an ALT number that has yet to be calculated or
// which is invalid for a particular struct such as [*antlr.BaseRuleContext]
var ATNInvalidAltNumber int
@@ -56,9 +54,9 @@ type ATN struct {
//
states []ATNState
- mu sync.Mutex
- stateMu sync.RWMutex
- edgeMu sync.RWMutex
+ mu Mutex
+ stateMu RWMutex
+ edgeMu RWMutex
}
// NewATN returns a new ATN struct representing the given grammarType and is used
diff --git a/vendor/github.com/antlr4-go/antlr/v4/atn_config.go b/vendor/github.com/antlr4-go/antlr/v4/atn_config.go
index a83f25d349..267308bb3d 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/atn_config.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/atn_config.go
@@ -73,9 +73,6 @@ func NewATNConfig1(c *ATNConfig, state ATNState, context *PredictionContext) *AT
// NewATNConfig creates a new ATNConfig instance given an existing config, a state, a context and a semantic context, other 'constructors'
// are just wrappers around this one.
func NewATNConfig(c *ATNConfig, state ATNState, context *PredictionContext, semanticContext SemanticContext) *ATNConfig {
- if semanticContext == nil {
- panic("semanticContext cannot be nil") // TODO: Remove this - probably put here for some bug that is now fixed
- }
b := &ATNConfig{}
b.InitATNConfig(c, state, c.GetAlt(), context, semanticContext)
b.cType = parserConfig
diff --git a/vendor/github.com/antlr4-go/antlr/v4/input_stream.go b/vendor/github.com/antlr4-go/antlr/v4/input_stream.go
index b737fe85fb..ab4e96be52 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/input_stream.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/input_stream.go
@@ -148,7 +148,7 @@ func (is *InputStream) GetTextFromInterval(i Interval) string {
}
func (*InputStream) GetSourceName() string {
- return ""
+ return "Obtained from string"
}
// String returns the entire input stream as a string
diff --git a/vendor/github.com/antlr4-go/antlr/v4/jcollect.go b/vendor/github.com/antlr4-go/antlr/v4/jcollect.go
index ceccd96d25..6d668f7983 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/jcollect.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/jcollect.go
@@ -8,7 +8,6 @@ import (
"container/list"
"runtime/debug"
"sort"
- "sync"
)
// Collectable is an interface that a struct should implement if it is to be
@@ -587,12 +586,12 @@ type VisitRecord struct {
type VisitList struct {
cache *list.List
- lock sync.RWMutex
+ lock RWMutex
}
var visitListPool = VisitList{
cache: list.New(),
- lock: sync.RWMutex{},
+ lock: RWMutex{},
}
// NewVisitRecord returns a new VisitRecord instance from the pool if available.
diff --git a/vendor/github.com/antlr4-go/antlr/v4/lexer.go b/vendor/github.com/antlr4-go/antlr/v4/lexer.go
index 3c7896a918..e5594b2168 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/lexer.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/lexer.go
@@ -207,7 +207,7 @@ func (b *BaseLexer) NextToken() Token {
for {
b.thetype = TokenInvalidType
- ttype := b.safeMatch()
+ ttype := b.safeMatch() // Defaults to LexerSkip
if b.input.LA(1) == TokenEOF {
b.hitEOF = true
diff --git a/vendor/github.com/antlr4-go/antlr/v4/ll1_analyzer.go b/vendor/github.com/antlr4-go/antlr/v4/ll1_analyzer.go
index 4955ac876f..dfdff000bc 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/ll1_analyzer.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/ll1_analyzer.go
@@ -40,6 +40,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet {
for alt := 0; alt < count; alt++ {
look[alt] = NewIntervalSet()
+ // TODO: This is one of the reasons that ATNConfigs are allocated and freed all the time - fix this tomorrow jim!
lookBusy := NewJStore[*ATNConfig, Comparator[*ATNConfig]](aConfEqInst, ClosureBusyCollection, "LL1Analyzer.getDecisionLookahead for lookBusy")
la.look1(s.GetTransitions()[alt].getTarget(), nil, BasePredictionContextEMPTY, look[alt], lookBusy, NewBitSet(), false, false)
diff --git a/vendor/github.com/antlr4-go/antlr/v4/mutex.go b/vendor/github.com/antlr4-go/antlr/v4/mutex.go
new file mode 100644
index 0000000000..2b0cda4745
--- /dev/null
+++ b/vendor/github.com/antlr4-go/antlr/v4/mutex.go
@@ -0,0 +1,41 @@
+//go:build !antlr.nomutex
+// +build !antlr.nomutex
+
+package antlr
+
+import "sync"
+
+// Mutex is a simple mutex implementation which just delegates to sync.Mutex, it
+// is used to provide a mutex implementation for the antlr package, which users
+// can turn off with the build tag -tags antlr.nomutex
+type Mutex struct {
+ mu sync.Mutex
+}
+
+func (m *Mutex) Lock() {
+ m.mu.Lock()
+}
+
+func (m *Mutex) Unlock() {
+ m.mu.Unlock()
+}
+
+type RWMutex struct {
+ mu sync.RWMutex
+}
+
+func (m *RWMutex) Lock() {
+ m.mu.Lock()
+}
+
+func (m *RWMutex) Unlock() {
+ m.mu.Unlock()
+}
+
+func (m *RWMutex) RLock() {
+ m.mu.RLock()
+}
+
+func (m *RWMutex) RUnlock() {
+ m.mu.RUnlock()
+}
diff --git a/vendor/github.com/antlr4-go/antlr/v4/mutex_nomutex.go b/vendor/github.com/antlr4-go/antlr/v4/mutex_nomutex.go
new file mode 100644
index 0000000000..35ce4353ee
--- /dev/null
+++ b/vendor/github.com/antlr4-go/antlr/v4/mutex_nomutex.go
@@ -0,0 +1,32 @@
+//go:build antlr.nomutex
+// +build antlr.nomutex
+
+package antlr
+
+type Mutex struct{}
+
+func (m *Mutex) Lock() {
+ // No-op
+}
+
+func (m *Mutex) Unlock() {
+ // No-op
+}
+
+type RWMutex struct{}
+
+func (m *RWMutex) Lock() {
+ // No-op
+}
+
+func (m *RWMutex) Unlock() {
+ // No-op
+}
+
+func (m *RWMutex) RLock() {
+ // No-op
+}
+
+func (m *RWMutex) RUnlock() {
+ // No-op
+}
diff --git a/vendor/github.com/antlr4-go/antlr/v4/parser_atn_simulator.go b/vendor/github.com/antlr4-go/antlr/v4/parser_atn_simulator.go
index ae2869692a..724fa17a19 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/parser_atn_simulator.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/parser_atn_simulator.go
@@ -10,8 +10,6 @@ import (
"strings"
)
-var ()
-
// ClosureBusy is a store of ATNConfigs and is a tiny abstraction layer over
// a standard JStore so that we can use Lazy instantiation of the JStore, mostly
// to avoid polluting the stats module with a ton of JStore instances with nothing in them.
@@ -883,7 +881,7 @@ func (p *ParserATNSimulator) getPredicatePredictions(ambigAlts *BitSet, altToPre
// the ERROR state was reached, outerContext as the initial parser context from the paper
// or the parser stack at the instant before prediction commences.
//
-// Teh func returns the value to return from [AdaptivePredict], or
+// The func returns the value to return from [AdaptivePredict], or
// [ATNInvalidAltNumber] if a suitable alternative was not
// identified and [AdaptivePredict] should report an error instead.
func (p *ParserATNSimulator) getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(configs *ATNConfigSet, outerContext ParserRuleContext) int {
diff --git a/vendor/github.com/antlr4-go/antlr/v4/prediction_context.go b/vendor/github.com/antlr4-go/antlr/v4/prediction_context.go
index c1b80cc1f0..a1d5186b8f 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/prediction_context.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/prediction_context.go
@@ -6,7 +6,6 @@ package antlr
import (
"fmt"
- "golang.org/x/exp/slices"
"strconv"
)
@@ -101,7 +100,7 @@ func NewArrayPredictionContext(parents []*PredictionContext, returnStates []int)
hash = murmurUpdate(hash, returnState)
}
hash = murmurFinish(hash, len(parents)<<1)
-
+
nec := &PredictionContext{}
nec.cachedHash = hash
nec.pcType = PredictionContextArray
@@ -115,6 +114,9 @@ func (p *PredictionContext) Hash() int {
}
func (p *PredictionContext) Equals(other Collectable[*PredictionContext]) bool {
+ if p == other {
+ return true
+ }
switch p.pcType {
case PredictionContextEmpty:
otherP := other.(*PredictionContext)
@@ -138,13 +140,11 @@ func (p *PredictionContext) ArrayEquals(o Collectable[*PredictionContext]) bool
if p.cachedHash != other.Hash() {
return false // can't be same if hash is different
}
-
+
// Must compare the actual array elements and not just the array address
//
- return slices.Equal(p.returnStates, other.returnStates) &&
- slices.EqualFunc(p.parents, other.parents, func(x, y *PredictionContext) bool {
- return x.Equals(y)
- })
+ return intSlicesEqual(p.returnStates, other.returnStates) &&
+ pcSliceEqual(p.parents, other.parents)
}
func (p *PredictionContext) SingletonEquals(other Collectable[*PredictionContext]) bool {
@@ -152,23 +152,23 @@ func (p *PredictionContext) SingletonEquals(other Collectable[*PredictionContext
return false
}
otherP := other.(*PredictionContext)
- if otherP == nil {
+ if otherP == nil || otherP.pcType != PredictionContextSingleton {
return false
}
-
+
if p.cachedHash != otherP.Hash() {
return false // Can't be same if hash is different
}
-
+
if p.returnState != otherP.getReturnState(0) {
return false
}
-
+
// Both parents must be nil if one is
if p.parentCtx == nil {
return otherP.parentCtx == nil
}
-
+
return p.parentCtx.Equals(otherP.parentCtx)
}
@@ -225,27 +225,27 @@ func (p *PredictionContext) String() string {
return "$"
case PredictionContextSingleton:
var up string
-
+
if p.parentCtx == nil {
up = ""
} else {
up = p.parentCtx.String()
}
-
+
if len(up) == 0 {
if p.returnState == BasePredictionContextEmptyReturnState {
return "$"
}
-
+
return strconv.Itoa(p.returnState)
}
-
+
return strconv.Itoa(p.returnState) + " " + up
case PredictionContextArray:
if p.isEmpty() {
return "[]"
}
-
+
s := "["
for i := 0; i < len(p.returnStates); i++ {
if i > 0 {
@@ -263,7 +263,7 @@ func (p *PredictionContext) String() string {
}
}
return s + "]"
-
+
default:
return "unknown"
}
@@ -309,18 +309,18 @@ func predictionContextFromRuleContext(a *ATN, outerContext RuleContext) *Predict
parent := predictionContextFromRuleContext(a, outerContext.GetParent().(RuleContext))
state := a.states[outerContext.GetInvokingState()]
transition := state.GetTransitions()[0]
-
+
return SingletonBasePredictionContextCreate(parent, transition.(*RuleTransition).followState.GetStateNumber())
}
func merge(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMap) *PredictionContext {
-
+
// Share same graph if both same
//
if a == b || a.Equals(b) {
return a
}
-
+
if a.pcType == PredictionContextSingleton && b.pcType == PredictionContextSingleton {
return mergeSingletons(a, b, rootIsWildcard, mergeCache)
}
@@ -334,7 +334,7 @@ func merge(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMap) *Pr
return b
}
}
-
+
// Convert either Singleton or Empty to arrays, so that we can merge them
//
ara := convertToArray(a)
@@ -395,7 +395,7 @@ func mergeSingletons(a, b *PredictionContext, rootIsWildcard bool, mergeCache *J
return previous
}
}
-
+
rootMerge := mergeRoot(a, b, rootIsWildcard)
if rootMerge != nil {
if mergeCache != nil {
@@ -564,7 +564,7 @@ func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMa
i := 0 // walks a
j := 0 // walks b
k := 0 // walks target M array
-
+
mergedReturnStates := make([]int, len(a.returnStates)+len(b.returnStates))
mergedParents := make([]*PredictionContext, len(a.returnStates)+len(b.returnStates))
// walk and merge to yield mergedParents, mergedReturnStates
@@ -626,9 +626,9 @@ func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMa
mergedParents = mergedParents[0:k]
mergedReturnStates = mergedReturnStates[0:k]
}
-
+
M := NewArrayPredictionContext(mergedParents, mergedReturnStates)
-
+
// if we created same array as a or b, return that instead
// TODO: JI track whether this is possible above during merge sort for speed and possibly avoid an allocation
if M.Equals(a) {
@@ -650,7 +650,7 @@ func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMa
return b
}
combineCommonParents(&mergedParents)
-
+
if mergeCache != nil {
mergeCache.Put(a, b, M)
}
@@ -666,7 +666,7 @@ func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMa
//goland:noinspection GoUnusedFunction
func combineCommonParents(parents *[]*PredictionContext) {
uniqueParents := NewJStore[*PredictionContext, Comparator[*PredictionContext]](pContextEqInst, PredictionContextCollection, "combineCommonParents for PredictionContext")
-
+
for p := 0; p < len(*parents); p++ {
parent := (*parents)[p]
_, _ = uniqueParents.Put(parent)
@@ -685,7 +685,7 @@ func getCachedBasePredictionContext(context *PredictionContext, contextCache *Pr
if present {
return existing
}
-
+
existing, present = contextCache.Get(context)
if present {
visited.Put(context, existing)
@@ -722,6 +722,6 @@ func getCachedBasePredictionContext(context *PredictionContext, contextCache *Pr
contextCache.add(updated)
visited.Put(updated, updated)
visited.Put(context, updated)
-
+
return updated
}
diff --git a/vendor/github.com/antlr4-go/antlr/v4/recognizer.go b/vendor/github.com/antlr4-go/antlr/v4/recognizer.go
index 2e0b504fb3..dcb8548cd1 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/recognizer.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/recognizer.go
@@ -56,7 +56,7 @@ var tokenTypeMapCache = make(map[string]int)
var ruleIndexMapCache = make(map[string]int)
func (b *BaseRecognizer) checkVersion(toolVersion string) {
- runtimeVersion := "4.12.0"
+ runtimeVersion := "4.13.1"
if runtimeVersion != toolVersion {
fmt.Println("ANTLR runtime and generated code versions disagree: " + runtimeVersion + "!=" + toolVersion)
}
diff --git a/vendor/github.com/antlr4-go/antlr/v4/statistics.go b/vendor/github.com/antlr4-go/antlr/v4/statistics.go
index 70c0673a0f..8cb5f3ed6f 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/statistics.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/statistics.go
@@ -9,7 +9,6 @@ import (
"path/filepath"
"sort"
"strconv"
- "sync"
)
// This file allows the user to collect statistics about the runtime of the ANTLR runtime. It is not enabled by default
@@ -30,7 +29,7 @@ type goRunStats struct {
// within this package.
//
jStats []*JStatRec
- jStatsLock sync.RWMutex
+ jStatsLock RWMutex
topN int
topNByMax []*JStatRec
topNByUsed []*JStatRec
diff --git a/vendor/github.com/antlr4-go/antlr/v4/token.go b/vendor/github.com/antlr4-go/antlr/v4/token.go
index 9670efb829..f5bc34229d 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/token.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/token.go
@@ -104,6 +104,25 @@ func (b *BaseToken) GetSource() *TokenSourceCharStreamPair {
return b.source
}
+func (b *BaseToken) GetText() string {
+ if b.text != "" {
+ return b.text
+ }
+ input := b.GetInputStream()
+ if input == nil {
+ return ""
+ }
+ n := input.Size()
+ if b.GetStart() < n && b.GetStop() < n {
+ return input.GetTextFromInterval(NewInterval(b.GetStart(), b.GetStop()))
+ }
+ return ""
+}
+
+func (b *BaseToken) SetText(text string) {
+ b.text = text
+}
+
func (b *BaseToken) GetTokenIndex() int {
return b.tokenIndex
}
@@ -120,6 +139,28 @@ func (b *BaseToken) GetInputStream() CharStream {
return b.source.charStream
}
+func (b *BaseToken) String() string {
+ txt := b.GetText()
+ if txt != "" {
+ txt = strings.Replace(txt, "\n", "\\n", -1)
+ txt = strings.Replace(txt, "\r", "\\r", -1)
+ txt = strings.Replace(txt, "\t", "\\t", -1)
+ } else {
+ txt = ""
+ }
+
+ var ch string
+ if b.GetChannel() > 0 {
+ ch = ",channel=" + strconv.Itoa(b.GetChannel())
+ } else {
+ ch = ""
+ }
+
+ return "[@" + strconv.Itoa(b.GetTokenIndex()) + "," + strconv.Itoa(b.GetStart()) + ":" + strconv.Itoa(b.GetStop()) + "='" +
+ txt + "',<" + strconv.Itoa(b.GetTokenType()) + ">" +
+ ch + "," + strconv.Itoa(b.GetLine()) + ":" + strconv.Itoa(b.GetColumn()) + "]"
+}
+
type CommonToken struct {
BaseToken
}
@@ -170,44 +211,3 @@ func (c *CommonToken) clone() *CommonToken {
t.text = c.GetText()
return t
}
-
-func (c *CommonToken) GetText() string {
- if c.text != "" {
- return c.text
- }
- input := c.GetInputStream()
- if input == nil {
- return ""
- }
- n := input.Size()
- if c.start < n && c.stop < n {
- return input.GetTextFromInterval(NewInterval(c.start, c.stop))
- }
- return ""
-}
-
-func (c *CommonToken) SetText(text string) {
- c.text = text
-}
-
-func (c *CommonToken) String() string {
- txt := c.GetText()
- if txt != "" {
- txt = strings.Replace(txt, "\n", "\\n", -1)
- txt = strings.Replace(txt, "\r", "\\r", -1)
- txt = strings.Replace(txt, "\t", "\\t", -1)
- } else {
- txt = ""
- }
-
- var ch string
- if c.channel > 0 {
- ch = ",channel=" + strconv.Itoa(c.channel)
- } else {
- ch = ""
- }
-
- return "[@" + strconv.Itoa(c.tokenIndex) + "," + strconv.Itoa(c.start) + ":" + strconv.Itoa(c.stop) + "='" +
- txt + "',<" + strconv.Itoa(c.tokenType) + ">" +
- ch + "," + strconv.Itoa(c.line) + ":" + strconv.Itoa(c.column) + "]"
-}
diff --git a/vendor/github.com/antlr4-go/antlr/v4/utils.go b/vendor/github.com/antlr4-go/antlr/v4/utils.go
index 733d7df9dc..36a37f247a 100644
--- a/vendor/github.com/antlr4-go/antlr/v4/utils.go
+++ b/vendor/github.com/antlr4-go/antlr/v4/utils.go
@@ -326,3 +326,56 @@ func isDirectory(dir string) (bool, error) {
}
return fileInfo.IsDir(), err
}
+
+// intSlicesEqual returns true if the two slices of ints are equal, and is a little
+// faster than slices.Equal.
+func intSlicesEqual(s1, s2 []int) bool {
+ if s1 == nil && s2 == nil {
+ return true
+ }
+ if s1 == nil || s2 == nil {
+ return false
+ }
+ if len(s1) == 0 && len(s2) == 0 {
+ return true
+ }
+
+ if len(s1) == 0 || len(s2) == 0 || len(s1) != len(s2) {
+ return false
+ }
+ // If the slices are using the same memory, then they are the same slice
+ if &s1[0] == &s2[0] {
+ return true
+ }
+ for i, v := range s1 {
+ if v != s2[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func pcSliceEqual(s1, s2 []*PredictionContext) bool {
+ if s1 == nil && s2 == nil {
+ return true
+ }
+ if s1 == nil || s2 == nil {
+ return false
+ }
+ if len(s1) == 0 && len(s2) == 0 {
+ return true
+ }
+ if len(s1) == 0 || len(s2) == 0 || len(s1) != len(s2) {
+ return false
+ }
+ // If the slices are using the same memory, then they are the same slice
+ if &s1[0] == &s2[0] {
+ return true
+ }
+ for i, v := range s1 {
+ if !v.Equals(s2[i]) {
+ return false
+ }
+ }
+ return true
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s
index b7723185b6..ce9f062894 100644
--- a/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s
@@ -1,4 +1,5 @@
-// +build amd64
+//go:build amd64 && !purego
+// +build amd64,!purego
#include "textflag.h"
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s
index 810aa9e648..ed33ba3d03 100644
--- a/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s
@@ -1,4 +1,5 @@
-// +build amd64
+//go:build amd64 && !purego
+// +build amd64,!purego
#include "textflag.h"
diff --git a/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s b/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s
index 5c4aeddecb..1fcc2dee17 100644
--- a/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s
+++ b/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s
@@ -1,4 +1,5 @@
-// +build amd64
+//go:build amd64 && !purego
+// +build amd64,!purego
#include "textflag.h"
#include "fp_amd64.h"
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s
index 435addf5e6..3f1f07c986 100644
--- a/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s
@@ -1,4 +1,5 @@
-// +build amd64
+//go:build amd64 && !purego
+// +build amd64,!purego
#include "textflag.h"
#include "fp_amd64.h"
diff --git a/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go b/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go
index 324bd8f334..c368b181b4 100644
--- a/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go
+++ b/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go
@@ -206,7 +206,7 @@ func newKeyFromSeed(privateKey, seed []byte) {
func signAll(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash bool) {
if len(ctx) > ContextMaxSize {
- panic(fmt.Errorf("ed448: bad context length: " + strconv.Itoa(len(ctx))))
+ panic(fmt.Errorf("ed448: bad context length: %v", len(ctx)))
}
H := sha3.NewShake256()
diff --git a/vendor/github.com/cloudflare/circl/sign/sign.go b/vendor/github.com/cloudflare/circl/sign/sign.go
index 13b20fa4b0..557d6f0960 100644
--- a/vendor/github.com/cloudflare/circl/sign/sign.go
+++ b/vendor/github.com/cloudflare/circl/sign/sign.go
@@ -107,4 +107,7 @@ var (
// ErrContextNotSupported is the error used if a context is not
// supported.
ErrContextNotSupported = errors.New("context not supported")
+
+ // ErrContextTooLong is the error used if the context string is too long.
+ ErrContextTooLong = errors.New("context string too long")
)
diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/build.go b/vendor/github.com/containerd/stargz-snapshotter/estargz/build.go
index b071cea51d..6aba0ef1f6 100644
--- a/vendor/github.com/containerd/stargz-snapshotter/estargz/build.go
+++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/build.go
@@ -436,9 +436,8 @@ func importTar(in io.ReaderAt) (*tarFile, error) {
if err != nil {
if err == io.EOF {
break
- } else {
- return nil, fmt.Errorf("failed to parse tar file, %w", err)
}
+ return nil, fmt.Errorf("failed to parse tar file, %w", err)
}
switch cleanEntryName(h.Name) {
case PrefetchLandmark, NoPrefetchLandmark:
diff --git a/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md b/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md
new file mode 100644
index 0000000000..04b5685ab4
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md
@@ -0,0 +1,178 @@
+# Changelog #
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/)
+and this project adheres to [Semantic Versioning](http://semver.org/).
+
+## [Unreleased] ##
+
+## [0.3.4] - 2024-10-09 ##
+
+### Fixed ###
+- Previously, some testing mocks we had resulted in us doing `import "testing"`
+ in non-`_test.go` code, which made some downstreams like Kubernetes unhappy.
+ This has been fixed. (#32)
+
+## [0.3.3] - 2024-09-30 ##
+
+### Fixed ###
+- The mode and owner verification logic in `MkdirAll` has been removed. This
+ was originally intended to protect against some theoretical attacks but upon
+ further consideration these protections don't actually buy us anything and
+ they were causing spurious errors with more complicated filesystem setups.
+- The "is the created directory empty" logic in `MkdirAll` has also been
+ removed. This was not causing us issues yet, but some pseudofilesystems (such
+ as `cgroup`) create non-empty directories and so this logic would've been
+ wrong for such cases.
+
+## [0.3.2] - 2024-09-13 ##
+
+### Changed ###
+- Passing the `S_ISUID` or `S_ISGID` modes to `MkdirAllInRoot` will now return
+ an explicit error saying that those bits are ignored by `mkdirat(2)`. In the
+ past a different error was returned, but since the silent ignoring behaviour
+ is codified in the man pages a more explicit error seems apt. While silently
+ ignoring these bits would be the most compatible option, it could lead to
+ users thinking their code sets these bits when it doesn't. Programs that need
+ to deal with compatibility can mask the bits themselves. (#23, #25)
+
+### Fixed ###
+- If a directory has `S_ISGID` set, then all child directories will have
+ `S_ISGID` set when created and a different gid will be used for any inode
+ created under the directory. Previously, the "expected owner and mode"
+ validation in `securejoin.MkdirAll` did not correctly handle this. We now
+ correctly handle this case. (#24, #25)
+
+## [0.3.1] - 2024-07-23 ##
+
+### Changed ###
+- By allowing `Open(at)InRoot` to opt-out of the extra work done by `MkdirAll`
+ to do the necessary "partial lookups", `Open(at)InRoot` now does less work
+ for both implementations (resulting in a many-fold decrease in the number of
+ operations for `openat2`, and a modest improvement for non-`openat2`) and is
+ far more guaranteed to match the correct `openat2(RESOLVE_IN_ROOT)`
+ behaviour.
+- We now use `readlinkat(fd, "")` where possible. For `Open(at)InRoot` this
+ effectively just means that we no longer risk getting spurious errors during
+ rename races. However, for our hardened procfs handler, this in theory should
+ prevent mount attacks from tricking us when doing magic-link readlinks (even
+ when using the unsafe host `/proc` handle). Unfortunately `Reopen` is still
+ potentially vulnerable to those kinds of somewhat-esoteric attacks.
+
+ Technically this [will only work on post-2.6.39 kernels][linux-readlinkat-emptypath]
+ but it seems incredibly unlikely anyone is using `filepath-securejoin` on a
+ pre-2011 kernel.
+
+### Fixed ###
+- Several improvements were made to the errors returned by `Open(at)InRoot` and
+ `MkdirAll` when dealing with invalid paths under the emulated (ie.
+ non-`openat2`) implementation. Previously, some paths would return the wrong
+ error (`ENOENT` when the last component was a non-directory), and other paths
+ would be returned as though they were acceptable (trailing-slash components
+ after a non-directory would be ignored by `Open(at)InRoot`).
+
+ These changes were done to match `openat2`'s behaviour and purely is a
+ consistency fix (most users are going to be using `openat2` anyway).
+
+[linux-readlinkat-emptypath]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=65cfc6722361570bfe255698d9cd4dccaf47570d
+
+## [0.3.0] - 2024-07-11 ##
+
+### Added ###
+- A new set of `*os.File`-based APIs have been added. These are adapted from
+ [libpathrs][] and we strongly suggest using them if possible (as they provide
+ far more protection against attacks than `SecureJoin`):
+
+ - `Open(at)InRoot` resolves a path inside a rootfs and returns an `*os.File`
+ handle to the path. Note that the handle returned is an `O_PATH` handle,
+ which cannot be used for reading or writing (as well as some other
+ operations -- [see open(2) for more details][open.2])
+
+ - `Reopen` takes an `O_PATH` file handle and safely re-opens it to upgrade
+ it to a regular handle. This can also be used with non-`O_PATH` handles,
+ but `O_PATH` is the most obvious application.
+
+ - `MkdirAll` is an implementation of `os.MkdirAll` that is safe to use to
+ create a directory tree within a rootfs.
+
+ As these are new APIs, they may change in the future. However, they should be
+ safe to start migrating to as we have extensive tests ensuring they behave
+ correctly and are safe against various races and other attacks.
+
+[libpathrs]: https://github.com/openSUSE/libpathrs
+[open.2]: https://www.man7.org/linux/man-pages/man2/open.2.html
+
+## [0.2.5] - 2024-05-03 ##
+
+### Changed ###
+- Some minor changes were made to how lexical components (like `..` and `.`)
+ are handled during path generation in `SecureJoin`. There is no behaviour
+ change as a result of this fix (the resulting paths are the same).
+
+### Fixed ###
+- The error returned when we hit a symlink loop now references the correct
+ path. (#10)
+
+## [0.2.4] - 2023-09-06 ##
+
+### Security ###
+- This release fixes a potential security issue in filepath-securejoin when
+ used on Windows ([GHSA-6xv5-86q9-7xr8][], which could be used to generate
+ paths outside of the provided rootfs in certain cases), as well as improving
+ the overall behaviour of filepath-securejoin when dealing with Windows paths
+ that contain volume names. Thanks to Paulo Gomes for discovering and fixing
+ these issues.
+
+### Fixed ###
+- Switch to GitHub Actions for CI so we can test on Windows as well as Linux
+ and MacOS.
+
+[GHSA-6xv5-86q9-7xr8]: https://github.com/advisories/GHSA-6xv5-86q9-7xr8
+
+## [0.2.3] - 2021-06-04 ##
+
+### Changed ###
+- Switch to Go 1.13-style `%w` error wrapping, letting us drop the dependency
+ on `github.com/pkg/errors`.
+
+## [0.2.2] - 2018-09-05 ##
+
+### Changed ###
+- Use `syscall.ELOOP` as the base error for symlink loops, rather than our own
+ (internal) error. This allows callers to more easily use `errors.Is` to check
+ for this case.
+
+## [0.2.1] - 2018-09-05 ##
+
+### Fixed ###
+- Use our own `IsNotExist` implementation, which lets us handle `ENOTDIR`
+ properly within `SecureJoin`.
+
+## [0.2.0] - 2017-07-19 ##
+
+We now have 100% test coverage!
+
+### Added ###
+- Add a `SecureJoinVFS` API that can be used for mocking (as we do in our new
+ tests) or for implementing custom handling of lookup operations (such as for
+ rootless containers, where work is necessary to access directories with weird
+ modes because we don't have `CAP_DAC_READ_SEARCH` or `CAP_DAC_OVERRIDE`).
+
+## 0.1.0 - 2017-07-19
+
+This is our first release of `github.com/cyphar/filepath-securejoin`,
+containing a full implementation with a coverage of 93.5% (the only missing
+cases are the error cases, which are hard to mocktest at the moment).
+
+[Unreleased]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.4...HEAD
+[0.3.3]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.3...v0.3.4
+[0.3.3]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.2...v0.3.3
+[0.3.2]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.1...v0.3.2
+[0.3.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.0...v0.3.1
+[0.3.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.2.5...v0.3.0
+[0.2.5]: https://github.com/cyphar/filepath-securejoin/compare/v0.2.4...v0.2.5
+[0.2.4]: https://github.com/cyphar/filepath-securejoin/compare/v0.2.3...v0.2.4
+[0.2.3]: https://github.com/cyphar/filepath-securejoin/compare/v0.2.2...v0.2.3
+[0.2.2]: https://github.com/cyphar/filepath-securejoin/compare/v0.2.1...v0.2.2
+[0.2.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.2.0...v0.2.1
+[0.2.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.1.0...v0.2.0
diff --git a/vendor/github.com/cyphar/filepath-securejoin/LICENSE b/vendor/github.com/cyphar/filepath-securejoin/LICENSE
index bec842f294..cb1ab88da0 100644
--- a/vendor/github.com/cyphar/filepath-securejoin/LICENSE
+++ b/vendor/github.com/cyphar/filepath-securejoin/LICENSE
@@ -1,5 +1,5 @@
Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved.
-Copyright (C) 2017 SUSE LLC. All rights reserved.
+Copyright (C) 2017-2024 SUSE LLC. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
diff --git a/vendor/github.com/cyphar/filepath-securejoin/README.md b/vendor/github.com/cyphar/filepath-securejoin/README.md
index 4eca0f2355..eaeb53fcd0 100644
--- a/vendor/github.com/cyphar/filepath-securejoin/README.md
+++ b/vendor/github.com/cyphar/filepath-securejoin/README.md
@@ -1,32 +1,26 @@
## `filepath-securejoin` ##
+[![Go Documentation](https://pkg.go.dev/badge/github.com/cyphar/filepath-securejoin.svg)](https://pkg.go.dev/github.com/cyphar/filepath-securejoin)
[![Build Status](https://github.com/cyphar/filepath-securejoin/actions/workflows/ci.yml/badge.svg)](https://github.com/cyphar/filepath-securejoin/actions/workflows/ci.yml)
-An implementation of `SecureJoin`, a [candidate for inclusion in the Go
-standard library][go#20126]. The purpose of this function is to be a "secure"
-alternative to `filepath.Join`, and in particular it provides certain
-guarantees that are not provided by `filepath.Join`.
-
-> **NOTE**: This code is *only* safe if you are not at risk of other processes
-> modifying path components after you've used `SecureJoin`. If it is possible
-> for a malicious process to modify path components of the resolved path, then
-> you will be vulnerable to some fairly trivial TOCTOU race conditions. [There
-> are some Linux kernel patches I'm working on which might allow for a better
-> solution.][lwn-obeneath]
->
-> In addition, with a slightly modified API it might be possible to use
-> `O_PATH` and verify that the opened path is actually the resolved one -- but
-> I have not done that yet. I might add it in the future as a helper function
-> to help users verify the path (we can't just return `/proc/self/fd/`
-> because that doesn't always work transparently for all users).
-
-This is the function prototype:
+### Old API ###
-```go
-func SecureJoin(root, unsafePath string) (string, error)
-```
+This library was originally just an implementation of `SecureJoin` which was
+[intended to be included in the Go standard library][go#20126] as a safer
+`filepath.Join` that would restrict the path lookup to be inside a root
+directory.
+
+The implementation was based on code that existed in several container
+runtimes. Unfortunately, this API is **fundamentally unsafe** against attackers
+that can modify path components after `SecureJoin` returns and before the
+caller uses the path, allowing for some fairly trivial TOCTOU attacks.
+
+`SecureJoin` (and `SecureJoinVFS`) are still provided by this library to
+support legacy users, but new users are strongly suggested to avoid using
+`SecureJoin` and instead use the [new api](#new-api) or switch to
+[libpathrs][libpathrs].
-This library **guarantees** the following:
+With the above limitations in mind, this library guarantees the following:
* If no error is set, the resulting string **must** be a child path of
`root` and will not contain any symlink path components (they will all be
@@ -47,7 +41,7 @@ This library **guarantees** the following:
A (trivial) implementation of this function on GNU/Linux systems could be done
with the following (note that this requires root privileges and is far more
opaque than the implementation in this library, and also requires that
-`readlink` is inside the `root` path):
+`readlink` is inside the `root` path and is trustworthy):
```go
package securejoin
@@ -70,9 +64,105 @@ func SecureJoin(root, unsafePath string) (string, error) {
}
```
-[lwn-obeneath]: https://lwn.net/Articles/767547/
+[libpathrs]: https://github.com/openSUSE/libpathrs
[go#20126]: https://github.com/golang/go/issues/20126
+### New API ###
+
+While we recommend users switch to [libpathrs][libpathrs] as soon as it has a
+stable release, some methods implemented by libpathrs have been ported to this
+library to ease the transition. These APIs are only supported on Linux.
+
+These APIs are implemented such that `filepath-securejoin` will
+opportunistically use certain newer kernel APIs that make these operations far
+more secure. In particular:
+
+* All of the lookup operations will use [`openat2`][openat2.2] on new enough
+ kernels (Linux 5.6 or later) to restrict lookups through magic-links and
+ bind-mounts (for certain operations) and to make use of `RESOLVE_IN_ROOT` to
+ efficiently resolve symlinks within a rootfs.
+
+* The APIs provide hardening against a malicious `/proc` mount to either detect
+ or avoid being tricked by a `/proc` that is not legitimate. This is done
+ using [`openat2`][openat2.2] for all users, and privileged users will also be
+ further protected by using [`fsopen`][fsopen.2] and [`open_tree`][open_tree.2]
+ (Linux 5.2 or later).
+
+[openat2.2]: https://www.man7.org/linux/man-pages/man2/openat2.2.html
+[fsopen.2]: https://github.com/brauner/man-pages-md/blob/main/fsopen.md
+[open_tree.2]: https://github.com/brauner/man-pages-md/blob/main/open_tree.md
+
+#### `OpenInRoot` ####
+
+```go
+func OpenInRoot(root, unsafePath string) (*os.File, error)
+func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error)
+func Reopen(handle *os.File, flags int) (*os.File, error)
+```
+
+`OpenInRoot` is a much safer version of
+
+```go
+path, err := securejoin.SecureJoin(root, unsafePath)
+file, err := os.OpenFile(path, unix.O_PATH|unix.O_CLOEXEC)
+```
+
+that protects against various race attacks that could lead to serious security
+issues, depending on the application. Note that the returned `*os.File` is an
+`O_PATH` file descriptor, which is quite restricted. Callers will probably need
+to use `Reopen` to get a more usable handle (this split is done to provide
+useful features like PTY spawning and to avoid users accidentally opening bad
+inodes that could cause a DoS).
+
+Callers need to be careful in how they use the returned `*os.File`. Usually it
+is only safe to operate on the handle directly, and it is very easy to create a
+security issue. [libpathrs][libpathrs] provides far more helpers to make using
+these handles safer -- there is currently no plan to port them to
+`filepath-securejoin`.
+
+`OpenatInRoot` is like `OpenInRoot` except that the root is provided using an
+`*os.File`. This allows you to ensure that multiple `OpenatInRoot` (or
+`MkdirAllHandle`) calls are operating on the same rootfs.
+
+> **NOTE**: Unlike `SecureJoin`, `OpenInRoot` will error out as soon as it hits
+> a dangling symlink or non-existent path. This is in contrast to `SecureJoin`
+> which treated non-existent components as though they were real directories,
+> and would allow for partial resolution of dangling symlinks. These behaviours
+> are at odds with how Linux treats non-existent paths and dangling symlinks,
+> and so these are no longer allowed.
+
+#### `MkdirAll` ####
+
+```go
+func MkdirAll(root, unsafePath string, mode int) error
+func MkdirAllHandle(root *os.File, unsafePath string, mode int) (*os.File, error)
+```
+
+`MkdirAll` is a much safer version of
+
+```go
+path, err := securejoin.SecureJoin(root, unsafePath)
+err = os.MkdirAll(path, mode)
+```
+
+that protects against the same kinds of races that `OpenInRoot` protects
+against.
+
+`MkdirAllHandle` is like `MkdirAll` except that the root is provided using an
+`*os.File` (the reason for this is the same as with `OpenatInRoot`) and an
+`*os.File` of the final created directory is returned (this directory is
+guaranteed to be effectively identical to the directory created by
+`MkdirAllHandle`, which is not possible to ensure by just using `OpenatInRoot`
+after `MkdirAll`).
+
+> **NOTE**: Unlike `SecureJoin`, `MkdirAll` will error out as soon as it hits
+> a dangling symlink or non-existent path. This is in contrast to `SecureJoin`
+> which treated non-existent components as though they were real directories,
+> and would allow for partial resolution of dangling symlinks. These behaviours
+> are at odds with how Linux treats non-existent paths and dangling symlinks,
+> and so these are no longer allowed. This means that `MkdirAll` will not
+> create non-existent directories referenced by a dangling symlink.
+
### License ###
The license of this project is the same as Go, which is a BSD 3-clause license
diff --git a/vendor/github.com/cyphar/filepath-securejoin/VERSION b/vendor/github.com/cyphar/filepath-securejoin/VERSION
index abd410582d..42045acae2 100644
--- a/vendor/github.com/cyphar/filepath-securejoin/VERSION
+++ b/vendor/github.com/cyphar/filepath-securejoin/VERSION
@@ -1 +1 @@
-0.2.4
+0.3.4
diff --git a/vendor/github.com/cyphar/filepath-securejoin/doc.go b/vendor/github.com/cyphar/filepath-securejoin/doc.go
new file mode 100644
index 0000000000..1ec7d065ef
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/doc.go
@@ -0,0 +1,39 @@
+// Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved.
+// Copyright (C) 2017-2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package securejoin implements a set of helpers to make it easier to write Go
+// code that is safe against symlink-related escape attacks. The primary idea
+// is to let you resolve a path within a rootfs directory as if the rootfs was
+// a chroot.
+//
+// securejoin has two APIs, a "legacy" API and a "modern" API.
+//
+// The legacy API is [SecureJoin] and [SecureJoinVFS]. These methods are
+// **not** safe against race conditions where an attacker changes the
+// filesystem after (or during) the [SecureJoin] operation.
+//
+// The new API is made up of [OpenInRoot] and [MkdirAll] (and derived
+// functions). These are safe against racing attackers and have several other
+// protections that are not provided by the legacy API. There are many more
+// operations that most programs expect to be able to do safely, but we do not
+// provide explicit support for them because we want to encourage users to
+// switch to [libpathrs](https://github.com/openSUSE/libpathrs) which is a
+// cross-language next-generation library that is entirely designed around
+// operating on paths safely.
+//
+// securejoin has been used by several container runtimes (Docker, runc,
+// Kubernetes, etc) for quite a few years as a de-facto standard for operating
+// on container filesystem paths "safely". However, most users still use the
+// legacy API which is unsafe against various attacks (there is a fairly long
+// history of CVEs in dependent as a result). Users should switch to the modern
+// API as soon as possible (or even better, switch to libpathrs).
+//
+// This project was initially intended to be included in the Go standard
+// library, but [it was rejected](https://go.dev/issue/20126). There is now a
+// [new Go proposal](https://go.dev/issue/67002) for a safe path resolution API
+// that shares some of the goals of filepath-securejoin. However, that design
+// is intended to work like `openat2(RESOLVE_BENEATH)` which does not fit the
+// usecase of container runtimes and most system tools.
+package securejoin
diff --git a/vendor/github.com/cyphar/filepath-securejoin/join.go b/vendor/github.com/cyphar/filepath-securejoin/join.go
index aa32b85fb8..e0ee3f2b57 100644
--- a/vendor/github.com/cyphar/filepath-securejoin/join.go
+++ b/vendor/github.com/cyphar/filepath-securejoin/join.go
@@ -1,17 +1,11 @@
// Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved.
-// Copyright (C) 2017 SUSE LLC. All rights reserved.
+// Copyright (C) 2017-2024 SUSE LLC. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Package securejoin is an implementation of the hopefully-soon-to-be-included
-// SecureJoin helper that is meant to be part of the "path/filepath" package.
-// The purpose of this project is to provide a PoC implementation to make the
-// SecureJoin proposal (https://github.com/golang/go/issues/20126) more
-// tangible.
package securejoin
import (
- "bytes"
"errors"
"os"
"path/filepath"
@@ -19,26 +13,34 @@ import (
"syscall"
)
+const maxSymlinkLimit = 255
+
// IsNotExist tells you if err is an error that implies that either the path
// accessed does not exist (or path components don't exist). This is
-// effectively a more broad version of os.IsNotExist.
+// effectively a more broad version of [os.IsNotExist].
func IsNotExist(err error) bool {
// Check that it's not actually an ENOTDIR, which in some cases is a more
// convoluted case of ENOENT (usually involving weird paths).
return errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) || errors.Is(err, syscall.ENOENT)
}
-// SecureJoinVFS joins the two given path components (similar to Join) except
+// SecureJoinVFS joins the two given path components (similar to [filepath.Join]) except
// that the returned path is guaranteed to be scoped inside the provided root
// path (when evaluated). Any symbolic links in the path are evaluated with the
// given root treated as the root of the filesystem, similar to a chroot. The
-// filesystem state is evaluated through the given VFS interface (if nil, the
-// standard os.* family of functions are used).
+// filesystem state is evaluated through the given [VFS] interface (if nil, the
+// standard [os].* family of functions are used).
//
// Note that the guarantees provided by this function only apply if the path
// components in the returned string are not modified (in other words are not
// replaced with symlinks on the filesystem) after this function has returned.
-// Such a symlink race is necessarily out-of-scope of SecureJoin.
+// Such a symlink race is necessarily out-of-scope of SecureJoinVFS.
+//
+// NOTE: Due to the above limitation, Linux users are strongly encouraged to
+// use [OpenInRoot] instead, which does safely protect against these kinds of
+// attacks. There is no way to solve this problem with SecureJoinVFS because
+// the API is fundamentally wrong (you cannot return a "safe" path string and
+// guarantee it won't be modified afterwards).
//
// Volume names in unsafePath are always discarded, regardless if they are
// provided via direct input or when evaluating symlinks. Therefore:
@@ -51,75 +53,73 @@ func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) {
}
unsafePath = filepath.FromSlash(unsafePath)
- var path bytes.Buffer
- n := 0
- for unsafePath != "" {
- if n > 255 {
- return "", &os.PathError{Op: "SecureJoin", Path: root + string(filepath.Separator) + unsafePath, Err: syscall.ELOOP}
+ var (
+ currentPath string
+ remainingPath = unsafePath
+ linksWalked int
+ )
+ for remainingPath != "" {
+ if v := filepath.VolumeName(remainingPath); v != "" {
+ remainingPath = remainingPath[len(v):]
}
- if v := filepath.VolumeName(unsafePath); v != "" {
- unsafePath = unsafePath[len(v):]
- }
-
- // Next path component, p.
- i := strings.IndexRune(unsafePath, filepath.Separator)
- var p string
- if i == -1 {
- p, unsafePath = unsafePath, ""
+ // Get the next path component.
+ var part string
+ if i := strings.IndexRune(remainingPath, filepath.Separator); i == -1 {
+ part, remainingPath = remainingPath, ""
} else {
- p, unsafePath = unsafePath[:i], unsafePath[i+1:]
+ part, remainingPath = remainingPath[:i], remainingPath[i+1:]
}
- // Create a cleaned path, using the lexical semantics of /../a, to
- // create a "scoped" path component which can safely be joined to fullP
- // for evaluation. At this point, path.String() doesn't contain any
- // symlink components.
- cleanP := filepath.Clean(string(filepath.Separator) + path.String() + p)
- if cleanP == string(filepath.Separator) {
- path.Reset()
+ // Apply the component lexically to the path we are building.
+ // currentPath does not contain any symlinks, and we are lexically
+ // dealing with a single component, so it's okay to do a filepath.Clean
+ // here.
+ nextPath := filepath.Join(string(filepath.Separator), currentPath, part)
+ if nextPath == string(filepath.Separator) {
+ currentPath = ""
continue
}
- fullP := filepath.Clean(root + cleanP)
+ fullPath := root + string(filepath.Separator) + nextPath
// Figure out whether the path is a symlink.
- fi, err := vfs.Lstat(fullP)
+ fi, err := vfs.Lstat(fullPath)
if err != nil && !IsNotExist(err) {
return "", err
}
// Treat non-existent path components the same as non-symlinks (we
// can't do any better here).
if IsNotExist(err) || fi.Mode()&os.ModeSymlink == 0 {
- path.WriteString(p)
- path.WriteRune(filepath.Separator)
+ currentPath = nextPath
continue
}
- // Only increment when we actually dereference a link.
- n++
+ // It's a symlink, so get its contents and expand it by prepending it
+ // to the yet-unparsed path.
+ linksWalked++
+ if linksWalked > maxSymlinkLimit {
+ return "", &os.PathError{Op: "SecureJoin", Path: root + string(filepath.Separator) + unsafePath, Err: syscall.ELOOP}
+ }
- // It's a symlink, expand it by prepending it to the yet-unparsed path.
- dest, err := vfs.Readlink(fullP)
+ dest, err := vfs.Readlink(fullPath)
if err != nil {
return "", err
}
+ remainingPath = dest + string(filepath.Separator) + remainingPath
// Absolute symlinks reset any work we've already done.
if filepath.IsAbs(dest) {
- path.Reset()
+ currentPath = ""
}
- unsafePath = dest + string(filepath.Separator) + unsafePath
}
- // We have to clean path.String() here because it may contain '..'
- // components that are entirely lexical, but would be misleading otherwise.
- // And finally do a final clean to ensure that root is also lexically
- // clean.
- fullP := filepath.Clean(string(filepath.Separator) + path.String())
- return filepath.Clean(root + fullP), nil
+ // There should be no lexical components like ".." left in the path here,
+ // but for safety clean up the path before joining it to the root.
+ finalPath := filepath.Join(string(filepath.Separator), currentPath)
+ return filepath.Join(root, finalPath), nil
}
-// SecureJoin is a wrapper around SecureJoinVFS that just uses the os.* library
-// of functions as the VFS. If in doubt, use this function over SecureJoinVFS.
+// SecureJoin is a wrapper around [SecureJoinVFS] that just uses the [os].* library
+// of functions as the [VFS]. If in doubt, use this function over [SecureJoinVFS].
func SecureJoin(root, unsafePath string) (string, error) {
return SecureJoinVFS(root, unsafePath, nil)
}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/lookup_linux.go b/vendor/github.com/cyphar/filepath-securejoin/lookup_linux.go
new file mode 100644
index 0000000000..290befa154
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/lookup_linux.go
@@ -0,0 +1,389 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path"
+ "path/filepath"
+ "slices"
+ "strings"
+
+ "golang.org/x/sys/unix"
+)
+
+type symlinkStackEntry struct {
+ // (dir, remainingPath) is what we would've returned if the link didn't
+ // exist. This matches what openat2(RESOLVE_IN_ROOT) would return in
+ // this case.
+ dir *os.File
+ remainingPath string
+ // linkUnwalked is the remaining path components from the original
+ // Readlink which we have yet to walk. When this slice is empty, we
+ // drop the link from the stack.
+ linkUnwalked []string
+}
+
+func (se symlinkStackEntry) String() string {
+ return fmt.Sprintf("<%s>/%s [->%s]", se.dir.Name(), se.remainingPath, strings.Join(se.linkUnwalked, "/"))
+}
+
+func (se symlinkStackEntry) Close() {
+ _ = se.dir.Close()
+}
+
+type symlinkStack []*symlinkStackEntry
+
+func (s *symlinkStack) IsEmpty() bool {
+ return s == nil || len(*s) == 0
+}
+
+func (s *symlinkStack) Close() {
+ if s != nil {
+ for _, link := range *s {
+ link.Close()
+ }
+ // TODO: Switch to clear once we switch to Go 1.21.
+ *s = nil
+ }
+}
+
+var (
+ errEmptyStack = errors.New("[internal] stack is empty")
+ errBrokenSymlinkStack = errors.New("[internal error] broken symlink stack")
+)
+
+func (s *symlinkStack) popPart(part string) error {
+ if s == nil || s.IsEmpty() {
+ // If there is nothing in the symlink stack, then the part was from the
+ // real path provided by the user, and this is a no-op.
+ return errEmptyStack
+ }
+ if part == "." {
+ // "." components are no-ops -- we drop them when doing SwapLink.
+ return nil
+ }
+
+ tailEntry := (*s)[len(*s)-1]
+
+ // Double-check that we are popping the component we expect.
+ if len(tailEntry.linkUnwalked) == 0 {
+ return fmt.Errorf("%w: trying to pop component %q of empty stack entry %s", errBrokenSymlinkStack, part, tailEntry)
+ }
+ headPart := tailEntry.linkUnwalked[0]
+ if headPart != part {
+ return fmt.Errorf("%w: trying to pop component %q but the last stack entry is %s (%q)", errBrokenSymlinkStack, part, tailEntry, headPart)
+ }
+
+ // Drop the component, but keep the entry around in case we are dealing
+ // with a "tail-chained" symlink.
+ tailEntry.linkUnwalked = tailEntry.linkUnwalked[1:]
+ return nil
+}
+
+func (s *symlinkStack) PopPart(part string) error {
+ if err := s.popPart(part); err != nil {
+ if errors.Is(err, errEmptyStack) {
+ // Skip empty stacks.
+ err = nil
+ }
+ return err
+ }
+
+ // Clean up any of the trailing stack entries that are empty.
+ for lastGood := len(*s) - 1; lastGood >= 0; lastGood-- {
+ entry := (*s)[lastGood]
+ if len(entry.linkUnwalked) > 0 {
+ break
+ }
+ entry.Close()
+ (*s) = (*s)[:lastGood]
+ }
+ return nil
+}
+
+func (s *symlinkStack) push(dir *os.File, remainingPath, linkTarget string) error {
+ if s == nil {
+ return nil
+ }
+ // Split the link target and clean up any "" parts.
+ linkTargetParts := slices.DeleteFunc(
+ strings.Split(linkTarget, "/"),
+ func(part string) bool { return part == "" || part == "." })
+
+ // Copy the directory so the caller doesn't close our copy.
+ dirCopy, err := dupFile(dir)
+ if err != nil {
+ return err
+ }
+
+ // Add to the stack.
+ *s = append(*s, &symlinkStackEntry{
+ dir: dirCopy,
+ remainingPath: remainingPath,
+ linkUnwalked: linkTargetParts,
+ })
+ return nil
+}
+
+func (s *symlinkStack) SwapLink(linkPart string, dir *os.File, remainingPath, linkTarget string) error {
+ // If we are currently inside a symlink resolution, remove the symlink
+ // component from the last symlink entry, but don't remove the entry even
+ // if it's empty. If we are a "tail-chained" symlink (a trailing symlink we
+ // hit during a symlink resolution) we need to keep the old symlink until
+ // we finish the resolution.
+ if err := s.popPart(linkPart); err != nil {
+ if !errors.Is(err, errEmptyStack) {
+ return err
+ }
+ // Push the component regardless of whether the stack was empty.
+ }
+ return s.push(dir, remainingPath, linkTarget)
+}
+
+func (s *symlinkStack) PopTopSymlink() (*os.File, string, bool) {
+ if s == nil || s.IsEmpty() {
+ return nil, "", false
+ }
+ tailEntry := (*s)[0]
+ *s = (*s)[1:]
+ return tailEntry.dir, tailEntry.remainingPath, true
+}
+
+// partialLookupInRoot tries to lookup as much of the request path as possible
+// within the provided root (a-la RESOLVE_IN_ROOT) and opens the final existing
+// component of the requested path, returning a file handle to the final
+// existing component and a string containing the remaining path components.
+func partialLookupInRoot(root *os.File, unsafePath string) (*os.File, string, error) {
+ return lookupInRoot(root, unsafePath, true)
+}
+
+func completeLookupInRoot(root *os.File, unsafePath string) (*os.File, error) {
+ handle, remainingPath, err := lookupInRoot(root, unsafePath, false)
+ if remainingPath != "" && err == nil {
+ // should never happen
+ err = fmt.Errorf("[bug] non-empty remaining path when doing a non-partial lookup: %q", remainingPath)
+ }
+ // lookupInRoot(partial=false) will always close the handle if an error is
+ // returned, so no need to double-check here.
+ return handle, err
+}
+
+func lookupInRoot(root *os.File, unsafePath string, partial bool) (Handle *os.File, _ string, _ error) {
+ unsafePath = filepath.ToSlash(unsafePath) // noop
+
+ // This is very similar to SecureJoin, except that we operate on the
+ // components using file descriptors. We then return the last component we
+ // managed open, along with the remaining path components not opened.
+
+ // Try to use openat2 if possible.
+ if hasOpenat2() {
+ return lookupOpenat2(root, unsafePath, partial)
+ }
+
+ // Get the "actual" root path from /proc/self/fd. This is necessary if the
+ // root is some magic-link like /proc/$pid/root, in which case we want to
+ // make sure when we do checkProcSelfFdPath that we are using the correct
+ // root path.
+ logicalRootPath, err := procSelfFdReadlink(root)
+ if err != nil {
+ return nil, "", fmt.Errorf("get real root path: %w", err)
+ }
+
+ currentDir, err := dupFile(root)
+ if err != nil {
+ return nil, "", fmt.Errorf("clone root fd: %w", err)
+ }
+ defer func() {
+ // If a handle is not returned, close the internal handle.
+ if Handle == nil {
+ _ = currentDir.Close()
+ }
+ }()
+
+ // symlinkStack is used to emulate how openat2(RESOLVE_IN_ROOT) treats
+ // dangling symlinks. If we hit a non-existent path while resolving a
+ // symlink, we need to return the (dir, remainingPath) that we had when we
+ // hit the symlink (treating the symlink as though it were a regular file).
+ // The set of (dir, remainingPath) sets is stored within the symlinkStack
+ // and we add and remove parts when we hit symlink and non-symlink
+ // components respectively. We need a stack because of recursive symlinks
+ // (symlinks that contain symlink components in their target).
+ //
+ // Note that the stack is ONLY used for book-keeping. All of the actual
+ // path walking logic is still based on currentPath/remainingPath and
+ // currentDir (as in SecureJoin).
+ var symStack *symlinkStack
+ if partial {
+ symStack = new(symlinkStack)
+ defer symStack.Close()
+ }
+
+ var (
+ linksWalked int
+ currentPath string
+ remainingPath = unsafePath
+ )
+ for remainingPath != "" {
+ // Save the current remaining path so if the part is not real we can
+ // return the path including the component.
+ oldRemainingPath := remainingPath
+
+ // Get the next path component.
+ var part string
+ if i := strings.IndexByte(remainingPath, '/'); i == -1 {
+ part, remainingPath = remainingPath, ""
+ } else {
+ part, remainingPath = remainingPath[:i], remainingPath[i+1:]
+ }
+ // If we hit an empty component, we need to treat it as though it is
+ // "." so that trailing "/" and "//" components on a non-directory
+ // correctly return the right error code.
+ if part == "" {
+ part = "."
+ }
+
+ // Apply the component lexically to the path we are building.
+ // currentPath does not contain any symlinks, and we are lexically
+ // dealing with a single component, so it's okay to do a filepath.Clean
+ // here.
+ nextPath := path.Join("/", currentPath, part)
+ // If we logically hit the root, just clone the root rather than
+ // opening the part and doing all of the other checks.
+ if nextPath == "/" {
+ if err := symStack.PopPart(part); err != nil {
+ return nil, "", fmt.Errorf("walking into root with part %q failed: %w", part, err)
+ }
+ // Jump to root.
+ rootClone, err := dupFile(root)
+ if err != nil {
+ return nil, "", fmt.Errorf("clone root fd: %w", err)
+ }
+ _ = currentDir.Close()
+ currentDir = rootClone
+ currentPath = nextPath
+ continue
+ }
+
+ // Try to open the next component.
+ nextDir, err := openatFile(currentDir, part, unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0)
+ switch {
+ case err == nil:
+ st, err := nextDir.Stat()
+ if err != nil {
+ _ = nextDir.Close()
+ return nil, "", fmt.Errorf("stat component %q: %w", part, err)
+ }
+
+ switch st.Mode() & os.ModeType {
+ case os.ModeSymlink:
+ // readlinkat implies AT_EMPTY_PATH since Linux 2.6.39. See
+ // Linux commit 65cfc6722361 ("readlinkat(), fchownat() and
+ // fstatat() with empty relative pathnames").
+ linkDest, err := readlinkatFile(nextDir, "")
+ // We don't need the handle anymore.
+ _ = nextDir.Close()
+ if err != nil {
+ return nil, "", err
+ }
+
+ linksWalked++
+ if linksWalked > maxSymlinkLimit {
+ return nil, "", &os.PathError{Op: "securejoin.lookupInRoot", Path: logicalRootPath + "/" + unsafePath, Err: unix.ELOOP}
+ }
+
+ // Swap out the symlink's component for the link entry itself.
+ if err := symStack.SwapLink(part, currentDir, oldRemainingPath, linkDest); err != nil {
+ return nil, "", fmt.Errorf("walking into symlink %q failed: push symlink: %w", part, err)
+ }
+
+ // Update our logical remaining path.
+ remainingPath = linkDest + "/" + remainingPath
+ // Absolute symlinks reset any work we've already done.
+ if path.IsAbs(linkDest) {
+ // Jump to root.
+ rootClone, err := dupFile(root)
+ if err != nil {
+ return nil, "", fmt.Errorf("clone root fd: %w", err)
+ }
+ _ = currentDir.Close()
+ currentDir = rootClone
+ currentPath = "/"
+ }
+
+ default:
+ // If we are dealing with a directory, simply walk into it.
+ _ = currentDir.Close()
+ currentDir = nextDir
+ currentPath = nextPath
+
+ // The part was real, so drop it from the symlink stack.
+ if err := symStack.PopPart(part); err != nil {
+ return nil, "", fmt.Errorf("walking into directory %q failed: %w", part, err)
+ }
+
+ // If we are operating on a .., make sure we haven't escaped.
+ // We only have to check for ".." here because walking down
+ // into a regular component component cannot cause you to
+ // escape. This mirrors the logic in RESOLVE_IN_ROOT, except we
+ // have to check every ".." rather than only checking after a
+ // rename or mount on the system.
+ if part == ".." {
+ // Make sure the root hasn't moved.
+ if err := checkProcSelfFdPath(logicalRootPath, root); err != nil {
+ return nil, "", fmt.Errorf("root path moved during lookup: %w", err)
+ }
+ // Make sure the path is what we expect.
+ fullPath := logicalRootPath + nextPath
+ if err := checkProcSelfFdPath(fullPath, currentDir); err != nil {
+ return nil, "", fmt.Errorf("walking into %q had unexpected result: %w", part, err)
+ }
+ }
+ }
+
+ default:
+ if !partial {
+ return nil, "", err
+ }
+ // If there are any remaining components in the symlink stack, we
+ // are still within a symlink resolution and thus we hit a dangling
+ // symlink. So pretend that the first symlink in the stack we hit
+ // was an ENOENT (to match openat2).
+ if oldDir, remainingPath, ok := symStack.PopTopSymlink(); ok {
+ _ = currentDir.Close()
+ return oldDir, remainingPath, err
+ }
+ // We have hit a final component that doesn't exist, so we have our
+ // partial open result. Note that we have to use the OLD remaining
+ // path, since the lookup failed.
+ return currentDir, oldRemainingPath, err
+ }
+ }
+
+ // If the unsafePath had a trailing slash, we need to make sure we try to
+ // do a relative "." open so that we will correctly return an error when
+ // the final component is a non-directory (to match openat2). In the
+ // context of openat2, a trailing slash and a trailing "/." are completely
+ // equivalent.
+ if strings.HasSuffix(unsafePath, "/") {
+ nextDir, err := openatFile(currentDir, ".", unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0)
+ if err != nil {
+ if !partial {
+ _ = currentDir.Close()
+ currentDir = nil
+ }
+ return currentDir, "", err
+ }
+ _ = currentDir.Close()
+ currentDir = nextDir
+ }
+
+ // All of the components existed!
+ return currentDir, "", nil
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go b/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go
new file mode 100644
index 0000000000..b5f674524c
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go
@@ -0,0 +1,207 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "slices"
+ "strings"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ errInvalidMode = errors.New("invalid permission mode")
+ errPossibleAttack = errors.New("possible attack detected")
+)
+
+// MkdirAllHandle is equivalent to [MkdirAll], except that it is safer to use
+// in two respects:
+//
+// - The caller provides the root directory as an *[os.File] (preferably O_PATH)
+// handle. This means that the caller can be sure which root directory is
+// being used. Note that this can be emulated by using /proc/self/fd/... as
+// the root path with [os.MkdirAll].
+//
+// - Once all of the directories have been created, an *[os.File] O_PATH handle
+// to the directory at unsafePath is returned to the caller. This is done in
+// an effectively-race-free way (an attacker would only be able to swap the
+// final directory component), which is not possible to emulate with
+// [MkdirAll].
+//
+// In addition, the returned handle is obtained far more efficiently than doing
+// a brand new lookup of unsafePath (such as with [SecureJoin] or openat2) after
+// doing [MkdirAll]. If you intend to open the directory after creating it, you
+// should use MkdirAllHandle.
+func MkdirAllHandle(root *os.File, unsafePath string, mode int) (_ *os.File, Err error) {
+ // Make sure there are no os.FileMode bits set.
+ if mode&^0o7777 != 0 {
+ return nil, fmt.Errorf("%w for mkdir 0o%.3o", errInvalidMode, mode)
+ }
+ // On Linux, mkdirat(2) (and os.Mkdir) silently ignore the suid and sgid
+ // bits. We could also silently ignore them but since we have very few
+ // users it seems more prudent to return an error so users notice that
+ // these bits will not be set.
+ if mode&^0o1777 != 0 {
+ return nil, fmt.Errorf("%w for mkdir 0o%.3o: suid and sgid are ignored by mkdir", errInvalidMode, mode)
+ }
+
+ // Try to open as much of the path as possible.
+ currentDir, remainingPath, err := partialLookupInRoot(root, unsafePath)
+ defer func() {
+ if Err != nil {
+ _ = currentDir.Close()
+ }
+ }()
+ if err != nil && !errors.Is(err, unix.ENOENT) {
+ return nil, fmt.Errorf("find existing subpath of %q: %w", unsafePath, err)
+ }
+
+ // If there is an attacker deleting directories as we walk into them,
+ // detect this proactively. Note this is guaranteed to detect if the
+ // attacker deleted any part of the tree up to currentDir.
+ //
+ // Once we walk into a dead directory, partialLookupInRoot would not be
+ // able to walk further down the tree (directories must be empty before
+ // they are deleted), and if the attacker has removed the entire tree we
+ // can be sure that anything that was originally inside a dead directory
+ // must also be deleted and thus is a dead directory in its own right.
+ //
+ // This is mostly a quality-of-life check, because mkdir will simply fail
+ // later if the attacker deletes the tree after this check.
+ if err := isDeadInode(currentDir); err != nil {
+ return nil, fmt.Errorf("finding existing subpath of %q: %w", unsafePath, err)
+ }
+
+ // Re-open the path to match the O_DIRECTORY reopen loop later (so that we
+ // always return a non-O_PATH handle). We also check that we actually got a
+ // directory.
+ if reopenDir, err := Reopen(currentDir, unix.O_DIRECTORY|unix.O_CLOEXEC); errors.Is(err, unix.ENOTDIR) {
+ return nil, fmt.Errorf("cannot create subdirectories in %q: %w", currentDir.Name(), unix.ENOTDIR)
+ } else if err != nil {
+ return nil, fmt.Errorf("re-opening handle to %q: %w", currentDir.Name(), err)
+ } else {
+ _ = currentDir.Close()
+ currentDir = reopenDir
+ }
+
+ remainingParts := strings.Split(remainingPath, string(filepath.Separator))
+ if slices.Contains(remainingParts, "..") {
+ // The path contained ".." components after the end of the "real"
+ // components. We could try to safely resolve ".." here but that would
+ // add a bunch of extra logic for something that it's not clear even
+ // needs to be supported. So just return an error.
+ //
+ // If we do filepath.Clean(remainingPath) then we end up with the
+ // problem that ".." can erase a trailing dangling symlink and produce
+ // a path that doesn't quite match what the user asked for.
+ return nil, fmt.Errorf("%w: yet-to-be-created path %q contains '..' components", unix.ENOENT, remainingPath)
+ }
+
+ // Make sure the mode doesn't have any type bits.
+ mode &^= unix.S_IFMT
+
+ // Create the remaining components.
+ for _, part := range remainingParts {
+ switch part {
+ case "", ".":
+ // Skip over no-op paths.
+ continue
+ }
+
+ // NOTE: mkdir(2) will not follow trailing symlinks, so we can safely
+ // create the final component without worrying about symlink-exchange
+ // attacks.
+ if err := unix.Mkdirat(int(currentDir.Fd()), part, uint32(mode)); err != nil {
+ err = &os.PathError{Op: "mkdirat", Path: currentDir.Name() + "/" + part, Err: err}
+ // Make the error a bit nicer if the directory is dead.
+ if err2 := isDeadInode(currentDir); err2 != nil {
+ err = fmt.Errorf("%w (%w)", err, err2)
+ }
+ return nil, err
+ }
+
+ // Get a handle to the next component. O_DIRECTORY means we don't need
+ // to use O_PATH.
+ var nextDir *os.File
+ if hasOpenat2() {
+ nextDir, err = openat2File(currentDir, part, &unix.OpenHow{
+ Flags: unix.O_NOFOLLOW | unix.O_DIRECTORY | unix.O_CLOEXEC,
+ Resolve: unix.RESOLVE_BENEATH | unix.RESOLVE_NO_SYMLINKS | unix.RESOLVE_NO_XDEV,
+ })
+ } else {
+ nextDir, err = openatFile(currentDir, part, unix.O_NOFOLLOW|unix.O_DIRECTORY|unix.O_CLOEXEC, 0)
+ }
+ if err != nil {
+ return nil, err
+ }
+ _ = currentDir.Close()
+ currentDir = nextDir
+
+ // It's possible that the directory we just opened was swapped by an
+ // attacker. Unfortunately there isn't much we can do to protect
+ // against this, and MkdirAll's behaviour is that we will reuse
+ // existing directories anyway so the need to protect against this is
+ // incredibly limited (and arguably doesn't even deserve mention here).
+ //
+ // Ideally we might want to check that the owner and mode match what we
+ // would've created -- unfortunately, it is non-trivial to verify that
+ // the owner and mode of the created directory match. While plain Unix
+ // DAC rules seem simple enough to emulate, there are a bunch of other
+ // factors that can change the mode or owner of created directories
+ // (default POSIX ACLs, mount options like uid=1,gid=2,umask=0 on
+ // filesystems like vfat, etc etc). We used to try to verify this but
+ // it just lead to a series of spurious errors.
+ //
+ // We could also check that the directory is non-empty, but
+ // unfortunately some pseduofilesystems (like cgroupfs) create
+ // non-empty directories, which would result in different spurious
+ // errors.
+ }
+ return currentDir, nil
+}
+
+// MkdirAll is a race-safe alternative to the [os.MkdirAll] function,
+// where the new directory is guaranteed to be within the root directory (if an
+// attacker can move directories from inside the root to outside the root, the
+// created directory tree might be outside of the root but the key constraint
+// is that at no point will we walk outside of the directory tree we are
+// creating).
+//
+// Effectively, MkdirAll(root, unsafePath, mode) is equivalent to
+//
+// path, _ := securejoin.SecureJoin(root, unsafePath)
+// err := os.MkdirAll(path, mode)
+//
+// But is much safer. The above implementation is unsafe because if an attacker
+// can modify the filesystem tree between [SecureJoin] and [os.MkdirAll], it is
+// possible for MkdirAll to resolve unsafe symlink components and create
+// directories outside of the root.
+//
+// If you plan to open the directory after you have created it or want to use
+// an open directory handle as the root, you should use [MkdirAllHandle] instead.
+// This function is a wrapper around [MkdirAllHandle].
+//
+// NOTE: The mode argument must be set the unix mode bits (unix.S_I...), not
+// the Go generic mode bits ([os.FileMode]...).
+func MkdirAll(root, unsafePath string, mode int) error {
+ rootDir, err := os.OpenFile(root, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0)
+ if err != nil {
+ return err
+ }
+ defer rootDir.Close()
+
+ f, err := MkdirAllHandle(rootDir, unsafePath, mode)
+ if err != nil {
+ return err
+ }
+ _ = f.Close()
+ return nil
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/open_linux.go b/vendor/github.com/cyphar/filepath-securejoin/open_linux.go
new file mode 100644
index 0000000000..230be73f0e
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/open_linux.go
@@ -0,0 +1,103 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "fmt"
+ "os"
+ "strconv"
+
+ "golang.org/x/sys/unix"
+)
+
+// OpenatInRoot is equivalent to [OpenInRoot], except that the root is provided
+// using an *[os.File] handle, to ensure that the correct root directory is used.
+func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error) {
+ handle, err := completeLookupInRoot(root, unsafePath)
+ if err != nil {
+ return nil, &os.PathError{Op: "securejoin.OpenInRoot", Path: unsafePath, Err: err}
+ }
+ return handle, nil
+}
+
+// OpenInRoot safely opens the provided unsafePath within the root.
+// Effectively, OpenInRoot(root, unsafePath) is equivalent to
+//
+// path, _ := securejoin.SecureJoin(root, unsafePath)
+// handle, err := os.OpenFile(path, unix.O_PATH|unix.O_CLOEXEC)
+//
+// But is much safer. The above implementation is unsafe because if an attacker
+// can modify the filesystem tree between [SecureJoin] and [os.OpenFile], it is
+// possible for the returned file to be outside of the root.
+//
+// Note that the returned handle is an O_PATH handle, meaning that only a very
+// limited set of operations will work on the handle. This is done to avoid
+// accidentally opening an untrusted file that could cause issues (such as a
+// disconnected TTY that could cause a DoS, or some other issue). In order to
+// use the returned handle, you can "upgrade" it to a proper handle using
+// [Reopen].
+func OpenInRoot(root, unsafePath string) (*os.File, error) {
+ rootDir, err := os.OpenFile(root, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0)
+ if err != nil {
+ return nil, err
+ }
+ defer rootDir.Close()
+ return OpenatInRoot(rootDir, unsafePath)
+}
+
+// Reopen takes an *[os.File] handle and re-opens it through /proc/self/fd.
+// Reopen(file, flags) is effectively equivalent to
+//
+// fdPath := fmt.Sprintf("/proc/self/fd/%d", file.Fd())
+// os.OpenFile(fdPath, flags|unix.O_CLOEXEC)
+//
+// But with some extra hardenings to ensure that we are not tricked by a
+// maliciously-configured /proc mount. While this attack scenario is not
+// common, in container runtimes it is possible for higher-level runtimes to be
+// tricked into configuring an unsafe /proc that can be used to attack file
+// operations. See [CVE-2019-19921] for more details.
+//
+// [CVE-2019-19921]: https://github.com/advisories/GHSA-fh74-hm69-rqjw
+func Reopen(handle *os.File, flags int) (*os.File, error) {
+ procRoot, err := getProcRoot()
+ if err != nil {
+ return nil, err
+ }
+
+ // We can't operate on /proc/thread-self/fd/$n directly when doing a
+ // re-open, so we need to open /proc/thread-self/fd and then open a single
+ // final component.
+ procFdDir, closer, err := procThreadSelf(procRoot, "fd/")
+ if err != nil {
+ return nil, fmt.Errorf("get safe /proc/thread-self/fd handle: %w", err)
+ }
+ defer procFdDir.Close()
+ defer closer()
+
+ // Try to detect if there is a mount on top of the magic-link we are about
+ // to open. If we are using unsafeHostProcRoot(), this could change after
+ // we check it (and there's nothing we can do about that) but for
+ // privateProcRoot() this should be guaranteed to be safe (at least since
+ // Linux 5.12[1], when anonymous mount namespaces were completely isolated
+ // from external mounts including mount propagation events).
+ //
+ // [1]: Linux commit ee2e3f50629f ("mount: fix mounting of detached mounts
+ // onto targets that reside on shared mounts").
+ fdStr := strconv.Itoa(int(handle.Fd()))
+ if err := checkSymlinkOvermount(procRoot, procFdDir, fdStr); err != nil {
+ return nil, fmt.Errorf("check safety of /proc/thread-self/fd/%s magiclink: %w", fdStr, err)
+ }
+
+ flags |= unix.O_CLOEXEC
+ // Rather than just wrapping openatFile, open-code it so we can copy
+ // handle.Name().
+ reopenFd, err := unix.Openat(int(procFdDir.Fd()), fdStr, flags, 0)
+ if err != nil {
+ return nil, fmt.Errorf("reopen fd %d: %w", handle.Fd(), err)
+ }
+ return os.NewFile(uintptr(reopenFd), handle.Name()), nil
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/openat2_linux.go b/vendor/github.com/cyphar/filepath-securejoin/openat2_linux.go
new file mode 100644
index 0000000000..ae3b381efe
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/openat2_linux.go
@@ -0,0 +1,128 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+
+ "golang.org/x/sys/unix"
+)
+
+var hasOpenat2 = sync.OnceValue(func() bool {
+ fd, err := unix.Openat2(unix.AT_FDCWD, ".", &unix.OpenHow{
+ Flags: unix.O_PATH | unix.O_CLOEXEC,
+ Resolve: unix.RESOLVE_NO_SYMLINKS | unix.RESOLVE_IN_ROOT,
+ })
+ if err != nil {
+ return false
+ }
+ _ = unix.Close(fd)
+ return true
+})
+
+func scopedLookupShouldRetry(how *unix.OpenHow, err error) bool {
+ // RESOLVE_IN_ROOT (and RESOLVE_BENEATH) can return -EAGAIN if we resolve
+ // ".." while a mount or rename occurs anywhere on the system. This could
+ // happen spuriously, or as the result of an attacker trying to mess with
+ // us during lookup.
+ //
+ // In addition, scoped lookups have a "safety check" at the end of
+ // complete_walk which will return -EXDEV if the final path is not in the
+ // root.
+ return how.Resolve&(unix.RESOLVE_IN_ROOT|unix.RESOLVE_BENEATH) != 0 &&
+ (errors.Is(err, unix.EAGAIN) || errors.Is(err, unix.EXDEV))
+}
+
+const scopedLookupMaxRetries = 10
+
+func openat2File(dir *os.File, path string, how *unix.OpenHow) (*os.File, error) {
+ fullPath := dir.Name() + "/" + path
+ // Make sure we always set O_CLOEXEC.
+ how.Flags |= unix.O_CLOEXEC
+ var tries int
+ for tries < scopedLookupMaxRetries {
+ fd, err := unix.Openat2(int(dir.Fd()), path, how)
+ if err != nil {
+ if scopedLookupShouldRetry(how, err) {
+ // We retry a couple of times to avoid the spurious errors, and
+ // if we are being attacked then returning -EAGAIN is the best
+ // we can do.
+ tries++
+ continue
+ }
+ return nil, &os.PathError{Op: "openat2", Path: fullPath, Err: err}
+ }
+ // If we are using RESOLVE_IN_ROOT, the name we generated may be wrong.
+ // NOTE: The procRoot code MUST NOT use RESOLVE_IN_ROOT, otherwise
+ // you'll get infinite recursion here.
+ if how.Resolve&unix.RESOLVE_IN_ROOT == unix.RESOLVE_IN_ROOT {
+ if actualPath, err := rawProcSelfFdReadlink(fd); err == nil {
+ fullPath = actualPath
+ }
+ }
+ return os.NewFile(uintptr(fd), fullPath), nil
+ }
+ return nil, &os.PathError{Op: "openat2", Path: fullPath, Err: errPossibleAttack}
+}
+
+func lookupOpenat2(root *os.File, unsafePath string, partial bool) (*os.File, string, error) {
+ if !partial {
+ file, err := openat2File(root, unsafePath, &unix.OpenHow{
+ Flags: unix.O_PATH | unix.O_CLOEXEC,
+ Resolve: unix.RESOLVE_IN_ROOT | unix.RESOLVE_NO_MAGICLINKS,
+ })
+ return file, "", err
+ }
+ return partialLookupOpenat2(root, unsafePath)
+}
+
+// partialLookupOpenat2 is an alternative implementation of
+// partialLookupInRoot, using openat2(RESOLVE_IN_ROOT) to more safely get a
+// handle to the deepest existing child of the requested path within the root.
+func partialLookupOpenat2(root *os.File, unsafePath string) (*os.File, string, error) {
+ // TODO: Implement this as a git-bisect-like binary search.
+
+ unsafePath = filepath.ToSlash(unsafePath) // noop
+ endIdx := len(unsafePath)
+ var lastError error
+ for endIdx > 0 {
+ subpath := unsafePath[:endIdx]
+
+ handle, err := openat2File(root, subpath, &unix.OpenHow{
+ Flags: unix.O_PATH | unix.O_CLOEXEC,
+ Resolve: unix.RESOLVE_IN_ROOT | unix.RESOLVE_NO_MAGICLINKS,
+ })
+ if err == nil {
+ // Jump over the slash if we have a non-"" remainingPath.
+ if endIdx < len(unsafePath) {
+ endIdx += 1
+ }
+ // We found a subpath!
+ return handle, unsafePath[endIdx:], lastError
+ }
+ if errors.Is(err, unix.ENOENT) || errors.Is(err, unix.ENOTDIR) {
+ // That path doesn't exist, let's try the next directory up.
+ endIdx = strings.LastIndexByte(subpath, '/')
+ lastError = err
+ continue
+ }
+ return nil, "", fmt.Errorf("open subpath: %w", err)
+ }
+ // If we couldn't open anything, the whole subpath is missing. Return a
+ // copy of the root fd so that the caller doesn't close this one by
+ // accident.
+ rootClone, err := dupFile(root)
+ if err != nil {
+ return nil, "", err
+ }
+ return rootClone, unsafePath, lastError
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go b/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go
new file mode 100644
index 0000000000..949fb5f2d8
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go
@@ -0,0 +1,59 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "os"
+ "path/filepath"
+
+ "golang.org/x/sys/unix"
+)
+
+func dupFile(f *os.File) (*os.File, error) {
+ fd, err := unix.FcntlInt(f.Fd(), unix.F_DUPFD_CLOEXEC, 0)
+ if err != nil {
+ return nil, os.NewSyscallError("fcntl(F_DUPFD_CLOEXEC)", err)
+ }
+ return os.NewFile(uintptr(fd), f.Name()), nil
+}
+
+func openatFile(dir *os.File, path string, flags int, mode int) (*os.File, error) {
+ // Make sure we always set O_CLOEXEC.
+ flags |= unix.O_CLOEXEC
+ fd, err := unix.Openat(int(dir.Fd()), path, flags, uint32(mode))
+ if err != nil {
+ return nil, &os.PathError{Op: "openat", Path: dir.Name() + "/" + path, Err: err}
+ }
+ // All of the paths we use with openatFile(2) are guaranteed to be
+ // lexically safe, so we can use path.Join here.
+ fullPath := filepath.Join(dir.Name(), path)
+ return os.NewFile(uintptr(fd), fullPath), nil
+}
+
+func fstatatFile(dir *os.File, path string, flags int) (unix.Stat_t, error) {
+ var stat unix.Stat_t
+ if err := unix.Fstatat(int(dir.Fd()), path, &stat, flags); err != nil {
+ return stat, &os.PathError{Op: "fstatat", Path: dir.Name() + "/" + path, Err: err}
+ }
+ return stat, nil
+}
+
+func readlinkatFile(dir *os.File, path string) (string, error) {
+ size := 4096
+ for {
+ linkBuf := make([]byte, size)
+ n, err := unix.Readlinkat(int(dir.Fd()), path, linkBuf)
+ if err != nil {
+ return "", &os.PathError{Op: "readlinkat", Path: dir.Name() + "/" + path, Err: err}
+ }
+ if n != size {
+ return string(linkBuf[:n]), nil
+ }
+ // Possible truncation, resize the buffer.
+ size *= 2
+ }
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go b/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go
new file mode 100644
index 0000000000..8cc827d704
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go
@@ -0,0 +1,440 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "runtime"
+ "strconv"
+ "sync"
+
+ "golang.org/x/sys/unix"
+)
+
+func fstat(f *os.File) (unix.Stat_t, error) {
+ var stat unix.Stat_t
+ if err := unix.Fstat(int(f.Fd()), &stat); err != nil {
+ return stat, &os.PathError{Op: "fstat", Path: f.Name(), Err: err}
+ }
+ return stat, nil
+}
+
+func fstatfs(f *os.File) (unix.Statfs_t, error) {
+ var statfs unix.Statfs_t
+ if err := unix.Fstatfs(int(f.Fd()), &statfs); err != nil {
+ return statfs, &os.PathError{Op: "fstatfs", Path: f.Name(), Err: err}
+ }
+ return statfs, nil
+}
+
+// The kernel guarantees that the root inode of a procfs mount has an
+// f_type of PROC_SUPER_MAGIC and st_ino of PROC_ROOT_INO.
+const (
+ procSuperMagic = 0x9fa0 // PROC_SUPER_MAGIC
+ procRootIno = 1 // PROC_ROOT_INO
+)
+
+func verifyProcRoot(procRoot *os.File) error {
+ if statfs, err := fstatfs(procRoot); err != nil {
+ return err
+ } else if statfs.Type != procSuperMagic {
+ return fmt.Errorf("%w: incorrect procfs root filesystem type 0x%x", errUnsafeProcfs, statfs.Type)
+ }
+ if stat, err := fstat(procRoot); err != nil {
+ return err
+ } else if stat.Ino != procRootIno {
+ return fmt.Errorf("%w: incorrect procfs root inode number %d", errUnsafeProcfs, stat.Ino)
+ }
+ return nil
+}
+
+var hasNewMountApi = sync.OnceValue(func() bool {
+ // All of the pieces of the new mount API we use (fsopen, fsconfig,
+ // fsmount, open_tree) were added together in Linux 5.1[1,2], so we can
+ // just check for one of the syscalls and the others should also be
+ // available.
+ //
+ // Just try to use open_tree(2) to open a file without OPEN_TREE_CLONE.
+ // This is equivalent to openat(2), but tells us if open_tree is
+ // available (and thus all of the other basic new mount API syscalls).
+ // open_tree(2) is most light-weight syscall to test here.
+ //
+ // [1]: merge commit 400913252d09
+ // [2]:
+ fd, err := unix.OpenTree(-int(unix.EBADF), "/", unix.OPEN_TREE_CLOEXEC)
+ if err != nil {
+ return false
+ }
+ _ = unix.Close(fd)
+ return true
+})
+
+func fsopen(fsName string, flags int) (*os.File, error) {
+ // Make sure we always set O_CLOEXEC.
+ flags |= unix.FSOPEN_CLOEXEC
+ fd, err := unix.Fsopen(fsName, flags)
+ if err != nil {
+ return nil, os.NewSyscallError("fsopen "+fsName, err)
+ }
+ return os.NewFile(uintptr(fd), "fscontext:"+fsName), nil
+}
+
+func fsmount(ctx *os.File, flags, mountAttrs int) (*os.File, error) {
+ // Make sure we always set O_CLOEXEC.
+ flags |= unix.FSMOUNT_CLOEXEC
+ fd, err := unix.Fsmount(int(ctx.Fd()), flags, mountAttrs)
+ if err != nil {
+ return nil, os.NewSyscallError("fsmount "+ctx.Name(), err)
+ }
+ return os.NewFile(uintptr(fd), "fsmount:"+ctx.Name()), nil
+}
+
+func newPrivateProcMount() (*os.File, error) {
+ procfsCtx, err := fsopen("proc", unix.FSOPEN_CLOEXEC)
+ if err != nil {
+ return nil, err
+ }
+ defer procfsCtx.Close()
+
+ // Try to configure hidepid=ptraceable,subset=pid if possible, but ignore errors.
+ _ = unix.FsconfigSetString(int(procfsCtx.Fd()), "hidepid", "ptraceable")
+ _ = unix.FsconfigSetString(int(procfsCtx.Fd()), "subset", "pid")
+
+ // Get an actual handle.
+ if err := unix.FsconfigCreate(int(procfsCtx.Fd())); err != nil {
+ return nil, os.NewSyscallError("fsconfig create procfs", err)
+ }
+ return fsmount(procfsCtx, unix.FSMOUNT_CLOEXEC, unix.MS_RDONLY|unix.MS_NODEV|unix.MS_NOEXEC|unix.MS_NOSUID)
+}
+
+func openTree(dir *os.File, path string, flags uint) (*os.File, error) {
+ dirFd := -int(unix.EBADF)
+ dirName := "."
+ if dir != nil {
+ dirFd = int(dir.Fd())
+ dirName = dir.Name()
+ }
+ // Make sure we always set O_CLOEXEC.
+ flags |= unix.OPEN_TREE_CLOEXEC
+ fd, err := unix.OpenTree(dirFd, path, flags)
+ if err != nil {
+ return nil, &os.PathError{Op: "open_tree", Path: path, Err: err}
+ }
+ return os.NewFile(uintptr(fd), dirName+"/"+path), nil
+}
+
+func clonePrivateProcMount() (_ *os.File, Err error) {
+ // Try to make a clone without using AT_RECURSIVE if we can. If this works,
+ // we can be sure there are no over-mounts and so if the root is valid then
+ // we're golden. Otherwise, we have to deal with over-mounts.
+ procfsHandle, err := openTree(nil, "/proc", unix.OPEN_TREE_CLONE)
+ if err != nil || hookForcePrivateProcRootOpenTreeAtRecursive(procfsHandle) {
+ procfsHandle, err = openTree(nil, "/proc", unix.OPEN_TREE_CLONE|unix.AT_RECURSIVE)
+ }
+ if err != nil {
+ return nil, fmt.Errorf("creating a detached procfs clone: %w", err)
+ }
+ defer func() {
+ if Err != nil {
+ _ = procfsHandle.Close()
+ }
+ }()
+ if err := verifyProcRoot(procfsHandle); err != nil {
+ return nil, err
+ }
+ return procfsHandle, nil
+}
+
+func privateProcRoot() (*os.File, error) {
+ if !hasNewMountApi() || hookForceGetProcRootUnsafe() {
+ return nil, fmt.Errorf("new mount api: %w", unix.ENOTSUP)
+ }
+ // Try to create a new procfs mount from scratch if we can. This ensures we
+ // can get a procfs mount even if /proc is fake (for whatever reason).
+ procRoot, err := newPrivateProcMount()
+ if err != nil || hookForcePrivateProcRootOpenTree(procRoot) {
+ // Try to clone /proc then...
+ procRoot, err = clonePrivateProcMount()
+ }
+ return procRoot, err
+}
+
+func unsafeHostProcRoot() (_ *os.File, Err error) {
+ procRoot, err := os.OpenFile("/proc", unix.O_PATH|unix.O_NOFOLLOW|unix.O_DIRECTORY|unix.O_CLOEXEC, 0)
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ if Err != nil {
+ _ = procRoot.Close()
+ }
+ }()
+ if err := verifyProcRoot(procRoot); err != nil {
+ return nil, err
+ }
+ return procRoot, nil
+}
+
+func doGetProcRoot() (*os.File, error) {
+ procRoot, err := privateProcRoot()
+ if err != nil {
+ // Fall back to using a /proc handle if making a private mount failed.
+ // If we have openat2, at least we can avoid some kinds of over-mount
+ // attacks, but without openat2 there's not much we can do.
+ procRoot, err = unsafeHostProcRoot()
+ }
+ return procRoot, err
+}
+
+var getProcRoot = sync.OnceValues(func() (*os.File, error) {
+ return doGetProcRoot()
+})
+
+var hasProcThreadSelf = sync.OnceValue(func() bool {
+ return unix.Access("/proc/thread-self/", unix.F_OK) == nil
+})
+
+var errUnsafeProcfs = errors.New("unsafe procfs detected")
+
+type procThreadSelfCloser func()
+
+// procThreadSelf returns a handle to /proc/thread-self/ (or an
+// equivalent handle on older kernels where /proc/thread-self doesn't exist).
+// Once finished with the handle, you must call the returned closer function
+// (runtime.UnlockOSThread). You must not pass the returned *os.File to other
+// Go threads or use the handle after calling the closer.
+//
+// This is similar to ProcThreadSelf from runc, but with extra hardening
+// applied and using *os.File.
+func procThreadSelf(procRoot *os.File, subpath string) (_ *os.File, _ procThreadSelfCloser, Err error) {
+ // We need to lock our thread until the caller is done with the handle
+ // because between getting the handle and using it we could get interrupted
+ // by the Go runtime and hit the case where the underlying thread is
+ // swapped out and the original thread is killed, resulting in
+ // pull-your-hair-out-hard-to-debug issues in the caller.
+ runtime.LockOSThread()
+ defer func() {
+ if Err != nil {
+ runtime.UnlockOSThread()
+ }
+ }()
+
+ // Figure out what prefix we want to use.
+ threadSelf := "thread-self/"
+ if !hasProcThreadSelf() || hookForceProcSelfTask() {
+ /// Pre-3.17 kernels don't have /proc/thread-self, so do it manually.
+ threadSelf = "self/task/" + strconv.Itoa(unix.Gettid()) + "/"
+ if _, err := fstatatFile(procRoot, threadSelf, unix.AT_SYMLINK_NOFOLLOW); err != nil || hookForceProcSelf() {
+ // In this case, we running in a pid namespace that doesn't match
+ // the /proc mount we have. This can happen inside runc.
+ //
+ // Unfortunately, there is no nice way to get the correct TID to
+ // use here because of the age of the kernel, so we have to just
+ // use /proc/self and hope that it works.
+ threadSelf = "self/"
+ }
+ }
+
+ // Grab the handle.
+ var (
+ handle *os.File
+ err error
+ )
+ if hasOpenat2() {
+ // We prefer being able to use RESOLVE_NO_XDEV if we can, to be
+ // absolutely sure we are operating on a clean /proc handle that
+ // doesn't have any cheeky overmounts that could trick us (including
+ // symlink mounts on top of /proc/thread-self). RESOLVE_BENEATH isn't
+ // strictly needed, but just use it since we have it.
+ //
+ // NOTE: /proc/self is technically a magic-link (the contents of the
+ // symlink are generated dynamically), but it doesn't use
+ // nd_jump_link() so RESOLVE_NO_MAGICLINKS allows it.
+ //
+ // NOTE: We MUST NOT use RESOLVE_IN_ROOT here, as openat2File uses
+ // procSelfFdReadlink to clean up the returned f.Name() if we use
+ // RESOLVE_IN_ROOT (which would lead to an infinite recursion).
+ handle, err = openat2File(procRoot, threadSelf+subpath, &unix.OpenHow{
+ Flags: unix.O_PATH | unix.O_NOFOLLOW | unix.O_CLOEXEC,
+ Resolve: unix.RESOLVE_BENEATH | unix.RESOLVE_NO_XDEV | unix.RESOLVE_NO_MAGICLINKS,
+ })
+ if err != nil {
+ return nil, nil, fmt.Errorf("%w: %w", errUnsafeProcfs, err)
+ }
+ } else {
+ handle, err = openatFile(procRoot, threadSelf+subpath, unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0)
+ if err != nil {
+ return nil, nil, fmt.Errorf("%w: %w", errUnsafeProcfs, err)
+ }
+ defer func() {
+ if Err != nil {
+ _ = handle.Close()
+ }
+ }()
+ // We can't detect bind-mounts of different parts of procfs on top of
+ // /proc (a-la RESOLVE_NO_XDEV), but we can at least be sure that we
+ // aren't on the wrong filesystem here.
+ if statfs, err := fstatfs(handle); err != nil {
+ return nil, nil, err
+ } else if statfs.Type != procSuperMagic {
+ return nil, nil, fmt.Errorf("%w: incorrect /proc/self/fd filesystem type 0x%x", errUnsafeProcfs, statfs.Type)
+ }
+ }
+ return handle, runtime.UnlockOSThread, nil
+}
+
+var hasStatxMountId = sync.OnceValue(func() bool {
+ var (
+ stx unix.Statx_t
+ // We don't care which mount ID we get. The kernel will give us the
+ // unique one if it is supported.
+ wantStxMask uint32 = unix.STATX_MNT_ID_UNIQUE | unix.STATX_MNT_ID
+ )
+ err := unix.Statx(-int(unix.EBADF), "/", 0, int(wantStxMask), &stx)
+ return err == nil && stx.Mask&wantStxMask != 0
+})
+
+func getMountId(dir *os.File, path string) (uint64, error) {
+ // If we don't have statx(STATX_MNT_ID*) support, we can't do anything.
+ if !hasStatxMountId() {
+ return 0, nil
+ }
+
+ var (
+ stx unix.Statx_t
+ // We don't care which mount ID we get. The kernel will give us the
+ // unique one if it is supported.
+ wantStxMask uint32 = unix.STATX_MNT_ID_UNIQUE | unix.STATX_MNT_ID
+ )
+
+ err := unix.Statx(int(dir.Fd()), path, unix.AT_EMPTY_PATH|unix.AT_SYMLINK_NOFOLLOW, int(wantStxMask), &stx)
+ if stx.Mask&wantStxMask == 0 {
+ // It's not a kernel limitation, for some reason we couldn't get a
+ // mount ID. Assume it's some kind of attack.
+ err = fmt.Errorf("%w: could not get mount id", errUnsafeProcfs)
+ }
+ if err != nil {
+ return 0, &os.PathError{Op: "statx(STATX_MNT_ID_...)", Path: dir.Name() + "/" + path, Err: err}
+ }
+ return stx.Mnt_id, nil
+}
+
+func checkSymlinkOvermount(procRoot *os.File, dir *os.File, path string) error {
+ // Get the mntId of our procfs handle.
+ expectedMountId, err := getMountId(procRoot, "")
+ if err != nil {
+ return err
+ }
+ // Get the mntId of the target magic-link.
+ gotMountId, err := getMountId(dir, path)
+ if err != nil {
+ return err
+ }
+ // As long as the directory mount is alive, even with wrapping mount IDs,
+ // we would expect to see a different mount ID here. (Of course, if we're
+ // using unsafeHostProcRoot() then an attaker could change this after we
+ // did this check.)
+ if expectedMountId != gotMountId {
+ return fmt.Errorf("%w: symlink %s/%s has an overmount obscuring the real link (mount ids do not match %d != %d)", errUnsafeProcfs, dir.Name(), path, expectedMountId, gotMountId)
+ }
+ return nil
+}
+
+func doRawProcSelfFdReadlink(procRoot *os.File, fd int) (string, error) {
+ fdPath := fmt.Sprintf("fd/%d", fd)
+ procFdLink, closer, err := procThreadSelf(procRoot, fdPath)
+ if err != nil {
+ return "", fmt.Errorf("get safe /proc/thread-self/%s handle: %w", fdPath, err)
+ }
+ defer procFdLink.Close()
+ defer closer()
+
+ // Try to detect if there is a mount on top of the magic-link. Since we use the handle directly
+ // provide to the closure. If the closure uses the handle directly, this
+ // should be safe in general (a mount on top of the path afterwards would
+ // not affect the handle itself) and will definitely be safe if we are
+ // using privateProcRoot() (at least since Linux 5.12[1], when anonymous
+ // mount namespaces were completely isolated from external mounts including
+ // mount propagation events).
+ //
+ // [1]: Linux commit ee2e3f50629f ("mount: fix mounting of detached mounts
+ // onto targets that reside on shared mounts").
+ if err := checkSymlinkOvermount(procRoot, procFdLink, ""); err != nil {
+ return "", fmt.Errorf("check safety of /proc/thread-self/fd/%d magiclink: %w", fd, err)
+ }
+
+ // readlinkat implies AT_EMPTY_PATH since Linux 2.6.39. See Linux commit
+ // 65cfc6722361 ("readlinkat(), fchownat() and fstatat() with empty
+ // relative pathnames").
+ return readlinkatFile(procFdLink, "")
+}
+
+func rawProcSelfFdReadlink(fd int) (string, error) {
+ procRoot, err := getProcRoot()
+ if err != nil {
+ return "", err
+ }
+ return doRawProcSelfFdReadlink(procRoot, fd)
+}
+
+func procSelfFdReadlink(f *os.File) (string, error) {
+ return rawProcSelfFdReadlink(int(f.Fd()))
+}
+
+var (
+ errPossibleBreakout = errors.New("possible breakout detected")
+ errInvalidDirectory = errors.New("wandered into deleted directory")
+ errDeletedInode = errors.New("cannot verify path of deleted inode")
+)
+
+func isDeadInode(file *os.File) error {
+ // If the nlink of a file drops to 0, there is an attacker deleting
+ // directories during our walk, which could result in weird /proc values.
+ // It's better to error out in this case.
+ stat, err := fstat(file)
+ if err != nil {
+ return fmt.Errorf("check for dead inode: %w", err)
+ }
+ if stat.Nlink == 0 {
+ err := errDeletedInode
+ if stat.Mode&unix.S_IFMT == unix.S_IFDIR {
+ err = errInvalidDirectory
+ }
+ return fmt.Errorf("%w %q", err, file.Name())
+ }
+ return nil
+}
+
+func checkProcSelfFdPath(path string, file *os.File) error {
+ if err := isDeadInode(file); err != nil {
+ return err
+ }
+ actualPath, err := procSelfFdReadlink(file)
+ if err != nil {
+ return fmt.Errorf("get path of handle: %w", err)
+ }
+ if actualPath != path {
+ return fmt.Errorf("%w: handle path %q doesn't match expected path %q", errPossibleBreakout, actualPath, path)
+ }
+ return nil
+}
+
+// Test hooks used in the procfs tests to verify that the fallback logic works.
+// See testing_mocks_linux_test.go and procfs_linux_test.go for more details.
+var (
+ hookForcePrivateProcRootOpenTree = hookDummyFile
+ hookForcePrivateProcRootOpenTreeAtRecursive = hookDummyFile
+ hookForceGetProcRootUnsafe = hookDummy
+
+ hookForceProcSelfTask = hookDummy
+ hookForceProcSelf = hookDummy
+)
+
+func hookDummy() bool { return false }
+func hookDummyFile(_ *os.File) bool { return false }
diff --git a/vendor/github.com/cyphar/filepath-securejoin/vfs.go b/vendor/github.com/cyphar/filepath-securejoin/vfs.go
index a82a5eae11..36373f8c51 100644
--- a/vendor/github.com/cyphar/filepath-securejoin/vfs.go
+++ b/vendor/github.com/cyphar/filepath-securejoin/vfs.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 SUSE LLC. All rights reserved.
+// Copyright (C) 2017-2024 SUSE LLC. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -10,19 +10,19 @@ import "os"
// are several projects (umoci and go-mtree) that are using this sort of
// interface.
-// VFS is the minimal interface necessary to use SecureJoinVFS. A nil VFS is
-// equivalent to using the standard os.* family of functions. This is mainly
+// VFS is the minimal interface necessary to use [SecureJoinVFS]. A nil VFS is
+// equivalent to using the standard [os].* family of functions. This is mainly
// used for the purposes of mock testing, but also can be used to otherwise use
-// SecureJoin with VFS-like system.
+// [SecureJoinVFS] with VFS-like system.
type VFS interface {
- // Lstat returns a FileInfo describing the named file. If the file is a
- // symbolic link, the returned FileInfo describes the symbolic link. Lstat
- // makes no attempt to follow the link. These semantics are identical to
- // os.Lstat.
+ // Lstat returns an [os.FileInfo] describing the named file. If the
+ // file is a symbolic link, the returned [os.FileInfo] describes the
+ // symbolic link. Lstat makes no attempt to follow the link.
+ // The semantics are identical to [os.Lstat].
Lstat(name string) (os.FileInfo, error)
- // Readlink returns the destination of the named symbolic link. These
- // semantics are identical to os.Readlink.
+ // Readlink returns the destination of the named symbolic link.
+ // The semantics are identical to [os.Readlink].
Readlink(name string) (string, error)
}
@@ -30,12 +30,6 @@ type VFS interface {
// module.
type osVFS struct{}
-// Lstat returns a FileInfo describing the named file. If the file is a
-// symbolic link, the returned FileInfo describes the symbolic link. Lstat
-// makes no attempt to follow the link. These semantics are identical to
-// os.Lstat.
func (o osVFS) Lstat(name string) (os.FileInfo, error) { return os.Lstat(name) }
-// Readlink returns the destination of the named symbolic link. These
-// semantics are identical to os.Readlink.
func (o osVFS) Readlink(name string) (string, error) { return os.Readlink(name) }
diff --git a/vendor/github.com/docker/docker-credential-helpers/client/client.go b/vendor/github.com/docker/docker-credential-helpers/client/client.go
index d1d0434cb5..7ca5ab7222 100644
--- a/vendor/github.com/docker/docker-credential-helpers/client/client.go
+++ b/vendor/github.com/docker/docker-credential-helpers/client/client.go
@@ -16,17 +16,15 @@ func isValidCredsMessage(msg string) error {
if credentials.IsCredentialsMissingServerURLMessage(msg) {
return credentials.NewErrCredentialsMissingServerURL()
}
-
if credentials.IsCredentialsMissingUsernameMessage(msg) {
return credentials.NewErrCredentialsMissingUsername()
}
-
return nil
}
// Store uses an external program to save credentials.
func Store(program ProgramFunc, creds *credentials.Credentials) error {
- cmd := program("store")
+ cmd := program(credentials.ActionStore)
buffer := new(bytes.Buffer)
if err := json.NewEncoder(buffer).Encode(creds); err != nil {
@@ -36,13 +34,10 @@ func Store(program ProgramFunc, creds *credentials.Credentials) error {
out, err := cmd.Output()
if err != nil {
- t := strings.TrimSpace(string(out))
-
- if isValidErr := isValidCredsMessage(t); isValidErr != nil {
+ if isValidErr := isValidCredsMessage(string(out)); isValidErr != nil {
err = isValidErr
}
-
- return fmt.Errorf("error storing credentials - err: %v, out: `%s`", err, t)
+ return fmt.Errorf("error storing credentials - err: %v, out: `%s`", err, strings.TrimSpace(string(out)))
}
return nil
@@ -50,22 +45,20 @@ func Store(program ProgramFunc, creds *credentials.Credentials) error {
// Get executes an external program to get the credentials from a native store.
func Get(program ProgramFunc, serverURL string) (*credentials.Credentials, error) {
- cmd := program("get")
+ cmd := program(credentials.ActionGet)
cmd.Input(strings.NewReader(serverURL))
out, err := cmd.Output()
if err != nil {
- t := strings.TrimSpace(string(out))
-
- if credentials.IsErrCredentialsNotFoundMessage(t) {
+ if credentials.IsErrCredentialsNotFoundMessage(string(out)) {
return nil, credentials.NewErrCredentialsNotFound()
}
- if isValidErr := isValidCredsMessage(t); isValidErr != nil {
+ if isValidErr := isValidCredsMessage(string(out)); isValidErr != nil {
err = isValidErr
}
- return nil, fmt.Errorf("error getting credentials - err: %v, out: `%s`", err, t)
+ return nil, fmt.Errorf("error getting credentials - err: %v, out: `%s`", err, strings.TrimSpace(string(out)))
}
resp := &credentials.Credentials{
@@ -81,7 +74,7 @@ func Get(program ProgramFunc, serverURL string) (*credentials.Credentials, error
// Erase executes a program to remove the server credentials from the native store.
func Erase(program ProgramFunc, serverURL string) error {
- cmd := program("erase")
+ cmd := program(credentials.ActionErase)
cmd.Input(strings.NewReader(serverURL))
out, err := cmd.Output()
if err != nil {
@@ -99,7 +92,7 @@ func Erase(program ProgramFunc, serverURL string) error {
// List executes a program to list server credentials in the native store.
func List(program ProgramFunc) (map[string]string, error) {
- cmd := program("list")
+ cmd := program(credentials.ActionList)
cmd.Input(strings.NewReader("unused"))
out, err := cmd.Output()
if err != nil {
diff --git a/vendor/github.com/docker/docker-credential-helpers/client/command.go b/vendor/github.com/docker/docker-credential-helpers/client/command.go
index 0183c06393..1936234bef 100644
--- a/vendor/github.com/docker/docker-credential-helpers/client/command.go
+++ b/vendor/github.com/docker/docker-credential-helpers/client/command.go
@@ -1,11 +1,9 @@
package client
import (
- "fmt"
"io"
"os"
-
- exec "golang.org/x/sys/execabs"
+ "os/exec"
)
// Program is an interface to execute external programs.
@@ -31,27 +29,26 @@ func NewShellProgramFuncWithEnv(name string, env *map[string]string) ProgramFunc
func createProgramCmdRedirectErr(commandName string, args []string, env *map[string]string) *exec.Cmd {
programCmd := exec.Command(commandName, args...)
- programCmd.Env = os.Environ()
if env != nil {
for k, v := range *env {
- programCmd.Env = append(programCmd.Env, fmt.Sprintf("%s=%s", k, v))
+ programCmd.Env = append(programCmd.Environ(), k+"="+v)
}
}
programCmd.Stderr = os.Stderr
return programCmd
}
-// Shell invokes shell commands to talk with a remote credentials helper.
+// Shell invokes shell commands to talk with a remote credentials-helper.
type Shell struct {
cmd *exec.Cmd
}
-// Output returns responses from the remote credentials helper.
+// Output returns responses from the remote credentials-helper.
func (s *Shell) Output() ([]byte, error) {
return s.cmd.Output()
}
-// Input sets the input to send to a remote credentials helper.
+// Input sets the input to send to a remote credentials-helper.
func (s *Shell) Input(in io.Reader) {
s.cmd.Stdin = in
}
diff --git a/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go b/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go
index 91d9d4bbae..eac5518849 100644
--- a/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go
+++ b/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go
@@ -10,6 +10,20 @@ import (
"strings"
)
+// Action defines the name of an action (sub-command) supported by a
+// credential-helper binary. It is an alias for "string", and mostly
+// for convenience.
+type Action = string
+
+// List of actions (sub-commands) supported by credential-helper binaries.
+const (
+ ActionStore Action = "store"
+ ActionGet Action = "get"
+ ActionErase Action = "erase"
+ ActionList Action = "list"
+ ActionVersion Action = "version"
+)
+
// Credentials holds the information shared between docker and the credentials store.
type Credentials struct {
ServerURL string
@@ -43,42 +57,52 @@ func SetCredsLabel(label string) {
CredsLabel = label
}
-// Serve initializes the credentials helper and parses the action argument.
+// Serve initializes the credentials-helper and parses the action argument.
// This function is designed to be called from a command line interface.
// It uses os.Args[1] as the key for the action.
// It uses os.Stdin as input and os.Stdout as output.
// This function terminates the program with os.Exit(1) if there is an error.
func Serve(helper Helper) {
- var err error
if len(os.Args) != 2 {
- err = fmt.Errorf("Usage: %s ", os.Args[0])
+ _, _ = fmt.Fprintln(os.Stdout, usage())
+ os.Exit(1)
}
- if err == nil {
- err = HandleCommand(helper, os.Args[1], os.Stdin, os.Stdout)
+ switch os.Args[1] {
+ case "--version", "-v":
+ _ = PrintVersion(os.Stdout)
+ os.Exit(0)
+ case "--help", "-h":
+ _, _ = fmt.Fprintln(os.Stdout, usage())
+ os.Exit(0)
}
- if err != nil {
- fmt.Fprintf(os.Stdout, "%v\n", err)
+ if err := HandleCommand(helper, os.Args[1], os.Stdin, os.Stdout); err != nil {
+ _, _ = fmt.Fprintln(os.Stdout, err)
os.Exit(1)
}
}
-// HandleCommand uses a helper and a key to run a credential action.
-func HandleCommand(helper Helper, key string, in io.Reader, out io.Writer) error {
- switch key {
- case "store":
+func usage() string {
+ return fmt.Sprintf("Usage: %s ", Name)
+}
+
+// HandleCommand runs a helper to execute a credential action.
+func HandleCommand(helper Helper, action Action, in io.Reader, out io.Writer) error {
+ switch action {
+ case ActionStore:
return Store(helper, in)
- case "get":
+ case ActionGet:
return Get(helper, in, out)
- case "erase":
+ case ActionErase:
return Erase(helper, in)
- case "list":
+ case ActionList:
return List(helper, out)
- case "version":
+ case ActionVersion:
return PrintVersion(out)
+ default:
+ return fmt.Errorf("%s: unknown action: %s", Name, action)
}
- return fmt.Errorf("Unknown credential action `%s`", key)
}
// Store uses a helper and an input reader to save credentials.
@@ -132,18 +156,17 @@ func Get(helper Helper, reader io.Reader, writer io.Writer) error {
return err
}
- resp := Credentials{
+ buffer.Reset()
+ err = json.NewEncoder(buffer).Encode(Credentials{
ServerURL: serverURL,
Username: username,
Secret: secret,
- }
-
- buffer.Reset()
- if err := json.NewEncoder(buffer).Encode(resp); err != nil {
+ })
+ if err != nil {
return err
}
- fmt.Fprint(writer, buffer.String())
+ _, _ = fmt.Fprint(writer, buffer.String())
return nil
}
@@ -181,6 +204,6 @@ func List(helper Helper, writer io.Writer) error {
// PrintVersion outputs the current version.
func PrintVersion(writer io.Writer) error {
- fmt.Fprintf(writer, "%s (%s) %s\n", Name, Package, Version)
+ _, _ = fmt.Fprintf(writer, "%s (%s) %s\n", Name, Package, Version)
return nil
}
diff --git a/vendor/github.com/docker/docker-credential-helpers/credentials/error.go b/vendor/github.com/docker/docker-credential-helpers/credentials/error.go
index fe6a5aef45..2283d5a44c 100644
--- a/vendor/github.com/docker/docker-credential-helpers/credentials/error.go
+++ b/vendor/github.com/docker/docker-credential-helpers/credentials/error.go
@@ -1,5 +1,10 @@
package credentials
+import (
+ "errors"
+ "strings"
+)
+
const (
// ErrCredentialsNotFound standardizes the not found error, so every helper returns
// the same message and docker can handle it properly.
@@ -21,6 +26,11 @@ func (errCredentialsNotFound) Error() string {
return errCredentialsNotFoundMessage
}
+// NotFound implements the [ErrNotFound][errdefs.ErrNotFound] interface.
+//
+// [errdefs.ErrNotFound]: https://pkg.go.dev/github.com/docker/docker@v24.0.1+incompatible/errdefs#ErrNotFound
+func (errCredentialsNotFound) NotFound() {}
+
// NewErrCredentialsNotFound creates a new error
// for when the credentials are not in the store.
func NewErrCredentialsNotFound() error {
@@ -30,8 +40,8 @@ func NewErrCredentialsNotFound() error {
// IsErrCredentialsNotFound returns true if the error
// was caused by not having a set of credentials in a store.
func IsErrCredentialsNotFound(err error) bool {
- _, ok := err.(errCredentialsNotFound)
- return ok
+ var target errCredentialsNotFound
+ return errors.As(err, &target)
}
// IsErrCredentialsNotFoundMessage returns true if the error
@@ -40,7 +50,7 @@ func IsErrCredentialsNotFound(err error) bool {
// This function helps to check messages returned by an
// external program via its standard output.
func IsErrCredentialsNotFoundMessage(err string) bool {
- return err == errCredentialsNotFoundMessage
+ return strings.TrimSpace(err) == errCredentialsNotFoundMessage
}
// errCredentialsMissingServerURL represents an error raised
@@ -53,6 +63,12 @@ func (errCredentialsMissingServerURL) Error() string {
return errCredentialsMissingServerURLMessage
}
+// InvalidParameter implements the [ErrInvalidParameter][errdefs.ErrInvalidParameter]
+// interface.
+//
+// [errdefs.ErrInvalidParameter]: https://pkg.go.dev/github.com/docker/docker@v24.0.1+incompatible/errdefs#ErrInvalidParameter
+func (errCredentialsMissingServerURL) InvalidParameter() {}
+
// errCredentialsMissingUsername represents an error raised
// when the credentials object has no username or when no
// username is provided to a credentials operation requiring
@@ -63,6 +79,12 @@ func (errCredentialsMissingUsername) Error() string {
return errCredentialsMissingUsernameMessage
}
+// InvalidParameter implements the [ErrInvalidParameter][errdefs.ErrInvalidParameter]
+// interface.
+//
+// [errdefs.ErrInvalidParameter]: https://pkg.go.dev/github.com/docker/docker@v24.0.1+incompatible/errdefs#ErrInvalidParameter
+func (errCredentialsMissingUsername) InvalidParameter() {}
+
// NewErrCredentialsMissingServerURL creates a new error for
// errCredentialsMissingServerURL.
func NewErrCredentialsMissingServerURL() error {
@@ -78,25 +100,25 @@ func NewErrCredentialsMissingUsername() error {
// IsCredentialsMissingServerURL returns true if the error
// was an errCredentialsMissingServerURL.
func IsCredentialsMissingServerURL(err error) bool {
- _, ok := err.(errCredentialsMissingServerURL)
- return ok
+ var target errCredentialsMissingServerURL
+ return errors.As(err, &target)
}
// IsCredentialsMissingServerURLMessage checks for an
// errCredentialsMissingServerURL in the error message.
func IsCredentialsMissingServerURLMessage(err string) bool {
- return err == errCredentialsMissingServerURLMessage
+ return strings.TrimSpace(err) == errCredentialsMissingServerURLMessage
}
// IsCredentialsMissingUsername returns true if the error
// was an errCredentialsMissingUsername.
func IsCredentialsMissingUsername(err error) bool {
- _, ok := err.(errCredentialsMissingUsername)
- return ok
+ var target errCredentialsMissingUsername
+ return errors.As(err, &target)
}
// IsCredentialsMissingUsernameMessage checks for an
// errCredentialsMissingUsername in the error message.
func IsCredentialsMissingUsernameMessage(err string) bool {
- return err == errCredentialsMissingUsernameMessage
+ return strings.TrimSpace(err) == errCredentialsMissingUsernameMessage
}
diff --git a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md
index 5edd5a7ca9..92b78048e2 100644
--- a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md
+++ b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md
@@ -1,6 +1,24 @@
# Change history of go-restful
-## [v3.11.0] - 2023-08-19
+
+## [v3.12.1] - 2024-05-28
+
+- fix misroute when dealing multiple webservice with regex (#549) (thanks Haitao Chen)
+
+## [v3.12.0] - 2024-03-11
+
+- add Flush method #529 (#538)
+- fix: Improper handling of empty POST requests (#543)
+
+## [v3.11.3] - 2024-01-09
+
+- better not have 2 tags on one commit
+
+## [v3.11.1, v3.11.2] - 2024-01-09
+
+- fix by restoring custom JSON handler functions (Mike Beaumont #540)
+
+## [v3.12.0] - 2023-08-19
- restored behavior as <= v3.9.0 with option to change path strategy using TrimRightSlashEnabled.
diff --git a/vendor/github.com/emicklei/go-restful/v3/README.md b/vendor/github.com/emicklei/go-restful/v3/README.md
index e3e30080ec..7234604e47 100644
--- a/vendor/github.com/emicklei/go-restful/v3/README.md
+++ b/vendor/github.com/emicklei/go-restful/v3/README.md
@@ -2,7 +2,6 @@ go-restful
==========
package for building REST-style Web Services using Google Go
-[![Build Status](https://travis-ci.org/emicklei/go-restful.png)](https://travis-ci.org/emicklei/go-restful)
[![Go Report Card](https://goreportcard.com/badge/github.com/emicklei/go-restful)](https://goreportcard.com/report/github.com/emicklei/go-restful)
[![GoDoc](https://godoc.org/github.com/emicklei/go-restful?status.svg)](https://pkg.go.dev/github.com/emicklei/go-restful)
[![codecov](https://codecov.io/gh/emicklei/go-restful/branch/master/graph/badge.svg)](https://codecov.io/gh/emicklei/go-restful)
@@ -95,8 +94,7 @@ There are several hooks to customize the behavior of the go-restful package.
- Trace logging
- Compression
- Encoders for other serializers
-- Use [jsoniter](https://github.com/json-iterator/go) by building this package using a build tag, e.g. `go build -tags=jsoniter .`
-- Use the package variable `TrimRightSlashEnabled` (default true) to control the behavior of matching routes that end with a slash `/`
+- Use the package variable `TrimRightSlashEnabled` (default true) to control the behavior of matching routes that end with a slash `/`
## Resources
diff --git a/vendor/github.com/emicklei/go-restful/v3/compress.go b/vendor/github.com/emicklei/go-restful/v3/compress.go
index 1ff239f99f..80adf55fdf 100644
--- a/vendor/github.com/emicklei/go-restful/v3/compress.go
+++ b/vendor/github.com/emicklei/go-restful/v3/compress.go
@@ -49,6 +49,16 @@ func (c *CompressingResponseWriter) CloseNotify() <-chan bool {
return c.writer.(http.CloseNotifier).CloseNotify()
}
+// Flush is part of http.Flusher interface. Noop if the underlying writer doesn't support it.
+func (c *CompressingResponseWriter) Flush() {
+ flusher, ok := c.writer.(http.Flusher)
+ if !ok {
+ // writer doesn't support http.Flusher interface
+ return
+ }
+ flusher.Flush()
+}
+
// Close the underlying compressor
func (c *CompressingResponseWriter) Close() error {
if c.isCompressorClosed() {
diff --git a/vendor/github.com/emicklei/go-restful/v3/curly.go b/vendor/github.com/emicklei/go-restful/v3/curly.go
index ba1fc5d5f1..6fd2bcd5a1 100644
--- a/vendor/github.com/emicklei/go-restful/v3/curly.go
+++ b/vendor/github.com/emicklei/go-restful/v3/curly.go
@@ -46,10 +46,10 @@ func (c CurlyRouter) SelectRoute(
// selectRoutes return a collection of Route from a WebService that matches the path tokens from the request.
func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortableCurlyRoutes {
candidates := make(sortableCurlyRoutes, 0, 8)
- for _, each := range ws.routes {
- matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens, each.hasCustomVerb)
+ for _, eachRoute := range ws.routes {
+ matches, paramCount, staticCount := c.matchesRouteByPathTokens(eachRoute.pathParts, requestTokens, eachRoute.hasCustomVerb)
if matches {
- candidates.add(curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers?
+ candidates.add(curlyRoute{eachRoute, paramCount, staticCount}) // TODO make sure Routes() return pointers?
}
}
sort.Sort(candidates)
@@ -72,7 +72,7 @@ func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []strin
return false, 0, 0
}
requestToken := requestTokens[i]
- if routeHasCustomVerb && hasCustomVerb(routeToken){
+ if routeHasCustomVerb && hasCustomVerb(routeToken) {
if !isMatchCustomVerb(routeToken, requestToken) {
return false, 0, 0
}
@@ -129,44 +129,52 @@ func (c CurlyRouter) detectRoute(candidateRoutes sortableCurlyRoutes, httpReques
// detectWebService returns the best matching webService given the list of path tokens.
// see also computeWebserviceScore
func (c CurlyRouter) detectWebService(requestTokens []string, webServices []*WebService) *WebService {
- var best *WebService
+ var bestWs *WebService
score := -1
- for _, each := range webServices {
- matches, eachScore := c.computeWebserviceScore(requestTokens, each.pathExpr.tokens)
+ for _, eachWS := range webServices {
+ matches, eachScore := c.computeWebserviceScore(requestTokens, eachWS.pathExpr.tokens)
if matches && (eachScore > score) {
- best = each
+ bestWs = eachWS
score = eachScore
}
}
- return best
+ return bestWs
}
// computeWebserviceScore returns whether tokens match and
// the weighted score of the longest matching consecutive tokens from the beginning.
-func (c CurlyRouter) computeWebserviceScore(requestTokens []string, tokens []string) (bool, int) {
- if len(tokens) > len(requestTokens) {
+func (c CurlyRouter) computeWebserviceScore(requestTokens []string, routeTokens []string) (bool, int) {
+ if len(routeTokens) > len(requestTokens) {
return false, 0
}
score := 0
- for i := 0; i < len(tokens); i++ {
- each := requestTokens[i]
- other := tokens[i]
- if len(each) == 0 && len(other) == 0 {
+ for i := 0; i < len(routeTokens); i++ {
+ eachRequestToken := requestTokens[i]
+ eachRouteToken := routeTokens[i]
+ if len(eachRequestToken) == 0 && len(eachRouteToken) == 0 {
score++
continue
}
- if len(other) > 0 && strings.HasPrefix(other, "{") {
+ if len(eachRouteToken) > 0 && strings.HasPrefix(eachRouteToken, "{") {
// no empty match
- if len(each) == 0 {
+ if len(eachRequestToken) == 0 {
return false, score
}
- score += 1
+ score++
+
+ if colon := strings.Index(eachRouteToken, ":"); colon != -1 {
+ // match by regex
+ matchesToken, _ := c.regularMatchesPathToken(eachRouteToken, colon, eachRequestToken)
+ if matchesToken {
+ score++ // extra score for regex match
+ }
+ }
} else {
// not a parameter
- if each != other {
+ if eachRequestToken != eachRouteToken {
return false, score
}
- score += (len(tokens) - i) * 10 //fuzzy
+ score += (len(routeTokens) - i) * 10 //fuzzy
}
}
return true, score
diff --git a/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go b/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go
index 66dfc824f5..9808752acd 100644
--- a/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go
+++ b/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go
@@ -5,11 +5,18 @@ package restful
// that can be found in the LICENSE file.
import (
+ "encoding/json"
"encoding/xml"
"strings"
"sync"
)
+var (
+ MarshalIndent = json.MarshalIndent
+ NewDecoder = json.NewDecoder
+ NewEncoder = json.NewEncoder
+)
+
// EntityReaderWriter can read and write values using an encoding such as JSON,XML.
type EntityReaderWriter interface {
// Read a serialized version of the value from the request.
diff --git a/vendor/github.com/emicklei/go-restful/v3/json.go b/vendor/github.com/emicklei/go-restful/v3/json.go
deleted file mode 100644
index 871165166a..0000000000
--- a/vendor/github.com/emicklei/go-restful/v3/json.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build !jsoniter
-
-package restful
-
-import "encoding/json"
-
-var (
- MarshalIndent = json.MarshalIndent
- NewDecoder = json.NewDecoder
- NewEncoder = json.NewEncoder
-)
diff --git a/vendor/github.com/emicklei/go-restful/v3/jsoniter.go b/vendor/github.com/emicklei/go-restful/v3/jsoniter.go
deleted file mode 100644
index 11b8f8ae7f..0000000000
--- a/vendor/github.com/emicklei/go-restful/v3/jsoniter.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// +build jsoniter
-
-package restful
-
-import "github.com/json-iterator/go"
-
-var (
- json = jsoniter.ConfigCompatibleWithStandardLibrary
- MarshalIndent = json.MarshalIndent
- NewDecoder = json.NewDecoder
- NewEncoder = json.NewEncoder
-)
diff --git a/vendor/github.com/emicklei/go-restful/v3/jsr311.go b/vendor/github.com/emicklei/go-restful/v3/jsr311.go
index 07a0c91e94..a9b3faaa81 100644
--- a/vendor/github.com/emicklei/go-restful/v3/jsr311.go
+++ b/vendor/github.com/emicklei/go-restful/v3/jsr311.go
@@ -155,7 +155,7 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R
method, length := httpRequest.Method, httpRequest.Header.Get("Content-Length")
if (method == http.MethodPost ||
method == http.MethodPut ||
- method == http.MethodPatch) && length == "" {
+ method == http.MethodPatch) && (length == "" || length == "0") {
return nil, NewError(
http.StatusUnsupportedMediaType,
fmt.Sprintf("415: Unsupported Media Type\n\nAvailable representations: %s", strings.Join(available, ", ")),
diff --git a/vendor/github.com/evanphx/json-patch/README.md b/vendor/github.com/evanphx/json-patch/README.md
index 28e3516937..97e319b21b 100644
--- a/vendor/github.com/evanphx/json-patch/README.md
+++ b/vendor/github.com/evanphx/json-patch/README.md
@@ -4,7 +4,7 @@
well as for calculating & applying [RFC7396 JSON merge patches](https://tools.ietf.org/html/rfc7396).
[![GoDoc](https://godoc.org/github.com/evanphx/json-patch?status.svg)](http://godoc.org/github.com/evanphx/json-patch)
-[![Build Status](https://travis-ci.org/evanphx/json-patch.svg?branch=master)](https://travis-ci.org/evanphx/json-patch)
+[![Build Status](https://github.com/evanphx/json-patch/actions/workflows/go.yml/badge.svg)](https://github.com/evanphx/json-patch/actions/workflows/go.yml)
[![Report Card](https://goreportcard.com/badge/github.com/evanphx/json-patch)](https://goreportcard.com/report/github.com/evanphx/json-patch)
# Get It!
@@ -314,4 +314,4 @@ go test -cover ./...
```
Builds for pull requests are tested automatically
-using [TravisCI](https://travis-ci.org/evanphx/json-patch).
+using [GitHub Actions](https://github.com/evanphx/json-patch/actions/workflows/go.yml).
diff --git a/vendor/github.com/evanphx/json-patch/patch.go b/vendor/github.com/evanphx/json-patch/patch.go
index 4bce5936d5..cd0274e1e4 100644
--- a/vendor/github.com/evanphx/json-patch/patch.go
+++ b/vendor/github.com/evanphx/json-patch/patch.go
@@ -359,7 +359,7 @@ func findObject(pd *container, path string) (container, string) {
next, ok := doc.get(decodePatchKey(part))
- if next == nil || ok != nil {
+ if next == nil || ok != nil || next.raw == nil {
return nil, ""
}
@@ -568,6 +568,29 @@ func (p Patch) replace(doc *container, op Operation) error {
return errors.Wrapf(err, "replace operation failed to decode path")
}
+ if path == "" {
+ val := op.value()
+
+ if val.which == eRaw {
+ if !val.tryDoc() {
+ if !val.tryAry() {
+ return errors.Wrapf(err, "replace operation value must be object or array")
+ }
+ }
+ }
+
+ switch val.which {
+ case eAry:
+ *doc = &val.ary
+ case eDoc:
+ *doc = &val.doc
+ case eRaw:
+ return errors.Wrapf(err, "replace operation hit impossible case")
+ }
+
+ return nil
+ }
+
con, key := findObject(doc, path)
if con == nil {
@@ -634,6 +657,25 @@ func (p Patch) test(doc *container, op Operation) error {
return errors.Wrapf(err, "test operation failed to decode path")
}
+ if path == "" {
+ var self lazyNode
+
+ switch sv := (*doc).(type) {
+ case *partialDoc:
+ self.doc = *sv
+ self.which = eDoc
+ case *partialArray:
+ self.ary = *sv
+ self.which = eAry
+ }
+
+ if self.equal(op.value()) {
+ return nil
+ }
+
+ return errors.Wrapf(ErrTestFailed, "testing value %s failed", path)
+ }
+
con, key := findObject(doc, path)
if con == nil {
@@ -646,7 +688,7 @@ func (p Patch) test(doc *container, op Operation) error {
}
if val == nil {
- if op.value().raw == nil {
+ if op.value() == nil || op.value().raw == nil {
return nil
}
return errors.Wrapf(ErrTestFailed, "testing value %s failed", path)
diff --git a/vendor/github.com/fsnotify/fsnotify/.cirrus.yml b/vendor/github.com/fsnotify/fsnotify/.cirrus.yml
index ffc7b992b3..f4e7dbf37b 100644
--- a/vendor/github.com/fsnotify/fsnotify/.cirrus.yml
+++ b/vendor/github.com/fsnotify/fsnotify/.cirrus.yml
@@ -1,7 +1,7 @@
freebsd_task:
name: 'FreeBSD'
freebsd_instance:
- image_family: freebsd-13-2
+ image_family: freebsd-14-1
install_script:
- pkg update -f
- pkg install -y go
@@ -9,5 +9,6 @@ freebsd_task:
# run tests as user "cirrus" instead of root
- pw useradd cirrus -m
- chown -R cirrus:cirrus .
- - FSNOTIFY_BUFFER=4096 sudo --preserve-env=FSNOTIFY_BUFFER -u cirrus go test -parallel 1 -race ./...
- - sudo --preserve-env=FSNOTIFY_BUFFER -u cirrus go test -parallel 1 -race ./...
+ - FSNOTIFY_BUFFER=4096 sudo --preserve-env=FSNOTIFY_BUFFER -u cirrus go test -parallel 1 -race ./...
+ - sudo --preserve-env=FSNOTIFY_BUFFER -u cirrus go test -parallel 1 -race ./...
+ - FSNOTIFY_DEBUG=1 sudo --preserve-env=FSNOTIFY_BUFFER -u cirrus go test -parallel 1 -race -v ./...
diff --git a/vendor/github.com/fsnotify/fsnotify/.editorconfig b/vendor/github.com/fsnotify/fsnotify/.editorconfig
deleted file mode 100644
index fad895851e..0000000000
--- a/vendor/github.com/fsnotify/fsnotify/.editorconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-root = true
-
-[*.go]
-indent_style = tab
-indent_size = 4
-insert_final_newline = true
-
-[*.{yml,yaml}]
-indent_style = space
-indent_size = 2
-insert_final_newline = true
-trim_trailing_whitespace = true
diff --git a/vendor/github.com/fsnotify/fsnotify/.gitattributes b/vendor/github.com/fsnotify/fsnotify/.gitattributes
deleted file mode 100644
index 32f1001be0..0000000000
--- a/vendor/github.com/fsnotify/fsnotify/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-go.sum linguist-generated
diff --git a/vendor/github.com/fsnotify/fsnotify/.gitignore b/vendor/github.com/fsnotify/fsnotify/.gitignore
index 391cc076b1..daea9dd6d6 100644
--- a/vendor/github.com/fsnotify/fsnotify/.gitignore
+++ b/vendor/github.com/fsnotify/fsnotify/.gitignore
@@ -5,3 +5,6 @@
# Output of go build ./cmd/fsnotify
/fsnotify
/fsnotify.exe
+
+/test/kqueue
+/test/a.out
diff --git a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md
index e0e5757549..fa854785d0 100644
--- a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md
+++ b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md
@@ -1,8 +1,36 @@
# Changelog
-Unreleased
-----------
-Nothing yet.
+1.8.0 2023-10-31
+----------------
+
+### Additions
+
+- all: add `FSNOTIFY_DEBUG` to print debug logs to stderr ([#619])
+
+### Changes and fixes
+
+- windows: fix behaviour of `WatchList()` to be consistent with other platforms ([#610])
+
+- kqueue: ignore events with Ident=0 ([#590])
+
+- kqueue: set O_CLOEXEC to prevent passing file descriptors to children ([#617])
+
+- kqueue: emit events as "/path/dir/file" instead of "path/link/file" when watching a symlink ([#625])
+
+- inotify: don't send event for IN_DELETE_SELF when also watching the parent ([#620])
+
+- inotify: fix panic when calling Remove() in a goroutine ([#650])
+
+- fen: allow watching subdirectories of watched directories ([#621])
+
+[#590]: https://github.com/fsnotify/fsnotify/pull/590
+[#610]: https://github.com/fsnotify/fsnotify/pull/610
+[#617]: https://github.com/fsnotify/fsnotify/pull/617
+[#619]: https://github.com/fsnotify/fsnotify/pull/619
+[#620]: https://github.com/fsnotify/fsnotify/pull/620
+[#621]: https://github.com/fsnotify/fsnotify/pull/621
+[#625]: https://github.com/fsnotify/fsnotify/pull/625
+[#650]: https://github.com/fsnotify/fsnotify/pull/650
1.7.0 - 2023-10-22
------------------
diff --git a/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md b/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md
index ea379759d5..e4ac2a2fff 100644
--- a/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md
+++ b/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md
@@ -1,7 +1,7 @@
Thank you for your interest in contributing to fsnotify! We try to review and
merge PRs in a reasonable timeframe, but please be aware that:
-- To avoid "wasted" work, please discus changes on the issue tracker first. You
+- To avoid "wasted" work, please discuss changes on the issue tracker first. You
can just send PRs, but they may end up being rejected for one reason or the
other.
@@ -20,6 +20,124 @@ platforms. Testing different platforms locally can be done with something like
Use the `-short` flag to make the "stress test" run faster.
+Writing new tests
+-----------------
+Scripts in the testdata directory allow creating test cases in a "shell-like"
+syntax. The basic format is:
+
+ script
+
+ Output:
+ desired output
+
+For example:
+
+ # Create a new empty file with some data.
+ watch /
+ echo data >/file
+
+ Output:
+ create /file
+ write /file
+
+Just create a new file to add a new test; select which tests to run with
+`-run TestScript/[path]`.
+
+script
+------
+The script is a "shell-like" script:
+
+ cmd arg arg
+
+Comments are supported with `#`:
+
+ # Comment
+ cmd arg arg # Comment
+
+All operations are done in a temp directory; a path like "/foo" is rewritten to
+"/tmp/TestFoo/foo".
+
+Arguments can be quoted with `"` or `'`; there are no escapes and they're
+functionally identical right now, but this may change in the future, so best to
+assume shell-like rules.
+
+ touch "/file with spaces"
+
+End-of-line escapes with `\` are not supported.
+
+### Supported commands
+
+ watch path [ops] # Watch the path, reporting events for it. Nothing is
+ # watched by default. Optionally a list of ops can be
+ # given, as with AddWith(path, WithOps(...)).
+ unwatch path # Stop watching the path.
+ watchlist n # Assert watchlist length.
+
+ stop # Stop running the script; for debugging.
+ debug [yes/no] # Enable/disable FSNOTIFY_DEBUG (tests are run in
+ parallel by default, so -parallel=1 is probably a good
+ idea).
+
+ touch path
+ mkdir [-p] dir
+ ln -s target link # Only ln -s supported.
+ mkfifo path
+ mknod dev path
+ mv src dst
+ rm [-r] path
+ chmod mode path # Octal only
+ sleep time-in-ms
+
+ cat path # Read path (does nothing with the data; just reads it).
+ echo str >>path # Append "str" to "path".
+ echo str >path # Truncate "path" and write "str".
+
+ require reason # Skip the test if "reason" is true; "skip" and
+ skip reason # "require" behave identical; it supports both for
+ # readability. Possible reasons are:
+ #
+ # always Always skip this test.
+ # symlink Symlinks are supported (requires admin
+ # permissions on Windows).
+ # mkfifo Platform doesn't support FIFO named sockets.
+ # mknod Platform doesn't support device nodes.
+
+
+output
+------
+After `Output:` the desired output is given; this is indented by convention, but
+that's not required.
+
+The format of that is:
+
+ # Comment
+ event path # Comment
+
+ system:
+ event path
+ system2:
+ event path
+
+Every event is one line, and any whitespace between the event and path are
+ignored. The path can optionally be surrounded in ". Anything after a "#" is
+ignored.
+
+Platform-specific tests can be added after GOOS; for example:
+
+ watch /
+ touch /file
+
+ Output:
+ # Tested if nothing else matches
+ create /file
+
+ # Windows-specific test.
+ windows:
+ write /file
+
+You can specify multiple platforms with a comma (e.g. "windows, linux:").
+"kqueue" is a shortcut for all kqueue systems (BSD, macOS).
+
[goon]: https://github.com/arp242/goon
[Vagrant]: https://www.vagrantup.com/
diff --git a/vendor/github.com/fsnotify/fsnotify/backend_fen.go b/vendor/github.com/fsnotify/fsnotify/backend_fen.go
index 28497f1dd8..c349c326c7 100644
--- a/vendor/github.com/fsnotify/fsnotify/backend_fen.go
+++ b/vendor/github.com/fsnotify/fsnotify/backend_fen.go
@@ -1,8 +1,8 @@
//go:build solaris
-// +build solaris
-// Note: the documentation on the Watcher type and methods is generated from
-// mkdoc.zsh
+// FEN backend for illumos (supported) and Solaris (untested, but should work).
+//
+// See port_create(3c) etc. for docs. https://www.illumos.org/man/3C/port_create
package fsnotify
@@ -12,150 +12,33 @@ import (
"os"
"path/filepath"
"sync"
+ "time"
+ "github.com/fsnotify/fsnotify/internal"
"golang.org/x/sys/unix"
)
-// Watcher watches a set of paths, delivering events on a channel.
-//
-// A watcher should not be copied (e.g. pass it by pointer, rather than by
-// value).
-//
-// # Linux notes
-//
-// When a file is removed a Remove event won't be emitted until all file
-// descriptors are closed, and deletes will always emit a Chmod. For example:
-//
-// fp := os.Open("file")
-// os.Remove("file") // Triggers Chmod
-// fp.Close() // Triggers Remove
-//
-// This is the event that inotify sends, so not much can be changed about this.
-//
-// The fs.inotify.max_user_watches sysctl variable specifies the upper limit
-// for the number of watches per user, and fs.inotify.max_user_instances
-// specifies the maximum number of inotify instances per user. Every Watcher you
-// create is an "instance", and every path you add is a "watch".
-//
-// These are also exposed in /proc as /proc/sys/fs/inotify/max_user_watches and
-// /proc/sys/fs/inotify/max_user_instances
-//
-// To increase them you can use sysctl or write the value to the /proc file:
-//
-// # Default values on Linux 5.18
-// sysctl fs.inotify.max_user_watches=124983
-// sysctl fs.inotify.max_user_instances=128
-//
-// To make the changes persist on reboot edit /etc/sysctl.conf or
-// /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check
-// your distro's documentation):
-//
-// fs.inotify.max_user_watches=124983
-// fs.inotify.max_user_instances=128
-//
-// Reaching the limit will result in a "no space left on device" or "too many open
-// files" error.
-//
-// # kqueue notes (macOS, BSD)
-//
-// kqueue requires opening a file descriptor for every file that's being watched;
-// so if you're watching a directory with five files then that's six file
-// descriptors. You will run in to your system's "max open files" limit faster on
-// these platforms.
-//
-// The sysctl variables kern.maxfiles and kern.maxfilesperproc can be used to
-// control the maximum number of open files, as well as /etc/login.conf on BSD
-// systems.
-//
-// # Windows notes
-//
-// Paths can be added as "C:\path\to\dir", but forward slashes
-// ("C:/path/to/dir") will also work.
-//
-// When a watched directory is removed it will always send an event for the
-// directory itself, but may not send events for all files in that directory.
-// Sometimes it will send events for all times, sometimes it will send no
-// events, and often only for some files.
-//
-// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest
-// value that is guaranteed to work with SMB filesystems. If you have many
-// events in quick succession this may not be enough, and you will have to use
-// [WithBufferSize] to increase the value.
-type Watcher struct {
- // Events sends the filesystem change events.
- //
- // fsnotify can send the following events; a "path" here can refer to a
- // file, directory, symbolic link, or special file like a FIFO.
- //
- // fsnotify.Create A new path was created; this may be followed by one
- // or more Write events if data also gets written to a
- // file.
- //
- // fsnotify.Remove A path was removed.
- //
- // fsnotify.Rename A path was renamed. A rename is always sent with the
- // old path as Event.Name, and a Create event will be
- // sent with the new name. Renames are only sent for
- // paths that are currently watched; e.g. moving an
- // unmonitored file into a monitored directory will
- // show up as just a Create. Similarly, renaming a file
- // to outside a monitored directory will show up as
- // only a Rename.
- //
- // fsnotify.Write A file or named pipe was written to. A Truncate will
- // also trigger a Write. A single "write action"
- // initiated by the user may show up as one or multiple
- // writes, depending on when the system syncs things to
- // disk. For example when compiling a large Go program
- // you may get hundreds of Write events, and you may
- // want to wait until you've stopped receiving them
- // (see the dedup example in cmd/fsnotify).
- //
- // Some systems may send Write event for directories
- // when the directory content changes.
- //
- // fsnotify.Chmod Attributes were changed. On Linux this is also sent
- // when a file is removed (or more accurately, when a
- // link to an inode is removed). On kqueue it's sent
- // when a file is truncated. On Windows it's never
- // sent.
+type fen struct {
Events chan Event
-
- // Errors sends any errors.
- //
- // ErrEventOverflow is used to indicate there are too many events:
- //
- // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl)
- // - windows: The buffer size is too small; WithBufferSize() can be used to increase it.
- // - kqueue, fen: Not used.
Errors chan error
mu sync.Mutex
port *unix.EventPort
- done chan struct{} // Channel for sending a "quit message" to the reader goroutine
- dirs map[string]struct{} // Explicitly watched directories
- watches map[string]struct{} // Explicitly watched non-directories
+ done chan struct{} // Channel for sending a "quit message" to the reader goroutine
+ dirs map[string]Op // Explicitly watched directories
+ watches map[string]Op // Explicitly watched non-directories
}
-// NewWatcher creates a new Watcher.
-func NewWatcher() (*Watcher, error) {
- return NewBufferedWatcher(0)
+func newBackend(ev chan Event, errs chan error) (backend, error) {
+ return newBufferedBackend(0, ev, errs)
}
-// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events
-// channel.
-//
-// The main use case for this is situations with a very large number of events
-// where the kernel buffer size can't be increased (e.g. due to lack of
-// permissions). An unbuffered Watcher will perform better for almost all use
-// cases, and whenever possible you will be better off increasing the kernel
-// buffers instead of adding a large userspace buffer.
-func NewBufferedWatcher(sz uint) (*Watcher, error) {
- w := &Watcher{
- Events: make(chan Event, sz),
- Errors: make(chan error),
- dirs: make(map[string]struct{}),
- watches: make(map[string]struct{}),
+func newBufferedBackend(sz uint, ev chan Event, errs chan error) (backend, error) {
+ w := &fen{
+ Events: ev,
+ Errors: errs,
+ dirs: make(map[string]Op),
+ watches: make(map[string]Op),
done: make(chan struct{}),
}
@@ -171,27 +54,30 @@ func NewBufferedWatcher(sz uint) (*Watcher, error) {
// sendEvent attempts to send an event to the user, returning true if the event
// was put in the channel successfully and false if the watcher has been closed.
-func (w *Watcher) sendEvent(name string, op Op) (sent bool) {
+func (w *fen) sendEvent(name string, op Op) (sent bool) {
select {
- case w.Events <- Event{Name: name, Op: op}:
- return true
case <-w.done:
return false
+ case w.Events <- Event{Name: name, Op: op}:
+ return true
}
}
// sendError attempts to send an error to the user, returning true if the error
// was put in the channel successfully and false if the watcher has been closed.
-func (w *Watcher) sendError(err error) (sent bool) {
- select {
- case w.Errors <- err:
+func (w *fen) sendError(err error) (sent bool) {
+ if err == nil {
return true
+ }
+ select {
case <-w.done:
return false
+ case w.Errors <- err:
+ return true
}
}
-func (w *Watcher) isClosed() bool {
+func (w *fen) isClosed() bool {
select {
case <-w.done:
return true
@@ -200,8 +86,7 @@ func (w *Watcher) isClosed() bool {
}
}
-// Close removes all watches and closes the Events channel.
-func (w *Watcher) Close() error {
+func (w *fen) Close() error {
// Take the lock used by associateFile to prevent lingering events from
// being processed after the close
w.mu.Lock()
@@ -213,60 +98,21 @@ func (w *Watcher) Close() error {
return w.port.Close()
}
-// Add starts monitoring the path for changes.
-//
-// A path can only be watched once; watching it more than once is a no-op and will
-// not return an error. Paths that do not yet exist on the filesystem cannot be
-// watched.
-//
-// A watch will be automatically removed if the watched path is deleted or
-// renamed. The exception is the Windows backend, which doesn't remove the
-// watcher on renames.
-//
-// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
-// filesystems (/proc, /sys, etc.) generally don't work.
-//
-// Returns [ErrClosed] if [Watcher.Close] was called.
-//
-// See [Watcher.AddWith] for a version that allows adding options.
-//
-// # Watching directories
-//
-// All files in a directory are monitored, including new files that are created
-// after the watcher is started. Subdirectories are not watched (i.e. it's
-// non-recursive).
-//
-// # Watching files
-//
-// Watching individual files (rather than directories) is generally not
-// recommended as many programs (especially editors) update files atomically: it
-// will write to a temporary file which is then moved to to destination,
-// overwriting the original (or some variant thereof). The watcher on the
-// original file is now lost, as that no longer exists.
-//
-// The upshot of this is that a power failure or crash won't leave a
-// half-written file.
-//
-// Watch the parent directory and use Event.Name to filter out files you're not
-// interested in. There is an example of this in cmd/fsnotify/file.go.
-func (w *Watcher) Add(name string) error { return w.AddWith(name) }
+func (w *fen) Add(name string) error { return w.AddWith(name) }
-// AddWith is like [Watcher.Add], but allows adding options. When using Add()
-// the defaults described below are used.
-//
-// Possible options are:
-//
-// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
-// other platforms. The default is 64K (65536 bytes).
-func (w *Watcher) AddWith(name string, opts ...addOpt) error {
+func (w *fen) AddWith(name string, opts ...addOpt) error {
if w.isClosed() {
return ErrClosed
}
- if w.port.PathIsWatched(name) {
- return nil
+ if debug {
+ fmt.Fprintf(os.Stderr, "FSNOTIFY_DEBUG: %s AddWith(%q)\n",
+ time.Now().Format("15:04:05.000000000"), name)
}
- _ = getOptions(opts...)
+ with := getOptions(opts...)
+ if !w.xSupports(with.op) {
+ return fmt.Errorf("%w: %s", xErrUnsupported, with.op)
+ }
// Currently we resolve symlinks that were explicitly requested to be
// watched. Otherwise we would use LStat here.
@@ -283,7 +129,7 @@ func (w *Watcher) AddWith(name string, opts ...addOpt) error {
}
w.mu.Lock()
- w.dirs[name] = struct{}{}
+ w.dirs[name] = with.op
w.mu.Unlock()
return nil
}
@@ -294,26 +140,22 @@ func (w *Watcher) AddWith(name string, opts ...addOpt) error {
}
w.mu.Lock()
- w.watches[name] = struct{}{}
+ w.watches[name] = with.op
w.mu.Unlock()
return nil
}
-// Remove stops monitoring the path for changes.
-//
-// Directories are always removed non-recursively. For example, if you added
-// /tmp/dir and /tmp/dir/subdir then you will need to remove both.
-//
-// Removing a path that has not yet been added returns [ErrNonExistentWatch].
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) Remove(name string) error {
+func (w *fen) Remove(name string) error {
if w.isClosed() {
return nil
}
if !w.port.PathIsWatched(name) {
return fmt.Errorf("%w: %s", ErrNonExistentWatch, name)
}
+ if debug {
+ fmt.Fprintf(os.Stderr, "FSNOTIFY_DEBUG: %s Remove(%q)\n",
+ time.Now().Format("15:04:05.000000000"), name)
+ }
// The user has expressed an intent. Immediately remove this name from
// whichever watch list it might be in. If it's not in there the delete
@@ -346,7 +188,7 @@ func (w *Watcher) Remove(name string) error {
}
// readEvents contains the main loop that runs in a goroutine watching for events.
-func (w *Watcher) readEvents() {
+func (w *fen) readEvents() {
// If this function returns, the watcher has been closed and we can close
// these channels
defer func() {
@@ -382,17 +224,19 @@ func (w *Watcher) readEvents() {
continue
}
+ if debug {
+ internal.Debug(pevent.Path, pevent.Events)
+ }
+
err = w.handleEvent(&pevent)
- if err != nil {
- if !w.sendError(err) {
- return
- }
+ if !w.sendError(err) {
+ return
}
}
}
}
-func (w *Watcher) handleDirectory(path string, stat os.FileInfo, follow bool, handler func(string, os.FileInfo, bool) error) error {
+func (w *fen) handleDirectory(path string, stat os.FileInfo, follow bool, handler func(string, os.FileInfo, bool) error) error {
files, err := os.ReadDir(path)
if err != nil {
return err
@@ -418,7 +262,7 @@ func (w *Watcher) handleDirectory(path string, stat os.FileInfo, follow bool, ha
// bitmap matches more than one event type (e.g. the file was both modified and
// had the attributes changed between when the association was created and the
// when event was returned)
-func (w *Watcher) handleEvent(event *unix.PortEvent) error {
+func (w *fen) handleEvent(event *unix.PortEvent) error {
var (
events = event.Events
path = event.Path
@@ -510,15 +354,9 @@ func (w *Watcher) handleEvent(event *unix.PortEvent) error {
}
if events&unix.FILE_MODIFIED != 0 {
- if fmode.IsDir() {
- if watchedDir {
- if err := w.updateDirectory(path); err != nil {
- return err
- }
- } else {
- if !w.sendEvent(path, Write) {
- return nil
- }
+ if fmode.IsDir() && watchedDir {
+ if err := w.updateDirectory(path); err != nil {
+ return err
}
} else {
if !w.sendEvent(path, Write) {
@@ -543,7 +381,7 @@ func (w *Watcher) handleEvent(event *unix.PortEvent) error {
return nil
}
-func (w *Watcher) updateDirectory(path string) error {
+func (w *fen) updateDirectory(path string) error {
// The directory was modified, so we must find unwatched entities and watch
// them. If something was removed from the directory, nothing will happen,
// as everything else should still be watched.
@@ -563,10 +401,8 @@ func (w *Watcher) updateDirectory(path string) error {
return err
}
err = w.associateFile(path, finfo, false)
- if err != nil {
- if !w.sendError(err) {
- return nil
- }
+ if !w.sendError(err) {
+ return nil
}
if !w.sendEvent(path, Create) {
return nil
@@ -575,7 +411,7 @@ func (w *Watcher) updateDirectory(path string) error {
return nil
}
-func (w *Watcher) associateFile(path string, stat os.FileInfo, follow bool) error {
+func (w *fen) associateFile(path string, stat os.FileInfo, follow bool) error {
if w.isClosed() {
return ErrClosed
}
@@ -593,34 +429,34 @@ func (w *Watcher) associateFile(path string, stat os.FileInfo, follow bool) erro
// cleared up that discrepancy. The most likely cause is that the event
// has fired but we haven't processed it yet.
err := w.port.DissociatePath(path)
- if err != nil && err != unix.ENOENT {
+ if err != nil && !errors.Is(err, unix.ENOENT) {
return err
}
}
- // FILE_NOFOLLOW means we watch symlinks themselves rather than their
- // targets.
- events := unix.FILE_MODIFIED | unix.FILE_ATTRIB | unix.FILE_NOFOLLOW
- if follow {
- // We *DO* follow symlinks for explicitly watched entries.
- events = unix.FILE_MODIFIED | unix.FILE_ATTRIB
+
+ var events int
+ if !follow {
+ // Watch symlinks themselves rather than their targets unless this entry
+ // is explicitly watched.
+ events |= unix.FILE_NOFOLLOW
+ }
+ if true { // TODO: implement withOps()
+ events |= unix.FILE_MODIFIED
}
- return w.port.AssociatePath(path, stat,
- events,
- stat.Mode())
+ if true {
+ events |= unix.FILE_ATTRIB
+ }
+ return w.port.AssociatePath(path, stat, events, stat.Mode())
}
-func (w *Watcher) dissociateFile(path string, stat os.FileInfo, unused bool) error {
+func (w *fen) dissociateFile(path string, stat os.FileInfo, unused bool) error {
if !w.port.PathIsWatched(path) {
return nil
}
return w.port.DissociatePath(path)
}
-// WatchList returns all paths explicitly added with [Watcher.Add] (and are not
-// yet removed).
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) WatchList() []string {
+func (w *fen) WatchList() []string {
if w.isClosed() {
return nil
}
@@ -638,3 +474,11 @@ func (w *Watcher) WatchList() []string {
return entries
}
+
+func (w *fen) xSupports(op Op) bool {
+ if op.Has(xUnportableOpen) || op.Has(xUnportableRead) ||
+ op.Has(xUnportableCloseWrite) || op.Has(xUnportableCloseRead) {
+ return false
+ }
+ return true
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/backend_inotify.go b/vendor/github.com/fsnotify/fsnotify/backend_inotify.go
index 921c1c1e40..36c311694c 100644
--- a/vendor/github.com/fsnotify/fsnotify/backend_inotify.go
+++ b/vendor/github.com/fsnotify/fsnotify/backend_inotify.go
@@ -1,8 +1,4 @@
//go:build linux && !appengine
-// +build linux,!appengine
-
-// Note: the documentation on the Watcher type and methods is generated from
-// mkdoc.zsh
package fsnotify
@@ -10,127 +6,20 @@ import (
"errors"
"fmt"
"io"
+ "io/fs"
"os"
"path/filepath"
"strings"
"sync"
+ "time"
"unsafe"
+ "github.com/fsnotify/fsnotify/internal"
"golang.org/x/sys/unix"
)
-// Watcher watches a set of paths, delivering events on a channel.
-//
-// A watcher should not be copied (e.g. pass it by pointer, rather than by
-// value).
-//
-// # Linux notes
-//
-// When a file is removed a Remove event won't be emitted until all file
-// descriptors are closed, and deletes will always emit a Chmod. For example:
-//
-// fp := os.Open("file")
-// os.Remove("file") // Triggers Chmod
-// fp.Close() // Triggers Remove
-//
-// This is the event that inotify sends, so not much can be changed about this.
-//
-// The fs.inotify.max_user_watches sysctl variable specifies the upper limit
-// for the number of watches per user, and fs.inotify.max_user_instances
-// specifies the maximum number of inotify instances per user. Every Watcher you
-// create is an "instance", and every path you add is a "watch".
-//
-// These are also exposed in /proc as /proc/sys/fs/inotify/max_user_watches and
-// /proc/sys/fs/inotify/max_user_instances
-//
-// To increase them you can use sysctl or write the value to the /proc file:
-//
-// # Default values on Linux 5.18
-// sysctl fs.inotify.max_user_watches=124983
-// sysctl fs.inotify.max_user_instances=128
-//
-// To make the changes persist on reboot edit /etc/sysctl.conf or
-// /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check
-// your distro's documentation):
-//
-// fs.inotify.max_user_watches=124983
-// fs.inotify.max_user_instances=128
-//
-// Reaching the limit will result in a "no space left on device" or "too many open
-// files" error.
-//
-// # kqueue notes (macOS, BSD)
-//
-// kqueue requires opening a file descriptor for every file that's being watched;
-// so if you're watching a directory with five files then that's six file
-// descriptors. You will run in to your system's "max open files" limit faster on
-// these platforms.
-//
-// The sysctl variables kern.maxfiles and kern.maxfilesperproc can be used to
-// control the maximum number of open files, as well as /etc/login.conf on BSD
-// systems.
-//
-// # Windows notes
-//
-// Paths can be added as "C:\path\to\dir", but forward slashes
-// ("C:/path/to/dir") will also work.
-//
-// When a watched directory is removed it will always send an event for the
-// directory itself, but may not send events for all files in that directory.
-// Sometimes it will send events for all times, sometimes it will send no
-// events, and often only for some files.
-//
-// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest
-// value that is guaranteed to work with SMB filesystems. If you have many
-// events in quick succession this may not be enough, and you will have to use
-// [WithBufferSize] to increase the value.
-type Watcher struct {
- // Events sends the filesystem change events.
- //
- // fsnotify can send the following events; a "path" here can refer to a
- // file, directory, symbolic link, or special file like a FIFO.
- //
- // fsnotify.Create A new path was created; this may be followed by one
- // or more Write events if data also gets written to a
- // file.
- //
- // fsnotify.Remove A path was removed.
- //
- // fsnotify.Rename A path was renamed. A rename is always sent with the
- // old path as Event.Name, and a Create event will be
- // sent with the new name. Renames are only sent for
- // paths that are currently watched; e.g. moving an
- // unmonitored file into a monitored directory will
- // show up as just a Create. Similarly, renaming a file
- // to outside a monitored directory will show up as
- // only a Rename.
- //
- // fsnotify.Write A file or named pipe was written to. A Truncate will
- // also trigger a Write. A single "write action"
- // initiated by the user may show up as one or multiple
- // writes, depending on when the system syncs things to
- // disk. For example when compiling a large Go program
- // you may get hundreds of Write events, and you may
- // want to wait until you've stopped receiving them
- // (see the dedup example in cmd/fsnotify).
- //
- // Some systems may send Write event for directories
- // when the directory content changes.
- //
- // fsnotify.Chmod Attributes were changed. On Linux this is also sent
- // when a file is removed (or more accurately, when a
- // link to an inode is removed). On kqueue it's sent
- // when a file is truncated. On Windows it's never
- // sent.
+type inotify struct {
Events chan Event
-
- // Errors sends any errors.
- //
- // ErrEventOverflow is used to indicate there are too many events:
- //
- // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl)
- // - windows: The buffer size is too small; WithBufferSize() can be used to increase it.
- // - kqueue, fen: Not used.
Errors chan error
// Store fd here as os.File.Read() will no longer return on close after
@@ -139,8 +28,26 @@ type Watcher struct {
inotifyFile *os.File
watches *watches
done chan struct{} // Channel for sending a "quit message" to the reader goroutine
- closeMu sync.Mutex
+ doneMu sync.Mutex
doneResp chan struct{} // Channel to respond to Close
+
+ // Store rename cookies in an array, with the index wrapping to 0. Almost
+ // all of the time what we get is a MOVED_FROM to set the cookie and the
+ // next event inotify sends will be MOVED_TO to read it. However, this is
+ // not guaranteed – as described in inotify(7) – and we may get other events
+ // between the two MOVED_* events (including other MOVED_* ones).
+ //
+ // A second issue is that moving a file outside the watched directory will
+ // trigger a MOVED_FROM to set the cookie, but we never see the MOVED_TO to
+ // read and delete it. So just storing it in a map would slowly leak memory.
+ //
+ // Doing it like this gives us a simple fast LRU-cache that won't allocate.
+ // Ten items should be more than enough for our purpose, and a loop over
+ // such a short array is faster than a map access anyway (not that it hugely
+ // matters since we're talking about hundreds of ns at the most, but still).
+ cookies [10]koekje
+ cookieIndex uint8
+ cookiesMu sync.Mutex
}
type (
@@ -150,9 +57,14 @@ type (
path map[string]uint32 // pathname → wd
}
watch struct {
- wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall)
- flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags)
- path string // Watch path.
+ wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall)
+ flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags)
+ path string // Watch path.
+ recurse bool // Recursion with ./...?
+ }
+ koekje struct {
+ cookie uint32
+ path string
}
)
@@ -179,23 +91,45 @@ func (w *watches) add(ww *watch) {
func (w *watches) remove(wd uint32) {
w.mu.Lock()
defer w.mu.Unlock()
- delete(w.path, w.wd[wd].path)
+ watch := w.wd[wd] // Could have had Remove() called. See #616.
+ if watch == nil {
+ return
+ }
+ delete(w.path, watch.path)
delete(w.wd, wd)
}
-func (w *watches) removePath(path string) (uint32, bool) {
+func (w *watches) removePath(path string) ([]uint32, error) {
w.mu.Lock()
defer w.mu.Unlock()
+ path, recurse := recursivePath(path)
wd, ok := w.path[path]
if !ok {
- return 0, false
+ return nil, fmt.Errorf("%w: %s", ErrNonExistentWatch, path)
+ }
+
+ watch := w.wd[wd]
+ if recurse && !watch.recurse {
+ return nil, fmt.Errorf("can't use /... with non-recursive watch %q", path)
}
delete(w.path, path)
delete(w.wd, wd)
+ if !watch.recurse {
+ return []uint32{wd}, nil
+ }
- return wd, true
+ wds := make([]uint32, 0, 8)
+ wds = append(wds, wd)
+ for p, rwd := range w.path {
+ if filepath.HasPrefix(p, path) {
+ delete(w.path, p)
+ delete(w.wd, rwd)
+ wds = append(wds, rwd)
+ }
+ }
+ return wds, nil
}
func (w *watches) byPath(path string) *watch {
@@ -236,20 +170,11 @@ func (w *watches) updatePath(path string, f func(*watch) (*watch, error)) error
return nil
}
-// NewWatcher creates a new Watcher.
-func NewWatcher() (*Watcher, error) {
- return NewBufferedWatcher(0)
+func newBackend(ev chan Event, errs chan error) (backend, error) {
+ return newBufferedBackend(0, ev, errs)
}
-// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events
-// channel.
-//
-// The main use case for this is situations with a very large number of events
-// where the kernel buffer size can't be increased (e.g. due to lack of
-// permissions). An unbuffered Watcher will perform better for almost all use
-// cases, and whenever possible you will be better off increasing the kernel
-// buffers instead of adding a large userspace buffer.
-func NewBufferedWatcher(sz uint) (*Watcher, error) {
+func newBufferedBackend(sz uint, ev chan Event, errs chan error) (backend, error) {
// Need to set nonblocking mode for SetDeadline to work, otherwise blocking
// I/O operations won't terminate on close.
fd, errno := unix.InotifyInit1(unix.IN_CLOEXEC | unix.IN_NONBLOCK)
@@ -257,12 +182,12 @@ func NewBufferedWatcher(sz uint) (*Watcher, error) {
return nil, errno
}
- w := &Watcher{
+ w := &inotify{
+ Events: ev,
+ Errors: errs,
fd: fd,
inotifyFile: os.NewFile(uintptr(fd), ""),
watches: newWatches(),
- Events: make(chan Event, sz),
- Errors: make(chan error),
done: make(chan struct{}),
doneResp: make(chan struct{}),
}
@@ -272,26 +197,29 @@ func NewBufferedWatcher(sz uint) (*Watcher, error) {
}
// Returns true if the event was sent, or false if watcher is closed.
-func (w *Watcher) sendEvent(e Event) bool {
+func (w *inotify) sendEvent(e Event) bool {
select {
- case w.Events <- e:
- return true
case <-w.done:
return false
+ case w.Events <- e:
+ return true
}
}
// Returns true if the error was sent, or false if watcher is closed.
-func (w *Watcher) sendError(err error) bool {
- select {
- case w.Errors <- err:
+func (w *inotify) sendError(err error) bool {
+ if err == nil {
return true
+ }
+ select {
case <-w.done:
return false
+ case w.Errors <- err:
+ return true
}
}
-func (w *Watcher) isClosed() bool {
+func (w *inotify) isClosed() bool {
select {
case <-w.done:
return true
@@ -300,15 +228,14 @@ func (w *Watcher) isClosed() bool {
}
}
-// Close removes all watches and closes the Events channel.
-func (w *Watcher) Close() error {
- w.closeMu.Lock()
+func (w *inotify) Close() error {
+ w.doneMu.Lock()
if w.isClosed() {
- w.closeMu.Unlock()
+ w.doneMu.Unlock()
return nil
}
close(w.done)
- w.closeMu.Unlock()
+ w.doneMu.Unlock()
// Causes any blocking reads to return with an error, provided the file
// still supports deadline operations.
@@ -323,78 +250,104 @@ func (w *Watcher) Close() error {
return nil
}
-// Add starts monitoring the path for changes.
-//
-// A path can only be watched once; watching it more than once is a no-op and will
-// not return an error. Paths that do not yet exist on the filesystem cannot be
-// watched.
-//
-// A watch will be automatically removed if the watched path is deleted or
-// renamed. The exception is the Windows backend, which doesn't remove the
-// watcher on renames.
-//
-// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
-// filesystems (/proc, /sys, etc.) generally don't work.
-//
-// Returns [ErrClosed] if [Watcher.Close] was called.
-//
-// See [Watcher.AddWith] for a version that allows adding options.
-//
-// # Watching directories
-//
-// All files in a directory are monitored, including new files that are created
-// after the watcher is started. Subdirectories are not watched (i.e. it's
-// non-recursive).
-//
-// # Watching files
-//
-// Watching individual files (rather than directories) is generally not
-// recommended as many programs (especially editors) update files atomically: it
-// will write to a temporary file which is then moved to to destination,
-// overwriting the original (or some variant thereof). The watcher on the
-// original file is now lost, as that no longer exists.
-//
-// The upshot of this is that a power failure or crash won't leave a
-// half-written file.
-//
-// Watch the parent directory and use Event.Name to filter out files you're not
-// interested in. There is an example of this in cmd/fsnotify/file.go.
-func (w *Watcher) Add(name string) error { return w.AddWith(name) }
-
-// AddWith is like [Watcher.Add], but allows adding options. When using Add()
-// the defaults described below are used.
-//
-// Possible options are:
-//
-// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
-// other platforms. The default is 64K (65536 bytes).
-func (w *Watcher) AddWith(name string, opts ...addOpt) error {
+func (w *inotify) Add(name string) error { return w.AddWith(name) }
+
+func (w *inotify) AddWith(path string, opts ...addOpt) error {
if w.isClosed() {
return ErrClosed
}
+ if debug {
+ fmt.Fprintf(os.Stderr, "FSNOTIFY_DEBUG: %s AddWith(%q)\n",
+ time.Now().Format("15:04:05.000000000"), path)
+ }
+
+ with := getOptions(opts...)
+ if !w.xSupports(with.op) {
+ return fmt.Errorf("%w: %s", xErrUnsupported, with.op)
+ }
- name = filepath.Clean(name)
- _ = getOptions(opts...)
+ path, recurse := recursivePath(path)
+ if recurse {
+ return filepath.WalkDir(path, func(root string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+ if !d.IsDir() {
+ if root == path {
+ return fmt.Errorf("fsnotify: not a directory: %q", path)
+ }
+ return nil
+ }
- var flags uint32 = unix.IN_MOVED_TO | unix.IN_MOVED_FROM |
- unix.IN_CREATE | unix.IN_ATTRIB | unix.IN_MODIFY |
- unix.IN_MOVE_SELF | unix.IN_DELETE | unix.IN_DELETE_SELF
+ // Send a Create event when adding new directory from a recursive
+ // watch; this is for "mkdir -p one/two/three". Usually all those
+ // directories will be created before we can set up watchers on the
+ // subdirectories, so only "one" would be sent as a Create event and
+ // not "one/two" and "one/two/three" (inotifywait -r has the same
+ // problem).
+ if with.sendCreate && root != path {
+ w.sendEvent(Event{Name: root, Op: Create})
+ }
+
+ return w.add(root, with, true)
+ })
+ }
- return w.watches.updatePath(name, func(existing *watch) (*watch, error) {
+ return w.add(path, with, false)
+}
+
+func (w *inotify) add(path string, with withOpts, recurse bool) error {
+ var flags uint32
+ if with.noFollow {
+ flags |= unix.IN_DONT_FOLLOW
+ }
+ if with.op.Has(Create) {
+ flags |= unix.IN_CREATE
+ }
+ if with.op.Has(Write) {
+ flags |= unix.IN_MODIFY
+ }
+ if with.op.Has(Remove) {
+ flags |= unix.IN_DELETE | unix.IN_DELETE_SELF
+ }
+ if with.op.Has(Rename) {
+ flags |= unix.IN_MOVED_TO | unix.IN_MOVED_FROM | unix.IN_MOVE_SELF
+ }
+ if with.op.Has(Chmod) {
+ flags |= unix.IN_ATTRIB
+ }
+ if with.op.Has(xUnportableOpen) {
+ flags |= unix.IN_OPEN
+ }
+ if with.op.Has(xUnportableRead) {
+ flags |= unix.IN_ACCESS
+ }
+ if with.op.Has(xUnportableCloseWrite) {
+ flags |= unix.IN_CLOSE_WRITE
+ }
+ if with.op.Has(xUnportableCloseRead) {
+ flags |= unix.IN_CLOSE_NOWRITE
+ }
+ return w.register(path, flags, recurse)
+}
+
+func (w *inotify) register(path string, flags uint32, recurse bool) error {
+ return w.watches.updatePath(path, func(existing *watch) (*watch, error) {
if existing != nil {
flags |= existing.flags | unix.IN_MASK_ADD
}
- wd, err := unix.InotifyAddWatch(w.fd, name, flags)
+ wd, err := unix.InotifyAddWatch(w.fd, path, flags)
if wd == -1 {
return nil, err
}
if existing == nil {
return &watch{
- wd: uint32(wd),
- path: name,
- flags: flags,
+ wd: uint32(wd),
+ path: path,
+ flags: flags,
+ recurse: recurse,
}, nil
}
@@ -404,49 +357,44 @@ func (w *Watcher) AddWith(name string, opts ...addOpt) error {
})
}
-// Remove stops monitoring the path for changes.
-//
-// Directories are always removed non-recursively. For example, if you added
-// /tmp/dir and /tmp/dir/subdir then you will need to remove both.
-//
-// Removing a path that has not yet been added returns [ErrNonExistentWatch].
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) Remove(name string) error {
+func (w *inotify) Remove(name string) error {
if w.isClosed() {
return nil
}
+ if debug {
+ fmt.Fprintf(os.Stderr, "FSNOTIFY_DEBUG: %s Remove(%q)\n",
+ time.Now().Format("15:04:05.000000000"), name)
+ }
return w.remove(filepath.Clean(name))
}
-func (w *Watcher) remove(name string) error {
- wd, ok := w.watches.removePath(name)
- if !ok {
- return fmt.Errorf("%w: %s", ErrNonExistentWatch, name)
- }
-
- success, errno := unix.InotifyRmWatch(w.fd, wd)
- if success == -1 {
- // TODO: Perhaps it's not helpful to return an error here in every case;
- // The only two possible errors are:
- //
- // - EBADF, which happens when w.fd is not a valid file descriptor
- // of any kind.
- // - EINVAL, which is when fd is not an inotify descriptor or wd
- // is not a valid watch descriptor. Watch descriptors are
- // invalidated when they are removed explicitly or implicitly;
- // explicitly by inotify_rm_watch, implicitly when the file they
- // are watching is deleted.
- return errno
+func (w *inotify) remove(name string) error {
+ wds, err := w.watches.removePath(name)
+ if err != nil {
+ return err
+ }
+
+ for _, wd := range wds {
+ _, err := unix.InotifyRmWatch(w.fd, wd)
+ if err != nil {
+ // TODO: Perhaps it's not helpful to return an error here in every
+ // case; the only two possible errors are:
+ //
+ // EBADF, which happens when w.fd is not a valid file descriptor of
+ // any kind.
+ //
+ // EINVAL, which is when fd is not an inotify descriptor or wd is
+ // not a valid watch descriptor. Watch descriptors are invalidated
+ // when they are removed explicitly or implicitly; explicitly by
+ // inotify_rm_watch, implicitly when the file they are watching is
+ // deleted.
+ return err
+ }
}
return nil
}
-// WatchList returns all paths explicitly added with [Watcher.Add] (and are not
-// yet removed).
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) WatchList() []string {
+func (w *inotify) WatchList() []string {
if w.isClosed() {
return nil
}
@@ -463,7 +411,7 @@ func (w *Watcher) WatchList() []string {
// readEvents reads from the inotify file descriptor, converts the
// received events into Event objects and sends them via the Events channel
-func (w *Watcher) readEvents() {
+func (w *inotify) readEvents() {
defer func() {
close(w.doneResp)
close(w.Errors)
@@ -506,15 +454,17 @@ func (w *Watcher) readEvents() {
continue
}
- var offset uint32
// We don't know how many events we just read into the buffer
// While the offset points to at least one whole event...
+ var offset uint32
for offset <= uint32(n-unix.SizeofInotifyEvent) {
var (
// Point "raw" to the event in the buffer
raw = (*unix.InotifyEvent)(unsafe.Pointer(&buf[offset]))
mask = uint32(raw.Mask)
nameLen = uint32(raw.Len)
+ // Move to the next event in the buffer
+ next = func() { offset += unix.SizeofInotifyEvent + nameLen }
)
if mask&unix.IN_Q_OVERFLOW != 0 {
@@ -523,21 +473,53 @@ func (w *Watcher) readEvents() {
}
}
- // If the event happened to the watched directory or the watched file, the kernel
- // doesn't append the filename to the event, but we would like to always fill the
- // the "Name" field with a valid filename. We retrieve the path of the watch from
- // the "paths" map.
+ /// If the event happened to the watched directory or the watched
+ /// file, the kernel doesn't append the filename to the event, but
+ /// we would like to always fill the the "Name" field with a valid
+ /// filename. We retrieve the path of the watch from the "paths"
+ /// map.
watch := w.watches.byWd(uint32(raw.Wd))
+ /// Can be nil if Remove() was called in another goroutine for this
+ /// path inbetween reading the events from the kernel and reading
+ /// the internal state. Not much we can do about it, so just skip.
+ /// See #616.
+ if watch == nil {
+ next()
+ continue
+ }
+
+ name := watch.path
+ if nameLen > 0 {
+ /// Point "bytes" at the first byte of the filename
+ bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))[:nameLen:nameLen]
+ /// The filename is padded with NULL bytes. TrimRight() gets rid of those.
+ name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
+ }
+
+ if debug {
+ internal.Debug(name, raw.Mask, raw.Cookie)
+ }
+
+ if mask&unix.IN_IGNORED != 0 { //&& event.Op != 0
+ next()
+ continue
+ }
// inotify will automatically remove the watch on deletes; just need
// to clean our state here.
- if watch != nil && mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF {
+ if mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF {
w.watches.remove(watch.wd)
}
+
// We can't really update the state when a watched path is moved;
// only IN_MOVE_SELF is sent and not IN_MOVED_{FROM,TO}. So remove
// the watch.
- if watch != nil && mask&unix.IN_MOVE_SELF == unix.IN_MOVE_SELF {
+ if mask&unix.IN_MOVE_SELF == unix.IN_MOVE_SELF {
+ if watch.recurse {
+ next() // Do nothing
+ continue
+ }
+
err := w.remove(watch.path)
if err != nil && !errors.Is(err, ErrNonExistentWatch) {
if !w.sendError(err) {
@@ -546,34 +528,69 @@ func (w *Watcher) readEvents() {
}
}
- var name string
- if watch != nil {
- name = watch.path
- }
- if nameLen > 0 {
- // Point "bytes" at the first byte of the filename
- bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))[:nameLen:nameLen]
- // The filename is padded with NULL bytes. TrimRight() gets rid of those.
- name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
+ /// Skip if we're watching both this path and the parent; the parent
+ /// will already send a delete so no need to do it twice.
+ if mask&unix.IN_DELETE_SELF != 0 {
+ if _, ok := w.watches.path[filepath.Dir(watch.path)]; ok {
+ next()
+ continue
+ }
}
- event := w.newEvent(name, mask)
+ ev := w.newEvent(name, mask, raw.Cookie)
+ // Need to update watch path for recurse.
+ if watch.recurse {
+ isDir := mask&unix.IN_ISDIR == unix.IN_ISDIR
+ /// New directory created: set up watch on it.
+ if isDir && ev.Has(Create) {
+ err := w.register(ev.Name, watch.flags, true)
+ if !w.sendError(err) {
+ return
+ }
- // Send the events that are not ignored on the events channel
- if mask&unix.IN_IGNORED == 0 {
- if !w.sendEvent(event) {
- return
+ // This was a directory rename, so we need to update all
+ // the children.
+ //
+ // TODO: this is of course pretty slow; we should use a
+ // better data structure for storing all of this, e.g. store
+ // children in the watch. I have some code for this in my
+ // kqueue refactor we can use in the future. For now I'm
+ // okay with this as it's not publicly available.
+ // Correctness first, performance second.
+ if ev.renamedFrom != "" {
+ w.watches.mu.Lock()
+ for k, ww := range w.watches.wd {
+ if k == watch.wd || ww.path == ev.Name {
+ continue
+ }
+ if strings.HasPrefix(ww.path, ev.renamedFrom) {
+ ww.path = strings.Replace(ww.path, ev.renamedFrom, ev.Name, 1)
+ w.watches.wd[k] = ww
+ }
+ }
+ w.watches.mu.Unlock()
+ }
}
}
- // Move to the next event in the buffer
- offset += unix.SizeofInotifyEvent + nameLen
+ /// Send the events that are not ignored on the events channel
+ if !w.sendEvent(ev) {
+ return
+ }
+ next()
}
}
}
-// newEvent returns an platform-independent Event based on an inotify mask.
-func (w *Watcher) newEvent(name string, mask uint32) Event {
+func (w *inotify) isRecursive(path string) bool {
+ ww := w.watches.byPath(path)
+ if ww == nil { // path could be a file, so also check the Dir.
+ ww = w.watches.byPath(filepath.Dir(path))
+ }
+ return ww != nil && ww.recurse
+}
+
+func (w *inotify) newEvent(name string, mask, cookie uint32) Event {
e := Event{Name: name}
if mask&unix.IN_CREATE == unix.IN_CREATE || mask&unix.IN_MOVED_TO == unix.IN_MOVED_TO {
e.Op |= Create
@@ -584,11 +601,58 @@ func (w *Watcher) newEvent(name string, mask uint32) Event {
if mask&unix.IN_MODIFY == unix.IN_MODIFY {
e.Op |= Write
}
+ if mask&unix.IN_OPEN == unix.IN_OPEN {
+ e.Op |= xUnportableOpen
+ }
+ if mask&unix.IN_ACCESS == unix.IN_ACCESS {
+ e.Op |= xUnportableRead
+ }
+ if mask&unix.IN_CLOSE_WRITE == unix.IN_CLOSE_WRITE {
+ e.Op |= xUnportableCloseWrite
+ }
+ if mask&unix.IN_CLOSE_NOWRITE == unix.IN_CLOSE_NOWRITE {
+ e.Op |= xUnportableCloseRead
+ }
if mask&unix.IN_MOVE_SELF == unix.IN_MOVE_SELF || mask&unix.IN_MOVED_FROM == unix.IN_MOVED_FROM {
e.Op |= Rename
}
if mask&unix.IN_ATTRIB == unix.IN_ATTRIB {
e.Op |= Chmod
}
+
+ if cookie != 0 {
+ if mask&unix.IN_MOVED_FROM == unix.IN_MOVED_FROM {
+ w.cookiesMu.Lock()
+ w.cookies[w.cookieIndex] = koekje{cookie: cookie, path: e.Name}
+ w.cookieIndex++
+ if w.cookieIndex > 9 {
+ w.cookieIndex = 0
+ }
+ w.cookiesMu.Unlock()
+ } else if mask&unix.IN_MOVED_TO == unix.IN_MOVED_TO {
+ w.cookiesMu.Lock()
+ var prev string
+ for _, c := range w.cookies {
+ if c.cookie == cookie {
+ prev = c.path
+ break
+ }
+ }
+ w.cookiesMu.Unlock()
+ e.renamedFrom = prev
+ }
+ }
return e
}
+
+func (w *inotify) xSupports(op Op) bool {
+ return true // Supports everything.
+}
+
+func (w *inotify) state() {
+ w.watches.mu.Lock()
+ defer w.watches.mu.Unlock()
+ for wd, ww := range w.watches.wd {
+ fmt.Fprintf(os.Stderr, "%4d: recurse=%t %q\n", wd, ww.recurse, ww.path)
+ }
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go b/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go
index 063a0915a0..d8de5ab76f 100644
--- a/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go
+++ b/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go
@@ -1,8 +1,4 @@
//go:build freebsd || openbsd || netbsd || dragonfly || darwin
-// +build freebsd openbsd netbsd dragonfly darwin
-
-// Note: the documentation on the Watcher type and methods is generated from
-// mkdoc.zsh
package fsnotify
@@ -11,174 +7,195 @@ import (
"fmt"
"os"
"path/filepath"
+ "runtime"
"sync"
+ "time"
+ "github.com/fsnotify/fsnotify/internal"
"golang.org/x/sys/unix"
)
-// Watcher watches a set of paths, delivering events on a channel.
-//
-// A watcher should not be copied (e.g. pass it by pointer, rather than by
-// value).
-//
-// # Linux notes
-//
-// When a file is removed a Remove event won't be emitted until all file
-// descriptors are closed, and deletes will always emit a Chmod. For example:
-//
-// fp := os.Open("file")
-// os.Remove("file") // Triggers Chmod
-// fp.Close() // Triggers Remove
-//
-// This is the event that inotify sends, so not much can be changed about this.
-//
-// The fs.inotify.max_user_watches sysctl variable specifies the upper limit
-// for the number of watches per user, and fs.inotify.max_user_instances
-// specifies the maximum number of inotify instances per user. Every Watcher you
-// create is an "instance", and every path you add is a "watch".
-//
-// These are also exposed in /proc as /proc/sys/fs/inotify/max_user_watches and
-// /proc/sys/fs/inotify/max_user_instances
-//
-// To increase them you can use sysctl or write the value to the /proc file:
-//
-// # Default values on Linux 5.18
-// sysctl fs.inotify.max_user_watches=124983
-// sysctl fs.inotify.max_user_instances=128
-//
-// To make the changes persist on reboot edit /etc/sysctl.conf or
-// /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check
-// your distro's documentation):
-//
-// fs.inotify.max_user_watches=124983
-// fs.inotify.max_user_instances=128
-//
-// Reaching the limit will result in a "no space left on device" or "too many open
-// files" error.
-//
-// # kqueue notes (macOS, BSD)
-//
-// kqueue requires opening a file descriptor for every file that's being watched;
-// so if you're watching a directory with five files then that's six file
-// descriptors. You will run in to your system's "max open files" limit faster on
-// these platforms.
-//
-// The sysctl variables kern.maxfiles and kern.maxfilesperproc can be used to
-// control the maximum number of open files, as well as /etc/login.conf on BSD
-// systems.
-//
-// # Windows notes
-//
-// Paths can be added as "C:\path\to\dir", but forward slashes
-// ("C:/path/to/dir") will also work.
-//
-// When a watched directory is removed it will always send an event for the
-// directory itself, but may not send events for all files in that directory.
-// Sometimes it will send events for all times, sometimes it will send no
-// events, and often only for some files.
-//
-// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest
-// value that is guaranteed to work with SMB filesystems. If you have many
-// events in quick succession this may not be enough, and you will have to use
-// [WithBufferSize] to increase the value.
-type Watcher struct {
- // Events sends the filesystem change events.
- //
- // fsnotify can send the following events; a "path" here can refer to a
- // file, directory, symbolic link, or special file like a FIFO.
- //
- // fsnotify.Create A new path was created; this may be followed by one
- // or more Write events if data also gets written to a
- // file.
- //
- // fsnotify.Remove A path was removed.
- //
- // fsnotify.Rename A path was renamed. A rename is always sent with the
- // old path as Event.Name, and a Create event will be
- // sent with the new name. Renames are only sent for
- // paths that are currently watched; e.g. moving an
- // unmonitored file into a monitored directory will
- // show up as just a Create. Similarly, renaming a file
- // to outside a monitored directory will show up as
- // only a Rename.
- //
- // fsnotify.Write A file or named pipe was written to. A Truncate will
- // also trigger a Write. A single "write action"
- // initiated by the user may show up as one or multiple
- // writes, depending on when the system syncs things to
- // disk. For example when compiling a large Go program
- // you may get hundreds of Write events, and you may
- // want to wait until you've stopped receiving them
- // (see the dedup example in cmd/fsnotify).
- //
- // Some systems may send Write event for directories
- // when the directory content changes.
- //
- // fsnotify.Chmod Attributes were changed. On Linux this is also sent
- // when a file is removed (or more accurately, when a
- // link to an inode is removed). On kqueue it's sent
- // when a file is truncated. On Windows it's never
- // sent.
+type kqueue struct {
Events chan Event
-
- // Errors sends any errors.
- //
- // ErrEventOverflow is used to indicate there are too many events:
- //
- // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl)
- // - windows: The buffer size is too small; WithBufferSize() can be used to increase it.
- // - kqueue, fen: Not used.
Errors chan error
- done chan struct{}
- kq int // File descriptor (as returned by the kqueue() syscall).
- closepipe [2]int // Pipe used for closing.
- mu sync.Mutex // Protects access to watcher data
- watches map[string]int // Watched file descriptors (key: path).
- watchesByDir map[string]map[int]struct{} // Watched file descriptors indexed by the parent directory (key: dirname(path)).
- userWatches map[string]struct{} // Watches added with Watcher.Add()
- dirFlags map[string]uint32 // Watched directories to fflags used in kqueue.
- paths map[int]pathInfo // File descriptors to path names for processing kqueue events.
- fileExists map[string]struct{} // Keep track of if we know this file exists (to stop duplicate create events).
- isClosed bool // Set to true when Close() is first called
+ kq int // File descriptor (as returned by the kqueue() syscall).
+ closepipe [2]int // Pipe used for closing kq.
+ watches *watches
+ done chan struct{}
+ doneMu sync.Mutex
}
-type pathInfo struct {
- name string
- isDir bool
+type (
+ watches struct {
+ mu sync.RWMutex
+ wd map[int]watch // wd → watch
+ path map[string]int // pathname → wd
+ byDir map[string]map[int]struct{} // dirname(path) → wd
+ seen map[string]struct{} // Keep track of if we know this file exists.
+ byUser map[string]struct{} // Watches added with Watcher.Add()
+ }
+ watch struct {
+ wd int
+ name string
+ linkName string // In case of links; name is the target, and this is the link.
+ isDir bool
+ dirFlags uint32
+ }
+)
+
+func newWatches() *watches {
+ return &watches{
+ wd: make(map[int]watch),
+ path: make(map[string]int),
+ byDir: make(map[string]map[int]struct{}),
+ seen: make(map[string]struct{}),
+ byUser: make(map[string]struct{}),
+ }
}
-// NewWatcher creates a new Watcher.
-func NewWatcher() (*Watcher, error) {
- return NewBufferedWatcher(0)
+func (w *watches) listPaths(userOnly bool) []string {
+ w.mu.RLock()
+ defer w.mu.RUnlock()
+
+ if userOnly {
+ l := make([]string, 0, len(w.byUser))
+ for p := range w.byUser {
+ l = append(l, p)
+ }
+ return l
+ }
+
+ l := make([]string, 0, len(w.path))
+ for p := range w.path {
+ l = append(l, p)
+ }
+ return l
}
-// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events
-// channel.
-//
-// The main use case for this is situations with a very large number of events
-// where the kernel buffer size can't be increased (e.g. due to lack of
-// permissions). An unbuffered Watcher will perform better for almost all use
-// cases, and whenever possible you will be better off increasing the kernel
-// buffers instead of adding a large userspace buffer.
-func NewBufferedWatcher(sz uint) (*Watcher, error) {
+func (w *watches) watchesInDir(path string) []string {
+ w.mu.RLock()
+ defer w.mu.RUnlock()
+
+ l := make([]string, 0, 4)
+ for fd := range w.byDir[path] {
+ info := w.wd[fd]
+ if _, ok := w.byUser[info.name]; !ok {
+ l = append(l, info.name)
+ }
+ }
+ return l
+}
+
+// Mark path as added by the user.
+func (w *watches) addUserWatch(path string) {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+ w.byUser[path] = struct{}{}
+}
+
+func (w *watches) addLink(path string, fd int) {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+
+ w.path[path] = fd
+ w.seen[path] = struct{}{}
+}
+
+func (w *watches) add(path, linkPath string, fd int, isDir bool) {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+
+ w.path[path] = fd
+ w.wd[fd] = watch{wd: fd, name: path, linkName: linkPath, isDir: isDir}
+
+ parent := filepath.Dir(path)
+ byDir, ok := w.byDir[parent]
+ if !ok {
+ byDir = make(map[int]struct{}, 1)
+ w.byDir[parent] = byDir
+ }
+ byDir[fd] = struct{}{}
+}
+
+func (w *watches) byWd(fd int) (watch, bool) {
+ w.mu.RLock()
+ defer w.mu.RUnlock()
+ info, ok := w.wd[fd]
+ return info, ok
+}
+
+func (w *watches) byPath(path string) (watch, bool) {
+ w.mu.RLock()
+ defer w.mu.RUnlock()
+ info, ok := w.wd[w.path[path]]
+ return info, ok
+}
+
+func (w *watches) updateDirFlags(path string, flags uint32) {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+
+ fd := w.path[path]
+ info := w.wd[fd]
+ info.dirFlags = flags
+ w.wd[fd] = info
+}
+
+func (w *watches) remove(fd int, path string) bool {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+
+ isDir := w.wd[fd].isDir
+ delete(w.path, path)
+ delete(w.byUser, path)
+
+ parent := filepath.Dir(path)
+ delete(w.byDir[parent], fd)
+
+ if len(w.byDir[parent]) == 0 {
+ delete(w.byDir, parent)
+ }
+
+ delete(w.wd, fd)
+ delete(w.seen, path)
+ return isDir
+}
+
+func (w *watches) markSeen(path string, exists bool) {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+ if exists {
+ w.seen[path] = struct{}{}
+ } else {
+ delete(w.seen, path)
+ }
+}
+
+func (w *watches) seenBefore(path string) bool {
+ w.mu.RLock()
+ defer w.mu.RUnlock()
+ _, ok := w.seen[path]
+ return ok
+}
+
+func newBackend(ev chan Event, errs chan error) (backend, error) {
+ return newBufferedBackend(0, ev, errs)
+}
+
+func newBufferedBackend(sz uint, ev chan Event, errs chan error) (backend, error) {
kq, closepipe, err := newKqueue()
if err != nil {
return nil, err
}
- w := &Watcher{
- kq: kq,
- closepipe: closepipe,
- watches: make(map[string]int),
- watchesByDir: make(map[string]map[int]struct{}),
- dirFlags: make(map[string]uint32),
- paths: make(map[int]pathInfo),
- fileExists: make(map[string]struct{}),
- userWatches: make(map[string]struct{}),
- Events: make(chan Event, sz),
- Errors: make(chan error),
- done: make(chan struct{}),
+ w := &kqueue{
+ Events: ev,
+ Errors: errs,
+ kq: kq,
+ closepipe: closepipe,
+ done: make(chan struct{}),
+ watches: newWatches(),
}
go w.readEvents()
@@ -203,6 +220,8 @@ func newKqueue() (kq int, closepipe [2]int, err error) {
unix.Close(kq)
return kq, closepipe, err
}
+ unix.CloseOnExec(closepipe[0])
+ unix.CloseOnExec(closepipe[1])
// Register changes to listen on the closepipe.
changes := make([]unix.Kevent_t, 1)
@@ -221,166 +240,108 @@ func newKqueue() (kq int, closepipe [2]int, err error) {
}
// Returns true if the event was sent, or false if watcher is closed.
-func (w *Watcher) sendEvent(e Event) bool {
+func (w *kqueue) sendEvent(e Event) bool {
select {
- case w.Events <- e:
- return true
case <-w.done:
return false
+ case w.Events <- e:
+ return true
}
}
// Returns true if the error was sent, or false if watcher is closed.
-func (w *Watcher) sendError(err error) bool {
+func (w *kqueue) sendError(err error) bool {
+ if err == nil {
+ return true
+ }
select {
+ case <-w.done:
+ return false
case w.Errors <- err:
return true
+ }
+}
+
+func (w *kqueue) isClosed() bool {
+ select {
case <-w.done:
+ return true
+ default:
return false
}
}
-// Close removes all watches and closes the Events channel.
-func (w *Watcher) Close() error {
- w.mu.Lock()
- if w.isClosed {
- w.mu.Unlock()
+func (w *kqueue) Close() error {
+ w.doneMu.Lock()
+ if w.isClosed() {
+ w.doneMu.Unlock()
return nil
}
- w.isClosed = true
+ close(w.done)
+ w.doneMu.Unlock()
- // copy paths to remove while locked
- pathsToRemove := make([]string, 0, len(w.watches))
- for name := range w.watches {
- pathsToRemove = append(pathsToRemove, name)
- }
- w.mu.Unlock() // Unlock before calling Remove, which also locks
+ pathsToRemove := w.watches.listPaths(false)
for _, name := range pathsToRemove {
w.Remove(name)
}
// Send "quit" message to the reader goroutine.
unix.Close(w.closepipe[1])
- close(w.done)
-
return nil
}
-// Add starts monitoring the path for changes.
-//
-// A path can only be watched once; watching it more than once is a no-op and will
-// not return an error. Paths that do not yet exist on the filesystem cannot be
-// watched.
-//
-// A watch will be automatically removed if the watched path is deleted or
-// renamed. The exception is the Windows backend, which doesn't remove the
-// watcher on renames.
-//
-// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
-// filesystems (/proc, /sys, etc.) generally don't work.
-//
-// Returns [ErrClosed] if [Watcher.Close] was called.
-//
-// See [Watcher.AddWith] for a version that allows adding options.
-//
-// # Watching directories
-//
-// All files in a directory are monitored, including new files that are created
-// after the watcher is started. Subdirectories are not watched (i.e. it's
-// non-recursive).
-//
-// # Watching files
-//
-// Watching individual files (rather than directories) is generally not
-// recommended as many programs (especially editors) update files atomically: it
-// will write to a temporary file which is then moved to to destination,
-// overwriting the original (or some variant thereof). The watcher on the
-// original file is now lost, as that no longer exists.
-//
-// The upshot of this is that a power failure or crash won't leave a
-// half-written file.
-//
-// Watch the parent directory and use Event.Name to filter out files you're not
-// interested in. There is an example of this in cmd/fsnotify/file.go.
-func (w *Watcher) Add(name string) error { return w.AddWith(name) }
+func (w *kqueue) Add(name string) error { return w.AddWith(name) }
-// AddWith is like [Watcher.Add], but allows adding options. When using Add()
-// the defaults described below are used.
-//
-// Possible options are:
-//
-// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
-// other platforms. The default is 64K (65536 bytes).
-func (w *Watcher) AddWith(name string, opts ...addOpt) error {
- _ = getOptions(opts...)
+func (w *kqueue) AddWith(name string, opts ...addOpt) error {
+ if debug {
+ fmt.Fprintf(os.Stderr, "FSNOTIFY_DEBUG: %s AddWith(%q)\n",
+ time.Now().Format("15:04:05.000000000"), name)
+ }
+
+ with := getOptions(opts...)
+ if !w.xSupports(with.op) {
+ return fmt.Errorf("%w: %s", xErrUnsupported, with.op)
+ }
- w.mu.Lock()
- w.userWatches[name] = struct{}{}
- w.mu.Unlock()
_, err := w.addWatch(name, noteAllEvents)
- return err
+ if err != nil {
+ return err
+ }
+ w.watches.addUserWatch(name)
+ return nil
}
-// Remove stops monitoring the path for changes.
-//
-// Directories are always removed non-recursively. For example, if you added
-// /tmp/dir and /tmp/dir/subdir then you will need to remove both.
-//
-// Removing a path that has not yet been added returns [ErrNonExistentWatch].
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) Remove(name string) error {
+func (w *kqueue) Remove(name string) error {
+ if debug {
+ fmt.Fprintf(os.Stderr, "FSNOTIFY_DEBUG: %s Remove(%q)\n",
+ time.Now().Format("15:04:05.000000000"), name)
+ }
return w.remove(name, true)
}
-func (w *Watcher) remove(name string, unwatchFiles bool) error {
- name = filepath.Clean(name)
- w.mu.Lock()
- if w.isClosed {
- w.mu.Unlock()
+func (w *kqueue) remove(name string, unwatchFiles bool) error {
+ if w.isClosed() {
return nil
}
- watchfd, ok := w.watches[name]
- w.mu.Unlock()
+
+ name = filepath.Clean(name)
+ info, ok := w.watches.byPath(name)
if !ok {
return fmt.Errorf("%w: %s", ErrNonExistentWatch, name)
}
- err := w.register([]int{watchfd}, unix.EV_DELETE, 0)
+ err := w.register([]int{info.wd}, unix.EV_DELETE, 0)
if err != nil {
return err
}
- unix.Close(watchfd)
-
- w.mu.Lock()
- isDir := w.paths[watchfd].isDir
- delete(w.watches, name)
- delete(w.userWatches, name)
-
- parentName := filepath.Dir(name)
- delete(w.watchesByDir[parentName], watchfd)
-
- if len(w.watchesByDir[parentName]) == 0 {
- delete(w.watchesByDir, parentName)
- }
+ unix.Close(info.wd)
- delete(w.paths, watchfd)
- delete(w.dirFlags, name)
- delete(w.fileExists, name)
- w.mu.Unlock()
+ isDir := w.watches.remove(info.wd, name)
// Find all watched paths that are in this directory that are not external.
if unwatchFiles && isDir {
- var pathsToRemove []string
- w.mu.Lock()
- for fd := range w.watchesByDir[name] {
- path := w.paths[fd]
- if _, ok := w.userWatches[path.name]; !ok {
- pathsToRemove = append(pathsToRemove, path.name)
- }
- }
- w.mu.Unlock()
+ pathsToRemove := w.watches.watchesInDir(name)
for _, name := range pathsToRemove {
// Since these are internal, not much sense in propagating error to
// the user, as that will just confuse them with an error about a
@@ -391,23 +352,11 @@ func (w *Watcher) remove(name string, unwatchFiles bool) error {
return nil
}
-// WatchList returns all paths explicitly added with [Watcher.Add] (and are not
-// yet removed).
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) WatchList() []string {
- w.mu.Lock()
- defer w.mu.Unlock()
- if w.isClosed {
+func (w *kqueue) WatchList() []string {
+ if w.isClosed() {
return nil
}
-
- entries := make([]string, 0, len(w.userWatches))
- for pathname := range w.userWatches {
- entries = append(entries, pathname)
- }
-
- return entries
+ return w.watches.listPaths(true)
}
// Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE)
@@ -417,34 +366,26 @@ const noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | un
// described in kevent(2).
//
// Returns the real path to the file which was added, with symlinks resolved.
-func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
- var isDir bool
- name = filepath.Clean(name)
-
- w.mu.Lock()
- if w.isClosed {
- w.mu.Unlock()
+func (w *kqueue) addWatch(name string, flags uint32) (string, error) {
+ if w.isClosed() {
return "", ErrClosed
}
- watchfd, alreadyWatching := w.watches[name]
- // We already have a watch, but we can still override flags.
- if alreadyWatching {
- isDir = w.paths[watchfd].isDir
- }
- w.mu.Unlock()
+ name = filepath.Clean(name)
+
+ info, alreadyWatching := w.watches.byPath(name)
if !alreadyWatching {
fi, err := os.Lstat(name)
if err != nil {
return "", err
}
- // Don't watch sockets or named pipes
+ // Don't watch sockets or named pipes.
if (fi.Mode()&os.ModeSocket == os.ModeSocket) || (fi.Mode()&os.ModeNamedPipe == os.ModeNamedPipe) {
return "", nil
}
- // Follow Symlinks.
+ // Follow symlinks.
if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
link, err := os.Readlink(name)
if err != nil {
@@ -455,18 +396,15 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
return "", nil
}
- w.mu.Lock()
- _, alreadyWatching = w.watches[link]
- w.mu.Unlock()
-
+ _, alreadyWatching = w.watches.byPath(link)
if alreadyWatching {
// Add to watches so we don't get spurious Create events later
// on when we diff the directories.
- w.watches[name] = 0
- w.fileExists[name] = struct{}{}
+ w.watches.addLink(name, 0)
return link, nil
}
+ info.linkName = name
name = link
fi, err = os.Lstat(name)
if err != nil {
@@ -477,7 +415,7 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
// Retry on EINTR; open() can return EINTR in practice on macOS.
// See #354, and Go issues 11180 and 39237.
for {
- watchfd, err = unix.Open(name, openMode, 0)
+ info.wd, err = unix.Open(name, openMode, 0)
if err == nil {
break
}
@@ -488,40 +426,25 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
return "", err
}
- isDir = fi.IsDir()
+ info.isDir = fi.IsDir()
}
- err := w.register([]int{watchfd}, unix.EV_ADD|unix.EV_CLEAR|unix.EV_ENABLE, flags)
+ err := w.register([]int{info.wd}, unix.EV_ADD|unix.EV_CLEAR|unix.EV_ENABLE, flags)
if err != nil {
- unix.Close(watchfd)
+ unix.Close(info.wd)
return "", err
}
if !alreadyWatching {
- w.mu.Lock()
- parentName := filepath.Dir(name)
- w.watches[name] = watchfd
-
- watchesByDir, ok := w.watchesByDir[parentName]
- if !ok {
- watchesByDir = make(map[int]struct{}, 1)
- w.watchesByDir[parentName] = watchesByDir
- }
- watchesByDir[watchfd] = struct{}{}
- w.paths[watchfd] = pathInfo{name: name, isDir: isDir}
- w.mu.Unlock()
+ w.watches.add(name, info.linkName, info.wd, info.isDir)
}
- if isDir {
- // Watch the directory if it has not been watched before, or if it was
- // watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles)
- w.mu.Lock()
-
+ // Watch the directory if it has not been watched before, or if it was
+ // watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles)
+ if info.isDir {
watchDir := (flags&unix.NOTE_WRITE) == unix.NOTE_WRITE &&
- (!alreadyWatching || (w.dirFlags[name]&unix.NOTE_WRITE) != unix.NOTE_WRITE)
- // Store flags so this watch can be updated later
- w.dirFlags[name] = flags
- w.mu.Unlock()
+ (!alreadyWatching || (info.dirFlags&unix.NOTE_WRITE) != unix.NOTE_WRITE)
+ w.watches.updateDirFlags(name, flags)
if watchDir {
if err := w.watchDirectoryFiles(name); err != nil {
@@ -534,7 +457,7 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
// readEvents reads from kqueue and converts the received kevents into
// Event values that it sends down the Events channel.
-func (w *Watcher) readEvents() {
+func (w *kqueue) readEvents() {
defer func() {
close(w.Events)
close(w.Errors)
@@ -543,50 +466,65 @@ func (w *Watcher) readEvents() {
}()
eventBuffer := make([]unix.Kevent_t, 10)
- for closed := false; !closed; {
+ for {
kevents, err := w.read(eventBuffer)
// EINTR is okay, the syscall was interrupted before timeout expired.
if err != nil && err != unix.EINTR {
if !w.sendError(fmt.Errorf("fsnotify.readEvents: %w", err)) {
- closed = true
+ return
}
- continue
}
- // Flush the events we received to the Events channel
for _, kevent := range kevents {
var (
- watchfd = int(kevent.Ident)
- mask = uint32(kevent.Fflags)
+ wd = int(kevent.Ident)
+ mask = uint32(kevent.Fflags)
)
// Shut down the loop when the pipe is closed, but only after all
// other events have been processed.
- if watchfd == w.closepipe[0] {
- closed = true
- continue
+ if wd == w.closepipe[0] {
+ return
}
- w.mu.Lock()
- path := w.paths[watchfd]
- w.mu.Unlock()
+ path, ok := w.watches.byWd(wd)
+ if debug {
+ internal.Debug(path.name, &kevent)
+ }
- event := w.newEvent(path.name, mask)
+ // On macOS it seems that sometimes an event with Ident=0 is
+ // delivered, and no other flags/information beyond that, even
+ // though we never saw such a file descriptor. For example in
+ // TestWatchSymlink/277 (usually at the end, but sometimes sooner):
+ //
+ // fmt.Printf("READ: %2d %#v\n", kevent.Ident, kevent)
+ // unix.Kevent_t{Ident:0x2a, Filter:-4, Flags:0x25, Fflags:0x2, Data:0, Udata:(*uint8)(nil)}
+ // unix.Kevent_t{Ident:0x0, Filter:-4, Flags:0x25, Fflags:0x2, Data:0, Udata:(*uint8)(nil)}
+ //
+ // The first is a normal event, the second with Ident 0. No error
+ // flag, no data, no ... nothing.
+ //
+ // I read a bit through bsd/kern_event.c from the xnu source, but I
+ // don't really see an obvious location where this is triggered –
+ // this doesn't seem intentional, but idk...
+ //
+ // Technically fd 0 is a valid descriptor, so only skip it if
+ // there's no path, and if we're on macOS.
+ if !ok && kevent.Ident == 0 && runtime.GOOS == "darwin" {
+ continue
+ }
+
+ event := w.newEvent(path.name, path.linkName, mask)
if event.Has(Rename) || event.Has(Remove) {
w.remove(event.Name, false)
- w.mu.Lock()
- delete(w.fileExists, event.Name)
- w.mu.Unlock()
+ w.watches.markSeen(event.Name, false)
}
if path.isDir && event.Has(Write) && !event.Has(Remove) {
- w.sendDirectoryChangeEvents(event.Name)
- } else {
- if !w.sendEvent(event) {
- closed = true
- continue
- }
+ w.dirChange(event.Name)
+ } else if !w.sendEvent(event) {
+ return
}
if event.Has(Remove) {
@@ -594,25 +532,34 @@ func (w *Watcher) readEvents() {
// mv f1 f2 will delete f2, then create f2.
if path.isDir {
fileDir := filepath.Clean(event.Name)
- w.mu.Lock()
- _, found := w.watches[fileDir]
- w.mu.Unlock()
+ _, found := w.watches.byPath(fileDir)
if found {
- err := w.sendDirectoryChangeEvents(fileDir)
- if err != nil {
- if !w.sendError(err) {
- closed = true
- }
+ // TODO: this branch is never triggered in any test.
+ // Added in d6220df (2012).
+ // isDir check added in 8611c35 (2016): https://github.com/fsnotify/fsnotify/pull/111
+ //
+ // I don't really get how this can be triggered either.
+ // And it wasn't triggered in the patch that added it,
+ // either.
+ //
+ // Original also had a comment:
+ // make sure the directory exists before we watch for
+ // changes. When we do a recursive watch and perform
+ // rm -rf, the parent directory might have gone
+ // missing, ignore the missing directory and let the
+ // upcoming delete event remove the watch from the
+ // parent directory.
+ err := w.dirChange(fileDir)
+ if !w.sendError(err) {
+ return
}
}
} else {
- filePath := filepath.Clean(event.Name)
- if fi, err := os.Lstat(filePath); err == nil {
- err := w.sendFileCreatedEventIfNew(filePath, fi)
- if err != nil {
- if !w.sendError(err) {
- closed = true
- }
+ path := filepath.Clean(event.Name)
+ if fi, err := os.Lstat(path); err == nil {
+ err := w.sendCreateIfNew(path, fi)
+ if !w.sendError(err) {
+ return
}
}
}
@@ -622,8 +569,14 @@ func (w *Watcher) readEvents() {
}
// newEvent returns an platform-independent Event based on kqueue Fflags.
-func (w *Watcher) newEvent(name string, mask uint32) Event {
+func (w *kqueue) newEvent(name, linkName string, mask uint32) Event {
e := Event{Name: name}
+ if linkName != "" {
+ // If the user watched "/path/link" then emit events as "/path/link"
+ // rather than "/path/target".
+ e.Name = linkName
+ }
+
if mask&unix.NOTE_DELETE == unix.NOTE_DELETE {
e.Op |= Remove
}
@@ -645,8 +598,7 @@ func (w *Watcher) newEvent(name string, mask uint32) Event {
}
// watchDirectoryFiles to mimic inotify when adding a watch on a directory
-func (w *Watcher) watchDirectoryFiles(dirPath string) error {
- // Get all files
+func (w *kqueue) watchDirectoryFiles(dirPath string) error {
files, err := os.ReadDir(dirPath)
if err != nil {
return err
@@ -674,9 +626,7 @@ func (w *Watcher) watchDirectoryFiles(dirPath string) error {
}
}
- w.mu.Lock()
- w.fileExists[cleanPath] = struct{}{}
- w.mu.Unlock()
+ w.watches.markSeen(cleanPath, true)
}
return nil
@@ -686,7 +636,7 @@ func (w *Watcher) watchDirectoryFiles(dirPath string) error {
//
// This functionality is to have the BSD watcher match the inotify, which sends
// a create event for files created in a watched directory.
-func (w *Watcher) sendDirectoryChangeEvents(dir string) error {
+func (w *kqueue) dirChange(dir string) error {
files, err := os.ReadDir(dir)
if err != nil {
// Directory no longer exists: we can ignore this safely. kqueue will
@@ -694,61 +644,51 @@ func (w *Watcher) sendDirectoryChangeEvents(dir string) error {
if errors.Is(err, os.ErrNotExist) {
return nil
}
- return fmt.Errorf("fsnotify.sendDirectoryChangeEvents: %w", err)
+ return fmt.Errorf("fsnotify.dirChange: %w", err)
}
for _, f := range files {
fi, err := f.Info()
if err != nil {
- return fmt.Errorf("fsnotify.sendDirectoryChangeEvents: %w", err)
+ return fmt.Errorf("fsnotify.dirChange: %w", err)
}
- err = w.sendFileCreatedEventIfNew(filepath.Join(dir, fi.Name()), fi)
+ err = w.sendCreateIfNew(filepath.Join(dir, fi.Name()), fi)
if err != nil {
// Don't need to send an error if this file isn't readable.
if errors.Is(err, unix.EACCES) || errors.Is(err, unix.EPERM) {
return nil
}
- return fmt.Errorf("fsnotify.sendDirectoryChangeEvents: %w", err)
+ return fmt.Errorf("fsnotify.dirChange: %w", err)
}
}
return nil
}
-// sendFileCreatedEvent sends a create event if the file isn't already being tracked.
-func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fi os.FileInfo) (err error) {
- w.mu.Lock()
- _, doesExist := w.fileExists[filePath]
- w.mu.Unlock()
- if !doesExist {
- if !w.sendEvent(Event{Name: filePath, Op: Create}) {
- return
+// Send a create event if the file isn't already being tracked, and start
+// watching this file.
+func (w *kqueue) sendCreateIfNew(path string, fi os.FileInfo) error {
+ if !w.watches.seenBefore(path) {
+ if !w.sendEvent(Event{Name: path, Op: Create}) {
+ return nil
}
}
- // like watchDirectoryFiles (but without doing another ReadDir)
- filePath, err = w.internalWatch(filePath, fi)
+ // Like watchDirectoryFiles, but without doing another ReadDir.
+ path, err := w.internalWatch(path, fi)
if err != nil {
return err
}
-
- w.mu.Lock()
- w.fileExists[filePath] = struct{}{}
- w.mu.Unlock()
-
+ w.watches.markSeen(path, true)
return nil
}
-func (w *Watcher) internalWatch(name string, fi os.FileInfo) (string, error) {
+func (w *kqueue) internalWatch(name string, fi os.FileInfo) (string, error) {
if fi.IsDir() {
// mimic Linux providing delete events for subdirectories, but preserve
// the flags used if currently watching subdirectory
- w.mu.Lock()
- flags := w.dirFlags[name]
- w.mu.Unlock()
-
- flags |= unix.NOTE_DELETE | unix.NOTE_RENAME
- return w.addWatch(name, flags)
+ info, _ := w.watches.byPath(name)
+ return w.addWatch(name, info.dirFlags|unix.NOTE_DELETE|unix.NOTE_RENAME)
}
// watch file to mimic Linux inotify
@@ -756,7 +696,7 @@ func (w *Watcher) internalWatch(name string, fi os.FileInfo) (string, error) {
}
// Register events with the queue.
-func (w *Watcher) register(fds []int, flags int, fflags uint32) error {
+func (w *kqueue) register(fds []int, flags int, fflags uint32) error {
changes := make([]unix.Kevent_t, len(fds))
for i, fd := range fds {
// SetKevent converts int to the platform-specific types.
@@ -773,10 +713,21 @@ func (w *Watcher) register(fds []int, flags int, fflags uint32) error {
}
// read retrieves pending events, or waits until an event occurs.
-func (w *Watcher) read(events []unix.Kevent_t) ([]unix.Kevent_t, error) {
+func (w *kqueue) read(events []unix.Kevent_t) ([]unix.Kevent_t, error) {
n, err := unix.Kevent(w.kq, nil, events, nil)
if err != nil {
return nil, err
}
return events[0:n], nil
}
+
+func (w *kqueue) xSupports(op Op) bool {
+ if runtime.GOOS == "freebsd" {
+ //return true // Supports everything.
+ }
+ if op.Has(xUnportableOpen) || op.Has(xUnportableRead) ||
+ op.Has(xUnportableCloseWrite) || op.Has(xUnportableCloseRead) {
+ return false
+ }
+ return true
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/backend_other.go b/vendor/github.com/fsnotify/fsnotify/backend_other.go
index d34a23c015..5eb5dbc66f 100644
--- a/vendor/github.com/fsnotify/fsnotify/backend_other.go
+++ b/vendor/github.com/fsnotify/fsnotify/backend_other.go
@@ -1,205 +1,23 @@
//go:build appengine || (!darwin && !dragonfly && !freebsd && !openbsd && !linux && !netbsd && !solaris && !windows)
-// +build appengine !darwin,!dragonfly,!freebsd,!openbsd,!linux,!netbsd,!solaris,!windows
-
-// Note: the documentation on the Watcher type and methods is generated from
-// mkdoc.zsh
package fsnotify
import "errors"
-// Watcher watches a set of paths, delivering events on a channel.
-//
-// A watcher should not be copied (e.g. pass it by pointer, rather than by
-// value).
-//
-// # Linux notes
-//
-// When a file is removed a Remove event won't be emitted until all file
-// descriptors are closed, and deletes will always emit a Chmod. For example:
-//
-// fp := os.Open("file")
-// os.Remove("file") // Triggers Chmod
-// fp.Close() // Triggers Remove
-//
-// This is the event that inotify sends, so not much can be changed about this.
-//
-// The fs.inotify.max_user_watches sysctl variable specifies the upper limit
-// for the number of watches per user, and fs.inotify.max_user_instances
-// specifies the maximum number of inotify instances per user. Every Watcher you
-// create is an "instance", and every path you add is a "watch".
-//
-// These are also exposed in /proc as /proc/sys/fs/inotify/max_user_watches and
-// /proc/sys/fs/inotify/max_user_instances
-//
-// To increase them you can use sysctl or write the value to the /proc file:
-//
-// # Default values on Linux 5.18
-// sysctl fs.inotify.max_user_watches=124983
-// sysctl fs.inotify.max_user_instances=128
-//
-// To make the changes persist on reboot edit /etc/sysctl.conf or
-// /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check
-// your distro's documentation):
-//
-// fs.inotify.max_user_watches=124983
-// fs.inotify.max_user_instances=128
-//
-// Reaching the limit will result in a "no space left on device" or "too many open
-// files" error.
-//
-// # kqueue notes (macOS, BSD)
-//
-// kqueue requires opening a file descriptor for every file that's being watched;
-// so if you're watching a directory with five files then that's six file
-// descriptors. You will run in to your system's "max open files" limit faster on
-// these platforms.
-//
-// The sysctl variables kern.maxfiles and kern.maxfilesperproc can be used to
-// control the maximum number of open files, as well as /etc/login.conf on BSD
-// systems.
-//
-// # Windows notes
-//
-// Paths can be added as "C:\path\to\dir", but forward slashes
-// ("C:/path/to/dir") will also work.
-//
-// When a watched directory is removed it will always send an event for the
-// directory itself, but may not send events for all files in that directory.
-// Sometimes it will send events for all times, sometimes it will send no
-// events, and often only for some files.
-//
-// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest
-// value that is guaranteed to work with SMB filesystems. If you have many
-// events in quick succession this may not be enough, and you will have to use
-// [WithBufferSize] to increase the value.
-type Watcher struct {
- // Events sends the filesystem change events.
- //
- // fsnotify can send the following events; a "path" here can refer to a
- // file, directory, symbolic link, or special file like a FIFO.
- //
- // fsnotify.Create A new path was created; this may be followed by one
- // or more Write events if data also gets written to a
- // file.
- //
- // fsnotify.Remove A path was removed.
- //
- // fsnotify.Rename A path was renamed. A rename is always sent with the
- // old path as Event.Name, and a Create event will be
- // sent with the new name. Renames are only sent for
- // paths that are currently watched; e.g. moving an
- // unmonitored file into a monitored directory will
- // show up as just a Create. Similarly, renaming a file
- // to outside a monitored directory will show up as
- // only a Rename.
- //
- // fsnotify.Write A file or named pipe was written to. A Truncate will
- // also trigger a Write. A single "write action"
- // initiated by the user may show up as one or multiple
- // writes, depending on when the system syncs things to
- // disk. For example when compiling a large Go program
- // you may get hundreds of Write events, and you may
- // want to wait until you've stopped receiving them
- // (see the dedup example in cmd/fsnotify).
- //
- // Some systems may send Write event for directories
- // when the directory content changes.
- //
- // fsnotify.Chmod Attributes were changed. On Linux this is also sent
- // when a file is removed (or more accurately, when a
- // link to an inode is removed). On kqueue it's sent
- // when a file is truncated. On Windows it's never
- // sent.
+type other struct {
Events chan Event
-
- // Errors sends any errors.
- //
- // ErrEventOverflow is used to indicate there are too many events:
- //
- // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl)
- // - windows: The buffer size is too small; WithBufferSize() can be used to increase it.
- // - kqueue, fen: Not used.
Errors chan error
}
-// NewWatcher creates a new Watcher.
-func NewWatcher() (*Watcher, error) {
+func newBackend(ev chan Event, errs chan error) (backend, error) {
return nil, errors.New("fsnotify not supported on the current platform")
}
-
-// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events
-// channel.
-//
-// The main use case for this is situations with a very large number of events
-// where the kernel buffer size can't be increased (e.g. due to lack of
-// permissions). An unbuffered Watcher will perform better for almost all use
-// cases, and whenever possible you will be better off increasing the kernel
-// buffers instead of adding a large userspace buffer.
-func NewBufferedWatcher(sz uint) (*Watcher, error) { return NewWatcher() }
-
-// Close removes all watches and closes the Events channel.
-func (w *Watcher) Close() error { return nil }
-
-// WatchList returns all paths explicitly added with [Watcher.Add] (and are not
-// yet removed).
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) WatchList() []string { return nil }
-
-// Add starts monitoring the path for changes.
-//
-// A path can only be watched once; watching it more than once is a no-op and will
-// not return an error. Paths that do not yet exist on the filesystem cannot be
-// watched.
-//
-// A watch will be automatically removed if the watched path is deleted or
-// renamed. The exception is the Windows backend, which doesn't remove the
-// watcher on renames.
-//
-// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
-// filesystems (/proc, /sys, etc.) generally don't work.
-//
-// Returns [ErrClosed] if [Watcher.Close] was called.
-//
-// See [Watcher.AddWith] for a version that allows adding options.
-//
-// # Watching directories
-//
-// All files in a directory are monitored, including new files that are created
-// after the watcher is started. Subdirectories are not watched (i.e. it's
-// non-recursive).
-//
-// # Watching files
-//
-// Watching individual files (rather than directories) is generally not
-// recommended as many programs (especially editors) update files atomically: it
-// will write to a temporary file which is then moved to to destination,
-// overwriting the original (or some variant thereof). The watcher on the
-// original file is now lost, as that no longer exists.
-//
-// The upshot of this is that a power failure or crash won't leave a
-// half-written file.
-//
-// Watch the parent directory and use Event.Name to filter out files you're not
-// interested in. There is an example of this in cmd/fsnotify/file.go.
-func (w *Watcher) Add(name string) error { return nil }
-
-// AddWith is like [Watcher.Add], but allows adding options. When using Add()
-// the defaults described below are used.
-//
-// Possible options are:
-//
-// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
-// other platforms. The default is 64K (65536 bytes).
-func (w *Watcher) AddWith(name string, opts ...addOpt) error { return nil }
-
-// Remove stops monitoring the path for changes.
-//
-// Directories are always removed non-recursively. For example, if you added
-// /tmp/dir and /tmp/dir/subdir then you will need to remove both.
-//
-// Removing a path that has not yet been added returns [ErrNonExistentWatch].
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) Remove(name string) error { return nil }
+func newBufferedBackend(sz uint, ev chan Event, errs chan error) (backend, error) {
+ return newBackend(ev, errs)
+}
+func (w *other) Close() error { return nil }
+func (w *other) WatchList() []string { return nil }
+func (w *other) Add(name string) error { return nil }
+func (w *other) AddWith(name string, opts ...addOpt) error { return nil }
+func (w *other) Remove(name string) error { return nil }
+func (w *other) xSupports(op Op) bool { return false }
diff --git a/vendor/github.com/fsnotify/fsnotify/backend_windows.go b/vendor/github.com/fsnotify/fsnotify/backend_windows.go
index 9bc91e5d61..c54a630838 100644
--- a/vendor/github.com/fsnotify/fsnotify/backend_windows.go
+++ b/vendor/github.com/fsnotify/fsnotify/backend_windows.go
@@ -1,12 +1,8 @@
//go:build windows
-// +build windows
// Windows backend based on ReadDirectoryChangesW()
//
// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-readdirectorychangesw
-//
-// Note: the documentation on the Watcher type and methods is generated from
-// mkdoc.zsh
package fsnotify
@@ -19,123 +15,15 @@ import (
"runtime"
"strings"
"sync"
+ "time"
"unsafe"
+ "github.com/fsnotify/fsnotify/internal"
"golang.org/x/sys/windows"
)
-// Watcher watches a set of paths, delivering events on a channel.
-//
-// A watcher should not be copied (e.g. pass it by pointer, rather than by
-// value).
-//
-// # Linux notes
-//
-// When a file is removed a Remove event won't be emitted until all file
-// descriptors are closed, and deletes will always emit a Chmod. For example:
-//
-// fp := os.Open("file")
-// os.Remove("file") // Triggers Chmod
-// fp.Close() // Triggers Remove
-//
-// This is the event that inotify sends, so not much can be changed about this.
-//
-// The fs.inotify.max_user_watches sysctl variable specifies the upper limit
-// for the number of watches per user, and fs.inotify.max_user_instances
-// specifies the maximum number of inotify instances per user. Every Watcher you
-// create is an "instance", and every path you add is a "watch".
-//
-// These are also exposed in /proc as /proc/sys/fs/inotify/max_user_watches and
-// /proc/sys/fs/inotify/max_user_instances
-//
-// To increase them you can use sysctl or write the value to the /proc file:
-//
-// # Default values on Linux 5.18
-// sysctl fs.inotify.max_user_watches=124983
-// sysctl fs.inotify.max_user_instances=128
-//
-// To make the changes persist on reboot edit /etc/sysctl.conf or
-// /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check
-// your distro's documentation):
-//
-// fs.inotify.max_user_watches=124983
-// fs.inotify.max_user_instances=128
-//
-// Reaching the limit will result in a "no space left on device" or "too many open
-// files" error.
-//
-// # kqueue notes (macOS, BSD)
-//
-// kqueue requires opening a file descriptor for every file that's being watched;
-// so if you're watching a directory with five files then that's six file
-// descriptors. You will run in to your system's "max open files" limit faster on
-// these platforms.
-//
-// The sysctl variables kern.maxfiles and kern.maxfilesperproc can be used to
-// control the maximum number of open files, as well as /etc/login.conf on BSD
-// systems.
-//
-// # Windows notes
-//
-// Paths can be added as "C:\path\to\dir", but forward slashes
-// ("C:/path/to/dir") will also work.
-//
-// When a watched directory is removed it will always send an event for the
-// directory itself, but may not send events for all files in that directory.
-// Sometimes it will send events for all times, sometimes it will send no
-// events, and often only for some files.
-//
-// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest
-// value that is guaranteed to work with SMB filesystems. If you have many
-// events in quick succession this may not be enough, and you will have to use
-// [WithBufferSize] to increase the value.
-type Watcher struct {
- // Events sends the filesystem change events.
- //
- // fsnotify can send the following events; a "path" here can refer to a
- // file, directory, symbolic link, or special file like a FIFO.
- //
- // fsnotify.Create A new path was created; this may be followed by one
- // or more Write events if data also gets written to a
- // file.
- //
- // fsnotify.Remove A path was removed.
- //
- // fsnotify.Rename A path was renamed. A rename is always sent with the
- // old path as Event.Name, and a Create event will be
- // sent with the new name. Renames are only sent for
- // paths that are currently watched; e.g. moving an
- // unmonitored file into a monitored directory will
- // show up as just a Create. Similarly, renaming a file
- // to outside a monitored directory will show up as
- // only a Rename.
- //
- // fsnotify.Write A file or named pipe was written to. A Truncate will
- // also trigger a Write. A single "write action"
- // initiated by the user may show up as one or multiple
- // writes, depending on when the system syncs things to
- // disk. For example when compiling a large Go program
- // you may get hundreds of Write events, and you may
- // want to wait until you've stopped receiving them
- // (see the dedup example in cmd/fsnotify).
- //
- // Some systems may send Write event for directories
- // when the directory content changes.
- //
- // fsnotify.Chmod Attributes were changed. On Linux this is also sent
- // when a file is removed (or more accurately, when a
- // link to an inode is removed). On kqueue it's sent
- // when a file is truncated. On Windows it's never
- // sent.
+type readDirChangesW struct {
Events chan Event
-
- // Errors sends any errors.
- //
- // ErrEventOverflow is used to indicate there are too many events:
- //
- // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl)
- // - windows: The buffer size is too small; WithBufferSize() can be used to increase it.
- // - kqueue, fen: Not used.
Errors chan error
port windows.Handle // Handle to completion port
@@ -147,48 +35,40 @@ type Watcher struct {
closed bool // Set to true when Close() is first called
}
-// NewWatcher creates a new Watcher.
-func NewWatcher() (*Watcher, error) {
- return NewBufferedWatcher(50)
+func newBackend(ev chan Event, errs chan error) (backend, error) {
+ return newBufferedBackend(50, ev, errs)
}
-// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events
-// channel.
-//
-// The main use case for this is situations with a very large number of events
-// where the kernel buffer size can't be increased (e.g. due to lack of
-// permissions). An unbuffered Watcher will perform better for almost all use
-// cases, and whenever possible you will be better off increasing the kernel
-// buffers instead of adding a large userspace buffer.
-func NewBufferedWatcher(sz uint) (*Watcher, error) {
+func newBufferedBackend(sz uint, ev chan Event, errs chan error) (backend, error) {
port, err := windows.CreateIoCompletionPort(windows.InvalidHandle, 0, 0, 0)
if err != nil {
return nil, os.NewSyscallError("CreateIoCompletionPort", err)
}
- w := &Watcher{
+ w := &readDirChangesW{
+ Events: ev,
+ Errors: errs,
port: port,
watches: make(watchMap),
input: make(chan *input, 1),
- Events: make(chan Event, sz),
- Errors: make(chan error),
quit: make(chan chan<- error, 1),
}
go w.readEvents()
return w, nil
}
-func (w *Watcher) isClosed() bool {
+func (w *readDirChangesW) isClosed() bool {
w.mu.Lock()
defer w.mu.Unlock()
return w.closed
}
-func (w *Watcher) sendEvent(name string, mask uint64) bool {
+func (w *readDirChangesW) sendEvent(name, renamedFrom string, mask uint64) bool {
if mask == 0 {
return false
}
event := w.newEvent(name, uint32(mask))
+ event.renamedFrom = renamedFrom
select {
case ch := <-w.quit:
w.quit <- ch
@@ -198,17 +78,19 @@ func (w *Watcher) sendEvent(name string, mask uint64) bool {
}
// Returns true if the error was sent, or false if watcher is closed.
-func (w *Watcher) sendError(err error) bool {
+func (w *readDirChangesW) sendError(err error) bool {
+ if err == nil {
+ return true
+ }
select {
case w.Errors <- err:
return true
case <-w.quit:
+ return false
}
- return false
}
-// Close removes all watches and closes the Events channel.
-func (w *Watcher) Close() error {
+func (w *readDirChangesW) Close() error {
if w.isClosed() {
return nil
}
@@ -226,57 +108,21 @@ func (w *Watcher) Close() error {
return <-ch
}
-// Add starts monitoring the path for changes.
-//
-// A path can only be watched once; watching it more than once is a no-op and will
-// not return an error. Paths that do not yet exist on the filesystem cannot be
-// watched.
-//
-// A watch will be automatically removed if the watched path is deleted or
-// renamed. The exception is the Windows backend, which doesn't remove the
-// watcher on renames.
-//
-// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
-// filesystems (/proc, /sys, etc.) generally don't work.
-//
-// Returns [ErrClosed] if [Watcher.Close] was called.
-//
-// See [Watcher.AddWith] for a version that allows adding options.
-//
-// # Watching directories
-//
-// All files in a directory are monitored, including new files that are created
-// after the watcher is started. Subdirectories are not watched (i.e. it's
-// non-recursive).
-//
-// # Watching files
-//
-// Watching individual files (rather than directories) is generally not
-// recommended as many programs (especially editors) update files atomically: it
-// will write to a temporary file which is then moved to to destination,
-// overwriting the original (or some variant thereof). The watcher on the
-// original file is now lost, as that no longer exists.
-//
-// The upshot of this is that a power failure or crash won't leave a
-// half-written file.
-//
-// Watch the parent directory and use Event.Name to filter out files you're not
-// interested in. There is an example of this in cmd/fsnotify/file.go.
-func (w *Watcher) Add(name string) error { return w.AddWith(name) }
+func (w *readDirChangesW) Add(name string) error { return w.AddWith(name) }
-// AddWith is like [Watcher.Add], but allows adding options. When using Add()
-// the defaults described below are used.
-//
-// Possible options are:
-//
-// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
-// other platforms. The default is 64K (65536 bytes).
-func (w *Watcher) AddWith(name string, opts ...addOpt) error {
+func (w *readDirChangesW) AddWith(name string, opts ...addOpt) error {
if w.isClosed() {
return ErrClosed
}
+ if debug {
+ fmt.Fprintf(os.Stderr, "FSNOTIFY_DEBUG: %s AddWith(%q)\n",
+ time.Now().Format("15:04:05.000000000"), filepath.ToSlash(name))
+ }
with := getOptions(opts...)
+ if !w.xSupports(with.op) {
+ return fmt.Errorf("%w: %s", xErrUnsupported, with.op)
+ }
if with.bufsize < 4096 {
return fmt.Errorf("fsnotify.WithBufferSize: buffer size cannot be smaller than 4096 bytes")
}
@@ -295,18 +141,14 @@ func (w *Watcher) AddWith(name string, opts ...addOpt) error {
return <-in.reply
}
-// Remove stops monitoring the path for changes.
-//
-// Directories are always removed non-recursively. For example, if you added
-// /tmp/dir and /tmp/dir/subdir then you will need to remove both.
-//
-// Removing a path that has not yet been added returns [ErrNonExistentWatch].
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) Remove(name string) error {
+func (w *readDirChangesW) Remove(name string) error {
if w.isClosed() {
return nil
}
+ if debug {
+ fmt.Fprintf(os.Stderr, "FSNOTIFY_DEBUG: %s Remove(%q)\n",
+ time.Now().Format("15:04:05.000000000"), filepath.ToSlash(name))
+ }
in := &input{
op: opRemoveWatch,
@@ -320,11 +162,7 @@ func (w *Watcher) Remove(name string) error {
return <-in.reply
}
-// WatchList returns all paths explicitly added with [Watcher.Add] (and are not
-// yet removed).
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) WatchList() []string {
+func (w *readDirChangesW) WatchList() []string {
if w.isClosed() {
return nil
}
@@ -335,7 +173,13 @@ func (w *Watcher) WatchList() []string {
entries := make([]string, 0, len(w.watches))
for _, entry := range w.watches {
for _, watchEntry := range entry {
- entries = append(entries, watchEntry.path)
+ for name := range watchEntry.names {
+ entries = append(entries, filepath.Join(watchEntry.path, name))
+ }
+ // the directory itself is being watched
+ if watchEntry.mask != 0 {
+ entries = append(entries, watchEntry.path)
+ }
}
}
@@ -361,7 +205,7 @@ const (
sysFSIGNORED = 0x8000
)
-func (w *Watcher) newEvent(name string, mask uint32) Event {
+func (w *readDirChangesW) newEvent(name string, mask uint32) Event {
e := Event{Name: name}
if mask&sysFSCREATE == sysFSCREATE || mask&sysFSMOVEDTO == sysFSMOVEDTO {
e.Op |= Create
@@ -417,7 +261,7 @@ type (
watchMap map[uint32]indexMap
)
-func (w *Watcher) wakeupReader() error {
+func (w *readDirChangesW) wakeupReader() error {
err := windows.PostQueuedCompletionStatus(w.port, 0, 0, nil)
if err != nil {
return os.NewSyscallError("PostQueuedCompletionStatus", err)
@@ -425,7 +269,7 @@ func (w *Watcher) wakeupReader() error {
return nil
}
-func (w *Watcher) getDir(pathname string) (dir string, err error) {
+func (w *readDirChangesW) getDir(pathname string) (dir string, err error) {
attr, err := windows.GetFileAttributes(windows.StringToUTF16Ptr(pathname))
if err != nil {
return "", os.NewSyscallError("GetFileAttributes", err)
@@ -439,7 +283,7 @@ func (w *Watcher) getDir(pathname string) (dir string, err error) {
return
}
-func (w *Watcher) getIno(path string) (ino *inode, err error) {
+func (w *readDirChangesW) getIno(path string) (ino *inode, err error) {
h, err := windows.CreateFile(windows.StringToUTF16Ptr(path),
windows.FILE_LIST_DIRECTORY,
windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE,
@@ -482,9 +326,8 @@ func (m watchMap) set(ino *inode, watch *watch) {
}
// Must run within the I/O thread.
-func (w *Watcher) addWatch(pathname string, flags uint64, bufsize int) error {
- //pathname, recurse := recursivePath(pathname)
- recurse := false
+func (w *readDirChangesW) addWatch(pathname string, flags uint64, bufsize int) error {
+ pathname, recurse := recursivePath(pathname)
dir, err := w.getDir(pathname)
if err != nil {
@@ -538,7 +381,7 @@ func (w *Watcher) addWatch(pathname string, flags uint64, bufsize int) error {
}
// Must run within the I/O thread.
-func (w *Watcher) remWatch(pathname string) error {
+func (w *readDirChangesW) remWatch(pathname string) error {
pathname, recurse := recursivePath(pathname)
dir, err := w.getDir(pathname)
@@ -566,11 +409,11 @@ func (w *Watcher) remWatch(pathname string) error {
return fmt.Errorf("%w: %s", ErrNonExistentWatch, pathname)
}
if pathname == dir {
- w.sendEvent(watch.path, watch.mask&sysFSIGNORED)
+ w.sendEvent(watch.path, "", watch.mask&sysFSIGNORED)
watch.mask = 0
} else {
name := filepath.Base(pathname)
- w.sendEvent(filepath.Join(watch.path, name), watch.names[name]&sysFSIGNORED)
+ w.sendEvent(filepath.Join(watch.path, name), "", watch.names[name]&sysFSIGNORED)
delete(watch.names, name)
}
@@ -578,23 +421,23 @@ func (w *Watcher) remWatch(pathname string) error {
}
// Must run within the I/O thread.
-func (w *Watcher) deleteWatch(watch *watch) {
+func (w *readDirChangesW) deleteWatch(watch *watch) {
for name, mask := range watch.names {
if mask&provisional == 0 {
- w.sendEvent(filepath.Join(watch.path, name), mask&sysFSIGNORED)
+ w.sendEvent(filepath.Join(watch.path, name), "", mask&sysFSIGNORED)
}
delete(watch.names, name)
}
if watch.mask != 0 {
if watch.mask&provisional == 0 {
- w.sendEvent(watch.path, watch.mask&sysFSIGNORED)
+ w.sendEvent(watch.path, "", watch.mask&sysFSIGNORED)
}
watch.mask = 0
}
}
// Must run within the I/O thread.
-func (w *Watcher) startRead(watch *watch) error {
+func (w *readDirChangesW) startRead(watch *watch) error {
err := windows.CancelIo(watch.ino.handle)
if err != nil {
w.sendError(os.NewSyscallError("CancelIo", err))
@@ -624,7 +467,7 @@ func (w *Watcher) startRead(watch *watch) error {
err := os.NewSyscallError("ReadDirectoryChanges", rdErr)
if rdErr == windows.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 {
// Watched directory was probably removed
- w.sendEvent(watch.path, watch.mask&sysFSDELETESELF)
+ w.sendEvent(watch.path, "", watch.mask&sysFSDELETESELF)
err = nil
}
w.deleteWatch(watch)
@@ -637,7 +480,7 @@ func (w *Watcher) startRead(watch *watch) error {
// readEvents reads from the I/O completion port, converts the
// received events into Event objects and sends them via the Events channel.
// Entry point to the I/O thread.
-func (w *Watcher) readEvents() {
+func (w *readDirChangesW) readEvents() {
var (
n uint32
key uintptr
@@ -700,7 +543,7 @@ func (w *Watcher) readEvents() {
}
case windows.ERROR_ACCESS_DENIED:
// Watched directory was probably removed
- w.sendEvent(watch.path, watch.mask&sysFSDELETESELF)
+ w.sendEvent(watch.path, "", watch.mask&sysFSDELETESELF)
w.deleteWatch(watch)
w.startRead(watch)
continue
@@ -733,6 +576,10 @@ func (w *Watcher) readEvents() {
name := windows.UTF16ToString(buf)
fullname := filepath.Join(watch.path, name)
+ if debug {
+ internal.Debug(fullname, raw.Action)
+ }
+
var mask uint64
switch raw.Action {
case windows.FILE_ACTION_REMOVED:
@@ -761,21 +608,22 @@ func (w *Watcher) readEvents() {
}
}
- sendNameEvent := func() {
- w.sendEvent(fullname, watch.names[name]&mask)
- }
if raw.Action != windows.FILE_ACTION_RENAMED_NEW_NAME {
- sendNameEvent()
+ w.sendEvent(fullname, "", watch.names[name]&mask)
}
if raw.Action == windows.FILE_ACTION_REMOVED {
- w.sendEvent(fullname, watch.names[name]&sysFSIGNORED)
+ w.sendEvent(fullname, "", watch.names[name]&sysFSIGNORED)
delete(watch.names, name)
}
- w.sendEvent(fullname, watch.mask&w.toFSnotifyFlags(raw.Action))
+ if watch.rename != "" && raw.Action == windows.FILE_ACTION_RENAMED_NEW_NAME {
+ w.sendEvent(fullname, filepath.Join(watch.path, watch.rename), watch.mask&w.toFSnotifyFlags(raw.Action))
+ } else {
+ w.sendEvent(fullname, "", watch.mask&w.toFSnotifyFlags(raw.Action))
+ }
+
if raw.Action == windows.FILE_ACTION_RENAMED_NEW_NAME {
- fullname = filepath.Join(watch.path, watch.rename)
- sendNameEvent()
+ w.sendEvent(filepath.Join(watch.path, watch.rename), "", watch.names[name]&mask)
}
// Move to the next event in the buffer
@@ -787,8 +635,7 @@ func (w *Watcher) readEvents() {
// Error!
if offset >= n {
//lint:ignore ST1005 Windows should be capitalized
- w.sendError(errors.New(
- "Windows system assumed buffer larger than it is, events have likely been missed"))
+ w.sendError(errors.New("Windows system assumed buffer larger than it is, events have likely been missed"))
break
}
}
@@ -799,7 +646,7 @@ func (w *Watcher) readEvents() {
}
}
-func (w *Watcher) toWindowsFlags(mask uint64) uint32 {
+func (w *readDirChangesW) toWindowsFlags(mask uint64) uint32 {
var m uint32
if mask&sysFSMODIFY != 0 {
m |= windows.FILE_NOTIFY_CHANGE_LAST_WRITE
@@ -810,7 +657,7 @@ func (w *Watcher) toWindowsFlags(mask uint64) uint32 {
return m
}
-func (w *Watcher) toFSnotifyFlags(action uint32) uint64 {
+func (w *readDirChangesW) toFSnotifyFlags(action uint32) uint64 {
switch action {
case windows.FILE_ACTION_ADDED:
return sysFSCREATE
@@ -825,3 +672,11 @@ func (w *Watcher) toFSnotifyFlags(action uint32) uint64 {
}
return 0
}
+
+func (w *readDirChangesW) xSupports(op Op) bool {
+ if op.Has(xUnportableOpen) || op.Has(xUnportableRead) ||
+ op.Has(xUnportableCloseWrite) || op.Has(xUnportableCloseRead) {
+ return false
+ }
+ return true
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/vendor/github.com/fsnotify/fsnotify/fsnotify.go
index 24c99cc499..0760efe916 100644
--- a/vendor/github.com/fsnotify/fsnotify/fsnotify.go
+++ b/vendor/github.com/fsnotify/fsnotify/fsnotify.go
@@ -3,19 +3,146 @@
//
// Currently supported systems:
//
-// Linux 2.6.32+ via inotify
-// BSD, macOS via kqueue
-// Windows via ReadDirectoryChangesW
-// illumos via FEN
+// - Linux via inotify
+// - BSD, macOS via kqueue
+// - Windows via ReadDirectoryChangesW
+// - illumos via FEN
+//
+// # FSNOTIFY_DEBUG
+//
+// Set the FSNOTIFY_DEBUG environment variable to "1" to print debug messages to
+// stderr. This can be useful to track down some problems, especially in cases
+// where fsnotify is used as an indirect dependency.
+//
+// Every event will be printed as soon as there's something useful to print,
+// with as little processing from fsnotify.
+//
+// Example output:
+//
+// FSNOTIFY_DEBUG: 11:34:23.633087586 256:IN_CREATE → "/tmp/file-1"
+// FSNOTIFY_DEBUG: 11:34:23.633202319 4:IN_ATTRIB → "/tmp/file-1"
+// FSNOTIFY_DEBUG: 11:34:28.989728764 512:IN_DELETE → "/tmp/file-1"
package fsnotify
import (
"errors"
"fmt"
+ "os"
"path/filepath"
"strings"
)
+// Watcher watches a set of paths, delivering events on a channel.
+//
+// A watcher should not be copied (e.g. pass it by pointer, rather than by
+// value).
+//
+// # Linux notes
+//
+// When a file is removed a Remove event won't be emitted until all file
+// descriptors are closed, and deletes will always emit a Chmod. For example:
+//
+// fp := os.Open("file")
+// os.Remove("file") // Triggers Chmod
+// fp.Close() // Triggers Remove
+//
+// This is the event that inotify sends, so not much can be changed about this.
+//
+// The fs.inotify.max_user_watches sysctl variable specifies the upper limit
+// for the number of watches per user, and fs.inotify.max_user_instances
+// specifies the maximum number of inotify instances per user. Every Watcher you
+// create is an "instance", and every path you add is a "watch".
+//
+// These are also exposed in /proc as /proc/sys/fs/inotify/max_user_watches and
+// /proc/sys/fs/inotify/max_user_instances
+//
+// To increase them you can use sysctl or write the value to the /proc file:
+//
+// # Default values on Linux 5.18
+// sysctl fs.inotify.max_user_watches=124983
+// sysctl fs.inotify.max_user_instances=128
+//
+// To make the changes persist on reboot edit /etc/sysctl.conf or
+// /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check
+// your distro's documentation):
+//
+// fs.inotify.max_user_watches=124983
+// fs.inotify.max_user_instances=128
+//
+// Reaching the limit will result in a "no space left on device" or "too many open
+// files" error.
+//
+// # kqueue notes (macOS, BSD)
+//
+// kqueue requires opening a file descriptor for every file that's being watched;
+// so if you're watching a directory with five files then that's six file
+// descriptors. You will run in to your system's "max open files" limit faster on
+// these platforms.
+//
+// The sysctl variables kern.maxfiles and kern.maxfilesperproc can be used to
+// control the maximum number of open files, as well as /etc/login.conf on BSD
+// systems.
+//
+// # Windows notes
+//
+// Paths can be added as "C:\\path\\to\\dir", but forward slashes
+// ("C:/path/to/dir") will also work.
+//
+// When a watched directory is removed it will always send an event for the
+// directory itself, but may not send events for all files in that directory.
+// Sometimes it will send events for all files, sometimes it will send no
+// events, and often only for some files.
+//
+// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest
+// value that is guaranteed to work with SMB filesystems. If you have many
+// events in quick succession this may not be enough, and you will have to use
+// [WithBufferSize] to increase the value.
+type Watcher struct {
+ b backend
+
+ // Events sends the filesystem change events.
+ //
+ // fsnotify can send the following events; a "path" here can refer to a
+ // file, directory, symbolic link, or special file like a FIFO.
+ //
+ // fsnotify.Create A new path was created; this may be followed by one
+ // or more Write events if data also gets written to a
+ // file.
+ //
+ // fsnotify.Remove A path was removed.
+ //
+ // fsnotify.Rename A path was renamed. A rename is always sent with the
+ // old path as Event.Name, and a Create event will be
+ // sent with the new name. Renames are only sent for
+ // paths that are currently watched; e.g. moving an
+ // unmonitored file into a monitored directory will
+ // show up as just a Create. Similarly, renaming a file
+ // to outside a monitored directory will show up as
+ // only a Rename.
+ //
+ // fsnotify.Write A file or named pipe was written to. A Truncate will
+ // also trigger a Write. A single "write action"
+ // initiated by the user may show up as one or multiple
+ // writes, depending on when the system syncs things to
+ // disk. For example when compiling a large Go program
+ // you may get hundreds of Write events, and you may
+ // want to wait until you've stopped receiving them
+ // (see the dedup example in cmd/fsnotify).
+ //
+ // Some systems may send Write event for directories
+ // when the directory content changes.
+ //
+ // fsnotify.Chmod Attributes were changed. On Linux this is also sent
+ // when a file is removed (or more accurately, when a
+ // link to an inode is removed). On kqueue it's sent
+ // when a file is truncated. On Windows it's never
+ // sent.
+ Events chan Event
+
+ // Errors sends any errors.
+ Errors chan error
+}
+
// Event represents a file system notification.
type Event struct {
// Path to the file or directory.
@@ -30,6 +157,16 @@ type Event struct {
// This is a bitmask and some systems may send multiple operations at once.
// Use the Event.Has() method instead of comparing with ==.
Op Op
+
+ // Create events will have this set to the old path if it's a rename. This
+ // only works when both the source and destination are watched. It's not
+ // reliable when watching individual files, only directories.
+ //
+ // For example "mv /tmp/file /tmp/rename" will emit:
+ //
+ // Event{Op: Rename, Name: "/tmp/file"}
+ // Event{Op: Create, Name: "/tmp/rename", RenamedFrom: "/tmp/file"}
+ renamedFrom string
}
// Op describes a set of file operations.
@@ -50,7 +187,7 @@ const (
// example "remove to trash" is often a rename).
Remove
- // The path was renamed to something else; any watched on it will be
+ // The path was renamed to something else; any watches on it will be
// removed.
Rename
@@ -60,15 +197,155 @@ const (
// get triggered very frequently by some software. For example, Spotlight
// indexing on macOS, anti-virus software, backup software, etc.
Chmod
+
+ // File descriptor was opened.
+ //
+ // Only works on Linux and FreeBSD.
+ xUnportableOpen
+
+ // File was read from.
+ //
+ // Only works on Linux and FreeBSD.
+ xUnportableRead
+
+ // File opened for writing was closed.
+ //
+ // Only works on Linux and FreeBSD.
+ //
+ // The advantage of using this over Write is that it's more reliable than
+ // waiting for Write events to stop. It's also faster (if you're not
+ // listening to Write events): copying a file of a few GB can easily
+ // generate tens of thousands of Write events in a short span of time.
+ xUnportableCloseWrite
+
+ // File opened for reading was closed.
+ //
+ // Only works on Linux and FreeBSD.
+ xUnportableCloseRead
)
-// Common errors that can be reported.
var (
+ // ErrNonExistentWatch is used when Remove() is called on a path that's not
+ // added.
ErrNonExistentWatch = errors.New("fsnotify: can't remove non-existent watch")
- ErrEventOverflow = errors.New("fsnotify: queue or buffer overflow")
- ErrClosed = errors.New("fsnotify: watcher already closed")
+
+ // ErrClosed is used when trying to operate on a closed Watcher.
+ ErrClosed = errors.New("fsnotify: watcher already closed")
+
+ // ErrEventOverflow is reported from the Errors channel when there are too
+ // many events:
+ //
+ // - inotify: inotify returns IN_Q_OVERFLOW – because there are too
+ // many queued events (the fs.inotify.max_queued_events
+ // sysctl can be used to increase this).
+ // - windows: The buffer size is too small; WithBufferSize() can be used to increase it.
+ // - kqueue, fen: Not used.
+ ErrEventOverflow = errors.New("fsnotify: queue or buffer overflow")
+
+ // ErrUnsupported is returned by AddWith() when WithOps() specified an
+ // Unportable event that's not supported on this platform.
+ xErrUnsupported = errors.New("fsnotify: not supported with this backend")
)
+// NewWatcher creates a new Watcher.
+func NewWatcher() (*Watcher, error) {
+ ev, errs := make(chan Event), make(chan error)
+ b, err := newBackend(ev, errs)
+ if err != nil {
+ return nil, err
+ }
+ return &Watcher{b: b, Events: ev, Errors: errs}, nil
+}
+
+// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events
+// channel.
+//
+// The main use case for this is situations with a very large number of events
+// where the kernel buffer size can't be increased (e.g. due to lack of
+// permissions). An unbuffered Watcher will perform better for almost all use
+// cases, and whenever possible you will be better off increasing the kernel
+// buffers instead of adding a large userspace buffer.
+func NewBufferedWatcher(sz uint) (*Watcher, error) {
+ ev, errs := make(chan Event), make(chan error)
+ b, err := newBufferedBackend(sz, ev, errs)
+ if err != nil {
+ return nil, err
+ }
+ return &Watcher{b: b, Events: ev, Errors: errs}, nil
+}
+
+// Add starts monitoring the path for changes.
+//
+// A path can only be watched once; watching it more than once is a no-op and will
+// not return an error. Paths that do not yet exist on the filesystem cannot be
+// watched.
+//
+// A watch will be automatically removed if the watched path is deleted or
+// renamed. The exception is the Windows backend, which doesn't remove the
+// watcher on renames.
+//
+// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
+// filesystems (/proc, /sys, etc.) generally don't work.
+//
+// Returns [ErrClosed] if [Watcher.Close] was called.
+//
+// See [Watcher.AddWith] for a version that allows adding options.
+//
+// # Watching directories
+//
+// All files in a directory are monitored, including new files that are created
+// after the watcher is started. Subdirectories are not watched (i.e. it's
+// non-recursive).
+//
+// # Watching files
+//
+// Watching individual files (rather than directories) is generally not
+// recommended as many programs (especially editors) update files atomically: it
+// will write to a temporary file which is then moved to destination,
+// overwriting the original (or some variant thereof). The watcher on the
+// original file is now lost, as that no longer exists.
+//
+// The upshot of this is that a power failure or crash won't leave a
+// half-written file.
+//
+// Watch the parent directory and use Event.Name to filter out files you're not
+// interested in. There is an example of this in cmd/fsnotify/file.go.
+func (w *Watcher) Add(path string) error { return w.b.Add(path) }
+
+// AddWith is like [Watcher.Add], but allows adding options. When using Add()
+// the defaults described below are used.
+//
+// Possible options are:
+//
+// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
+// other platforms. The default is 64K (65536 bytes).
+func (w *Watcher) AddWith(path string, opts ...addOpt) error { return w.b.AddWith(path, opts...) }
+
+// Remove stops monitoring the path for changes.
+//
+// Directories are always removed non-recursively. For example, if you added
+// /tmp/dir and /tmp/dir/subdir then you will need to remove both.
+//
+// Removing a path that has not yet been added returns [ErrNonExistentWatch].
+//
+// Returns nil if [Watcher.Close] was called.
+func (w *Watcher) Remove(path string) error { return w.b.Remove(path) }
+
+// Close removes all watches and closes the Events channel.
+func (w *Watcher) Close() error { return w.b.Close() }
+
+// WatchList returns all paths explicitly added with [Watcher.Add] (and are not
+// yet removed).
+//
+// Returns nil if [Watcher.Close] was called.
+func (w *Watcher) WatchList() []string { return w.b.WatchList() }
+
+// Supports reports if all the listed operations are supported by this platform.
+//
+// Create, Write, Remove, Rename, and Chmod are always supported. It can only
+// return false for an Op starting with Unportable.
+func (w *Watcher) xSupports(op Op) bool { return w.b.xSupports(op) }
+
func (o Op) String() string {
var b strings.Builder
if o.Has(Create) {
@@ -80,6 +357,18 @@ func (o Op) String() string {
if o.Has(Write) {
b.WriteString("|WRITE")
}
+ if o.Has(xUnportableOpen) {
+ b.WriteString("|OPEN")
+ }
+ if o.Has(xUnportableRead) {
+ b.WriteString("|READ")
+ }
+ if o.Has(xUnportableCloseWrite) {
+ b.WriteString("|CLOSE_WRITE")
+ }
+ if o.Has(xUnportableCloseRead) {
+ b.WriteString("|CLOSE_READ")
+ }
if o.Has(Rename) {
b.WriteString("|RENAME")
}
@@ -100,24 +389,48 @@ func (e Event) Has(op Op) bool { return e.Op.Has(op) }
// String returns a string representation of the event with their path.
func (e Event) String() string {
+ if e.renamedFrom != "" {
+ return fmt.Sprintf("%-13s %q ← %q", e.Op.String(), e.Name, e.renamedFrom)
+ }
return fmt.Sprintf("%-13s %q", e.Op.String(), e.Name)
}
type (
+ backend interface {
+ Add(string) error
+ AddWith(string, ...addOpt) error
+ Remove(string) error
+ WatchList() []string
+ Close() error
+ xSupports(Op) bool
+ }
addOpt func(opt *withOpts)
withOpts struct {
- bufsize int
+ bufsize int
+ op Op
+ noFollow bool
+ sendCreate bool
}
)
+var debug = func() bool {
+ // Check for exactly "1" (rather than mere existence) so we can add
+ // options/flags in the future. I don't know if we ever want that, but it's
+ // nice to leave the option open.
+ return os.Getenv("FSNOTIFY_DEBUG") == "1"
+}()
+
var defaultOpts = withOpts{
bufsize: 65536, // 64K
+ op: Create | Write | Remove | Rename | Chmod,
}
func getOptions(opts ...addOpt) withOpts {
with := defaultOpts
for _, o := range opts {
- o(&with)
+ if o != nil {
+ o(&with)
+ }
}
return with
}
@@ -136,9 +449,44 @@ func WithBufferSize(bytes int) addOpt {
return func(opt *withOpts) { opt.bufsize = bytes }
}
+// WithOps sets which operations to listen for. The default is [Create],
+// [Write], [Remove], [Rename], and [Chmod].
+//
+// Excluding operations you're not interested in can save quite a bit of CPU
+// time; in some use cases there may be hundreds of thousands of useless Write
+// or Chmod operations per second.
+//
+// This can also be used to add unportable operations not supported by all
+// platforms; unportable operations all start with "Unportable":
+// [UnportableOpen], [UnportableRead], [UnportableCloseWrite], and
+// [UnportableCloseRead].
+//
+// AddWith returns an error when using an unportable operation that's not
+// supported. Use [Watcher.Support] to check for support.
+func withOps(op Op) addOpt {
+ return func(opt *withOpts) { opt.op = op }
+}
+
+// WithNoFollow disables following symlinks, so the symlinks themselves are
+// watched.
+func withNoFollow() addOpt {
+ return func(opt *withOpts) { opt.noFollow = true }
+}
+
+// "Internal" option for recursive watches on inotify.
+func withCreate() addOpt {
+ return func(opt *withOpts) { opt.sendCreate = true }
+}
+
+var enableRecurse = false
+
// Check if this path is recursive (ends with "/..." or "\..."), and return the
// path with the /... stripped.
func recursivePath(path string) (string, bool) {
+ path = filepath.Clean(path)
+ if !enableRecurse { // Only enabled in tests for now.
+ return path, false
+ }
if filepath.Base(path) == "..." {
return filepath.Dir(path), true
}
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/darwin.go b/vendor/github.com/fsnotify/fsnotify/internal/darwin.go
new file mode 100644
index 0000000000..b0eab10090
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/darwin.go
@@ -0,0 +1,39 @@
+//go:build darwin
+
+package internal
+
+import (
+ "syscall"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ SyscallEACCES = syscall.EACCES
+ UnixEACCES = unix.EACCES
+)
+
+var maxfiles uint64
+
+// Go 1.19 will do this automatically: https://go-review.googlesource.com/c/go/+/393354/
+func SetRlimit() {
+ var l syscall.Rlimit
+ err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &l)
+ if err == nil && l.Cur != l.Max {
+ l.Cur = l.Max
+ syscall.Setrlimit(syscall.RLIMIT_NOFILE, &l)
+ }
+ maxfiles = l.Cur
+
+ if n, err := syscall.SysctlUint32("kern.maxfiles"); err == nil && uint64(n) < maxfiles {
+ maxfiles = uint64(n)
+ }
+
+ if n, err := syscall.SysctlUint32("kern.maxfilesperproc"); err == nil && uint64(n) < maxfiles {
+ maxfiles = uint64(n)
+ }
+}
+
+func Maxfiles() uint64 { return maxfiles }
+func Mkfifo(path string, mode uint32) error { return unix.Mkfifo(path, mode) }
+func Mknod(path string, mode uint32, dev int) error { return unix.Mknod(path, mode, dev) }
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/debug_darwin.go b/vendor/github.com/fsnotify/fsnotify/internal/debug_darwin.go
new file mode 100644
index 0000000000..928319fb09
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/debug_darwin.go
@@ -0,0 +1,57 @@
+package internal
+
+import "golang.org/x/sys/unix"
+
+var names = []struct {
+ n string
+ m uint32
+}{
+ {"NOTE_ABSOLUTE", unix.NOTE_ABSOLUTE},
+ {"NOTE_ATTRIB", unix.NOTE_ATTRIB},
+ {"NOTE_BACKGROUND", unix.NOTE_BACKGROUND},
+ {"NOTE_CHILD", unix.NOTE_CHILD},
+ {"NOTE_CRITICAL", unix.NOTE_CRITICAL},
+ {"NOTE_DELETE", unix.NOTE_DELETE},
+ {"NOTE_EXEC", unix.NOTE_EXEC},
+ {"NOTE_EXIT", unix.NOTE_EXIT},
+ {"NOTE_EXITSTATUS", unix.NOTE_EXITSTATUS},
+ {"NOTE_EXIT_CSERROR", unix.NOTE_EXIT_CSERROR},
+ {"NOTE_EXIT_DECRYPTFAIL", unix.NOTE_EXIT_DECRYPTFAIL},
+ {"NOTE_EXIT_DETAIL", unix.NOTE_EXIT_DETAIL},
+ {"NOTE_EXIT_DETAIL_MASK", unix.NOTE_EXIT_DETAIL_MASK},
+ {"NOTE_EXIT_MEMORY", unix.NOTE_EXIT_MEMORY},
+ {"NOTE_EXIT_REPARENTED", unix.NOTE_EXIT_REPARENTED},
+ {"NOTE_EXTEND", unix.NOTE_EXTEND},
+ {"NOTE_FFAND", unix.NOTE_FFAND},
+ {"NOTE_FFCOPY", unix.NOTE_FFCOPY},
+ {"NOTE_FFCTRLMASK", unix.NOTE_FFCTRLMASK},
+ {"NOTE_FFLAGSMASK", unix.NOTE_FFLAGSMASK},
+ {"NOTE_FFNOP", unix.NOTE_FFNOP},
+ {"NOTE_FFOR", unix.NOTE_FFOR},
+ {"NOTE_FORK", unix.NOTE_FORK},
+ {"NOTE_FUNLOCK", unix.NOTE_FUNLOCK},
+ {"NOTE_LEEWAY", unix.NOTE_LEEWAY},
+ {"NOTE_LINK", unix.NOTE_LINK},
+ {"NOTE_LOWAT", unix.NOTE_LOWAT},
+ {"NOTE_MACHTIME", unix.NOTE_MACHTIME},
+ {"NOTE_MACH_CONTINUOUS_TIME", unix.NOTE_MACH_CONTINUOUS_TIME},
+ {"NOTE_NONE", unix.NOTE_NONE},
+ {"NOTE_NSECONDS", unix.NOTE_NSECONDS},
+ {"NOTE_OOB", unix.NOTE_OOB},
+ //{"NOTE_PCTRLMASK", unix.NOTE_PCTRLMASK}, -0x100000 (?!)
+ {"NOTE_PDATAMASK", unix.NOTE_PDATAMASK},
+ {"NOTE_REAP", unix.NOTE_REAP},
+ {"NOTE_RENAME", unix.NOTE_RENAME},
+ {"NOTE_REVOKE", unix.NOTE_REVOKE},
+ {"NOTE_SECONDS", unix.NOTE_SECONDS},
+ {"NOTE_SIGNAL", unix.NOTE_SIGNAL},
+ {"NOTE_TRACK", unix.NOTE_TRACK},
+ {"NOTE_TRACKERR", unix.NOTE_TRACKERR},
+ {"NOTE_TRIGGER", unix.NOTE_TRIGGER},
+ {"NOTE_USECONDS", unix.NOTE_USECONDS},
+ {"NOTE_VM_ERROR", unix.NOTE_VM_ERROR},
+ {"NOTE_VM_PRESSURE", unix.NOTE_VM_PRESSURE},
+ {"NOTE_VM_PRESSURE_SUDDEN_TERMINATE", unix.NOTE_VM_PRESSURE_SUDDEN_TERMINATE},
+ {"NOTE_VM_PRESSURE_TERMINATE", unix.NOTE_VM_PRESSURE_TERMINATE},
+ {"NOTE_WRITE", unix.NOTE_WRITE},
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/debug_dragonfly.go b/vendor/github.com/fsnotify/fsnotify/internal/debug_dragonfly.go
new file mode 100644
index 0000000000..3186b0c349
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/debug_dragonfly.go
@@ -0,0 +1,33 @@
+package internal
+
+import "golang.org/x/sys/unix"
+
+var names = []struct {
+ n string
+ m uint32
+}{
+ {"NOTE_ATTRIB", unix.NOTE_ATTRIB},
+ {"NOTE_CHILD", unix.NOTE_CHILD},
+ {"NOTE_DELETE", unix.NOTE_DELETE},
+ {"NOTE_EXEC", unix.NOTE_EXEC},
+ {"NOTE_EXIT", unix.NOTE_EXIT},
+ {"NOTE_EXTEND", unix.NOTE_EXTEND},
+ {"NOTE_FFAND", unix.NOTE_FFAND},
+ {"NOTE_FFCOPY", unix.NOTE_FFCOPY},
+ {"NOTE_FFCTRLMASK", unix.NOTE_FFCTRLMASK},
+ {"NOTE_FFLAGSMASK", unix.NOTE_FFLAGSMASK},
+ {"NOTE_FFNOP", unix.NOTE_FFNOP},
+ {"NOTE_FFOR", unix.NOTE_FFOR},
+ {"NOTE_FORK", unix.NOTE_FORK},
+ {"NOTE_LINK", unix.NOTE_LINK},
+ {"NOTE_LOWAT", unix.NOTE_LOWAT},
+ {"NOTE_OOB", unix.NOTE_OOB},
+ {"NOTE_PCTRLMASK", unix.NOTE_PCTRLMASK},
+ {"NOTE_PDATAMASK", unix.NOTE_PDATAMASK},
+ {"NOTE_RENAME", unix.NOTE_RENAME},
+ {"NOTE_REVOKE", unix.NOTE_REVOKE},
+ {"NOTE_TRACK", unix.NOTE_TRACK},
+ {"NOTE_TRACKERR", unix.NOTE_TRACKERR},
+ {"NOTE_TRIGGER", unix.NOTE_TRIGGER},
+ {"NOTE_WRITE", unix.NOTE_WRITE},
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/debug_freebsd.go b/vendor/github.com/fsnotify/fsnotify/internal/debug_freebsd.go
new file mode 100644
index 0000000000..f69fdb930f
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/debug_freebsd.go
@@ -0,0 +1,42 @@
+package internal
+
+import "golang.org/x/sys/unix"
+
+var names = []struct {
+ n string
+ m uint32
+}{
+ {"NOTE_ABSTIME", unix.NOTE_ABSTIME},
+ {"NOTE_ATTRIB", unix.NOTE_ATTRIB},
+ {"NOTE_CHILD", unix.NOTE_CHILD},
+ {"NOTE_CLOSE", unix.NOTE_CLOSE},
+ {"NOTE_CLOSE_WRITE", unix.NOTE_CLOSE_WRITE},
+ {"NOTE_DELETE", unix.NOTE_DELETE},
+ {"NOTE_EXEC", unix.NOTE_EXEC},
+ {"NOTE_EXIT", unix.NOTE_EXIT},
+ {"NOTE_EXTEND", unix.NOTE_EXTEND},
+ {"NOTE_FFAND", unix.NOTE_FFAND},
+ {"NOTE_FFCOPY", unix.NOTE_FFCOPY},
+ {"NOTE_FFCTRLMASK", unix.NOTE_FFCTRLMASK},
+ {"NOTE_FFLAGSMASK", unix.NOTE_FFLAGSMASK},
+ {"NOTE_FFNOP", unix.NOTE_FFNOP},
+ {"NOTE_FFOR", unix.NOTE_FFOR},
+ {"NOTE_FILE_POLL", unix.NOTE_FILE_POLL},
+ {"NOTE_FORK", unix.NOTE_FORK},
+ {"NOTE_LINK", unix.NOTE_LINK},
+ {"NOTE_LOWAT", unix.NOTE_LOWAT},
+ {"NOTE_MSECONDS", unix.NOTE_MSECONDS},
+ {"NOTE_NSECONDS", unix.NOTE_NSECONDS},
+ {"NOTE_OPEN", unix.NOTE_OPEN},
+ {"NOTE_PCTRLMASK", unix.NOTE_PCTRLMASK},
+ {"NOTE_PDATAMASK", unix.NOTE_PDATAMASK},
+ {"NOTE_READ", unix.NOTE_READ},
+ {"NOTE_RENAME", unix.NOTE_RENAME},
+ {"NOTE_REVOKE", unix.NOTE_REVOKE},
+ {"NOTE_SECONDS", unix.NOTE_SECONDS},
+ {"NOTE_TRACK", unix.NOTE_TRACK},
+ {"NOTE_TRACKERR", unix.NOTE_TRACKERR},
+ {"NOTE_TRIGGER", unix.NOTE_TRIGGER},
+ {"NOTE_USECONDS", unix.NOTE_USECONDS},
+ {"NOTE_WRITE", unix.NOTE_WRITE},
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/debug_kqueue.go b/vendor/github.com/fsnotify/fsnotify/internal/debug_kqueue.go
new file mode 100644
index 0000000000..607e683bd7
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/debug_kqueue.go
@@ -0,0 +1,32 @@
+//go:build freebsd || openbsd || netbsd || dragonfly || darwin
+
+package internal
+
+import (
+ "fmt"
+ "os"
+ "strings"
+ "time"
+
+ "golang.org/x/sys/unix"
+)
+
+func Debug(name string, kevent *unix.Kevent_t) {
+ mask := uint32(kevent.Fflags)
+
+ var (
+ l []string
+ unknown = mask
+ )
+ for _, n := range names {
+ if mask&n.m == n.m {
+ l = append(l, n.n)
+ unknown ^= n.m
+ }
+ }
+ if unknown > 0 {
+ l = append(l, fmt.Sprintf("0x%x", unknown))
+ }
+ fmt.Fprintf(os.Stderr, "FSNOTIFY_DEBUG: %s %10d:%-60s → %q\n",
+ time.Now().Format("15:04:05.000000000"), mask, strings.Join(l, " | "), name)
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/debug_linux.go b/vendor/github.com/fsnotify/fsnotify/internal/debug_linux.go
new file mode 100644
index 0000000000..35c734be43
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/debug_linux.go
@@ -0,0 +1,56 @@
+package internal
+
+import (
+ "fmt"
+ "os"
+ "strings"
+ "time"
+
+ "golang.org/x/sys/unix"
+)
+
+func Debug(name string, mask, cookie uint32) {
+ names := []struct {
+ n string
+ m uint32
+ }{
+ {"IN_ACCESS", unix.IN_ACCESS},
+ {"IN_ATTRIB", unix.IN_ATTRIB},
+ {"IN_CLOSE", unix.IN_CLOSE},
+ {"IN_CLOSE_NOWRITE", unix.IN_CLOSE_NOWRITE},
+ {"IN_CLOSE_WRITE", unix.IN_CLOSE_WRITE},
+ {"IN_CREATE", unix.IN_CREATE},
+ {"IN_DELETE", unix.IN_DELETE},
+ {"IN_DELETE_SELF", unix.IN_DELETE_SELF},
+ {"IN_IGNORED", unix.IN_IGNORED},
+ {"IN_ISDIR", unix.IN_ISDIR},
+ {"IN_MODIFY", unix.IN_MODIFY},
+ {"IN_MOVE", unix.IN_MOVE},
+ {"IN_MOVED_FROM", unix.IN_MOVED_FROM},
+ {"IN_MOVED_TO", unix.IN_MOVED_TO},
+ {"IN_MOVE_SELF", unix.IN_MOVE_SELF},
+ {"IN_OPEN", unix.IN_OPEN},
+ {"IN_Q_OVERFLOW", unix.IN_Q_OVERFLOW},
+ {"IN_UNMOUNT", unix.IN_UNMOUNT},
+ }
+
+ var (
+ l []string
+ unknown = mask
+ )
+ for _, n := range names {
+ if mask&n.m == n.m {
+ l = append(l, n.n)
+ unknown ^= n.m
+ }
+ }
+ if unknown > 0 {
+ l = append(l, fmt.Sprintf("0x%x", unknown))
+ }
+ var c string
+ if cookie > 0 {
+ c = fmt.Sprintf("(cookie: %d) ", cookie)
+ }
+ fmt.Fprintf(os.Stderr, "FSNOTIFY_DEBUG: %s %-30s → %s%q\n",
+ time.Now().Format("15:04:05.000000000"), strings.Join(l, "|"), c, name)
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/debug_netbsd.go b/vendor/github.com/fsnotify/fsnotify/internal/debug_netbsd.go
new file mode 100644
index 0000000000..e5b3b6f694
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/debug_netbsd.go
@@ -0,0 +1,25 @@
+package internal
+
+import "golang.org/x/sys/unix"
+
+var names = []struct {
+ n string
+ m uint32
+}{
+ {"NOTE_ATTRIB", unix.NOTE_ATTRIB},
+ {"NOTE_CHILD", unix.NOTE_CHILD},
+ {"NOTE_DELETE", unix.NOTE_DELETE},
+ {"NOTE_EXEC", unix.NOTE_EXEC},
+ {"NOTE_EXIT", unix.NOTE_EXIT},
+ {"NOTE_EXTEND", unix.NOTE_EXTEND},
+ {"NOTE_FORK", unix.NOTE_FORK},
+ {"NOTE_LINK", unix.NOTE_LINK},
+ {"NOTE_LOWAT", unix.NOTE_LOWAT},
+ {"NOTE_PCTRLMASK", unix.NOTE_PCTRLMASK},
+ {"NOTE_PDATAMASK", unix.NOTE_PDATAMASK},
+ {"NOTE_RENAME", unix.NOTE_RENAME},
+ {"NOTE_REVOKE", unix.NOTE_REVOKE},
+ {"NOTE_TRACK", unix.NOTE_TRACK},
+ {"NOTE_TRACKERR", unix.NOTE_TRACKERR},
+ {"NOTE_WRITE", unix.NOTE_WRITE},
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/debug_openbsd.go b/vendor/github.com/fsnotify/fsnotify/internal/debug_openbsd.go
new file mode 100644
index 0000000000..1dd455bc5a
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/debug_openbsd.go
@@ -0,0 +1,28 @@
+package internal
+
+import "golang.org/x/sys/unix"
+
+var names = []struct {
+ n string
+ m uint32
+}{
+ {"NOTE_ATTRIB", unix.NOTE_ATTRIB},
+ // {"NOTE_CHANGE", unix.NOTE_CHANGE}, // Not on 386?
+ {"NOTE_CHILD", unix.NOTE_CHILD},
+ {"NOTE_DELETE", unix.NOTE_DELETE},
+ {"NOTE_EOF", unix.NOTE_EOF},
+ {"NOTE_EXEC", unix.NOTE_EXEC},
+ {"NOTE_EXIT", unix.NOTE_EXIT},
+ {"NOTE_EXTEND", unix.NOTE_EXTEND},
+ {"NOTE_FORK", unix.NOTE_FORK},
+ {"NOTE_LINK", unix.NOTE_LINK},
+ {"NOTE_LOWAT", unix.NOTE_LOWAT},
+ {"NOTE_PCTRLMASK", unix.NOTE_PCTRLMASK},
+ {"NOTE_PDATAMASK", unix.NOTE_PDATAMASK},
+ {"NOTE_RENAME", unix.NOTE_RENAME},
+ {"NOTE_REVOKE", unix.NOTE_REVOKE},
+ {"NOTE_TRACK", unix.NOTE_TRACK},
+ {"NOTE_TRACKERR", unix.NOTE_TRACKERR},
+ {"NOTE_TRUNCATE", unix.NOTE_TRUNCATE},
+ {"NOTE_WRITE", unix.NOTE_WRITE},
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/debug_solaris.go b/vendor/github.com/fsnotify/fsnotify/internal/debug_solaris.go
new file mode 100644
index 0000000000..f1b2e73bd5
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/debug_solaris.go
@@ -0,0 +1,45 @@
+package internal
+
+import (
+ "fmt"
+ "os"
+ "strings"
+ "time"
+
+ "golang.org/x/sys/unix"
+)
+
+func Debug(name string, mask int32) {
+ names := []struct {
+ n string
+ m int32
+ }{
+ {"FILE_ACCESS", unix.FILE_ACCESS},
+ {"FILE_MODIFIED", unix.FILE_MODIFIED},
+ {"FILE_ATTRIB", unix.FILE_ATTRIB},
+ {"FILE_TRUNC", unix.FILE_TRUNC},
+ {"FILE_NOFOLLOW", unix.FILE_NOFOLLOW},
+ {"FILE_DELETE", unix.FILE_DELETE},
+ {"FILE_RENAME_TO", unix.FILE_RENAME_TO},
+ {"FILE_RENAME_FROM", unix.FILE_RENAME_FROM},
+ {"UNMOUNTED", unix.UNMOUNTED},
+ {"MOUNTEDOVER", unix.MOUNTEDOVER},
+ {"FILE_EXCEPTION", unix.FILE_EXCEPTION},
+ }
+
+ var (
+ l []string
+ unknown = mask
+ )
+ for _, n := range names {
+ if mask&n.m == n.m {
+ l = append(l, n.n)
+ unknown ^= n.m
+ }
+ }
+ if unknown > 0 {
+ l = append(l, fmt.Sprintf("0x%x", unknown))
+ }
+ fmt.Fprintf(os.Stderr, "FSNOTIFY_DEBUG: %s %10d:%-30s → %q\n",
+ time.Now().Format("15:04:05.000000000"), mask, strings.Join(l, " | "), name)
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/debug_windows.go b/vendor/github.com/fsnotify/fsnotify/internal/debug_windows.go
new file mode 100644
index 0000000000..52bf4ce53b
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/debug_windows.go
@@ -0,0 +1,40 @@
+package internal
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+ "time"
+
+ "golang.org/x/sys/windows"
+)
+
+func Debug(name string, mask uint32) {
+ names := []struct {
+ n string
+ m uint32
+ }{
+ {"FILE_ACTION_ADDED", windows.FILE_ACTION_ADDED},
+ {"FILE_ACTION_REMOVED", windows.FILE_ACTION_REMOVED},
+ {"FILE_ACTION_MODIFIED", windows.FILE_ACTION_MODIFIED},
+ {"FILE_ACTION_RENAMED_OLD_NAME", windows.FILE_ACTION_RENAMED_OLD_NAME},
+ {"FILE_ACTION_RENAMED_NEW_NAME", windows.FILE_ACTION_RENAMED_NEW_NAME},
+ }
+
+ var (
+ l []string
+ unknown = mask
+ )
+ for _, n := range names {
+ if mask&n.m == n.m {
+ l = append(l, n.n)
+ unknown ^= n.m
+ }
+ }
+ if unknown > 0 {
+ l = append(l, fmt.Sprintf("0x%x", unknown))
+ }
+ fmt.Fprintf(os.Stderr, "FSNOTIFY_DEBUG: %s %-65s → %q\n",
+ time.Now().Format("15:04:05.000000000"), strings.Join(l, " | "), filepath.ToSlash(name))
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/freebsd.go b/vendor/github.com/fsnotify/fsnotify/internal/freebsd.go
new file mode 100644
index 0000000000..547df1df84
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/freebsd.go
@@ -0,0 +1,31 @@
+//go:build freebsd
+
+package internal
+
+import (
+ "syscall"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ SyscallEACCES = syscall.EACCES
+ UnixEACCES = unix.EACCES
+)
+
+var maxfiles uint64
+
+func SetRlimit() {
+ // Go 1.19 will do this automatically: https://go-review.googlesource.com/c/go/+/393354/
+ var l syscall.Rlimit
+ err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &l)
+ if err == nil && l.Cur != l.Max {
+ l.Cur = l.Max
+ syscall.Setrlimit(syscall.RLIMIT_NOFILE, &l)
+ }
+ maxfiles = uint64(l.Cur)
+}
+
+func Maxfiles() uint64 { return maxfiles }
+func Mkfifo(path string, mode uint32) error { return unix.Mkfifo(path, mode) }
+func Mknod(path string, mode uint32, dev int) error { return unix.Mknod(path, mode, uint64(dev)) }
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/internal.go b/vendor/github.com/fsnotify/fsnotify/internal/internal.go
new file mode 100644
index 0000000000..7daa45e19e
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/internal.go
@@ -0,0 +1,2 @@
+// Package internal contains some helpers.
+package internal
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/unix.go b/vendor/github.com/fsnotify/fsnotify/internal/unix.go
new file mode 100644
index 0000000000..30976ce973
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/unix.go
@@ -0,0 +1,31 @@
+//go:build !windows && !darwin && !freebsd
+
+package internal
+
+import (
+ "syscall"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ SyscallEACCES = syscall.EACCES
+ UnixEACCES = unix.EACCES
+)
+
+var maxfiles uint64
+
+func SetRlimit() {
+ // Go 1.19 will do this automatically: https://go-review.googlesource.com/c/go/+/393354/
+ var l syscall.Rlimit
+ err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &l)
+ if err == nil && l.Cur != l.Max {
+ l.Cur = l.Max
+ syscall.Setrlimit(syscall.RLIMIT_NOFILE, &l)
+ }
+ maxfiles = uint64(l.Cur)
+}
+
+func Maxfiles() uint64 { return maxfiles }
+func Mkfifo(path string, mode uint32) error { return unix.Mkfifo(path, mode) }
+func Mknod(path string, mode uint32, dev int) error { return unix.Mknod(path, mode, dev) }
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/unix2.go b/vendor/github.com/fsnotify/fsnotify/internal/unix2.go
new file mode 100644
index 0000000000..37dfeddc28
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/unix2.go
@@ -0,0 +1,7 @@
+//go:build !windows
+
+package internal
+
+func HasPrivilegesForSymlink() bool {
+ return true
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/internal/windows.go b/vendor/github.com/fsnotify/fsnotify/internal/windows.go
new file mode 100644
index 0000000000..a72c649549
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/internal/windows.go
@@ -0,0 +1,41 @@
+//go:build windows
+
+package internal
+
+import (
+ "errors"
+
+ "golang.org/x/sys/windows"
+)
+
+// Just a dummy.
+var (
+ SyscallEACCES = errors.New("dummy")
+ UnixEACCES = errors.New("dummy")
+)
+
+func SetRlimit() {}
+func Maxfiles() uint64 { return 1<<64 - 1 }
+func Mkfifo(path string, mode uint32) error { return errors.New("no FIFOs on Windows") }
+func Mknod(path string, mode uint32, dev int) error { return errors.New("no device nodes on Windows") }
+
+func HasPrivilegesForSymlink() bool {
+ var sid *windows.SID
+ err := windows.AllocateAndInitializeSid(
+ &windows.SECURITY_NT_AUTHORITY,
+ 2,
+ windows.SECURITY_BUILTIN_DOMAIN_RID,
+ windows.DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ &sid)
+ if err != nil {
+ return false
+ }
+ defer windows.FreeSid(sid)
+ token := windows.Token(0)
+ member, err := token.IsMember(sid)
+ if err != nil {
+ return false
+ }
+ return member || token.IsElevated()
+}
diff --git a/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh b/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh
deleted file mode 100644
index 99012ae653..0000000000
--- a/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh
+++ /dev/null
@@ -1,259 +0,0 @@
-#!/usr/bin/env zsh
-[ "${ZSH_VERSION:-}" = "" ] && echo >&2 "Only works with zsh" && exit 1
-setopt err_exit no_unset pipefail extended_glob
-
-# Simple script to update the godoc comments on all watchers so you don't need
-# to update the same comment 5 times.
-
-watcher=$(</tmp/x
- print -r -- $cmt >>/tmp/x
- tail -n+$(( end + 1 )) $file >>/tmp/x
- mv /tmp/x $file
- done
-}
-
-set-cmt '^type Watcher struct ' $watcher
-set-cmt '^func NewWatcher(' $new
-set-cmt '^func NewBufferedWatcher(' $newbuffered
-set-cmt '^func (w \*Watcher) Add(' $add
-set-cmt '^func (w \*Watcher) AddWith(' $addwith
-set-cmt '^func (w \*Watcher) Remove(' $remove
-set-cmt '^func (w \*Watcher) Close(' $close
-set-cmt '^func (w \*Watcher) WatchList(' $watchlist
-set-cmt '^[[:space:]]*Events *chan Event$' $events
-set-cmt '^[[:space:]]*Errors *chan error$' $errors
diff --git a/vendor/github.com/fsnotify/fsnotify/system_bsd.go b/vendor/github.com/fsnotify/fsnotify/system_bsd.go
index 4322b0b885..f65e8fe3ed 100644
--- a/vendor/github.com/fsnotify/fsnotify/system_bsd.go
+++ b/vendor/github.com/fsnotify/fsnotify/system_bsd.go
@@ -1,5 +1,4 @@
//go:build freebsd || openbsd || netbsd || dragonfly
-// +build freebsd openbsd netbsd dragonfly
package fsnotify
diff --git a/vendor/github.com/fsnotify/fsnotify/system_darwin.go b/vendor/github.com/fsnotify/fsnotify/system_darwin.go
index 5da5ffa78f..a29fc7aab6 100644
--- a/vendor/github.com/fsnotify/fsnotify/system_darwin.go
+++ b/vendor/github.com/fsnotify/fsnotify/system_darwin.go
@@ -1,5 +1,4 @@
//go:build darwin
-// +build darwin
package fsnotify
diff --git a/vendor/github.com/go-git/go-billy/v5/Makefile b/vendor/github.com/go-git/go-billy/v5/Makefile
index 74dad8b491..3c95ddeaac 100644
--- a/vendor/github.com/go-git/go-billy/v5/Makefile
+++ b/vendor/github.com/go-git/go-billy/v5/Makefile
@@ -1,6 +1,7 @@
# Go parameters
GOCMD = go
GOTEST = $(GOCMD) test
+WASIRUN_WRAPPER := $(CURDIR)/scripts/wasirun-wrapper
.PHONY: test
test:
@@ -9,3 +10,9 @@ test:
test-coverage:
echo "" > $(COVERAGE_REPORT); \
$(GOTEST) -coverprofile=$(COVERAGE_REPORT) -coverpkg=./... -covermode=$(COVERAGE_MODE) ./...
+
+.PHONY: wasitest
+wasitest: export GOARCH=wasm
+wasitest: export GOOS=wasip1
+wasitest:
+ $(GOTEST) -exec $(WASIRUN_WRAPPER) ./...
diff --git a/vendor/github.com/go-git/go-billy/v5/fs.go b/vendor/github.com/go-git/go-billy/v5/fs.go
index a9efccdeb2..d86f9d8236 100644
--- a/vendor/github.com/go-git/go-billy/v5/fs.go
+++ b/vendor/github.com/go-git/go-billy/v5/fs.go
@@ -164,6 +164,8 @@ type File interface {
// Name returns the name of the file as presented to Open.
Name() string
io.Writer
+ // TODO: Add io.WriterAt for v6
+ // io.WriterAt
io.Reader
io.ReaderAt
io.Seeker
diff --git a/vendor/github.com/go-git/go-billy/v5/memfs/memory.go b/vendor/github.com/go-git/go-billy/v5/memfs/memory.go
index dab73968b6..6cbd7d08ca 100644
--- a/vendor/github.com/go-git/go-billy/v5/memfs/memory.go
+++ b/vendor/github.com/go-git/go-billy/v5/memfs/memory.go
@@ -9,6 +9,7 @@ import (
"path/filepath"
"sort"
"strings"
+ "syscall"
"time"
"github.com/go-git/go-billy/v5"
@@ -18,16 +19,19 @@ import (
const separator = filepath.Separator
-// Memory a very convenient filesystem based on memory files
+var errNotLink = errors.New("not a link")
+
+// Memory a very convenient filesystem based on memory files.
type Memory struct {
s *storage
tempCount int
}
-//New returns a new Memory filesystem.
+// New returns a new Memory filesystem.
func New() billy.Filesystem {
fs := &Memory{s: newStorage()}
+ fs.s.New("/", 0755|os.ModeDir, 0)
return chroot.New(fs, string(separator))
}
@@ -57,7 +61,9 @@ func (fs *Memory) OpenFile(filename string, flag int, perm os.FileMode) (billy.F
}
if target, isLink := fs.resolveLink(filename, f); isLink {
- return fs.OpenFile(target, flag, perm)
+ if target != filename {
+ return fs.OpenFile(target, flag, perm)
+ }
}
}
@@ -68,8 +74,6 @@ func (fs *Memory) OpenFile(filename string, flag int, perm os.FileMode) (billy.F
return f.Duplicate(filename, perm, flag), nil
}
-var errNotLink = errors.New("not a link")
-
func (fs *Memory) resolveLink(fullpath string, f *file) (target string, isLink bool) {
if !isSymlink(f.mode) {
return fullpath, false
@@ -131,8 +135,12 @@ func (a ByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (fs *Memory) ReadDir(path string) ([]os.FileInfo, error) {
if f, has := fs.s.Get(path); has {
if target, isLink := fs.resolveLink(path, f); isLink {
- return fs.ReadDir(target)
+ if target != path {
+ return fs.ReadDir(target)
+ }
}
+ } else {
+ return nil, &os.PathError{Op: "open", Path: path, Err: syscall.ENOENT}
}
var entries []os.FileInfo
@@ -169,17 +177,19 @@ func (fs *Memory) Remove(filename string) error {
return fs.s.Remove(filename)
}
+// Falls back to Go's filepath.Join, which works differently depending on the
+// OS where the code is being executed.
func (fs *Memory) Join(elem ...string) string {
return filepath.Join(elem...)
}
func (fs *Memory) Symlink(target, link string) error {
- _, err := fs.Stat(link)
+ _, err := fs.Lstat(link)
if err == nil {
return os.ErrExist
}
- if !os.IsNotExist(err) {
+ if !errors.Is(err, os.ErrNotExist) {
return err
}
@@ -230,7 +240,7 @@ func (f *file) Read(b []byte) (int, error) {
n, err := f.ReadAt(b, f.position)
f.position += int64(n)
- if err == io.EOF && n != 0 {
+ if errors.Is(err, io.EOF) && n != 0 {
err = nil
}
@@ -269,6 +279,10 @@ func (f *file) Seek(offset int64, whence int) (int64, error) {
}
func (f *file) Write(p []byte) (int, error) {
+ return f.WriteAt(p, f.position)
+}
+
+func (f *file) WriteAt(p []byte, off int64) (int, error) {
if f.isClosed {
return 0, os.ErrClosed
}
@@ -277,8 +291,8 @@ func (f *file) Write(p []byte) (int, error) {
return 0, errors.New("write not supported")
}
- n, err := f.content.WriteAt(p, f.position)
- f.position += int64(n)
+ n, err := f.content.WriteAt(p, off)
+ f.position = off + int64(n)
return n, err
}
diff --git a/vendor/github.com/go-git/go-billy/v5/memfs/storage.go b/vendor/github.com/go-git/go-billy/v5/memfs/storage.go
index e3c4e38bff..16b48ce002 100644
--- a/vendor/github.com/go-git/go-billy/v5/memfs/storage.go
+++ b/vendor/github.com/go-git/go-billy/v5/memfs/storage.go
@@ -6,6 +6,7 @@ import (
"io"
"os"
"path/filepath"
+ "strings"
"sync"
)
@@ -112,7 +113,7 @@ func (s *storage) Rename(from, to string) error {
move := [][2]string{{from, to}}
for pathFrom := range s.files {
- if pathFrom == from || !filepath.HasPrefix(pathFrom, from) {
+ if pathFrom == from || !strings.HasPrefix(pathFrom, from) {
continue
}
diff --git a/vendor/github.com/go-git/go-billy/v5/osfs/os_bound.go b/vendor/github.com/go-git/go-billy/v5/osfs/os_bound.go
index b4b6dbc07a..c0a6109901 100644
--- a/vendor/github.com/go-git/go-billy/v5/osfs/os_bound.go
+++ b/vendor/github.com/go-git/go-billy/v5/osfs/os_bound.go
@@ -246,6 +246,10 @@ func (fs *BoundOS) insideBaseDir(filename string) (bool, error) {
// a dir that is within the fs.baseDir, by first evaluating any symlinks
// that either filename or fs.baseDir may contain.
func (fs *BoundOS) insideBaseDirEval(filename string) (bool, error) {
+ // "/" contains all others.
+ if fs.baseDir == "/" {
+ return true, nil
+ }
dir, err := filepath.EvalSymlinks(filepath.Dir(filename))
if dir == "" || os.IsNotExist(err) {
dir = filepath.Dir(filename)
@@ -255,7 +259,7 @@ func (fs *BoundOS) insideBaseDirEval(filename string) (bool, error) {
wd = fs.baseDir
}
if filename != wd && dir != wd && !strings.HasPrefix(dir, wd+string(filepath.Separator)) {
- return false, fmt.Errorf("path outside base dir")
+ return false, fmt.Errorf("%q: path outside base dir %q: %w", filename, fs.baseDir, os.ErrNotExist)
}
return true, nil
}
diff --git a/vendor/github.com/go-git/go-billy/v5/osfs/os_posix.go b/vendor/github.com/go-git/go-billy/v5/osfs/os_posix.go
index d834a1145a..6fb8273f17 100644
--- a/vendor/github.com/go-git/go-billy/v5/osfs/os_posix.go
+++ b/vendor/github.com/go-git/go-billy/v5/osfs/os_posix.go
@@ -1,5 +1,5 @@
-//go:build !plan9 && !windows && !js
-// +build !plan9,!windows,!js
+//go:build !plan9 && !windows && !wasm
+// +build !plan9,!windows,!wasm
package osfs
diff --git a/vendor/github.com/go-git/go-billy/v5/osfs/os_wasip1.go b/vendor/github.com/go-git/go-billy/v5/osfs/os_wasip1.go
new file mode 100644
index 0000000000..79e6e33192
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/osfs/os_wasip1.go
@@ -0,0 +1,34 @@
+//go:build wasip1
+// +build wasip1
+
+package osfs
+
+import (
+ "os"
+ "syscall"
+)
+
+func (f *file) Lock() error {
+ f.m.Lock()
+ defer f.m.Unlock()
+ return nil
+}
+
+func (f *file) Unlock() error {
+ f.m.Lock()
+ defer f.m.Unlock()
+ return nil
+}
+
+func rename(from, to string) error {
+ return os.Rename(from, to)
+}
+
+// umask sets umask to a new value, and returns a func which allows the
+// caller to reset it back to what it was originally.
+func umask(new int) func() {
+ old := syscall.Umask(new)
+ return func() {
+ syscall.Umask(old)
+ }
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/util/util.go b/vendor/github.com/go-git/go-billy/v5/util/util.go
index 5c77128c3c..2cdd832c73 100644
--- a/vendor/github.com/go-git/go-billy/v5/util/util.go
+++ b/vendor/github.com/go-git/go-billy/v5/util/util.go
@@ -1,6 +1,7 @@
package util
import (
+ "errors"
"io"
"os"
"path/filepath"
@@ -33,14 +34,14 @@ func removeAll(fs billy.Basic, path string) error {
// Simple case: if Remove works, we're done.
err := fs.Remove(path)
- if err == nil || os.IsNotExist(err) {
+ if err == nil || errors.Is(err, os.ErrNotExist) {
return nil
}
// Otherwise, is this a directory we need to recurse into?
dir, serr := fs.Stat(path)
if serr != nil {
- if os.IsNotExist(serr) {
+ if errors.Is(serr, os.ErrNotExist) {
return nil
}
@@ -60,7 +61,7 @@ func removeAll(fs billy.Basic, path string) error {
// Directory.
fis, err := dirfs.ReadDir(path)
if err != nil {
- if os.IsNotExist(err) {
+ if errors.Is(err, os.ErrNotExist) {
// Race. It was deleted between the Lstat and Open.
// Return nil per RemoveAll's docs.
return nil
@@ -81,7 +82,7 @@ func removeAll(fs billy.Basic, path string) error {
// Remove directory.
err1 := fs.Remove(path)
- if err1 == nil || os.IsNotExist(err1) {
+ if err1 == nil || errors.Is(err1, os.ErrNotExist) {
return nil
}
@@ -96,22 +97,26 @@ func removeAll(fs billy.Basic, path string) error {
// WriteFile writes data to a file named by filename in the given filesystem.
// If the file does not exist, WriteFile creates it with permissions perm;
// otherwise WriteFile truncates it before writing.
-func WriteFile(fs billy.Basic, filename string, data []byte, perm os.FileMode) error {
+func WriteFile(fs billy.Basic, filename string, data []byte, perm os.FileMode) (err error) {
f, err := fs.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
if err != nil {
return err
}
+ defer func() {
+ if f != nil {
+ err1 := f.Close()
+ if err == nil {
+ err = err1
+ }
+ }
+ }()
n, err := f.Write(data)
if err == nil && n < len(data) {
err = io.ErrShortWrite
}
- if err1 := f.Close(); err == nil {
- err = err1
- }
-
- return err
+ return nil
}
// Random number state.
@@ -154,7 +159,7 @@ func TempFile(fs billy.Basic, dir, prefix string) (f billy.File, err error) {
for i := 0; i < 10000; i++ {
name := filepath.Join(dir, prefix+nextSuffix())
f, err = fs.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
- if os.IsExist(err) {
+ if errors.Is(err, os.ErrExist) {
if nconflict++; nconflict > 10 {
randmu.Lock()
rand = reseed()
@@ -185,7 +190,7 @@ func TempDir(fs billy.Dir, dir, prefix string) (name string, err error) {
for i := 0; i < 10000; i++ {
try := filepath.Join(dir, prefix+nextSuffix())
err = fs.MkdirAll(try, 0700)
- if os.IsExist(err) {
+ if errors.Is(err, os.ErrExist) {
if nconflict++; nconflict > 10 {
randmu.Lock()
rand = reseed()
@@ -193,8 +198,8 @@ func TempDir(fs billy.Dir, dir, prefix string) (name string, err error) {
}
continue
}
- if os.IsNotExist(err) {
- if _, err := os.Stat(dir); os.IsNotExist(err) {
+ if errors.Is(err, os.ErrNotExist) {
+ if _, err := os.Stat(dir); errors.Is(err, os.ErrNotExist) {
return "", err
}
}
@@ -272,7 +277,7 @@ func ReadFile(fs billy.Basic, name string) ([]byte, error) {
data = data[:len(data)+n]
if err != nil {
- if err == io.EOF {
+ if errors.Is(err, io.EOF) {
err = nil
}
diff --git a/vendor/github.com/go-kit/log/.gitignore b/vendor/github.com/go-kit/log/.gitignore
deleted file mode 100644
index 66fd13c903..0000000000
--- a/vendor/github.com/go-kit/log/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Binaries for programs and plugins
-*.exe
-*.exe~
-*.dll
-*.so
-*.dylib
-
-# Test binary, built with `go test -c`
-*.test
-
-# Output of the go coverage tool, specifically when used with LiteIDE
-*.out
-
-# Dependency directories (remove the comment below to include it)
-# vendor/
diff --git a/vendor/github.com/go-kit/log/LICENSE b/vendor/github.com/go-kit/log/LICENSE
deleted file mode 100644
index bb5bdb9cb8..0000000000
--- a/vendor/github.com/go-kit/log/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2021 Go kit
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/vendor/github.com/go-kit/log/README.md b/vendor/github.com/go-kit/log/README.md
deleted file mode 100644
index 8067794657..0000000000
--- a/vendor/github.com/go-kit/log/README.md
+++ /dev/null
@@ -1,156 +0,0 @@
-# package log
-
-[![Go Reference](https://pkg.go.dev/badge/github.com/go-kit/log.svg)](https://pkg.go.dev/github.com/go-kit/log)
-[![Go Report Card](https://goreportcard.com/badge/go-kit/log)](https://goreportcard.com/report/go-kit/log)
-[![GitHub Actions](https://github.com/go-kit/log/actions/workflows/test.yml/badge.svg)](https://github.com/go-kit/log/actions/workflows/test.yml)
-[![Coverage Status](https://coveralls.io/repos/github/go-kit/log/badge.svg?branch=main)](https://coveralls.io/github/go-kit/log?branch=main)
-
-`package log` provides a minimal interface for structured logging in services.
-It may be wrapped to encode conventions, enforce type-safety, provide leveled
-logging, and so on. It can be used for both typical application log events,
-and log-structured data streams.
-
-## Structured logging
-
-Structured logging is, basically, conceding to the reality that logs are
-_data_, and warrant some level of schematic rigor. Using a stricter,
-key/value-oriented message format for our logs, containing contextual and
-semantic information, makes it much easier to get insight into the
-operational activity of the systems we build. Consequently, `package log` is
-of the strong belief that "[the benefits of structured logging outweigh the
-minimal effort involved](https://www.thoughtworks.com/radar/techniques/structured-logging)".
-
-Migrating from unstructured to structured logging is probably a lot easier
-than you'd expect.
-
-```go
-// Unstructured
-log.Printf("HTTP server listening on %s", addr)
-
-// Structured
-logger.Log("transport", "HTTP", "addr", addr, "msg", "listening")
-```
-
-## Usage
-
-### Typical application logging
-
-```go
-w := log.NewSyncWriter(os.Stderr)
-logger := log.NewLogfmtLogger(w)
-logger.Log("question", "what is the meaning of life?", "answer", 42)
-
-// Output:
-// question="what is the meaning of life?" answer=42
-```
-
-### Contextual Loggers
-
-```go
-func main() {
- var logger log.Logger
- logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
- logger = log.With(logger, "instance_id", 123)
-
- logger.Log("msg", "starting")
- NewWorker(log.With(logger, "component", "worker")).Run()
- NewSlacker(log.With(logger, "component", "slacker")).Run()
-}
-
-// Output:
-// instance_id=123 msg=starting
-// instance_id=123 component=worker msg=running
-// instance_id=123 component=slacker msg=running
-```
-
-### Interact with stdlib logger
-
-Redirect stdlib logger to Go kit logger.
-
-```go
-import (
- "os"
- stdlog "log"
- kitlog "github.com/go-kit/log"
-)
-
-func main() {
- logger := kitlog.NewJSONLogger(kitlog.NewSyncWriter(os.Stdout))
- stdlog.SetOutput(kitlog.NewStdlibAdapter(logger))
- stdlog.Print("I sure like pie")
-}
-
-// Output:
-// {"msg":"I sure like pie","ts":"2016/01/01 12:34:56"}
-```
-
-Or, if, for legacy reasons, you need to pipe all of your logging through the
-stdlib log package, you can redirect Go kit logger to the stdlib logger.
-
-```go
-logger := kitlog.NewLogfmtLogger(kitlog.StdlibWriter{})
-logger.Log("legacy", true, "msg", "at least it's something")
-
-// Output:
-// 2016/01/01 12:34:56 legacy=true msg="at least it's something"
-```
-
-### Timestamps and callers
-
-```go
-var logger log.Logger
-logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
-logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
-
-logger.Log("msg", "hello")
-
-// Output:
-// ts=2016-01-01T12:34:56Z caller=main.go:15 msg=hello
-```
-
-## Levels
-
-Log levels are supported via the [level package](https://godoc.org/github.com/go-kit/log/level).
-
-## Supported output formats
-
-- [Logfmt](https://brandur.org/logfmt) ([see also](https://blog.codeship.com/logfmt-a-log-format-thats-easy-to-read-and-write))
-- JSON
-
-## Enhancements
-
-`package log` is centered on the one-method Logger interface.
-
-```go
-type Logger interface {
- Log(keyvals ...interface{}) error
-}
-```
-
-This interface, and its supporting code like is the product of much iteration
-and evaluation. For more details on the evolution of the Logger interface,
-see [The Hunt for a Logger Interface](http://go-talks.appspot.com/github.com/ChrisHines/talks/structured-logging/structured-logging.slide#1),
-a talk by [Chris Hines](https://github.com/ChrisHines).
-Also, please see
-[#63](https://github.com/go-kit/kit/issues/63),
-[#76](https://github.com/go-kit/kit/pull/76),
-[#131](https://github.com/go-kit/kit/issues/131),
-[#157](https://github.com/go-kit/kit/pull/157),
-[#164](https://github.com/go-kit/kit/issues/164), and
-[#252](https://github.com/go-kit/kit/pull/252)
-to review historical conversations about package log and the Logger interface.
-
-Value-add packages and suggestions,
-like improvements to [the leveled logger](https://godoc.org/github.com/go-kit/log/level),
-are of course welcome. Good proposals should
-
-- Be composable with [contextual loggers](https://godoc.org/github.com/go-kit/log#With),
-- Not break the behavior of [log.Caller](https://godoc.org/github.com/go-kit/log#Caller) in any wrapped contextual loggers, and
-- Be friendly to packages that accept only an unadorned log.Logger.
-
-## Benchmarks & comparisons
-
-There are a few Go logging benchmarks and comparisons that include Go kit's package log.
-
-- [imkira/go-loggers-bench](https://github.com/imkira/go-loggers-bench) includes kit/log
-- [uber-common/zap](https://github.com/uber-common/zap), a zero-alloc logging library, includes a comparison with kit/log
diff --git a/vendor/github.com/go-kit/log/doc.go b/vendor/github.com/go-kit/log/doc.go
deleted file mode 100644
index f744382fe4..0000000000
--- a/vendor/github.com/go-kit/log/doc.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// Package log provides a structured logger.
-//
-// Structured logging produces logs easily consumed later by humans or
-// machines. Humans might be interested in debugging errors, or tracing
-// specific requests. Machines might be interested in counting interesting
-// events, or aggregating information for off-line processing. In both cases,
-// it is important that the log messages are structured and actionable.
-// Package log is designed to encourage both of these best practices.
-//
-// Basic Usage
-//
-// The fundamental interface is Logger. Loggers create log events from
-// key/value data. The Logger interface has a single method, Log, which
-// accepts a sequence of alternating key/value pairs, which this package names
-// keyvals.
-//
-// type Logger interface {
-// Log(keyvals ...interface{}) error
-// }
-//
-// Here is an example of a function using a Logger to create log events.
-//
-// func RunTask(task Task, logger log.Logger) string {
-// logger.Log("taskID", task.ID, "event", "starting task")
-// ...
-// logger.Log("taskID", task.ID, "event", "task complete")
-// }
-//
-// The keys in the above example are "taskID" and "event". The values are
-// task.ID, "starting task", and "task complete". Every key is followed
-// immediately by its value.
-//
-// Keys are usually plain strings. Values may be any type that has a sensible
-// encoding in the chosen log format. With structured logging it is a good
-// idea to log simple values without formatting them. This practice allows
-// the chosen logger to encode values in the most appropriate way.
-//
-// Contextual Loggers
-//
-// A contextual logger stores keyvals that it includes in all log events.
-// Building appropriate contextual loggers reduces repetition and aids
-// consistency in the resulting log output. With, WithPrefix, and WithSuffix
-// add context to a logger. We can use With to improve the RunTask example.
-//
-// func RunTask(task Task, logger log.Logger) string {
-// logger = log.With(logger, "taskID", task.ID)
-// logger.Log("event", "starting task")
-// ...
-// taskHelper(task.Cmd, logger)
-// ...
-// logger.Log("event", "task complete")
-// }
-//
-// The improved version emits the same log events as the original for the
-// first and last calls to Log. Passing the contextual logger to taskHelper
-// enables each log event created by taskHelper to include the task.ID even
-// though taskHelper does not have access to that value. Using contextual
-// loggers this way simplifies producing log output that enables tracing the
-// life cycle of individual tasks. (See the Contextual example for the full
-// code of the above snippet.)
-//
-// Dynamic Contextual Values
-//
-// A Valuer function stored in a contextual logger generates a new value each
-// time an event is logged. The Valuer example demonstrates how this feature
-// works.
-//
-// Valuers provide the basis for consistently logging timestamps and source
-// code location. The log package defines several valuers for that purpose.
-// See Timestamp, DefaultTimestamp, DefaultTimestampUTC, Caller, and
-// DefaultCaller. A common logger initialization sequence that ensures all log
-// entries contain a timestamp and source location looks like this:
-//
-// logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout))
-// logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
-//
-// Concurrent Safety
-//
-// Applications with multiple goroutines want each log event written to the
-// same logger to remain separate from other log events. Package log provides
-// two simple solutions for concurrent safe logging.
-//
-// NewSyncWriter wraps an io.Writer and serializes each call to its Write
-// method. Using a SyncWriter has the benefit that the smallest practical
-// portion of the logging logic is performed within a mutex, but it requires
-// the formatting Logger to make only one call to Write per log event.
-//
-// NewSyncLogger wraps any Logger and serializes each call to its Log method.
-// Using a SyncLogger has the benefit that it guarantees each log event is
-// handled atomically within the wrapped logger, but it typically serializes
-// both the formatting and output logic. Use a SyncLogger if the formatting
-// logger may perform multiple writes per log event.
-//
-// Error Handling
-//
-// This package relies on the practice of wrapping or decorating loggers with
-// other loggers to provide composable pieces of functionality. It also means
-// that Logger.Log must return an error because some
-// implementations—especially those that output log data to an io.Writer—may
-// encounter errors that cannot be handled locally. This in turn means that
-// Loggers that wrap other loggers should return errors from the wrapped
-// logger up the stack.
-//
-// Fortunately, the decorator pattern also provides a way to avoid the
-// necessity to check for errors every time an application calls Logger.Log.
-// An application required to panic whenever its Logger encounters
-// an error could initialize its logger as follows.
-//
-// fmtlogger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout))
-// logger := log.LoggerFunc(func(keyvals ...interface{}) error {
-// if err := fmtlogger.Log(keyvals...); err != nil {
-// panic(err)
-// }
-// return nil
-// })
-package log
diff --git a/vendor/github.com/go-kit/log/json_logger.go b/vendor/github.com/go-kit/log/json_logger.go
deleted file mode 100644
index d0faed4f09..0000000000
--- a/vendor/github.com/go-kit/log/json_logger.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package log
-
-import (
- "encoding"
- "encoding/json"
- "fmt"
- "io"
- "reflect"
-)
-
-type jsonLogger struct {
- io.Writer
-}
-
-// NewJSONLogger returns a Logger that encodes keyvals to the Writer as a
-// single JSON object. Each log event produces no more than one call to
-// w.Write. The passed Writer must be safe for concurrent use by multiple
-// goroutines if the returned Logger will be used concurrently.
-func NewJSONLogger(w io.Writer) Logger {
- return &jsonLogger{w}
-}
-
-func (l *jsonLogger) Log(keyvals ...interface{}) error {
- n := (len(keyvals) + 1) / 2 // +1 to handle case when len is odd
- m := make(map[string]interface{}, n)
- for i := 0; i < len(keyvals); i += 2 {
- k := keyvals[i]
- var v interface{} = ErrMissingValue
- if i+1 < len(keyvals) {
- v = keyvals[i+1]
- }
- merge(m, k, v)
- }
- enc := json.NewEncoder(l.Writer)
- enc.SetEscapeHTML(false)
- return enc.Encode(m)
-}
-
-func merge(dst map[string]interface{}, k, v interface{}) {
- var key string
- switch x := k.(type) {
- case string:
- key = x
- case fmt.Stringer:
- key = safeString(x)
- default:
- key = fmt.Sprint(x)
- }
-
- // We want json.Marshaler and encoding.TextMarshaller to take priority over
- // err.Error() and v.String(). But json.Marshall (called later) does that by
- // default so we force a no-op if it's one of those 2 case.
- switch x := v.(type) {
- case json.Marshaler:
- case encoding.TextMarshaler:
- case error:
- v = safeError(x)
- case fmt.Stringer:
- v = safeString(x)
- }
-
- dst[key] = v
-}
-
-func safeString(str fmt.Stringer) (s string) {
- defer func() {
- if panicVal := recover(); panicVal != nil {
- if v := reflect.ValueOf(str); v.Kind() == reflect.Ptr && v.IsNil() {
- s = "NULL"
- } else {
- s = fmt.Sprintf("PANIC in String method: %v", panicVal)
- }
- }
- }()
- s = str.String()
- return
-}
-
-func safeError(err error) (s interface{}) {
- defer func() {
- if panicVal := recover(); panicVal != nil {
- if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() {
- s = nil
- } else {
- s = fmt.Sprintf("PANIC in Error method: %v", panicVal)
- }
- }
- }()
- s = err.Error()
- return
-}
diff --git a/vendor/github.com/go-kit/log/level/doc.go b/vendor/github.com/go-kit/log/level/doc.go
deleted file mode 100644
index fd681dcf92..0000000000
--- a/vendor/github.com/go-kit/log/level/doc.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Package level implements leveled logging on top of Go kit's log package. To
-// use the level package, create a logger as per normal in your func main, and
-// wrap it with level.NewFilter.
-//
-// var logger log.Logger
-// logger = log.NewLogfmtLogger(os.Stderr)
-// logger = level.NewFilter(logger, level.AllowInfo()) // <--
-// logger = log.With(logger, "ts", log.DefaultTimestampUTC)
-//
-// It's also possible to configure log level from a string. For instance from
-// a flag, environment variable or configuration file.
-//
-// fs := flag.NewFlagSet("myprogram")
-// lvl := fs.String("log", "info", "debug, info, warn, error")
-//
-// var logger log.Logger
-// logger = log.NewLogfmtLogger(os.Stderr)
-// logger = level.NewFilter(logger, level.Allow(level.ParseDefault(*lvl, level.InfoValue()))) // <--
-// logger = log.With(logger, "ts", log.DefaultTimestampUTC)
-//
-// Then, at the callsites, use one of the level.Debug, Info, Warn, or Error
-// helper methods to emit leveled log events.
-//
-// logger.Log("foo", "bar") // as normal, no level
-// level.Debug(logger).Log("request_id", reqID, "trace_data", trace.Get())
-// if value > 100 {
-// level.Error(logger).Log("value", value)
-// }
-//
-// NewFilter allows precise control over what happens when a log event is
-// emitted without a level key, or if a squelched level is used. Check the
-// Option functions for details.
-package level
diff --git a/vendor/github.com/go-kit/log/level/level.go b/vendor/github.com/go-kit/log/level/level.go
deleted file mode 100644
index c641d98552..0000000000
--- a/vendor/github.com/go-kit/log/level/level.go
+++ /dev/null
@@ -1,256 +0,0 @@
-package level
-
-import (
- "errors"
- "strings"
-
- "github.com/go-kit/log"
-)
-
-// ErrInvalidLevelString is returned whenever an invalid string is passed to Parse.
-var ErrInvalidLevelString = errors.New("invalid level string")
-
-// Error returns a logger that includes a Key/ErrorValue pair.
-func Error(logger log.Logger) log.Logger {
- return log.WithPrefix(logger, Key(), ErrorValue())
-}
-
-// Warn returns a logger that includes a Key/WarnValue pair.
-func Warn(logger log.Logger) log.Logger {
- return log.WithPrefix(logger, Key(), WarnValue())
-}
-
-// Info returns a logger that includes a Key/InfoValue pair.
-func Info(logger log.Logger) log.Logger {
- return log.WithPrefix(logger, Key(), InfoValue())
-}
-
-// Debug returns a logger that includes a Key/DebugValue pair.
-func Debug(logger log.Logger) log.Logger {
- return log.WithPrefix(logger, Key(), DebugValue())
-}
-
-// NewFilter wraps next and implements level filtering. See the commentary on
-// the Option functions for a detailed description of how to configure levels.
-// If no options are provided, all leveled log events created with Debug,
-// Info, Warn or Error helper methods are squelched and non-leveled log
-// events are passed to next unmodified.
-func NewFilter(next log.Logger, options ...Option) log.Logger {
- l := &logger{
- next: next,
- }
- for _, option := range options {
- option(l)
- }
- return l
-}
-
-type logger struct {
- next log.Logger
- allowed level
- squelchNoLevel bool
- errNotAllowed error
- errNoLevel error
-}
-
-func (l *logger) Log(keyvals ...interface{}) error {
- var hasLevel, levelAllowed bool
- for i := 1; i < len(keyvals); i += 2 {
- if v, ok := keyvals[i].(*levelValue); ok {
- hasLevel = true
- levelAllowed = l.allowed&v.level != 0
- break
- }
- }
- if !hasLevel && l.squelchNoLevel {
- return l.errNoLevel
- }
- if hasLevel && !levelAllowed {
- return l.errNotAllowed
- }
- return l.next.Log(keyvals...)
-}
-
-// Option sets a parameter for the leveled logger.
-type Option func(*logger)
-
-// Allow the provided log level to pass.
-func Allow(v Value) Option {
- switch v {
- case debugValue:
- return AllowDebug()
- case infoValue:
- return AllowInfo()
- case warnValue:
- return AllowWarn()
- case errorValue:
- return AllowError()
- default:
- return AllowNone()
- }
-}
-
-// AllowAll is an alias for AllowDebug.
-func AllowAll() Option {
- return AllowDebug()
-}
-
-// AllowDebug allows error, warn, info and debug level log events to pass.
-func AllowDebug() Option {
- return allowed(levelError | levelWarn | levelInfo | levelDebug)
-}
-
-// AllowInfo allows error, warn and info level log events to pass.
-func AllowInfo() Option {
- return allowed(levelError | levelWarn | levelInfo)
-}
-
-// AllowWarn allows error and warn level log events to pass.
-func AllowWarn() Option {
- return allowed(levelError | levelWarn)
-}
-
-// AllowError allows only error level log events to pass.
-func AllowError() Option {
- return allowed(levelError)
-}
-
-// AllowNone allows no leveled log events to pass.
-func AllowNone() Option {
- return allowed(0)
-}
-
-func allowed(allowed level) Option {
- return func(l *logger) { l.allowed = allowed }
-}
-
-// Parse a string to its corresponding level value. Valid strings are "debug",
-// "info", "warn", and "error". Strings are normalized via strings.TrimSpace and
-// strings.ToLower.
-func Parse(level string) (Value, error) {
- switch strings.TrimSpace(strings.ToLower(level)) {
- case debugValue.name:
- return debugValue, nil
- case infoValue.name:
- return infoValue, nil
- case warnValue.name:
- return warnValue, nil
- case errorValue.name:
- return errorValue, nil
- default:
- return nil, ErrInvalidLevelString
- }
-}
-
-// ParseDefault calls Parse and returns the default Value on error.
-func ParseDefault(level string, def Value) Value {
- v, err := Parse(level)
- if err != nil {
- return def
- }
- return v
-}
-
-// ErrNotAllowed sets the error to return from Log when it squelches a log
-// event disallowed by the configured Allow[Level] option. By default,
-// ErrNotAllowed is nil; in this case the log event is squelched with no
-// error.
-func ErrNotAllowed(err error) Option {
- return func(l *logger) { l.errNotAllowed = err }
-}
-
-// SquelchNoLevel instructs Log to squelch log events with no level, so that
-// they don't proceed through to the wrapped logger. If SquelchNoLevel is set
-// to true and a log event is squelched in this way, the error value
-// configured with ErrNoLevel is returned to the caller.
-func SquelchNoLevel(squelch bool) Option {
- return func(l *logger) { l.squelchNoLevel = squelch }
-}
-
-// ErrNoLevel sets the error to return from Log when it squelches a log event
-// with no level. By default, ErrNoLevel is nil; in this case the log event is
-// squelched with no error.
-func ErrNoLevel(err error) Option {
- return func(l *logger) { l.errNoLevel = err }
-}
-
-// NewInjector wraps next and returns a logger that adds a Key/level pair to
-// the beginning of log events that don't already contain a level. In effect,
-// this gives a default level to logs without a level.
-func NewInjector(next log.Logger, level Value) log.Logger {
- return &injector{
- next: next,
- level: level,
- }
-}
-
-type injector struct {
- next log.Logger
- level interface{}
-}
-
-func (l *injector) Log(keyvals ...interface{}) error {
- for i := 1; i < len(keyvals); i += 2 {
- if _, ok := keyvals[i].(*levelValue); ok {
- return l.next.Log(keyvals...)
- }
- }
- kvs := make([]interface{}, len(keyvals)+2)
- kvs[0], kvs[1] = key, l.level
- copy(kvs[2:], keyvals)
- return l.next.Log(kvs...)
-}
-
-// Value is the interface that each of the canonical level values implement.
-// It contains unexported methods that prevent types from other packages from
-// implementing it and guaranteeing that NewFilter can distinguish the levels
-// defined in this package from all other values.
-type Value interface {
- String() string
- levelVal()
-}
-
-// Key returns the unique key added to log events by the loggers in this
-// package.
-func Key() interface{} { return key }
-
-// ErrorValue returns the unique value added to log events by Error.
-func ErrorValue() Value { return errorValue }
-
-// WarnValue returns the unique value added to log events by Warn.
-func WarnValue() Value { return warnValue }
-
-// InfoValue returns the unique value added to log events by Info.
-func InfoValue() Value { return infoValue }
-
-// DebugValue returns the unique value added to log events by Debug.
-func DebugValue() Value { return debugValue }
-
-var (
- // key is of type interface{} so that it allocates once during package
- // initialization and avoids allocating every time the value is added to a
- // []interface{} later.
- key interface{} = "level"
-
- errorValue = &levelValue{level: levelError, name: "error"}
- warnValue = &levelValue{level: levelWarn, name: "warn"}
- infoValue = &levelValue{level: levelInfo, name: "info"}
- debugValue = &levelValue{level: levelDebug, name: "debug"}
-)
-
-type level byte
-
-const (
- levelDebug level = 1 << iota
- levelInfo
- levelWarn
- levelError
-)
-
-type levelValue struct {
- name string
- level
-}
-
-func (v *levelValue) String() string { return v.name }
-func (v *levelValue) levelVal() {}
diff --git a/vendor/github.com/go-kit/log/log.go b/vendor/github.com/go-kit/log/log.go
deleted file mode 100644
index 62e11adace..0000000000
--- a/vendor/github.com/go-kit/log/log.go
+++ /dev/null
@@ -1,179 +0,0 @@
-package log
-
-import "errors"
-
-// Logger is the fundamental interface for all log operations. Log creates a
-// log event from keyvals, a variadic sequence of alternating keys and values.
-// Implementations must be safe for concurrent use by multiple goroutines. In
-// particular, any implementation of Logger that appends to keyvals or
-// modifies or retains any of its elements must make a copy first.
-type Logger interface {
- Log(keyvals ...interface{}) error
-}
-
-// ErrMissingValue is appended to keyvals slices with odd length to substitute
-// the missing value.
-var ErrMissingValue = errors.New("(MISSING)")
-
-// With returns a new contextual logger with keyvals prepended to those passed
-// to calls to Log. If logger is also a contextual logger created by With,
-// WithPrefix, or WithSuffix, keyvals is appended to the existing context.
-//
-// The returned Logger replaces all value elements (odd indexes) containing a
-// Valuer with their generated value for each call to its Log method.
-func With(logger Logger, keyvals ...interface{}) Logger {
- if len(keyvals) == 0 {
- return logger
- }
- l := newContext(logger)
- kvs := append(l.keyvals, keyvals...)
- if len(kvs)%2 != 0 {
- kvs = append(kvs, ErrMissingValue)
- }
- return &context{
- logger: l.logger,
- // Limiting the capacity of the stored keyvals ensures that a new
- // backing array is created if the slice must grow in Log or With.
- // Using the extra capacity without copying risks a data race that
- // would violate the Logger interface contract.
- keyvals: kvs[:len(kvs):len(kvs)],
- hasValuer: l.hasValuer || containsValuer(keyvals),
- sKeyvals: l.sKeyvals,
- sHasValuer: l.sHasValuer,
- }
-}
-
-// WithPrefix returns a new contextual logger with keyvals prepended to those
-// passed to calls to Log. If logger is also a contextual logger created by
-// With, WithPrefix, or WithSuffix, keyvals is prepended to the existing context.
-//
-// The returned Logger replaces all value elements (odd indexes) containing a
-// Valuer with their generated value for each call to its Log method.
-func WithPrefix(logger Logger, keyvals ...interface{}) Logger {
- if len(keyvals) == 0 {
- return logger
- }
- l := newContext(logger)
- // Limiting the capacity of the stored keyvals ensures that a new
- // backing array is created if the slice must grow in Log or With.
- // Using the extra capacity without copying risks a data race that
- // would violate the Logger interface contract.
- n := len(l.keyvals) + len(keyvals)
- if len(keyvals)%2 != 0 {
- n++
- }
- kvs := make([]interface{}, 0, n)
- kvs = append(kvs, keyvals...)
- if len(kvs)%2 != 0 {
- kvs = append(kvs, ErrMissingValue)
- }
- kvs = append(kvs, l.keyvals...)
- return &context{
- logger: l.logger,
- keyvals: kvs,
- hasValuer: l.hasValuer || containsValuer(keyvals),
- sKeyvals: l.sKeyvals,
- sHasValuer: l.sHasValuer,
- }
-}
-
-// WithSuffix returns a new contextual logger with keyvals appended to those
-// passed to calls to Log. If logger is also a contextual logger created by
-// With, WithPrefix, or WithSuffix, keyvals is appended to the existing context.
-//
-// The returned Logger replaces all value elements (odd indexes) containing a
-// Valuer with their generated value for each call to its Log method.
-func WithSuffix(logger Logger, keyvals ...interface{}) Logger {
- if len(keyvals) == 0 {
- return logger
- }
- l := newContext(logger)
- // Limiting the capacity of the stored keyvals ensures that a new
- // backing array is created if the slice must grow in Log or With.
- // Using the extra capacity without copying risks a data race that
- // would violate the Logger interface contract.
- n := len(l.sKeyvals) + len(keyvals)
- if len(keyvals)%2 != 0 {
- n++
- }
- kvs := make([]interface{}, 0, n)
- kvs = append(kvs, keyvals...)
- if len(kvs)%2 != 0 {
- kvs = append(kvs, ErrMissingValue)
- }
- kvs = append(l.sKeyvals, kvs...)
- return &context{
- logger: l.logger,
- keyvals: l.keyvals,
- hasValuer: l.hasValuer,
- sKeyvals: kvs,
- sHasValuer: l.sHasValuer || containsValuer(keyvals),
- }
-}
-
-// context is the Logger implementation returned by With, WithPrefix, and
-// WithSuffix. It wraps a Logger and holds keyvals that it includes in all
-// log events. Its Log method calls bindValues to generate values for each
-// Valuer in the context keyvals.
-//
-// A context must always have the same number of stack frames between calls to
-// its Log method and the eventual binding of Valuers to their value. This
-// requirement comes from the functional requirement to allow a context to
-// resolve application call site information for a Caller stored in the
-// context. To do this we must be able to predict the number of logging
-// functions on the stack when bindValues is called.
-//
-// Two implementation details provide the needed stack depth consistency.
-//
-// 1. newContext avoids introducing an additional layer when asked to
-// wrap another context.
-// 2. With, WithPrefix, and WithSuffix avoid introducing an additional
-// layer by returning a newly constructed context with a merged keyvals
-// rather than simply wrapping the existing context.
-type context struct {
- logger Logger
- keyvals []interface{}
- sKeyvals []interface{} // suffixes
- hasValuer bool
- sHasValuer bool
-}
-
-func newContext(logger Logger) *context {
- if c, ok := logger.(*context); ok {
- return c
- }
- return &context{logger: logger}
-}
-
-// Log replaces all value elements (odd indexes) containing a Valuer in the
-// stored context with their generated value, appends keyvals, and passes the
-// result to the wrapped Logger.
-func (l *context) Log(keyvals ...interface{}) error {
- kvs := append(l.keyvals, keyvals...)
- if len(kvs)%2 != 0 {
- kvs = append(kvs, ErrMissingValue)
- }
- if l.hasValuer {
- // If no keyvals were appended above then we must copy l.keyvals so
- // that future log events will reevaluate the stored Valuers.
- if len(keyvals) == 0 {
- kvs = append([]interface{}{}, l.keyvals...)
- }
- bindValues(kvs[:(len(l.keyvals))])
- }
- kvs = append(kvs, l.sKeyvals...)
- if l.sHasValuer {
- bindValues(kvs[len(kvs)-len(l.sKeyvals):])
- }
- return l.logger.Log(kvs...)
-}
-
-// LoggerFunc is an adapter to allow use of ordinary functions as Loggers. If
-// f is a function with the appropriate signature, LoggerFunc(f) is a Logger
-// object that calls f.
-type LoggerFunc func(...interface{}) error
-
-// Log implements Logger by calling f(keyvals...).
-func (f LoggerFunc) Log(keyvals ...interface{}) error {
- return f(keyvals...)
-}
diff --git a/vendor/github.com/go-kit/log/logfmt_logger.go b/vendor/github.com/go-kit/log/logfmt_logger.go
deleted file mode 100644
index a00305298b..0000000000
--- a/vendor/github.com/go-kit/log/logfmt_logger.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package log
-
-import (
- "bytes"
- "io"
- "sync"
-
- "github.com/go-logfmt/logfmt"
-)
-
-type logfmtEncoder struct {
- *logfmt.Encoder
- buf bytes.Buffer
-}
-
-func (l *logfmtEncoder) Reset() {
- l.Encoder.Reset()
- l.buf.Reset()
-}
-
-var logfmtEncoderPool = sync.Pool{
- New: func() interface{} {
- var enc logfmtEncoder
- enc.Encoder = logfmt.NewEncoder(&enc.buf)
- return &enc
- },
-}
-
-type logfmtLogger struct {
- w io.Writer
-}
-
-// NewLogfmtLogger returns a logger that encodes keyvals to the Writer in
-// logfmt format. Each log event produces no more than one call to w.Write.
-// The passed Writer must be safe for concurrent use by multiple goroutines if
-// the returned Logger will be used concurrently.
-func NewLogfmtLogger(w io.Writer) Logger {
- return &logfmtLogger{w}
-}
-
-func (l logfmtLogger) Log(keyvals ...interface{}) error {
- enc := logfmtEncoderPool.Get().(*logfmtEncoder)
- enc.Reset()
- defer logfmtEncoderPool.Put(enc)
-
- if err := enc.EncodeKeyvals(keyvals...); err != nil {
- return err
- }
-
- // Add newline to the end of the buffer
- if err := enc.EndRecord(); err != nil {
- return err
- }
-
- // The Logger interface requires implementations to be safe for concurrent
- // use by multiple goroutines. For this implementation that means making
- // only one call to l.w.Write() for each call to Log.
- if _, err := l.w.Write(enc.buf.Bytes()); err != nil {
- return err
- }
- return nil
-}
diff --git a/vendor/github.com/go-kit/log/nop_logger.go b/vendor/github.com/go-kit/log/nop_logger.go
deleted file mode 100644
index 1047d626c4..0000000000
--- a/vendor/github.com/go-kit/log/nop_logger.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package log
-
-type nopLogger struct{}
-
-// NewNopLogger returns a logger that doesn't do anything.
-func NewNopLogger() Logger { return nopLogger{} }
-
-func (nopLogger) Log(...interface{}) error { return nil }
diff --git a/vendor/github.com/go-kit/log/staticcheck.conf b/vendor/github.com/go-kit/log/staticcheck.conf
deleted file mode 100644
index 528438b97d..0000000000
--- a/vendor/github.com/go-kit/log/staticcheck.conf
+++ /dev/null
@@ -1 +0,0 @@
-checks = ["all"]
diff --git a/vendor/github.com/go-kit/log/stdlib.go b/vendor/github.com/go-kit/log/stdlib.go
deleted file mode 100644
index 0338edbe2b..0000000000
--- a/vendor/github.com/go-kit/log/stdlib.go
+++ /dev/null
@@ -1,151 +0,0 @@
-package log
-
-import (
- "bytes"
- "io"
- "log"
- "regexp"
- "strings"
-)
-
-// StdlibWriter implements io.Writer by invoking the stdlib log.Print. It's
-// designed to be passed to a Go kit logger as the writer, for cases where
-// it's necessary to redirect all Go kit log output to the stdlib logger.
-//
-// If you have any choice in the matter, you shouldn't use this. Prefer to
-// redirect the stdlib log to the Go kit logger via NewStdlibAdapter.
-type StdlibWriter struct{}
-
-// Write implements io.Writer.
-func (w StdlibWriter) Write(p []byte) (int, error) {
- log.Print(strings.TrimSpace(string(p)))
- return len(p), nil
-}
-
-// StdlibAdapter wraps a Logger and allows it to be passed to the stdlib
-// logger's SetOutput. It will extract date/timestamps, filenames, and
-// messages, and place them under relevant keys.
-type StdlibAdapter struct {
- Logger
- timestampKey string
- fileKey string
- messageKey string
- prefix string
- joinPrefixToMsg bool
-}
-
-// StdlibAdapterOption sets a parameter for the StdlibAdapter.
-type StdlibAdapterOption func(*StdlibAdapter)
-
-// TimestampKey sets the key for the timestamp field. By default, it's "ts".
-func TimestampKey(key string) StdlibAdapterOption {
- return func(a *StdlibAdapter) { a.timestampKey = key }
-}
-
-// FileKey sets the key for the file and line field. By default, it's "caller".
-func FileKey(key string) StdlibAdapterOption {
- return func(a *StdlibAdapter) { a.fileKey = key }
-}
-
-// MessageKey sets the key for the actual log message. By default, it's "msg".
-func MessageKey(key string) StdlibAdapterOption {
- return func(a *StdlibAdapter) { a.messageKey = key }
-}
-
-// Prefix configures the adapter to parse a prefix from stdlib log events. If
-// you provide a non-empty prefix to the stdlib logger, then your should provide
-// that same prefix to the adapter via this option.
-//
-// By default, the prefix isn't included in the msg key. Set joinPrefixToMsg to
-// true if you want to include the parsed prefix in the msg.
-func Prefix(prefix string, joinPrefixToMsg bool) StdlibAdapterOption {
- return func(a *StdlibAdapter) { a.prefix = prefix; a.joinPrefixToMsg = joinPrefixToMsg }
-}
-
-// NewStdlibAdapter returns a new StdlibAdapter wrapper around the passed
-// logger. It's designed to be passed to log.SetOutput.
-func NewStdlibAdapter(logger Logger, options ...StdlibAdapterOption) io.Writer {
- a := StdlibAdapter{
- Logger: logger,
- timestampKey: "ts",
- fileKey: "caller",
- messageKey: "msg",
- }
- for _, option := range options {
- option(&a)
- }
- return a
-}
-
-func (a StdlibAdapter) Write(p []byte) (int, error) {
- p = a.handlePrefix(p)
-
- result := subexps(p)
- keyvals := []interface{}{}
- var timestamp string
- if date, ok := result["date"]; ok && date != "" {
- timestamp = date
- }
- if time, ok := result["time"]; ok && time != "" {
- if timestamp != "" {
- timestamp += " "
- }
- timestamp += time
- }
- if timestamp != "" {
- keyvals = append(keyvals, a.timestampKey, timestamp)
- }
- if file, ok := result["file"]; ok && file != "" {
- keyvals = append(keyvals, a.fileKey, file)
- }
- if msg, ok := result["msg"]; ok {
- msg = a.handleMessagePrefix(msg)
- keyvals = append(keyvals, a.messageKey, msg)
- }
- if err := a.Logger.Log(keyvals...); err != nil {
- return 0, err
- }
- return len(p), nil
-}
-
-func (a StdlibAdapter) handlePrefix(p []byte) []byte {
- if a.prefix != "" {
- p = bytes.TrimPrefix(p, []byte(a.prefix))
- }
- return p
-}
-
-func (a StdlibAdapter) handleMessagePrefix(msg string) string {
- if a.prefix == "" {
- return msg
- }
-
- msg = strings.TrimPrefix(msg, a.prefix)
- if a.joinPrefixToMsg {
- msg = a.prefix + msg
- }
- return msg
-}
-
-const (
- logRegexpDate = `(?P[0-9]{4}/[0-9]{2}/[0-9]{2})?[ ]?`
- logRegexpTime = `(?P