Skip to content
  •  
  •  
  •  
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ check-latest-tags-strict: ## Check ':latest' image tags in YAML (strict; fails o

.PHONY: presubmit
presubmit: LINT_NEW_ONLY=true
presubmit: git-branch-check signed-commits-check go-mod-check format lint vulncheck check-latest-tags-strict
presubmit: git-branch-check signed-commits-check go-mod-check format lint vulncheck check-latest-tags-strict verify-boilerplate

.PHONY: git-branch-check
git-branch-check:
Expand Down Expand Up @@ -343,6 +343,10 @@ post-deploy-test: ## Run post deployment tests
verify-manifests: kubectl-validate ## Validate deployment manifests.
KUBECTL_VALIDATE="$(KUBECTL_VALIDATE)" hack/verify-manifests.sh

.PHONY: verify-boilerplate
verify-boilerplate: ## Check that .go and .sh files carry a copyright notice.
hack/copyright.sh verify

##@ Helm

.PHONY: verify-helm-charts
Expand Down
1 change: 1 addition & 0 deletions apix/config/v1alpha1/doc.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2026 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
1 change: 1 addition & 0 deletions apix/config/v1alpha1/endpointpickerconfig_types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2026 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
1 change: 1 addition & 0 deletions apix/config/v1alpha1/endpointpickerconfig_types_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2026 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
1 change: 1 addition & 0 deletions apix/v1alpha2/doc.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2026 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
1 change: 1 addition & 0 deletions apix/v1alpha2/inferencemodelrewrite_types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2026 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
1 change: 1 addition & 0 deletions apix/v1alpha2/inferenceobjective_types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2026 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion cmd/epp/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2025 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion cmd/epp/runner/feature_gate_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2025 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
1 change: 1 addition & 0 deletions cmd/epp/runner/health.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2026 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
1 change: 1 addition & 0 deletions cmd/epp/runner/health_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2026 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion cmd/epp/runner/multicluster_config_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2026 The Kubernetes Authors.
Copyright 2026 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion cmd/epp/runner/resolve_discovery_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2025 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion cmd/epp/runner/run_with_file_discovery_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2025 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion cmd/epp/runner/rungroup.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2025 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
1 change: 1 addition & 0 deletions cmd/epp/runner/runner.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright 2026 The Kubernetes Authors.
Copyright 2026 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -1225,7 +1226,7 @@
mux.Handle(path, h)
}
}
srv := &http.Server{Addr: fmt.Sprintf(":%d", port), Handler: mux}

Check failure on line 1229 in cmd/epp/runner/runner.go

View workflow job for this annotation

GitHub Actions / lint

