Skip to content

Conversation

tadiwa-aizen
Copy link
Contributor

@tadiwa-aizen tadiwa-aizen commented Sep 26, 2025

What changed and why?

Added a new RPM spec file generator (generate_spec.py) that creates distribution-specific .spec files by extracting versions from Cargo.toml/rust-toolchain.toml, scanning git submodules for bundled library declarations, and merging this data with distro-specific templates containing appropriate package names and build commands.

Also added the template file for Amazon Linux 2023 (templates/amzn2023.spec.template) containing AL2023-specific BuildRequires, runtime dependencies, and build commands including manual cargo build steps and rust-toolset requirements.

Usage :

uv run python generate_spec.py amzn2023

Generated amzn2023.spec


Please confirm there's no breaking change, or call out any that are made.

No breaking change

Does this change need a changelog entry? Does it require a version change?

No


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and I agree to the terms of the Developer Certificate of Origin (DCO).

@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
@tadiwa-aizen tadiwa-aizen temporarily deployed to PR integration tests September 26, 2025 07:44 — with GitHub Actions Inactive
It allows you to mount an S3 bucket as a local file system, providing
high-throughput access to S3 objects through standard file system operations.

This package includes bundled AWS Common Runtime (CRT) libraries and
Copy link
Contributor

Choose a reason for hiding this comment

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

Does building the srpm file always produce the exact same binary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted, removed, it


# Fedora packaging guidlines require a manifest that lists the names and versions of all
# crates in the vendor tarball. They also note that this file must be added as a %license file. Macros which do this automatically are not available on all platforms.
grep -E '^(name|version) = ' Cargo.lock \
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we doing this if we're importing a pre-built license file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So the manifest is different from the THIRD_PARTY_LICENSES, which is essentially legal stuff and not much detail on dependancies.

The manifest allows for security scanners to see everything we've bundled. It's like the provides section above but for the entire projects dependancies, and not just the CRT.

As seen here: https://docs.fedoraproject.org/en-US/packaging-guidelines/Rust/#_vendored_dependencies

/usr/bin/mount-s3
/usr/sbin/mount.mount-s3

%changelog
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this changelog meant to be for this rpm or for Mountpoint itself?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the changelog for the desert linux package mainly. We already have one here. For this will mainly track each release into AL, thus i assume its best to track each release from 1.20.0 onwards.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we just provide link to our changelog on GitHub here instead? Do we really need to duplicate changelog here?

# the default lower limit.
ulimit -n 4096
cargo test --release --frozen --offline -- \
--skip mnt::test::mount_unmount \
Copy link
Contributor

Choose a reason for hiding this comment

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

Why skip these tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Kj doesnt allow you to mount in the builds run.


Requires: fuse

# BUNDLED C/C++ LIBRARIES - Required virtual provides for security tracking
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please add instructions to always add new CRT libraries to this file?

Maybe as a comment into https://github.com/awslabs/mountpoint-s3/blob/7854f020d9f31efaf0e392367cf844f059c30b47/mountpoint-s3-crt-sys/UPDATING_CRT.md or

/// The CRT libraries we use, in order of their dependencies.
const CRT_LIBRARIES: &[&str] = &[
"aws-c-common",
"aws-c-cal",
"aws-c-io",
"aws-c-compression",
"aws-c-http",
"aws-c-sdkutils",
"aws-c-auth",
"aws-checksums",
"aws-c-s3",
];
so that we won't forget.

BuildRequires: clang
BuildRequires: clang-devel
BuildRequires: llvm
BuildRequires: rust
Copy link
Contributor

Choose a reason for hiding this comment

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

Which version of rust is this? Can we specify exact version to match rust version in

channel = "1.88"
?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted, I'll leave the
BuildRequires: rust >= 1.88
BuildRequires: cargo >= 1.88

Copy link
Contributor

Choose a reason for hiding this comment

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

we should match exact version as in our other builds? (if we want same/reproducable builds)

Let's do rust = 1.88 instead?

It allows you to mount an S3 bucket as a local file system, providing
high-throughput access to S3 objects through standard file system operations.

This package includes bundled AWS Common Runtime (CRT) libraries and
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to talk about CRT and Rust libraries in the package description? Sounds like just an implementation detail (which could change in the future).

