Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support heroku-24 #280

Closed
wants to merge 5 commits into from
Closed

Support heroku-24 #280

wants to merge 5 commits into from

Conversation

runesoerensen
Copy link
Contributor

@runesoerensen runesoerensen commented May 6, 2024

This PR adds support for heroku-24 including downloading arch specific Ruby binaries depending on the current host architecture.

The cache isn't currently invalidated if the host architecture changes.

@runesoerensen runesoerensen changed the base branch from main to fix-lint-errors May 6, 2024 15:33
@runesoerensen runesoerensen self-assigned this May 6, 2024
@runesoerensen runesoerensen added the rust Pull requests that update Rust code label May 6, 2024
@runesoerensen runesoerensen marked this pull request as ready for review May 6, 2024 15:34
@runesoerensen runesoerensen requested review from schneems and a team as code owners May 6, 2024 15:34
Base automatically changed from fix-lint-errors to main May 6, 2024 19:41
Copy link
Contributor

@schneems schneems left a comment

Choose a reason for hiding this comment

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

Need to support dynamically pulling based on currently running architecture (instead of only supporting amd64). I left a comment below. Thanks for the PR!

url.path_segments_mut()
.map_err(|()| RubyInstallError::InvalidBaseUrl(String::from(base)))?
.push(stack)
.push("amd64")
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 a great starting point. The only thing I would change is to use the architecture of the current machine. We're doing this in classic via shelling out https://github.com/heroku/heroku-buildpack-ruby/blob/fd6585411cbf86d363ad0824f53d8edba1d7afed/lib/language_pack/base.rb#L45-L57.

I'm hoping on a plane in a few hours and then out tomorrow, if you're available to take a stab at adding that extra logic that would be amazing 🙏🏻. If not, I can take this commit and add that on top.

I was working towards upgrading libcnb first, but seeing how compact this PR is, I think I like the idea of merging this in now and cutting a builder so people can play with it.

Copy link
Member

@edmorley edmorley May 7, 2024

Choose a reason for hiding this comment

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

@runesoerensen @schneems The multi-arch CNB release automation relies upon the buildpack having declared [[targets]] in order to know to create the OCI images and .cnb files (attached to the GitHub release) as multi-arch. As such, adding support for Heroku-24 via [[stacks]] will mean the releases will continue to be single arch and so cannot be added to the heroku/builder:24 builder, since CNBs in there need to support ARM64 too. As such, the priority is to upgrade to newer libcnb.rs and [[targets]].

The only thing I would change is to use the architecture of the current machine. We're doing this in classic via shelling out

We shouldn't shell out for this in our CNBs. We should either:

  1. Use context.target.arch (once the CNB has upgraded libcnb and switched to targets)
  2. Or, use a Rust compile time conditional (https://doc.rust-lang.org/reference/conditional-compilation.html)

See also:
https://salesforce-internal.slack.com/archives/C02GZCPPV38/p1712568024934129?thread_ts=1712073915.519419&cid=C02GZCPPV38

Copy link
Contributor Author

@runesoerensen runesoerensen May 7, 2024

Choose a reason for hiding this comment

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

Yep shelling out is definitely not the best approach here.. This is somewhat related to heroku/buildpacks-nodejs#814 (comment) -- e.g. whether to use the CNB targets, or the compile-time conditional (or std::env::consts::ARCH as in the node.js sample).

I alluded to a conversation I had with @Malax on this (re env provided target arch vs compile-time conditionals) in the other PR. What do you think about this @Malax (and did I remember the conversation correctly :-))?

Copy link
Member

Choose a reason for hiding this comment

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

For Python I used context.target.arch during the build since I have to use other fields from content.target anyway, such as the distro name/version, so it seemed to make sense to use all metadata from the same place:
https://github.com/heroku/buildpacks-python/blob/de378063c83e1eec6302e79f93f189162b5bbbbf/src/python_version.rs#L39-L47

(Though for the tests, I have to use conditional compilation: https://github.com/heroku/buildpacks-python/blob/de378063c83e1eec6302e79f93f189162b5bbbbf/tests/mod.rs#L29-L35)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For sure, seems like it'd make a lot of sense to also use context.target in this buildpack when the buildpack is updated to newer libcnb.rs and targets.

I've updated this implementation to also factor in the current arch -- should be fairly straightforward to adapt this to use the Target instead.

@@ -174,6 +194,9 @@ pub(crate) enum RubyInstallError {
#[error("Invalid base url {0}")]
InvalidBaseUrl(String),

#[error("Unsupported architecture: {0}")]
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 want to go a little above and beyond and list out the supported architectures.

In general, any time we're failing because a value was unexpected based on a list of currently known/supported values, I want to output both what was actually output (the current architecture) but also what was expected (either arm64 or amd64 etc.)

This can help the future development errors/issues for example if someone accidentally adds a space like " arm64". Even if we think such an issue would be rare, I don't see a downside in adding that information to the error message (other than that requirement will influence the implementation, such as needing to move the information to a const, for example.

Copy link
Contributor

@schneems schneems left a comment

Choose a reason for hiding this comment

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

Thanks for iterating on this. I can take it over from here. I left one comment on an error message improvement as an FYI, but I don't need you to do anything. I'll grab you code to a new branch and iterate on some of Ed's comments.

@schneems
Copy link
Contributor

It made more sense to move over to a new branch than to try to replay main on top of this. I am doing the work over at #284. I want to be mindful to not delete this branch until heroku/ruby has heroku-24 support on main and a release as I know some might be using this branch from git.

@edmorley
Copy link
Member

as I know some might be using this branch from git.

The buildpack can't be used directly from a branch since it would need compiling. The only other scenario is where someone might be using a shared crate, but this PR doesn't touch shared code.

@schneems
Copy link
Contributor

I've merged #284. I've queued up a major release GHA (since there's something marked as CHANGED due to the lifecycle requirement changing).

@edmorley
Copy link
Member

Resolved by #284.

@edmorley edmorley closed this May 20, 2024
@edmorley edmorley deleted the support-heroku-24 branch May 20, 2024 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rust Pull requests that update Rust code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants