From 852f6b2ced317d2f699439b02398f16e896b70fd Mon Sep 17 00:00:00 2001 From: Bradley G Smith Date: Feb 02 2024 19:55:05 +0000 Subject: Prepare Repository For New Workflow The new workflow uses newrelease.sh to generate the spec file from a template and from values in newrelease.conf. The conf file is excluded from the repository. --- diff --git a/.gitignore b/.gitignore index 97ec439..3949a38 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +newrelease.conf /kubernetes-3ddd0f4.tar.gz /kubernetes-aef86a9.tar.gz /kubernetes-95ee5ab.tar.gz diff --git a/newrelease.sh b/newrelease.sh new file mode 100755 index 0000000..15d9765 --- /dev/null +++ b/newrelease.sh @@ -0,0 +1,125 @@ +#!/bin/bash + +# Use newrelease.sh to update the kubernetes spec file with any change in release +# or go lang version. The goal is to separate changes to the spec file related +# to kubernetes from changes to spec file function and capabilities. This is not +# needed for the current kubernetes packages in Fedora (a single version of +# k8s for each Fedora release), but useful if not necessary for the planned +# deployment of multiple versions of k8s per Fedora release. +# +# +set -o errexit +set -o nounset +set -o pipefail + +# default configuration file name +CFG_NAME=./newrelease.conf + +# default template name postfix +# TEMPLATE_POSTFIX="-template.spec" + +### +### newrelease - set up for a new version of kubernetes. Does the following: +### 1. Checks for configuration file and will generate draft +### configuration file if missing. +### 2. Use data from configuration file to generate kubernetes.spec +### from the ./template/kubernetes.yaml template file. +### 3. Download source, if needed, based on configuration. +### +### Configuration file is named 'newrelease.conf'. +### +### Usage: +### newrelease.sh -- this help file +### newrelease.sh -h -- this help file +### newrelease.sh -y -- execute using configuration file +### +### Options: +### -y Execute script. If missing configuration file, generate draft and exit +### -h Show this message +### + +# See: https://gist.github.com/kovetskiy/a4bb510595b3a6b17bfd1bd9ac8bb4a5 +help() { + sed -rn 's/^### ?//;T;p' "$0" +} + +if [[ $# == 0 || $1 == -h || "$1" != "-y" ]]; then + help + exit 1 +fi + +# load config file from local directory using CFG_NAME +# format is standard bash source. + +# variables are: +# SPEC_NAME - name of the spec file to process +# GIT_TAG - release tag of package +# GOLANG_VERSION - minimal golang version (version used in build) + +if [ -f "$CFG_NAME" ] +then +# shellcheck disable=SC1090 + source "${CFG_NAME}" + echo "Sourcing ${CFG_NAME}" +else + echo " Creating draft configuration file" + echo " Edit ${CFG_NAME} with release information and rerun script" + { + printf "# spec file name\nexport SPEC_NAME=kubernetes\n\n" + printf "# spec template name and path\nTEMPLATE=./template/template.spec\n\n" + printf "# kubernetes release tag from git repository\n# e.g. export GIT_TAG=v1.24.3\nexport GIT_TAG=vxx.xx.xx\n\n" + printf "# the 'built-with' golang version - expressed as SEMVER\n# e.g. export GOLANG_VERSION=1.18.3\nexport GOLANG_VERSION=xx.xx.xx" + } >> "${CFG_NAME}" + exit 1 +fi + +# generate needed values +# do not edit warning +export WARNING="# Do not edit this spec file. (Re-)Generate using newrelease.sh" +# spec file in this repository +SPEC=${SPEC_NAME}.spec + +# strip and v or V prefix, if any for tar file name and spec name +export TAR_VERSION="${GIT_TAG#[vV]}" +# replace dash (if any) with tilde for spec file version +export SPEC_VERSION="${TAR_VERSION//-/\~}" +# export MAJ_MIN +MAJ_MIN=$( echo "${SPEC_VERSION}" | cut -f1,2 -d".") + + +# echo settings +echo "Spec file: ${SPEC}" +echo "Spec name: ${SPEC_NAME}" +echo "Template: ${TEMPLATE}" +echo "GIT Tag: ${GIT_TAG}" +echo "Tar Version: $TAR_VERSION}" +echo "Version: ${SPEC_VERSION}" +echo "Major:Minor: ${MAJ_MIN}" +echo "Golang Version: ${GOLANG_VERSION}" + +# basic clean up - remove spec if they exist +if [ -f "./${SPEC}" ]; then + rm "./${SPEC}" + echo "removed old spec file" +fi + +# create spec file from template using variables from +# configuration file +# inspiration: https://blog.tratif.com/2023/01/27/bash-tips-3-templating-in-bash-scripts/ +echo "creating ${SPEC}" + +# spec template spec file (must exist) +if ! [ -f "${TEMPLATE}" ]; then + echo "${TEMPLATE} - spec template missing" + exit 1 +fi + +# shellcheck disable=2016 +< "${TEMPLATE}" envsubst '$WARNING,$GIT_TAG,$TAR_VERSION,$SPEC_NAME,$SPEC_VERSION,$GOLANG_VERSION' > "${SPEC}" + +# download source +echo "Downloading source if needed" +echo "${SPEC_NAME}-${TAR_VERSION}.tar.gz" +spectool -g -s 0 "${SPEC}" + +echo "****Don't forget to run: fedpkg new-sources ${SPEC_NAME}-${TAR_VERSION}.tar.gz" diff --git a/template/kubernetes-template.spec b/template/kubernetes-template.spec new file mode 100644 index 0000000..8d47aeb --- /dev/null +++ b/template/kubernetes-template.spec @@ -0,0 +1,423 @@ +$WARNING + +%global with_debug 0 + +%if 0%{?with_debug} +# https://bugzilla.redhat.com/show_bug.cgi?id=995136#c12 +%global _dwz_low_mem_die_limit 0 +%else +%global debug_package %{nil} +%endif + +%global provider github +%global provider_tld com +%global owner kubernetes +%global repo kubernetes +# https://github.com/kubernetes/kubernetes + +%global provider_prefix %{provider}.%{provider_tld}/%{owner}/%{repo} +%global import_path kubernetes.io/ + +# **** release metadata **** +# populated by envsubst in newrelease.sh +%global gittag $GIT_TAG +%global tar_ver $TAR_VERSION +%global k8s_name $SPEC_NAME +%global k8s_ver $SPEC_VERSION +# golang 'built with' version +%global golangver $GOLANG_VERSION + +# last release version of these rpms prior to F40 restructure +# should not change once restructure goes into rawhide +%global switchver 1.28.6-4 + +# Needed otherwise "version_ldflags=$(kube::version_ldflags)" doesn't work +%global _buildshell /bin/bash +%global _checkshell /bin/bash + +############################################## +Name: %{k8s_name} +Version: %{k8s_ver} +Release: %autorelease +Summary: Open Source Production-Grade Container Scheduling And Management Platform +License: ASL 2.0 +URL: https://%{import_path} +ExclusiveArch: x86_64 aarch64 ppc64le s390x %{arm} +Source0: https://%{provider_prefix}/archive/%{gittag}/%{repo}-%{tar_ver}.tar.gz + +Source101: kube-proxy.service +Source102: kube-apiserver.service +Source103: kube-scheduler.service +Source104: kube-controller-manager.service +Source105: kubelet.service +Source106: environ-apiserver +Source107: environ-config +Source108: environ-controller-manager +Source109: environ-kubelet +Source110: environ-kubelet.kubeconfig +Source111: environ-proxy +Source112: environ-scheduler +Source113: kubernetes-accounting.conf +Source114: kubeadm.conf +Source115: kubernetes.conf +Source116: %{repo}.sysusers + +Patch3: build-with-debug-info.patch + +############################################## +# main package components - installs kubelet, kubeadm and necessary +# configuration files. Recommends kubernetes-client. + +# build requirements for kubelet, kubeadm +BuildRequires: golang >= %{golangver} +BuildRequires: make +BuildRequires: go-md2man +BuildRequires: systemd +BuildRequires: rsync + +# needed per fedora documentation - may drop as /run not used +# and kube user no longer needed +BuildRequires: systemd-rpm-macros +%{?sysusers_requires_compat} + +# additonal kubelet requirements +Requires: (containerd or cri-o) +Recommends: cri-o = %{version}-%{release} +Requires: conntrack-tools + +Requires(pre): shadow-utils +Requires: socat +Recommends: %{name}-client = %{version}-%{release} + +# additional kubeadm requirements +Requires: containernetworking-plugins +Requires: cri-tools + +# require same version for kubernetes-client if installed +Conflicts: %{name}-client < %{version}-%{release} +Conflicts: %{name}-client > %{version}-%{release} + +# provides and obsoletes kubernetes-node and kubernetes-kubeadm +Provides: kubernetes-kubeadm = %{version}-%{release} +Obsoletes: kubernetes-kubeadm <= %{switchver} +Provides: kubernetes-node = %{version}-%{release} +Obsoletes: kubernetes-node <= %{switchver} + +%description +%{summary} +Installs kubeadm and kubelet, the two basic components needed to +bootstrap, and run a cluster. The kubernetes-client sub-package, +containing kubectl, is recommended but not strictly required. +The kubernetes-client sub-package should be installed on +control plane machines. + +############################################## +%package client +Summary: Kubernetes client tools + +BuildRequires: golang >= %{golangver} +BuildRequires: make + +Conflicts: %{name} < %{version}-%{release} +Conflicts: %{name} > %{version}-%{release} + +%description client +Installs kubectl, the Kubernetes command line client. + +############################################## +%package legacy-systemd +Summary: Legacy systemd services for control plane and/or node + +BuildRequires: golang >= %{golangver} +BuildRequires: systemd +BuildRequires: rsync +BuildRequires: make +BuildRequires: go-md2man + +Requires(pre): shadow-utils +Requires: %{name} = %{version}-%{release} + +# obsoletes kubernetes-master in part +Provides: kubernetes-master = %{version}-%{release} +Obsoletes: kubernetes-master <= %{switchver} + +%description legacy-systemd +Legacy systemd services needed for manual installation of Kubernetes +on control plane or node machines. Not needed for most modern clusters. +If kubeadm is used to bootstrap Kubernetes then this rpm is not +needed as kubeadm will install these services as static pods in +the cluster on nodes as needed. If these services are used, enable + all services on each control plane. Enable kube-proxy on all nodes. + +############################################## +############################################## +%prep +%setup -q -n %{repo}-%{tar_ver} + +%if 0%{?with_debug} +%patch3 -p1 +%endif + +# src/k8s.io/kubernetes/pkg/util/certificates +# Patch the code to remove eliptic.P224 support +# For whatever reason: +# https://groups.google.com/forum/#!topic/Golang-nuts/Oq4rouLEvrU +for dir in vendor/github.com/google/certificate-transparency/go/x509 pkg/util/certificates; do + if [ -d "${dir}" ]; then + pushd ${dir} + sed -i "/^[^=]*$/ s/oidNamedCurveP224/oidNamedCurveP256/g" *.go + sed -i "/^[^=]*$/ s/elliptic\.P224/elliptic.P256/g" *.go + popd + fi +done + +mkdir -p src/k8s.io/kubernetes +mv $(ls | grep -v "^src$") src/k8s.io/kubernetes/. + +# mv command above skips all dot files. Move .generated_files and all +#.go* files +mv .generated_files src/k8s.io/kubernetes/. +mv .go* src/k8s.io/kubernetes/. + +############### + +%build + +# As of K8S 1.26.3/1.25.8/1.24.12 upstream now builds with an explicit +# version of go and will try to fetch that version if not present. +# FORCE_HOTS_GO=y overrides that specification by using the host's +# version of go. This spec file continues to use build requires to +# require as a minimum the 'built with' go version from upstream. +# +# Packagers need to ensure that the go version on the build host contains +# any security patches and other critical fixes that are part of the +# "built with" version. Go maintainers typically release patch updates +# for both supported versions of Go that contain the same security +# updates. +export FORCE_HOST_GO=y + +pushd src/k8s.io/kubernetes/ +source hack/lib/init.sh +kube::golang::setup_env + +export KUBE_GIT_TREE_STATE="clean" +export KUBE_GIT_COMMIT=%{commit} +export KUBE_GIT_VERSION=v{version} +export KUBE_EXTRA_GOPATH=$(pwd)/Godeps/_workspace + +# Build each binary separately to generate a unique build-id. +# Otherwise: Duplicate build-ids /builddir/build/BUILDROOT/.../usr/bin/kube-apiserver and /builddir/build/BUILDROOT/.../usr/bin/kubeadm +make WHAT="cmd/kube-proxy" +make WHAT="cmd/kube-apiserver" +make WHAT="cmd/kube-controller-manager" +make WHAT="cmd/kubelet" +make WHAT="cmd/kubeadm" +make WHAT="cmd/kube-scheduler" +make WHAT="cmd/kubectl" + +# Gen docs +make WHAT="cmd/gendocs" +make WHAT="cmd/genkubedocs" +make WHAT="cmd/genman" +make WHAT="cmd/genyaml" +kube::util::gen-docs . + +############### + +%install +pushd src/k8s.io/kubernetes/ +source hack/lib/init.sh +kube::golang::setup_env + +%ifarch ppc64le +output_path="_output/local/go/bin" +%else +output_path="${KUBE_OUTPUT_BINPATH}/$(kube::golang::host_platform)" +%endif + +echo "+++ INSTALLING binaries" +install -m 755 -d %{buildroot}%{_bindir} +install -p -m 755 -t %{buildroot}%{_bindir} ${output_path}/kube-proxy +install -p -m 755 -t %{buildroot}%{_bindir} ${output_path}/kube-apiserver +install -p -m 755 -t %{buildroot}%{_bindir} ${output_path}/kube-controller-manager +install -p -m 755 -t %{buildroot}%{_bindir} ${output_path}/kubelet +install -p -m 755 -t %{buildroot}%{_bindir} ${output_path}/kubeadm +install -p -m 755 -t %{buildroot}%{_bindir} ${output_path}/kube-scheduler +install -p -m 755 -t %{buildroot}%{_bindir} ${output_path}/kubectl + +echo "+++ INSTALLING kubelet service config" +install -d -m 0755 %{buildroot}/%{_unitdir}/kubelet.service.d +install -p -m 0644 -t %{buildroot}/%{_unitdir}/kubelet.service.d %{SOURCE114} + +echo "+++ INSTALLING shell completion" +install -dm 0755 %{buildroot}/%{bash_completions_dir} +%{buildroot}%{_bindir}/kubectl completion bash > %{buildroot}/%{bash_completions_dir}/kubectl +install -dm 0755 %{buildroot}/%{fish_completions_dir} +%{buildroot}%{_bindir}/kubectl completion fish > %{buildroot}/%{fish_completions_dir}/kubectl.fish +install -dm 0755 %{buildroot}/%{zsh_completions_dir} +%{buildroot}%{_bindir}/kubectl completion zsh > %{buildroot}/%{zsh_completions_dir}/_kubectl + +echo "+++ INSTALLING config files" +%define remove_environ_prefix() %(echo -n %1|sed 's/.*environ-//g') +install -d -m 0755 %{buildroot}%{_sysconfdir}/%{repo} +install -d -m 0700 %{buildroot}%{_sysconfdir}/%{repo}/manifests +install -m 644 -T %{SOURCE106} %{buildroot}%{_sysconfdir}/%{repo}/%{remove_environ_prefix %{SOURCE106}} +install -m 644 -T %{SOURCE107} %{buildroot}%{_sysconfdir}/%{repo}/%{remove_environ_prefix %{SOURCE107}} +install -m 644 -T %{SOURCE108} %{buildroot}%{_sysconfdir}/%{repo}/%{remove_environ_prefix %{SOURCE108}} +install -m 644 -T %{SOURCE109} %{buildroot}%{_sysconfdir}/%{repo}/%{remove_environ_prefix %{SOURCE109}} +install -m 644 -T %{SOURCE110} %{buildroot}%{_sysconfdir}/%{repo}/%{remove_environ_prefix %{SOURCE110}} +install -m 644 -T %{SOURCE111} %{buildroot}%{_sysconfdir}/%{repo}/%{remove_environ_prefix %{SOURCE111}} +install -m 644 -T %{SOURCE112} %{buildroot}%{_sysconfdir}/%{repo}/%{remove_environ_prefix %{SOURCE112}} + +# place systemd/tmpfiles.d/kubernetes.conf to /usr/lib/tmpfiles.d/kubernetes.conf +install -d -m 0755 %{buildroot}%{_tmpfilesdir} +install -p -m 0644 -t %{buildroot}/%{_tmpfilesdir} %{SOURCE115} + +echo "+++ INSTALLING sysusers.d" +install -D -m 0644 -vp %{SOURCE116} %{buildroot}%{_sysusersdir}/%{repo}.conf + +# enable CPU and Memory accounting +install -d -m 0755 %{buildroot}/%{_sysconfdir}/systemd/system.conf.d +install -p -m 0644 -t %{buildroot}/%{_sysconfdir}/systemd/system.conf.d %{SOURCE113} + +echo "+++ INSTALLING service files" +install -d -m 0755 %{buildroot}%{_unitdir} +install -m 0644 -t %{buildroot}%{_unitdir} %{SOURCE101} +install -m 0644 -t %{buildroot}%{_unitdir} %{SOURCE102} +install -m 0644 -t %{buildroot}%{_unitdir} %{SOURCE103} +install -m 0644 -t %{buildroot}%{_unitdir} %{SOURCE104} +install -m 0644 -t %{buildroot}%{_unitdir} %{SOURCE105} + +echo "+++ INSTALLING manpages" +install -d %{buildroot}%{_mandir}/man1 +# from k8s tarball copied docs/man/man1/*.1 +install -p -m 644 docs/man/man1/*.1 %{buildroot}%{_mandir}/man1 + +# install the place the kubelet defaults to put volumes and default folder structure +install -d %{buildroot}%{_sharedstatedir}/kubelet + +mkdir -p %{buildroot}/run +install -d -m 0755 %{buildroot}/run/%{repo}/ +popd + +mv src/k8s.io/kubernetes/CHANGELOG/CHANGELOG-*.md . +mv src/k8s.io/kubernetes/*.md . +mv src/k8s.io/kubernetes/LICENSE . +# CHANGELOG.md is symlink to CHANGELOG/README.md and not actual +# change log. no need to include generated rpms +rm CHANGELOG.md + +%check +if [ 1 != 1 ]; then +echo "******Testing the commands*****" +hack/test-cmd.sh +echo "******Benchmarking kube********" +hack/benchmark-go.sh + +# In Fedora 20 and RHEL7 the go cover tools isn't available correctly +echo "******Testing the go code******" +hack/test-go.sh +echo "******Testing integration******" +hack/test-integration.sh --use_go_build +fi + +############################################## +%files +%license LICENSE +%doc *.md + +# kubelet +%{_mandir}/man1/kubelet.1* +%{_bindir}/kubelet +%{_unitdir}/kubelet.service +%{_sysusersdir}/%{repo}.conf +%dir %{_sharedstatedir}/kubelet +%dir %{_sysconfdir}/%{repo} +%dir %{_sysconfdir}/%{repo}/manifests +%config(noreplace) %{_sysconfdir}/%{repo}/config +%config(noreplace) %{_sysconfdir}/%{repo}/kubelet +# % config(noreplace) % {_sysconfdir}/% {repo}/proxy +%config(noreplace) %{_sysconfdir}/%{repo}/kubelet.kubeconfig +%config(noreplace) %{_sysconfdir}/systemd/system.conf.d/kubernetes-accounting.conf +%{_tmpfilesdir}/kubernetes.conf +%verify(not size mtime md5) %attr(755, kube,kube) %dir /run/%{repo} + +# kubeadm +%{_mandir}/man1/kubeadm.1* +%{_mandir}/man1/kubeadm-* +%{_bindir}/kubeadm +%dir %{_unitdir}/kubelet.service.d +%config(noreplace) %{_unitdir}/kubelet.service.d/kubeadm.conf + +############################################## +%files client +%license LICENSE +%doc *.md +%{_mandir}/man1/kubectl.1* +%{_mandir}/man1/kubectl-* +%{_bindir}/kubectl +%{bash_completions_dir}/kubectl +%{fish_completions_dir}/kubectl.fish +%{zsh_completions_dir}/_kubectl + +############################################## + +%files legacy-systemd +%license LICENSE +%doc *.md +%{_mandir}/man1/kube-apiserver.1* +%{_mandir}/man1/kube-controller-manager.1* +%{_mandir}/man1/kube-scheduler.1* +%{_mandir}/man1/kube-proxy.1* +%attr(754, -, kube) %caps(cap_net_bind_service=ep) %{_bindir}/kube-apiserver +%{_bindir}/kube-controller-manager +%{_bindir}/kube-scheduler +%{_bindir}/kube-proxy +%{_unitdir}/kube-proxy.service +%{_unitdir}/kube-apiserver.service +%{_unitdir}/kube-controller-manager.service +%{_unitdir}/kube-scheduler.service +%{_sysusersdir}/%{repo}.conf +%dir %{_sysconfdir}/%{repo} +%config(noreplace) %{_sysconfdir}/%{repo}/apiserver +%config(noreplace) %{_sysconfdir}/%{repo}/scheduler +%config(noreplace) %{_sysconfdir}/%{repo}/config +%config(noreplace) %{_sysconfdir}/%{repo}/controller-manager +%config(noreplace) %{_sysconfdir}/%{repo}/proxy +%{_tmpfilesdir}/kubernetes.conf +%verify(not size mtime md5) %attr(755, kube,kube) %dir /run/%{repo} + +############################################## + +%pre legacy-systemd +%sysusers_create_compat %{SOURCE116} + +%post legacy-systemd +%systemd_post kube-apiserver kube-scheduler kube-controller-manager kube-proxy + +%preun legacy-systemd +%systemd_preun kube-apiserver kube-scheduler kube-controller-manager kube-proxy + +%postun legacy-systemd +%systemd_postun kube-apiserver kube-scheduler kube-controller-manager kube-proxy + + +%pre +%sysusers_create_compat %{SOURCE116} + +%post +%systemd_post kubelet +# If accounting is not currently enabled systemd reexec +if [[ `systemctl show kubelet | grep -q -e CPUAccounting=no -e MemoryAccounting=no; echo $?` -eq 0 ]]; then + systemctl daemon-reexec +fi + +%preun +%systemd_preun kubelet + +%postun +%systemd_postun kubelet + +############################################ +%changelog +%autochangelog