BuildRequires: make
BuildRequires: which

Requires: fuse
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we specify that we need fuse v2? E.g. >= 2.9.0?

/opt/aws/mountpoint-s3/bin/mount-s3
/opt/aws/mountpoint-s3/cargo-vendor.txt
/usr/bin/mount-s3
/usr/sbin/mount.mount-s3
Copy link
Contributor

Choose a reason for hiding this comment

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

Did we test/validate that fstab feature works with this new Mountpoint AL2023 RPM? As I understand there are no automatic tests for fstab for this new RPM

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, fstab works fine, i've tested it. We could add automated tests the the current AMI test CR if you'd like?


Name: mount-s3
Version: 1.20.0
Release: 1.amzn2023
Copy link
Contributor

@yerzhan7 yerzhan7 Sep 26, 2025

Choose a reason for hiding this comment

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

In the future there might be new Amazon Linux version and we might need to release RPM versions for both AL2023 and the new Amazon Linux. So, would we re-use the same spec file for both Amazon linux versions or will we create 2 separate spec files?

I am just thinking that maybe we should rename this file to package/amazon-linux-2023-packaging.spec if we hardcode AL2023 on this line?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can do 1.%{dist} to that automatically expands to 1.amz2023 via macro?

Version: 1.20.0
Release: 1.amzn2023
Summary: High-performance file system for Amazon S3

Copy link
Contributor

Choose a reason for hiding this comment

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

Should we also add BuildArchitectures: x86_64 aarch64?

Provides: bundled(aws-c-io)
Provides: bundled(aws-c-s3)
Provides: bundled(aws-c-sdkutils)
Provides: bundled(aws-lc)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should specify exact version that we are bundling so that it's easier to track vulnerabilities.

E.g. Provides: bundled(aws-lc) = 1.61.3

