diff --git a/Makefile.kube_git.var b/Makefile.kube_git.var index d090db6646..362f2a7a08 100644 --- a/Makefile.kube_git.var +++ b/Makefile.kube_git.var @@ -1,5 +1,5 @@ KUBE_GIT_MAJOR=1 KUBE_GIT_MINOR=32 KUBE_GIT_VERSION=v1.32.5 -KUBE_GIT_COMMIT=d92880b14300b76b867a83ec887e280a5b77b52e +KUBE_GIT_COMMIT=02b9b7e65987d5aa4559c318725354713838b5a2 KUBE_GIT_TREE_STATE=clean diff --git a/Makefile.version.aarch64.var b/Makefile.version.aarch64.var index b80c7af816..e8e8e2e15c 100644 --- a/Makefile.version.aarch64.var +++ b/Makefile.version.aarch64.var @@ -1 +1 @@ -OCP_VERSION := 4.20.0-0.nightly-arm64-2025-06-26-231650 +OCP_VERSION := 4.20.0-0.nightly-arm64-2025-06-30-210738 diff --git a/Makefile.version.x86_64.var b/Makefile.version.x86_64.var index 371472d1ef..cfad12bad6 100644 --- a/Makefile.version.x86_64.var +++ b/Makefile.version.x86_64.var @@ -1 +1 @@ -OCP_VERSION := 4.20.0-0.nightly-2025-06-20-214016 +OCP_VERSION := 4.20.0-0.nightly-2025-06-28-115226 diff --git a/assets/components/csi-snapshot-controller/csi_controller_deployment.yaml b/assets/components/csi-snapshot-controller/csi_controller_deployment.yaml index 6455c44360..5b48acfc99 100644 --- a/assets/components/csi-snapshot-controller/csi_controller_deployment.yaml +++ b/assets/components/csi-snapshot-controller/csi_controller_deployment.yaml @@ -23,6 +23,8 @@ spec: openshift.io/required-scc: restricted-v2 labels: app: csi-snapshot-controller + openshift.storage.network-policy.dns: allow + openshift.storage.network-policy.api-server: allow spec: securityContext: runAsNonRoot: true diff --git a/assets/components/multus/kustomization.x86_64.yaml b/assets/components/multus/kustomization.x86_64.yaml index 0f8e00616c..3b4697729a 100644 --- a/assets/components/multus/kustomization.x86_64.yaml +++ b/assets/components/multus/kustomization.x86_64.yaml @@ -2,7 +2,7 @@ images: - name: multus-cni-microshift newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:3d9f7262c02f2397a56b9f83de5565342563173aab799204c9d240c99ba851fa + digest: sha256:d4221a4a53fafbe04c7d46556f4f72c485407d814f18b5cf7b14410403c05761 - name: containernetworking-plugins-microshift newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:32c69f5819b3ec0bdc9e6296aebb64c26d8845943857f1c44095379de92969c3 + digest: sha256:467ffccb5a3b4511b80f18f7097a5a9e9bb6362f97697be585a0211f191ef3e9 diff --git a/assets/components/multus/release-multus-aarch64.json b/assets/components/multus/release-multus-aarch64.json index f53bfa2889..a608140d55 100644 --- a/assets/components/multus/release-multus-aarch64.json +++ b/assets/components/multus/release-multus-aarch64.json @@ -1,6 +1,6 @@ { "release": { - "base": "4.20.0-0.nightly-arm64-2025-06-26-231650" + "base": "4.20.0-0.nightly-arm64-2025-06-30-210738" }, "images": { "multus-cni-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:dff6b68a409a3e5cdd679d7a26420abd5ecd75027edd17bb2dbcbab489506530", diff --git a/assets/components/multus/release-multus-x86_64.json b/assets/components/multus/release-multus-x86_64.json index e376d1e81d..464d754f98 100644 --- a/assets/components/multus/release-multus-x86_64.json +++ b/assets/components/multus/release-multus-x86_64.json @@ -1,9 +1,9 @@ { "release": { - "base": "4.20.0-0.nightly-2025-06-20-214016" + "base": "4.20.0-0.nightly-2025-06-28-115226" }, "images": { - "multus-cni-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:3d9f7262c02f2397a56b9f83de5565342563173aab799204c9d240c99ba851fa", - "containernetworking-plugins-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:32c69f5819b3ec0bdc9e6296aebb64c26d8845943857f1c44095379de92969c3" + "multus-cni-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:d4221a4a53fafbe04c7d46556f4f72c485407d814f18b5cf7b14410403c05761", + "containernetworking-plugins-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:467ffccb5a3b4511b80f18f7097a5a9e9bb6362f97697be585a0211f191ef3e9" } } diff --git a/assets/optional/kube-proxy/kustomization.x86_64.yaml b/assets/optional/kube-proxy/kustomization.x86_64.yaml index 73ff17c5d5..4a0465eb10 100644 --- a/assets/optional/kube-proxy/kustomization.x86_64.yaml +++ b/assets/optional/kube-proxy/kustomization.x86_64.yaml @@ -2,4 +2,4 @@ images: - name: kube-proxy newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:e73c2485b0b50c8dccaedea2311aad6ee3036377d8ae8047a26bc2a2f4b6c549 + digest: sha256:3a6a8daae223fc315f73045d733fbc0f5c4f4a2cd5ec1cd87b5fada17fec89b3 diff --git a/assets/optional/kube-proxy/release-kube-proxy-aarch64.json b/assets/optional/kube-proxy/release-kube-proxy-aarch64.json index 29efec991e..ccd4fc6460 100644 --- a/assets/optional/kube-proxy/release-kube-proxy-aarch64.json +++ b/assets/optional/kube-proxy/release-kube-proxy-aarch64.json @@ -1,6 +1,6 @@ { "release": { - "base": "4.20.0-0.nightly-arm64-2025-06-26-231650" + "base": "4.20.0-0.nightly-arm64-2025-06-30-210738" }, "images": { "kube-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:eb3a68321a7e1c65789da0b389a455dd3efd2eb5680953e4dc7bdc06d4b4446c" diff --git a/assets/optional/kube-proxy/release-kube-proxy-x86_64.json b/assets/optional/kube-proxy/release-kube-proxy-x86_64.json index 9177d5e5c4..17e502fcab 100644 --- a/assets/optional/kube-proxy/release-kube-proxy-x86_64.json +++ b/assets/optional/kube-proxy/release-kube-proxy-x86_64.json @@ -1,8 +1,8 @@ { "release": { - "base": "4.20.0-0.nightly-2025-06-20-214016" + "base": "4.20.0-0.nightly-2025-06-28-115226" }, "images": { - "kube-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:e73c2485b0b50c8dccaedea2311aad6ee3036377d8ae8047a26bc2a2f4b6c549" + "kube-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:3a6a8daae223fc315f73045d733fbc0f5c4f4a2cd5ec1cd87b5fada17fec89b3" } } diff --git a/assets/optional/operator-lifecycle-manager/kustomization.x86_64.yaml b/assets/optional/operator-lifecycle-manager/kustomization.x86_64.yaml index b4550c66d4..8b2525ebe3 100644 --- a/assets/optional/operator-lifecycle-manager/kustomization.x86_64.yaml +++ b/assets/optional/operator-lifecycle-manager/kustomization.x86_64.yaml @@ -2,13 +2,13 @@ images: - name: quay.io/operator-framework/olm newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:9dc4358e925dc1dc81f9427514708943a2715eae86a8852ba2e92321ad8a0d86 + digest: sha256:81d3f05911fc7990851d300eadf647906572038320a08f45041d99f6a4298d4f - name: quay.io/operator-framework/configmap-operator-registry newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:445d517dd9a06261876e48fe4770b3ed4205e9e2d56a9cf23977cffcbcedcea0 + digest: sha256:cc8a240588f4443132195d1e064e2579d24155334436a98f9381fb2b62d2d2a8 - name: quay.io/openshift/origin-kube-rbac-proxy newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:997327803da16f984825119d4e77f9bda5d4c702195463a984b0a7c67c41ab3f + digest: sha256:09d24c9a29e1502c869acded81d9fece81240d5ebf7a8a4af2ff34b9f42a873e patches: - patch: |- @@ -16,12 +16,12 @@ patches: path: /spec/template/spec/containers/0/env/- value: name: OPERATOR_REGISTRY_IMAGE - value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:445d517dd9a06261876e48fe4770b3ed4205e9e2d56a9cf23977cffcbcedcea0 + value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:cc8a240588f4443132195d1e064e2579d24155334436a98f9381fb2b62d2d2a8 - op: add path: /spec/template/spec/containers/0/env/- value: name: OLM_IMAGE - value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9dc4358e925dc1dc81f9427514708943a2715eae86a8852ba2e92321ad8a0d86 + value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:81d3f05911fc7990851d300eadf647906572038320a08f45041d99f6a4298d4f target: kind: Deployment labelSelector: app=catalog-operator diff --git a/assets/optional/operator-lifecycle-manager/release-olm-aarch64.json b/assets/optional/operator-lifecycle-manager/release-olm-aarch64.json index 214c52e5d7..a266778903 100644 --- a/assets/optional/operator-lifecycle-manager/release-olm-aarch64.json +++ b/assets/optional/operator-lifecycle-manager/release-olm-aarch64.json @@ -1,6 +1,6 @@ { "release": { - "base": "4.20.0-0.nightly-arm64-2025-06-26-231650" + "base": "4.20.0-0.nightly-arm64-2025-06-30-210738" }, "images": { "operator-lifecycle-manager": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:6fe3da3ac60585ec10b0b5b6fa2e43be4cb596c79c122cd337eca840d9a306d9", diff --git a/assets/optional/operator-lifecycle-manager/release-olm-x86_64.json b/assets/optional/operator-lifecycle-manager/release-olm-x86_64.json index b585fb3690..d059b19da2 100644 --- a/assets/optional/operator-lifecycle-manager/release-olm-x86_64.json +++ b/assets/optional/operator-lifecycle-manager/release-olm-x86_64.json @@ -1,10 +1,10 @@ { "release": { - "base": "4.20.0-0.nightly-2025-06-20-214016" + "base": "4.20.0-0.nightly-2025-06-28-115226" }, "images": { - "operator-lifecycle-manager": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9dc4358e925dc1dc81f9427514708943a2715eae86a8852ba2e92321ad8a0d86", - "operator-registry": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:445d517dd9a06261876e48fe4770b3ed4205e9e2d56a9cf23977cffcbcedcea0", - "kube-rbac-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:997327803da16f984825119d4e77f9bda5d4c702195463a984b0a7c67c41ab3f" + "operator-lifecycle-manager": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:81d3f05911fc7990851d300eadf647906572038320a08f45041d99f6a4298d4f", + "operator-registry": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:cc8a240588f4443132195d1e064e2579d24155334436a98f9381fb2b62d2d2a8", + "kube-rbac-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:09d24c9a29e1502c869acded81d9fece81240d5ebf7a8a4af2ff34b9f42a873e" } } diff --git a/assets/release/release-aarch64.json b/assets/release/release-aarch64.json index e5bca5b7c6..d8a97e4bd5 100644 --- a/assets/release/release-aarch64.json +++ b/assets/release/release-aarch64.json @@ -1,6 +1,6 @@ { "release": { - "base": "4.20.0-0.nightly-arm64-2025-06-26-231650" + "base": "4.20.0-0.nightly-arm64-2025-06-30-210738" }, "images": { "cli": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:3c7be2010440b12c9b97acd8b61aad07ead88ce7db9dca85e58f3f8a74f11be1", diff --git a/assets/release/release-x86_64.json b/assets/release/release-x86_64.json index d03ad986fa..45001b179e 100644 --- a/assets/release/release-x86_64.json +++ b/assets/release/release-x86_64.json @@ -1,16 +1,16 @@ { "release": { - "base": "4.20.0-0.nightly-2025-06-20-214016" + "base": "4.20.0-0.nightly-2025-06-28-115226" }, "images": { - "cli": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:64e75c90e9f9a6ab779a939dd4a9f702f5a89f8a7b527e1507a6be6716274e96", - "coredns": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:3ae5042b13d85dc3468f14cc4965ed41cf6e3079c9742911fb7107c4c9fb3215", - "haproxy-router": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:5f7e1af518a8959e7dd7e86b6333cd11cdc859522a53145a8cc9fd66a97fe22f", - "kube-rbac-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:997327803da16f984825119d4e77f9bda5d4c702195463a984b0a7c67c41ab3f", - "ovn-kubernetes-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:8a611e730a21f73af0b8640e144bd7504b8badde0e9ba4493778d77901e4f9ac", - "pod": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:efc88fe98bb6c628d08bac26a529e7e859309d58f9460b045f0584fd6d31e0f6", - "service-ca-operator": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:5675cb173bcf6b221d214cc26c1f0619ab67129e8681a3af92c3d5596f23e11b", + "cli": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:d07348b8d200a8de1cdfe1bbba24c7b6b29924a821ec7eff7e2c41eb65d2dec1", + "coredns": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:6373952c5874a7ce13d0d700787689b4b32b611ee593535015c3a34de9b39998", + "haproxy-router": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:517e6ecc165325a5f772ff3df06471bb7763e097c6658f68ea04253262341e02", + "kube-rbac-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:09d24c9a29e1502c869acded81d9fece81240d5ebf7a8a4af2ff34b9f42a873e", + "ovn-kubernetes-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f2a4b7d4b1f55a7bba2fbcffa2f46b4ff7eb4700bda39f6c96bdf72b37e87608", + "pod": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:e9266796a89c250c91f49e4bffcd724afbc8c0b9e836eccee3d39a3d2c495e9a", + "service-ca-operator": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:5d34f5fec40338f231e7936bada0e07fa6ac7df461c2445050fc502d83e8a3a6", "lvms_operator": "registry.redhat.io/lvms4/lvms-rhel9-operator@sha256:b372811ed8263f80c0903a63e9fd9d05d4dbf2b4d7adcb32304108124841e5bc", - "csi-snapshot-controller": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:59f0d645823ec364d6f295d244cf21b0d51d85dc9566df4e3435ad0f6b1a6371" + "csi-snapshot-controller": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:b8c5cc3cc366b9c859ae62961ab59ee87b04ebf2bea68205ceb3bd6aa9794fbe" } } diff --git a/deps/github.com/openshift/kubernetes/openshift-hack/rebase.sh b/deps/github.com/openshift/kubernetes/openshift-hack/rebase.sh index 70ea50b38b..ed2fdbbed5 100755 --- a/deps/github.com/openshift/kubernetes/openshift-hack/rebase.sh +++ b/deps/github.com/openshift/kubernetes/openshift-hack/rebase.sh @@ -126,7 +126,7 @@ fi # openshift-hack/images/hyperkube/Dockerfile.rhel still has FROM pointing to old tag # we need to remove the prefix "v" from the $k8s_tag to stay compatible sed -i -E "s/(io.openshift.build.versions=\"kubernetes=)(1.[1-9]+.[1-9]+)/\1${k8s_tag:1}/" openshift-hack/images/hyperkube/Dockerfile.rhel -go_mod_go_ver=$(grep -E 'go 1\.[1-9][0-9]?' go.mod | sed -E 's/go (1\.[1-9][0-9]?)/\1/') +go_mod_go_ver=$(grep -E 'go 1\.[1-9][0-9]?' go.mod | sed -E 's/go (1\.[1-9][0-9]?)/\1/' | cut -d '.' -f 1,2) # Need to handle mod versions like 1.23 and 1.23.4; our release images only have major.minor tag="rhel-8-release-golang-${go_mod_go_ver}-openshift-${openshift_release#release-}" # update openshift go.mod dependencies diff --git a/deps/github.com/openshift/kubernetes/test/integration/apiserver/cel/validatingadmissionpolicy_test.go b/deps/github.com/openshift/kubernetes/test/integration/apiserver/cel/validatingadmissionpolicy_test.go index 72e2fac942..9aeeced36d 100644 --- a/deps/github.com/openshift/kubernetes/test/integration/apiserver/cel/validatingadmissionpolicy_test.go +++ b/deps/github.com/openshift/kubernetes/test/integration/apiserver/cel/validatingadmissionpolicy_test.go @@ -66,6 +66,8 @@ import ( authorizationv1 "k8s.io/api/authorization/v1" v1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" + utilrand "k8s.io/apimachinery/pkg/util/rand" + utilvalidation "k8s.io/apimachinery/pkg/util/validation" ) // Short term fix to refresh the policy source cache faster for tests @@ -3005,8 +3007,17 @@ func secondaryAuthorizationServiceAccountClient(t *testing.T, adminClient *clien func withWaitReadyConstraintAndExpression(policy *admissionregistrationv1.ValidatingAdmissionPolicy) *admissionregistrationv1.ValidatingAdmissionPolicy { policy = policy.DeepCopy() + + testMarkerName := fmt.Sprintf("test-marker-%s", utilrand.String(utilvalidation.DNS1123SubdomainMaxLength-len("test-marker-"))) + annotations := policy.GetAnnotations() + if annotations == nil { + annotations = make(map[string]string) + } + annotations["test-marker-name"] = testMarkerName + policy.SetAnnotations(annotations) + policy.Spec.MatchConstraints.ResourceRules = append(policy.Spec.MatchConstraints.ResourceRules, admissionregistrationv1.NamedRuleWithOperations{ - ResourceNames: []string{"test-marker"}, + ResourceNames: []string{testMarkerName}, RuleWithOperations: admissionregistrationv1.RuleWithOperations{ Operations: []admissionregistrationv1.OperationType{ "UPDATE", @@ -3025,7 +3036,7 @@ func withWaitReadyConstraintAndExpression(policy *admissionregistrationv1.Valida }, }) policy.Spec.Validations = append([]admissionregistrationv1.Validation{{ - Expression: "object.metadata.name != 'test-marker'", + Expression: fmt.Sprintf("object.metadata.name != '%s'", testMarkerName), Message: "marker denied; policy is ready", }}, policy.Spec.Validations...) return policy @@ -3040,14 +3051,23 @@ func createAndWaitReadyNamespaced(t *testing.T, client clientset.Interface, bind } func createAndWaitReadyNamespacedWithWarnHandler(t *testing.T, client clientset.Interface, binding *admissionregistrationv1.ValidatingAdmissionPolicyBinding, matchLabels map[string]string, ns string, handler *warningHandler) error { - marker := &v1.Endpoints{ObjectMeta: metav1.ObjectMeta{Name: "test-marker", Namespace: ns, Labels: matchLabels}} + policy, err := client.AdmissionregistrationV1().ValidatingAdmissionPolicies().Get(context.TODO(), binding.Spec.PolicyName, metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + testMarkerName := "test-marker" + if testMarkerNameAnnotation, ok := policy.GetAnnotations()["test-marker-name"]; ok { + testMarkerName = testMarkerNameAnnotation + } + + marker := &v1.Endpoints{ObjectMeta: metav1.ObjectMeta{Name: testMarkerName, Namespace: ns, Labels: matchLabels}} defer func() { err := client.CoreV1().Endpoints(ns).Delete(context.TODO(), marker.Name, metav1.DeleteOptions{}) if err != nil { t.Logf("error deleting marker: %v", err) } }() - marker, err := client.CoreV1().Endpoints(ns).Create(context.TODO(), marker, metav1.CreateOptions{}) + marker, err = client.CoreV1().Endpoints(ns).Create(context.TODO(), marker, metav1.CreateOptions{}) if err != nil { return err } diff --git a/etcd/go.mod b/etcd/go.mod index 243859324a..8e6414b343 100644 --- a/etcd/go.mod +++ b/etcd/go.mod @@ -26,14 +26,18 @@ require ( require ( github.com/blang/semver/v4 v4.0.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-kit/kit v0.9.0 // indirect + github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/oklog/run v1.1.0 // indirect github.com/openshift/library-go v0.0.0-20250217144305-c917e6d528b2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/squat/generic-device-plugin v0.0.0-20250313105706-6475ff5d0927 // indirect github.com/vishvananda/netlink v1.3.1-0.20250206174618-62fb240731fa // indirect github.com/vishvananda/netns v0.0.4 // indirect github.com/x448/float16 v0.8.4 // indirect @@ -44,6 +48,7 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect k8s.io/apiserver v1.32.5 // indirect + k8s.io/kubelet v1.32.5 // indirect ) require ( diff --git a/etcd/go.sum b/etcd/go.sum index 71f616489e..b24759255d 100644 --- a/etcd/go.sum +++ b/etcd/go.sum @@ -53,8 +53,11 @@ github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXE github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +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 v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -69,6 +72,8 @@ github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDsl 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-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= 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= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -156,6 +161,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/openshift/api v0.0.0-20250213010142-f5b09d13c01f h1:HH+BqfxONWB2kknhCLAjiAievsyb56WvLGXdNOseI8g= @@ -213,6 +220,8 @@ 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/squat/generic-device-plugin v0.0.0-20250313105706-6475ff5d0927 h1:ku27KO9QGKiPvTSVrOP2qUzvM3v+TDdvPmyB6vGl678= +github.com/squat/generic-device-plugin v0.0.0-20250313105706-6475ff5d0927/go.mod h1:rFRt0GxGw04yGcbfSqoUENZH0p+1oL6IziAVQ31NAVw= 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.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= diff --git a/etcd/vendor/github.com/go-kit/kit/LICENSE b/etcd/vendor/github.com/go-kit/kit/LICENSE new file mode 100644 index 0000000000..9d83342acd --- /dev/null +++ b/etcd/vendor/github.com/go-kit/kit/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Peter Bourgon + +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/etcd/vendor/github.com/go-kit/kit/log/README.md b/etcd/vendor/github.com/go-kit/kit/log/README.md new file mode 100644 index 0000000000..a201a3d922 --- /dev/null +++ b/etcd/vendor/github.com/go-kit/kit/log/README.md @@ -0,0 +1,151 @@ +# package log + +`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/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/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/kit/log/level), +are of course welcome. Good proposals should + +- Be composable with [contextual loggers](https://godoc.org/github.com/go-kit/kit/log#With), +- Not break the behavior of [log.Caller](https://godoc.org/github.com/go-kit/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/etcd/vendor/github.com/go-kit/kit/log/doc.go b/etcd/vendor/github.com/go-kit/kit/log/doc.go new file mode 100644 index 0000000000..918c0af46f --- /dev/null +++ b/etcd/vendor/github.com/go-kit/kit/log/doc.go @@ -0,0 +1,116 @@ +// 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 and WithPrefix 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/etcd/vendor/github.com/go-kit/kit/log/json_logger.go b/etcd/vendor/github.com/go-kit/kit/log/json_logger.go new file mode 100644 index 0000000000..66094b4dd3 --- /dev/null +++ b/etcd/vendor/github.com/go-kit/kit/log/json_logger.go @@ -0,0 +1,89 @@ +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) + } + return json.NewEncoder(l.Writer).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 { + panic(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 { + panic(panicVal) + } + } + }() + s = err.Error() + return +} diff --git a/etcd/vendor/github.com/go-kit/kit/log/level/doc.go b/etcd/vendor/github.com/go-kit/kit/log/level/doc.go new file mode 100644 index 0000000000..505d307b11 --- /dev/null +++ b/etcd/vendor/github.com/go-kit/kit/log/level/doc.go @@ -0,0 +1,22 @@ +// 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) +// +// 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/etcd/vendor/github.com/go-kit/kit/log/level/level.go b/etcd/vendor/github.com/go-kit/kit/log/level/level.go new file mode 100644 index 0000000000..fceafc454a --- /dev/null +++ b/etcd/vendor/github.com/go-kit/kit/log/level/level.go @@ -0,0 +1,205 @@ +package level + +import "github.com/go-kit/kit/log" + +// 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) + +// 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 } +} + +// 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 Warn. +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/etcd/vendor/github.com/go-kit/kit/log/log.go b/etcd/vendor/github.com/go-kit/kit/log/log.go new file mode 100644 index 0000000000..66a9e2fde7 --- /dev/null +++ b/etcd/vendor/github.com/go-kit/kit/log/log.go @@ -0,0 +1,135 @@ +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 or +// WithPrefix, 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), + } +} + +// 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 or WithPrefix, 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), + } +} + +// context is the Logger implementation returned by With and WithPrefix. 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 and WithPrefix 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{} + hasValuer 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)]) + } + 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/etcd/vendor/github.com/go-kit/kit/log/logfmt_logger.go b/etcd/vendor/github.com/go-kit/kit/log/logfmt_logger.go new file mode 100644 index 0000000000..a00305298b --- /dev/null +++ b/etcd/vendor/github.com/go-kit/kit/log/logfmt_logger.go @@ -0,0 +1,62 @@ +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/etcd/vendor/github.com/go-kit/kit/log/nop_logger.go b/etcd/vendor/github.com/go-kit/kit/log/nop_logger.go new file mode 100644 index 0000000000..1047d626c4 --- /dev/null +++ b/etcd/vendor/github.com/go-kit/kit/log/nop_logger.go @@ -0,0 +1,8 @@ +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/etcd/vendor/github.com/go-kit/kit/log/stdlib.go b/etcd/vendor/github.com/go-kit/kit/log/stdlib.go new file mode 100644 index 0000000000..ff96b5dee5 --- /dev/null +++ b/etcd/vendor/github.com/go-kit/kit/log/stdlib.go @@ -0,0 +1,116 @@ +package log + +import ( + "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 +} + +// 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 } +} + +// 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) { + 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 { + keyvals = append(keyvals, a.messageKey, msg) + } + if err := a.Logger.Log(keyvals...); err != nil { + return 0, err + } + return len(p), nil +} + +const ( + logRegexpDate = `(?P[0-9]{4}/[0-9]{2}/[0-9]{2})?[ ]?` + logRegexpTime = `(?P