-
Notifications
You must be signed in to change notification settings - Fork 71
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
Confusing behavior when append/prepend to PATH with no delimiter #285
Comments
@buildpacks/buildpack-authors-tooling-maintainers care to provide some input here? |
The bin of a layer is in fact automatically prepended to the PATH with the correct delimiter. This is why you are seeing "the whole layer path twice" in the first example, and I could still see a case for default the PATH delimiter in cases where buildpacks explicitly prepend or append to the PATH but given the above functionality those cases are less common than one might imagine. |
Correct, but if you have any prepend values without a delimiter, that PATH that was auto added is no longer valid as it’s treated as one whole path.
You’re saying appending and prepending is not common? I use them a bunch. Even if a failure mode isn’t common I think we should at minimum warn when there is likely incorrect behavior, ideally error or auto fix the problem (with an escape valve). The problem is less about the specific failure mode expectations, and more about the difficulty of debugging this failure mode when things go wrong. |
We talked about this a bit at the core team sync today. From what I understand we don't want to special case I do concur with @schneems, there is a default delimiter if we do nothing that the spec is already doing with every |
I have been hit by this before too. I don't think it was with PATH, but with appending to other env variables. The default of no delimiter was confusing and took me a minute to figure out what was going on. I think if it had defaulted to an actual value, like This is just my experience and other's may have different experiences but, I can't think of a case where I'm appending/prepending values in a buildpack and I actually want to just concat all the values together. I most commonly want a path delimiter, followed by space or comma. If we defaulted to the path separator, I think that would provide a more natural behavior. Even if it's not right in all cases, it's right for many and in the cases where it's not right, it's pretty obviously not right. For the Windows/Unix scenario, it seems like the platform should know that and be able to adjust automatically. So the spec could say it defaults to the OS path separator. |
One way to think of this is that there is a default now, it's just effectively the same as a zero-width string. If we treat this as a current default then a possible proposal going forward could be to deprecate and replace it with a new default:
What do you think? |
@schneems and @dmikusa-pivotal You make some good points. I would prefer requiring a delimiter to changing the default b/c
|
@ekcasey I'm OK with that. So if you have no delimiter set, then it fails. If you have a delimiter of ``, that's OK. Otherwise, you need to set your own delimiter to something useful. The buildpack author would be required to handle |
yeah, that kind of sucks :(, though not sure how many windows + unix buildpacks we have out in the wild. |
In general, I don't want to know about OS differences, I want to use APIs that abstract those differences for me. My preference as a buildpack author would be to default to the OS delimiter. Brainstorming an alternative: We could have CNB write out the delimiter to a file for us so we could read that in and use it instead of having to implement our own OS switching detection. That's one way that I wouldn't have to think about it, but I would still prefer to not have to jump through that hoop by using a default. Regarding the worries around the deprecation cycle: I would implement the deprecation warning in the current major version, then change the behavior in the next major version rev. I would expect developers to upgrade to the latest patch release of a major version before trying to jump major versions. Basically, if they do that, it's a little on them that they didn't see the warning and skipped the major version breaking changes changelog. A more difficult, but safer alternative to relying on the developer to upgrade versions in a safe manner could be to track prior versions of the spec being used (somehow) and emit a diff of deprecations since the prior stored version. For example if you jumped from 0.2 to 1.2 then that could be detected and you could get a list of everything deprecated between those versions. I think that such tracking and warning could be very user friendly, but I'm betting it's overly complicated compared to a simple deprecate/change cycle (which is already a bit time consuming). |
I would love to resolve this. At the very least we should fix the spec to defined the existing behaviour - since having it undocumented (as well as an unhelpful default), doesn't help with user confusion. Next, we need to decide whether to:
In addition, there were questions above about whether anyone was relying on the current default of the empty string, and so would be broken by (1). To help answer this, I took a look at usages in the wild using GitHub code search. Starting with Heroku's libcnb.rs powered buildpacks, I found zero usages of the default empty string delimiter, a handful of cases of a single space being used as a delimiter (for Looking at the Paketo buildpacks, which use either packit or the Go based libcnb env APIs, I similarly found zero usages of the default empty string delimiter, a handful of cases of a single space being used as a delimiter (for Finally, looking at the GCP buildpacks, I again found zero usages of the default empty string delimiter, one case of a single space being used as a delimiter (for As such:
|
Just to be clear, OS path separator would be the default delimiter for ALL env vars, not just PATH, right? @edmorley would you be willing to open an RFC for this? |
Context
I was building a simple Ruby CNB when I came across this behavior. I prepended
/layers/heroku_ruby/ruby/bin
to the PATH, but found thatecho $PATH
ended up being the whole layer path twice:That was confusing. I thought perhaps it was expecting a relative path instead of absolute, so I tried pretending
bin
and got this output:That behavior was also confusing. After a lot of debugging, the cause was that I was pretending to PATH without specifying a delimiter.
Observations
<layerpath>/bin
will always be on the PATH. However, it's possible to modify the PATH by accident, so that's no longer true https://github.com/buildpacks/spec/blob/main/buildpack.md#layer-pathsPaths forward
In addition, I would like to propose some possible future changes to the spec:
prepend
andappend
an error unless a delimiter is specified.bin
of a layer on thePATH
even if a CNB modifies the PATH.The text was updated successfully, but these errors were encountered: