diff --git a/.github/goreleaser.yml b/.github/goreleaser.yml index 2b1899514..6c0ae33e8 100644 --- a/.github/goreleaser.yml +++ b/.github/goreleaser.yml @@ -27,6 +27,14 @@ archives: ids: - silo name_template: "silo_{{ .Env.PKG_VERSION }}_{{ .Os }}_{{ .Arch }}" + # Explicit so the license materials cannot silently drop out of the + # binary archives: GoReleaser's default file globs would miss NOTICE. + # CREDITS stays out deliberately -- at 1.8MB it would dominate the + # archive; it remains available in the repository and the OCI image. + files: + - README.md + - LICENSE + - NOTICE checksum: name_template: "silo_{{ .Env.PKG_VERSION }}_checksums.txt" diff --git a/.github/nfpm.yml b/.github/nfpm.yml index 05182a793..7d376c16e 100644 --- a/.github/nfpm.yml +++ b/.github/nfpm.yml @@ -42,6 +42,60 @@ contents: mode: 0644 owner: root group: root + # The license materials are declared once per packager: nfpm only honors + # type: license on rpm and silently drops such entries from deb and apk, so + # the rpm keeps its %license flag while deb and apk carry plain files at the + # same path. + - src: ${NFPM_LICENSE} + dst: /usr/share/doc/silo/LICENSE + type: license + packager: rpm + expand: true + file_info: + mode: 0644 + owner: root + group: root + - src: ${NFPM_NOTICE} + dst: /usr/share/doc/silo/NOTICE + type: license + packager: rpm + expand: true + file_info: + mode: 0644 + owner: root + group: root + - src: ${NFPM_LICENSE} + dst: /usr/share/doc/silo/LICENSE + packager: deb + expand: true + file_info: + mode: 0644 + owner: root + group: root + - src: ${NFPM_NOTICE} + dst: /usr/share/doc/silo/NOTICE + packager: deb + expand: true + file_info: + mode: 0644 + owner: root + group: root + - src: ${NFPM_LICENSE} + dst: /usr/share/doc/silo/LICENSE + packager: apk + expand: true + file_info: + mode: 0644 + owner: root + group: root + - src: ${NFPM_NOTICE} + dst: /usr/share/doc/silo/NOTICE + packager: apk + expand: true + file_info: + mode: 0644 + owner: root + group: root scripts: postinstall: buildscripts/package/postinstall.sh diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml index b61fc8e3e..af49d8f66 100644 --- a/.github/workflows/docker-release.yml +++ b/.github/workflows/docker-release.yml @@ -126,7 +126,7 @@ jobs: archive="${assets_dir}/silo_${PKG_VERSION}_linux_${arch}.tar.gz" mkdir -p "${context}/dockerscripts" tar -xzf "${archive}" -C "${context}" silo - cp Dockerfile.goreleaser LICENSE CREDITS "${context}/" + cp Dockerfile.goreleaser LICENSE NOTICE CREDITS "${context}/" cp dockerscripts/docker-entrypoint.sh dockerscripts/download-static-curl.sh \ "${context}/dockerscripts/" done diff --git a/.github/workflows/test-release.yml b/.github/workflows/test-release.yml index 8bc650f41..3397977b7 100644 --- a/.github/workflows/test-release.yml +++ b/.github/workflows/test-release.yml @@ -171,6 +171,8 @@ jobs: service_sha="$(sha256sum ../../silo.service | awk '{print $1}')" defaults_sha="$(sha256sum ../../silo.env | awk '{print $1}')" sysusers_sha="$(sha256sum ../../silo.sysusers | awk '{print $1}')" + license_sha="$(sha256sum ../../LICENSE | awk '{print $1}')" + notice_sha="$(sha256sum ../../NOTICE | awk '{print $1}')" rpm_file="silo-${PKG_VERSION}-1.x86_64.rpm" test "$(rpm -qp --queryformat '%{VENDOR}' "${rpm_file}")" = "${expected_vendor}" @@ -184,7 +186,16 @@ jobs: rpm -qpl "${rpm_file}" | grep -Fx '/usr/lib/systemd/system/silo.service' rpm -qpl "${rpm_file}" | grep -Fx '/etc/default/silo' rpm -qpl "${rpm_file}" | grep -Fx '/usr/lib/sysusers.d/silo.conf' - test "$(rpm -qpl "${rpm_file}" | wc -l)" -eq 4 + rpm -qpl "${rpm_file}" | grep -Fx '/usr/share/doc/silo/LICENSE' + rpm -qpl "${rpm_file}" | grep -Fx '/usr/share/doc/silo/NOTICE' + test "$(rpm -qpl "${rpm_file}" | wc -l)" -eq 6 + # nfpm only honors type: license on rpm, which is why nfpm.yml + # declares the license materials once per packager. Pin the rpm + # %license flag so that split cannot silently regress. + rpm -qp --queryformat '[%{FILEFLAGS:fflags} %{FILENAMES}\n]' "${rpm_file}" \ + | grep -Fx 'l /usr/share/doc/silo/LICENSE' + rpm -qp --queryformat '[%{FILEFLAGS:fflags} %{FILENAMES}\n]' "${rpm_file}" \ + | grep -Fx 'l /usr/share/doc/silo/NOTICE' if rpm -qp --conflicts "${rpm_file}" | grep -qi minio; then echo "RPM must not declare a cross-name conflict with MinIO" >&2 exit 1 @@ -209,7 +220,9 @@ jobs: dpkg-deb --contents "${deb_file}" | grep -E 'usr/lib/systemd/system/silo\.service$' dpkg-deb --contents "${deb_file}" | grep -E 'etc/default/silo$' dpkg-deb --contents "${deb_file}" | grep -E 'usr/lib/sysusers\.d/silo\.conf$' - test "$(dpkg-deb --contents "${deb_file}" | awk '$1 !~ /^d/ { count++ } END { print count + 0 }')" -eq 4 + dpkg-deb --contents "${deb_file}" | grep -E 'usr/share/doc/silo/LICENSE$' + dpkg-deb --contents "${deb_file}" | grep -E 'usr/share/doc/silo/NOTICE$' + test "$(dpkg-deb --contents "${deb_file}" | awk '$1 !~ /^d/ { count++ } END { print count + 0 }')" -eq 6 test -z "$(dpkg-deb --field "${deb_file}" Conflicts)" test -z "$(dpkg-deb --field "${deb_file}" Replaces)" test -z "$(dpkg-deb --field "${deb_file}" Provides)" @@ -224,7 +237,9 @@ jobs: tar -tzf "silo_${PKG_VERSION}_x86_64.apk" | grep -Fx 'usr/lib/systemd/system/silo.service' tar -tzf "silo_${PKG_VERSION}_x86_64.apk" | grep -Fx 'etc/default/silo' tar -tzf "silo_${PKG_VERSION}_x86_64.apk" | grep -Fx 'usr/lib/sysusers.d/silo.conf' - test "$(tar -tzf "silo_${PKG_VERSION}_x86_64.apk" | awk '$0 !~ /^\./ && $0 !~ /\/$/ { count++ } END { print count + 0 }')" -eq 4 + tar -tzf "silo_${PKG_VERSION}_x86_64.apk" | grep -Fx 'usr/share/doc/silo/LICENSE' + tar -tzf "silo_${PKG_VERSION}_x86_64.apk" | grep -Fx 'usr/share/doc/silo/NOTICE' + test "$(tar -tzf "silo_${PKG_VERSION}_x86_64.apk" | awk '$0 !~ /^\./ && $0 !~ /\/$/ { count++ } END { print count + 0 }')" -eq 6 if grep -Ei '^provides = .*minio' <<< "${apk_info}"; then echo "APK must not provide a MinIO package alias" >&2 exit 1 @@ -269,14 +284,22 @@ jobs: "silo-${PKG_VERSION}-1.${rpm_arch}.rpm" | awk '$1 == "/etc/default/silo" { print $2 }')" rpm_sysusers_sha="$(rpm -qp --queryformat '[%{FILENAMES} %{FILEDIGESTS}\n]' \ "silo-${PKG_VERSION}-1.${rpm_arch}.rpm" | awk '$1 == "/usr/lib/sysusers.d/silo.conf" { print $2 }')" + rpm_license_sha="$(rpm -qp --queryformat '[%{FILENAMES} %{FILEDIGESTS}\n]' \ + "silo-${PKG_VERSION}-1.${rpm_arch}.rpm" | awk '$1 == "/usr/share/doc/silo/LICENSE" { print $2 }')" + rpm_notice_sha="$(rpm -qp --queryformat '[%{FILENAMES} %{FILEDIGESTS}\n]' \ + "silo-${PKG_VERSION}-1.${rpm_arch}.rpm" | awk '$1 == "/usr/share/doc/silo/NOTICE" { print $2 }')" deb_sha="$(ar p "silo_${PKG_VERSION}_${deb_arch}.deb" data.tar.gz | tar -xzOf - ./usr/bin/silo | sha256sum | awk '{print $1}')" deb_service_sha="$(ar p "silo_${PKG_VERSION}_${deb_arch}.deb" data.tar.gz | tar -xzOf - ./usr/lib/systemd/system/silo.service | sha256sum | awk '{print $1}')" deb_defaults_sha="$(ar p "silo_${PKG_VERSION}_${deb_arch}.deb" data.tar.gz | tar -xzOf - ./etc/default/silo | sha256sum | awk '{print $1}')" deb_sysusers_sha="$(ar p "silo_${PKG_VERSION}_${deb_arch}.deb" data.tar.gz | tar -xzOf - ./usr/lib/sysusers.d/silo.conf | sha256sum | awk '{print $1}')" + deb_license_sha="$(ar p "silo_${PKG_VERSION}_${deb_arch}.deb" data.tar.gz | tar -xzOf - ./usr/share/doc/silo/LICENSE | sha256sum | awk '{print $1}')" + deb_notice_sha="$(ar p "silo_${PKG_VERSION}_${deb_arch}.deb" data.tar.gz | tar -xzOf - ./usr/share/doc/silo/NOTICE | sha256sum | awk '{print $1}')" apk_sha="$(tar -xzOf "silo_${PKG_VERSION}_${apk_arch}.apk" usr/bin/silo | sha256sum | awk '{print $1}')" apk_service_sha="$(tar -xzOf "silo_${PKG_VERSION}_${apk_arch}.apk" usr/lib/systemd/system/silo.service | sha256sum | awk '{print $1}')" apk_defaults_sha="$(tar -xzOf "silo_${PKG_VERSION}_${apk_arch}.apk" etc/default/silo | sha256sum | awk '{print $1}')" apk_sysusers_sha="$(tar -xzOf "silo_${PKG_VERSION}_${apk_arch}.apk" usr/lib/sysusers.d/silo.conf | sha256sum | awk '{print $1}')" + apk_license_sha="$(tar -xzOf "silo_${PKG_VERSION}_${apk_arch}.apk" usr/share/doc/silo/LICENSE | sha256sum | awk '{print $1}')" + apk_notice_sha="$(tar -xzOf "silo_${PKG_VERSION}_${apk_arch}.apk" usr/share/doc/silo/NOTICE | sha256sum | awk '{print $1}')" test "${source_sha}" = "${rpm_sha}" test "${source_sha}" = "${deb_sha}" @@ -290,6 +313,12 @@ jobs: test "${sysusers_sha}" = "${rpm_sysusers_sha}" test "${sysusers_sha}" = "${deb_sysusers_sha}" test "${sysusers_sha}" = "${apk_sysusers_sha}" + test "${license_sha}" = "${rpm_license_sha}" + test "${license_sha}" = "${deb_license_sha}" + test "${license_sha}" = "${apk_license_sha}" + test "${notice_sha}" = "${rpm_notice_sha}" + test "${notice_sha}" = "${deb_notice_sha}" + test "${notice_sha}" = "${apk_notice_sha}" done find . -maxdepth 1 -type f | sort diff --git a/Dockerfile.goreleaser b/Dockerfile.goreleaser index 895485e79..296b83f82 100644 --- a/Dockerfile.goreleaser +++ b/Dockerfile.goreleaser @@ -91,6 +91,7 @@ COPY --from=build /go/bin/mcli /usr/bin/mcli COPY --from=build /go/bin/curl* /usr/bin/ COPY dockerscripts/docker-entrypoint.sh /usr/bin/docker-entrypoint.sh COPY LICENSE /licenses/LICENSE +COPY NOTICE /licenses/NOTICE COPY CREDITS /licenses/CREDITS RUN chmod +x /usr/bin/silo /usr/bin/mcli /usr/bin/docker-entrypoint.sh && \ diff --git a/Makefile b/Makefile index af37ba8a4..bd7afbcaa 100644 --- a/Makefile +++ b/Makefile @@ -215,7 +215,7 @@ docker: checks build-debugging ## builds the local Linux Silo container image CGO_ENABLED=0 GOOS=linux GOARCH=$(GOARCH) go build -tags kqueue -trimpath \ --ldflags "$(LDFLAGS)" -o "$$context/silo"; \ mkdir -p "$$context/dockerscripts"; \ - cp Dockerfile.goreleaser LICENSE CREDITS "$$context/"; \ + cp Dockerfile.goreleaser LICENSE NOTICE CREDITS "$$context/"; \ cp dockerscripts/docker-entrypoint.sh dockerscripts/download-static-curl.sh \ "$$context/dockerscripts/"; \ docker build -q --no-cache --platform linux/$(GOARCH) -t $(TAG) --build-arg TARGETARCH=$(GOARCH) \ diff --git a/NOTICE b/NOTICE index 9111013e8..8d65db8b8 100644 --- a/NOTICE +++ b/NOTICE @@ -1,4 +1,4 @@ -MinIO Project, (C) 2015-2023 MinIO, Inc. +MinIO Project, (C) 2015-2025 MinIO, Inc. This product includes software developed at MinIO, Inc. (https://min.io/). diff --git a/buildscripts/package-release.sh b/buildscripts/package-release.sh index 948449731..bb128df78 100755 --- a/buildscripts/package-release.sh +++ b/buildscripts/package-release.sh @@ -37,6 +37,8 @@ fi unit_file="${repo_dir}/silo.service" defaults_file="${repo_dir}/silo.env" sysusers_file="${repo_dir}/silo.sysusers" +license_file="${repo_dir}/LICENSE" +notice_file="${repo_dir}/NOTICE" postinstall_file="${repo_dir}/buildscripts/package/postinstall.sh" preremove_file="${repo_dir}/buildscripts/package/preremove.sh" if [ ! -f "${unit_file}" ]; then @@ -51,6 +53,12 @@ if [ ! -f "${sysusers_file}" ]; then echo "Missing sysusers file: ${sysusers_file}" >&2 exit 1 fi +for distributed_doc in "${license_file}" "${notice_file}"; do + if [ ! -s "${distributed_doc}" ]; then + echo "Missing license material: ${distributed_doc}" >&2 + exit 1 + fi +done for lifecycle_script in "${postinstall_file}" "${preremove_file}"; do if [ ! -x "${lifecycle_script}" ]; then echo "Missing executable package lifecycle script: ${lifecycle_script}" >&2 @@ -122,11 +130,13 @@ build_arch() { ( cd "${repo_dir}" - PKG_VERSION="${PKG_VERSION}" NFPM_RELEASE=1 NFPM_ARCH="${goarch}" NFPM_SOURCE="${source}" NFPM_UNIT="${unit_file}" NFPM_DEFAULTS="${defaults_file}" NFPM_SYSUSERS="${sysusers_file}" \ + export NFPM_UNIT="${unit_file}" NFPM_DEFAULTS="${defaults_file}" NFPM_SYSUSERS="${sysusers_file}" \ + NFPM_LICENSE="${license_file}" NFPM_NOTICE="${notice_file}" + PKG_VERSION="${PKG_VERSION}" NFPM_RELEASE=1 NFPM_ARCH="${goarch}" NFPM_SOURCE="${source}" \ nfpm package --config "${nfpm_config}" --packager rpm --target "${rpm_file}" - PKG_VERSION="${PKG_VERSION}" NFPM_RELEASE='' NFPM_ARCH="${goarch}" NFPM_SOURCE="${source}" NFPM_UNIT="${unit_file}" NFPM_DEFAULTS="${defaults_file}" NFPM_SYSUSERS="${sysusers_file}" \ + PKG_VERSION="${PKG_VERSION}" NFPM_RELEASE='' NFPM_ARCH="${goarch}" NFPM_SOURCE="${source}" \ nfpm package --config "${nfpm_config}" --packager deb --target "${deb_file}" - PKG_VERSION="${PKG_VERSION}" NFPM_RELEASE='' NFPM_ARCH="${goarch}" NFPM_SOURCE="${source}" NFPM_UNIT="${unit_file}" NFPM_DEFAULTS="${defaults_file}" NFPM_SYSUSERS="${sysusers_file}" \ + PKG_VERSION="${PKG_VERSION}" NFPM_RELEASE='' NFPM_ARCH="${goarch}" NFPM_SOURCE="${source}" \ nfpm package --config "${nfpm_config}" --packager apk --target "${apk_file}" ) diff --git a/buildscripts/sign-release-rpms.sh b/buildscripts/sign-release-rpms.sh index f8b66bc1c..32816626d 100755 --- a/buildscripts/sign-release-rpms.sh +++ b/buildscripts/sign-release-rpms.sh @@ -17,7 +17,9 @@ expected_group="Applications/File" expected_payload="/etc/default/silo /usr/bin/silo /usr/lib/systemd/system/silo.service -/usr/lib/sysusers.d/silo.conf" +/usr/lib/sysusers.d/silo.conf +/usr/share/doc/silo/LICENSE +/usr/share/doc/silo/NOTICE" repository="${GH_REPO:-pgsty/silo}" container="${DNFUPDATE_CONTAINER:-dnfupdate}" upload=false diff --git a/buildscripts/verify-rebrand.sh b/buildscripts/verify-rebrand.sh index ba810cbef..d707c18dd 100755 --- a/buildscripts/verify-rebrand.sh +++ b/buildscripts/verify-rebrand.sh @@ -120,6 +120,8 @@ require_text cmd/build-constants.go 'upstreamCopyrightEndYear = "2025"' require_text cmd/build-constants.go 'forkCopyrightStartYear = "2025"' require_text cmd/main.go 'upstreamCopyrightEndYear' reject_text cmd/main.go 'CopyrightYear = strconv.Itoa(time.Now().Year())' +require_text NOTICE 'MinIO Project, (C) 2015-2025 MinIO, Inc.' +require_text NOTICE 'Silo Project modifications, (C) 2025-2026 PGSTY.' # Contribution policy: no CLA, inbound=outbound, DCO sign-off enforced in CI. require_file .github/workflows/dco.yml diff --git a/silo.service b/silo.service index c49416d53..54fa8f52a 100644 --- a/silo.service +++ b/silo.service @@ -9,8 +9,6 @@ AssertFileIsExecutable=/usr/bin/silo [Service] Type=notify -WorkingDirectory=/usr/local - User=silo Group=silo ProtectProc=invisible