G112: Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server (gosec)
go func() {
<-ctx.Done()
shutdownCtx, cancel := context.WithTimeout(context.Background(), metricsShutdownTimeout)
Expand Down
1 change: 1 addition & 0 deletions cmd/epp/runner/test_runner.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright 2025 The Kubernetes Authors.
Copyright 2026 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
255 changes: 255 additions & 0 deletions hack/copyright.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
#!/usr/bin/env bash

# Copyright 2026 The llm-d Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Manage copyright notices across .go and .sh files.
#
# Files migrated from sigs.k8s.io/gateway-api-inference-extension (GAIE) carry
# "The Kubernetes Authors"; files that originated in llm-d org repos carry
# "The llm-d Authors"; GAIE-derived files later modified here carry both.
#
# Usage:
# hack/copyright.sh verify Fail if any in-scope file has no recognized
# notice. Does not check which notice; that is
# a provenance question, not a syntax one. This
# is the default and the make presubmit gate.
# hack/copyright.sh fix Insert the llm-d notice into files that have
# no notice at all. Never touches a file that
# already carries any notice - see 'classify'
# for files whose existing notice is wrong.
# hack/copyright.sh classify Report provenance per file, derived from
# local git history, to guide manually
# correcting misattributed notices.
#
# Generated files ("Code generated ... DO NOT EDIT." in the first 5 lines)
# are skipped in every mode.

set -o errexit
set -o nounset
set -o pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "${REPO_ROOT}"

MODE="${1:-verify}"

# GAIE commits are self-identifying: scripts/migrate-gaie-paths.sh rewrites bare
# #NNN issue refs in migrated commit messages to this qualified form.
GAIE_MARKER='kubernetes-sigs/gateway-api-inference-extension#'
# Commits that only rewrite import paths after a migration; their bodies record
# the exact src -> dest map and introduce no new code.
MECHANICAL_GREP=(--grep='^chore: rewrite imports from' --grep='^chore: rename go model')

LLMD_RE='Copyright [0-9]{4}(, [0-9]{4})* The llm-d Authors\.'
K8S_RE='Copyright [0-9]{4}(, [0-9]{4})* The Kubernetes Authors\.'
GENERATED_RE='Code generated .* DO NOT EDIT\.'

LLMD_BLOCK_GO='/*
Copyright %s The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'

LLMD_BLOCK_SH='# Copyright %s The llm-d Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

'

in_scope_files() {
git ls-files '*.go' '*.sh'
}

is_generated() {
head -5 "$1" | grep -qE "${GENERATED_RE}"
}

has_llmd_notice() { grep -qE "${LLMD_RE}" "$1"; }
has_k8s_notice() { grep -qE "${K8S_RE}" "$1"; }
has_any_notice() { has_llmd_notice "$1" || has_k8s_notice "$1"; }

# Year of a file's first commit, following renames; falls back to the current
# year for files git has never seen (new, uncommitted files).
creation_year() {
local year
year=$(git log --follow --diff-filter=A --format=%ad --date=format:%Y -- "$1" | tail -1)
echo "${year:-$(date +%Y)}"
}

cmd_verify() {
local missing=()
local f
while IFS= read -r f; do
is_generated "${f}" && continue
has_any_notice "${f}" || missing+=("${f}")
done < <(in_scope_files)

if [[ ${#missing[@]} -eq 0 ]]; then
echo "All in-scope files carry a recognized copyright notice."
return 0
fi

echo "ERROR: the following files have no recognized copyright notice:"
printf ' %s\n' "${missing[@]}"
return 1
}

cmd_fix() {
local fixed=0
local f
while IFS= read -r f; do
is_generated "${f}" && continue
has_any_notice "${f}" && continue

local year block tmp
year=$(creation_year "${f}")
tmp=$(mktemp)
case "${f}" in
*.go)
# A leading //go:build (or legacy // +build) constraint must stay the
# very first thing in the file, ahead of the license block, or
# gofmt moves it there itself.
local build_lines=0
if [[ "$(head -1 "${f}")" == '//go:build'* || "$(head -1 "${f}")" == '// +build'* ]]; then
build_lines=$(awk '/^\/\/go:build|^\/\/ \+build|^$/{n++; next} {exit} END{print n+0}' "${f}")
fi
if [[ "${build_lines}" -gt 0 ]]; then
head -n "${build_lines}" "${f}" > "${tmp}"
printf "${LLMD_BLOCK_GO}" "${year}" >> "${tmp}"
tail -n +"$((build_lines + 1))" "${f}" >> "${tmp}"
else
printf "${LLMD_BLOCK_GO}" "${year}" > "${tmp}"
cat "${f}" >> "${tmp}"
fi
;;
*.sh)
if [[ "$(head -1 "${f}")" == '#!'* ]]; then
head -1 "${f}" > "${tmp}"
echo >> "${tmp}"
printf "${LLMD_BLOCK_SH}" "${year}" >> "${tmp}"
tail -n +2 "${f}" >> "${tmp}"
else
printf "${LLMD_BLOCK_SH}" "${year}" > "${tmp}"
cat "${f}" >> "${tmp}"
fi
;;
*)
rm -f "${tmp}"
continue
;;
esac
cat "${tmp}" > "${f}" && rm -f "${tmp}"
echo "fixed: ${f}"
fixed=$((fixed + 1))
done < <(in_scope_files)
echo "${fixed} file(s) updated"
}

cmd_classify() {
echo "Building GAIE-commit marker set..." >&2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

classify's history heuristic self-pollutes after this PR's own commits
internal/runnable/leader_election.go and pkg/epp/util/env/env_test.go were manually classified (correctly) as "unmodified GAIE import" and given only the Kubernetes notice. Re-running classify on the final tree now flags both as NEEDS-LLMD-NOTICE, because the backfill commit itself (chore: backfill missing copyright notices) is not GAIE-marked or in the mechanical-rewrite grep list, so it counts as a "local touch" that flips the classification. This means any future incidental commit (a typo fix, a lint pass) will permanently and falsely flag an otherwise-untouched GAIE file.
Since only verify (not classify) is gated in make presubmit, this doesn't block anything today, but it's worth a one-line comment in the script noting the limitation, or excluding commits that touch only the license header from the "local touch" set.

local gaie_file mech_file notlocal_file
gaie_file=$(mktemp); mech_file=$(mktemp); notlocal_file=$(mktemp)
trap 'rm -f "${gaie_file}" "${mech_file}" "${notlocal_file}"' RETURN

git log --format=%H --grep="${GAIE_MARKER}" -F | sort -u > "${gaie_file}"
git log --format=%H "${MECHANICAL_GREP[@]}" | sort -u > "${mech_file}"
sort -mu "${gaie_file}" "${mech_file}" > "${notlocal_file}"

local gaie_count mech_count total_count
gaie_count=$(wc -l < "${gaie_file}")
mech_count=$(wc -l < "${mech_file}")
total_count=$(git rev-list --count HEAD)
echo "GAIE-marked commits: ${gaie_count} / ${total_count} total"
echo "Mechanical import-rewrite commits: ${mech_count}"
echo

local llmd_only=0 k8s_only=0 both=0
local f origin creator
while IFS= read -r f; do

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the loop has no is_generated check, unlike cmd_verify and cmd_fix. Running classify on the final tree reports 6 false positives (zz_generated.*.go x4, vllm_engine.pb.go, vllm_engine_grpc.pb.go) that are deliberately, correctly exempted everywhere else.
One-line fix: add is_generated "${f}" && continue to the loop, matching the other two modes.

creator=$(git log --follow --diff-filter=A --format=%H -- "${f}" | tail -1)
if [[ -z "${creator}" ]]; then
creator=$(git log --format=%H -- "${f}" | tail -1)
fi
if grep -qxF "${creator}" "${gaie_file}"; then
origin="GAIE"
else
origin="LLMD"
fi

local has_l has_k
has_llmd_notice "${f}" && has_l=1 || has_l=0
has_k8s_notice "${f}" && has_k=1 || has_k=0

if [[ "${origin}" == "LLMD" ]]; then
llmd_only=$((llmd_only + 1))
[[ "${has_k}" == 1 ]] && echo "MISATTRIBUTED(llm-d origin, k8s notice, needs human review): ${f}"
else
# GAIE origin: k8s-only vs both depends on whether local history added
# real changes beyond the mechanical import rewrite.
local touches
touches=$(comm -23 <(git log --follow --format=%H -- "${f}" | sort -u) "${notlocal_file}" | wc -l)
if [[ "${touches}" -eq 0 ]]; then
k8s_only=$((k8s_only + 1))
[[ "${has_l}" == 1 && "${has_k}" == 0 ]] && \
echo "NEEDS-K8S-NOTICE(unmodified GAIE import, llm-d-only notice): ${f}"
[[ "${has_l}" == 0 && "${has_k}" == 0 ]] && \
echo "NEEDS-K8S-NOTICE(unmodified GAIE import, no notice): ${f}"
else
both=$((both + 1))
[[ "${has_l}" == 0 ]] && echo "NEEDS-LLMD-NOTICE(modified GAIE import): ${f}"
[[ "${has_l}" == 1 && "${has_k}" == 0 ]] && \
echo "NEEDS-K8S-NOTICE(modified GAIE import, llm-d-only notice): ${f}"
fi
fi
done < <(in_scope_files | grep '\.go$')

echo
echo "Summary (Go files):"
echo " llm-d origin: ${llmd_only}"
echo " Kubernetes only: ${k8s_only}"
echo " Both (GAIE + local): ${both}"
}

case "${MODE}" in
verify) cmd_verify ;;
fix) cmd_fix ;;
classify) cmd_classify ;;
*)
echo "usage: $0 [verify|fix|classify]" >&2
exit 2
;;
esac
1 change: 1 addition & 0 deletions hack/referencer.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright 2024 The Kubernetes Authors.
Copyright 2026 The llm-d Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
Loading
Loading