@tadiwa-aizen tadiwa-aizen requested a deployment to PR integration tests October 2, 2025 22:43 — with GitHub Actions Waiting
@tadiwa-aizen tadiwa-aizen requested a deployment to PR integration tests October 2, 2025 22:43 — with GitHub Actions Waiting
@tadiwa-aizen tadiwa-aizen requested a deployment to PR integration tests October 2, 2025 22:43 — with GitHub Actions Waiting
@tadiwa-aizen tadiwa-aizen changed the title Al2023 spec file Spec file generator Oct 7, 2025
@tadiwa-aizen tadiwa-aizen requested a deployment to PR integration tests October 7, 2025 21:07 — with GitHub Actions Waiting
@tadiwa-aizen tadiwa-aizen requested a deployment to PR integration tests October 8, 2025 17:18 — with GitHub Actions Waiting
@@ -0,0 +1,49 @@
{# Amazon Linux 2023 Template - Distribution-specific sections #}

Copy link
Contributor Author

@tadiwa-aizen tadiwa-aizen Oct 9, 2025

Choose a reason for hiding this comment

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

This is the spec file created:

%bcond_without check

Name:           mount-s3
Version:        1.21.0
Release:        amzn2023
Summary:        Mountpoint for Amazon S3

License:        Apache-2.0
URL:            https://github.com/awslabs/mountpoint-s3 
Source0:        mountpoint-s3-1.21.0.tar.gz
Source1:        LICENSE
Source2:        NOTICE
Source3:        THIRD_PARTY_LICENSES

BuildRequires:  clang
BuildRequires:  clang-devel
BuildRequires:  rust >= 1.88      
BuildRequires:  cargo >= 1.88    
BuildRequires:  cmake
BuildRequires:  gcc
BuildRequires:  gcc-c++
BuildRequires:  git
BuildRequires:  pkgconfig
BuildRequires:  fuse-devel
BuildRequires:  glibc-devel
BuildRequires:  glibc-headers
BuildRequires:  glibc-static
BuildRequires:  libstdc++-devel
BuildRequires:  nasm
BuildRequires:  make
BuildRequires:  which
BuildRequires:  rust-packaging
BuildRequires:  rust-toolset

ExclusiveArch: x86_64 aarch64

Provides: bundled(aws-c-auth) = 0.9.0
Provides: bundled(aws-c-cal) = 0.9.2
Provides: bundled(aws-c-common) = 0.12.4
Provides: bundled(aws-c-compression) = 0.3.1
Provides: bundled(aws-c-http) = 0.10.3
Provides: bundled(aws-c-io) = 0.21.1
Provides: bundled(aws-c-s3) = 0.8.5
Provides: bundled(aws-c-sdkutils) = 0.2.4
Provides: bundled(aws-checksums) = 0.2.6
Provides: bundled(aws-lc) = 1.53.1
Provides: bundled(s2n-tls) = 1.5.18

Requires:       ca-certificates
Requires:       fuse >= 2.9.0
Requires:       fuse-libs >= 2.9.0

%description
Mountpoint for Amazon S3 is a simple, high-throughput file client for
mounting an Amazon S3 bucket as a local file system. With Mountpoint for Amazon
S3, your applications can access objects stored in Amazon S3 through file
operations like open and read. Mountpoint for Amazon S3 automatically
translates these operations into S3 object API calls, giving your applications
access to the elastic storage and throughput of Amazon S3 through a file
interface.

%build
export CFLAGS="${CFLAGS:-%{optflags}} -O2 -Wno-error=cpp"
export CMAKE_C_FLAGS="$CFLAGS"

export MOUNTPOINT_S3_AWS_RELEASE="amzn2023"

cargo build --release

%cargo_vendor_manifest

%prep
%autosetup -n mountpoint-s3
%cargo_prep -v vendor

%install
mkdir -p %{buildroot}/opt/aws/mountpoint-s3/bin
mkdir -p %{buildroot}/%{_prefix}/sbin
mkdir -p %{buildroot}/%{_bindir}
install -m 755 target/release/mount-s3 %{buildroot}/opt/aws/mountpoint-s3/bin/mount-s3
install -m 644 NOTICE %{buildroot}/opt/aws/mountpoint-s3/
install -m 644 LICENSE %{buildroot}/opt/aws/mountpoint-s3/
install -m 644 THIRD_PARTY_LICENSES %{buildroot}/opt/aws/mountpoint-s3/
install -m 644 cargo-vendor.txt %{buildroot}/opt/aws/mountpoint-s3/
echo "1.21.0" > %{buildroot}/opt/aws/mountpoint-s3/VERSION
ln -sf /opt/aws/mountpoint-s3/bin/mount-s3 %{buildroot}/%{_bindir}/mount-s3
ln -sf /opt/aws/mountpoint-s3/bin/mount-s3 %{buildroot}/%{_prefix}/sbin/mount.mount-s3

%files
%defattr(-,root,root,-)
%dir %attr(755,root,root) /opt/aws/mountpoint-s3
%dir %attr(755,root,root) /opt/aws/mountpoint-s3/bin
%attr(755,root,root) /opt/aws/mountpoint-s3/bin/mount-s3
%doc %attr(644,root,root) /opt/aws/mountpoint-s3/NOTICE
%license %attr(644,root,root) /opt/aws/mountpoint-s3/LICENSE
%license %attr(644,root,root) /opt/aws/mountpoint-s3/cargo-vendor.txt
%attr(644,root,root) /opt/aws/mountpoint-s3/THIRD_PARTY_LICENSES
%attr(644,root,root) /opt/aws/mountpoint-s3/VERSION
%attr(755,root,root) %{_bindir}/mount-s3
%attr(755,root,root) %{_prefix}/sbin/mount.mount-s3

%changelog
* Thu Oct 09 2025 Mountpoint-S3 Team <s3-opensource@amazon.com> - 1.21.0+amzn2023
- Mountpoint-S3 1.21.0 amzn2023 release
- Refer to https://github.com/awslabs/mountpoint-s3/blob/main/mountpoint-s3/CHANGELOG.md

Copy link
Contributor

Choose a reason for hiding this comment

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

I still see rust >= 1.88. I thought we agreed to change it to exact version, no? rust = 1.88

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, Source0: mountpoint-s3-%{version}.tar.gz still didn't to resolve to exact version? mountpoint-s3-1.21.0.tar.gz

Copy link
Contributor

Choose a reason for hiding this comment

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

I still see rust >= 1.88. I thought we agreed to change it to exact version, no? rust = 1.88

Discussed offline.

from datetime import datetime
from jinja2 import Environment, FileSystemLoader

script_dir = os.path.dirname(__file__)
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider using pathlib.Path here - this makes path manipulation more readable



def get_version():
cargo_path = os.path.join(project_root, "mountpoint-s3", "Cargo.toml")
Copy link
Contributor

Choose a reason for hiding this comment

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



def generate_bundled_provides(submodule_versions):
provides = []
Copy link
Contributor

Choose a reason for hiding this comment

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

Nb: does a list comprehension look better here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cool, ill try something like this

def generate_bundled_provides(submodule_versions):
    return "\n".join([f"Provides: bundled({lib_name}) = {lib_version}" 
                      for lib_name, lib_version in submodule_versions.items()])



def main():
if len(sys.argv) != 2:
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider using argparse

template = env.get_template(template_file)
template_content = template.render(**template_data)

spec_content = f"""%bcond_without check
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should ideally be it's own file

spec_content = f"""%bcond_without check

Name: mount-s3
Version: {version}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we mixing f-strings and jinja templating?

Signed-off-by: Tadiwa Magwenzi <tadiwaom@amazon.com>
Signed-off-by: Tadiwa Magwenzi <tadiwaom@amazon.com>
@tadiwa-aizen tadiwa-aizen requested a deployment to PR integration tests October 9, 2025 16:24 — with GitHub Actions Waiting
Signed-off-by: Tadiwa Magwenzi <tadiwaom@amazon.com>
#!/usr/bin/env python3

"""
This RPM spec generator creates distribution-specific .spec files using template inheritance.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this accurate?

)
versions = {}
for line in result.stdout.strip().split('\n'):
if line.strip():
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this if statement need to be here?

if line.strip():
match line.strip().split(' ', 1):
case [name, version]:
versions[name] = version.lstrip('v')
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: use removeprefix


def generate_bundled_provides(submodule_versions):
return "\n".join(
[f"Provides: bundled({lib_name}) = {lib_version}" for lib_name, lib_version in submodule_versions.items()]
Copy link
Contributor

Choose a reason for hiding this comment

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

Using a generator comprehension suffices


args = parser.parse_args()
build_target = args.build_target
template_file = f"{build_target}.spec.template"
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be another argument?

# Checking if template exists
template_path = templates_dir / template_file
if not template_path.exists():
print(f"Error: Template file {template_path} not found")
Copy link
Contributor

Choose a reason for hiding this comment

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

Raise an exception

version = get_version()
rust_version = get_rust_version()
submodule_versions = get_submodule_versions()
current_date = datetime.now().strftime("%a %b %d %Y")
Copy link
Contributor

Choose a reason for hiding this comment

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

We've traditionally used this April 9, 2025 as our date format - why change it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its RPM changelog format, they include the day, you can double check by running dnf changelog x .


template = env.get_template(template_file)

spec_content = template.render(**template_data)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why use kwarg splatting here when you can just pass in arguments normally?

template_data = {
'version': version,
'rust_version': rust_version,
'build_target': build_target,
Copy link
Contributor

Choose a reason for hiding this comment

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

This is always constant for a given spec file. Why do we need to pass this in as an argument?

Signed-off-by: Tadiwa Magwenzi <tadiwaom@amazon.com>
Signed-off-by: Tadiwa Magwenzi <tadiwaom@amazon.com>
template_path = templates_dir / template_file

if not template_path.exists():
raise Exception(f"Template file {template_path} not found")
Copy link
Contributor

Choose a reason for hiding this comment

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

return versions


def generate_bundled_provides(submodule_versions):
Copy link
Contributor

Choose a reason for hiding this comment

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

You're not actually using this function

%autosetup -n mountpoint-s3
%cargo_prep -v vendor

{% raw %}
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need these raw blocks for something?

Signed-off-by: Tadiwa Magwenzi <tadiwaom@amazon.com>
Signed-off-by: Tadiwa Magwenzi <tadiwaom@amazon.com>
Signed-off-by: Tadiwa Magwenzi <tadiwaom@amazon.com>
Signed-off-by: Tadiwa Magwenzi <tadiwaom@amazon.com>
Signed-off-by: Tadiwa Magwenzi <tadiwaom@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants