Skip to content

Conversation

@a-ovchinnikov
Copy link
Contributor

@a-ovchinnikov a-ovchinnikov commented Nov 14, 2024

It turned out that due to a yet unknown change somewhere
in the ecosystem bundler started ignoring instructions
to not access the web during a build when a git dependency
was present.

This change adds a workaround that explicitly forbids
consulting remotes for branches and references and also
pins a path to local repository in a config.

Maintainers will complete the following section

  • Commit messages are descriptive enough
  • Code coverage from testing does not decrease and new code is covered
  • Docs updated (if applicable)
  • Docs links in the code are still valid (if docs were updated)

Note: if the contribution is external (not from an organization member), the CI
pipeline will not run automatically. After verifying that the CI is safe to run:

Copy link
Member

@eskultety eskultety left a comment

Choose a reason for hiding this comment

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

This approach seems to be the only one that makes bundler stop accessing the internet with git dependencies, regardless of any extra env variables used sadly.

While at it, I think this effort should also contain the following changes:

  • enforce BUNDLE_ALLOW_OFFLINE_INSTALL - didn't do anything for git deps, but seems very relevant to our use case in general
  • enforce BUNDLE_DISABLE_VERSION_CHECK - I've encountered different bundler behaviour with different versions and older versions were particularly stubborn trying to check the latest version of bundler online, sometimes it was a hard failure, sometimes bundler ignored it and proceeded further where it failed on the build
  • enforce BUNDLE_DISABLE_LOCAL_REVISION_CHECK - it has a similar function to your BUNDLE_DISABLE_LOCAL_BRANCH_CHECK
  • stop enforcing BUNDLE_DEPLOYMENT - this is a user's choice for how they wish to distributed their built app which we don't control and should not try doing; it's essentially a way of vendoring one's app which is not our business. Moreover, it doesn't seem to have any effect on the offline install per se

@a-ovchinnikov a-ovchinnikov force-pushed the bundler_containment_procedure_1411 branch from 00c7df6 to 457eae2 Compare November 15, 2024 19:13
Copy link
Member

@eskultety eskultety left a comment

Choose a reason for hiding this comment

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

I don't see BUNDLE_DEPLOYMENT being dropped anywhere in any commit. I also think that commit 2 and 3's order should be swapped (first make changes, the lift the restriction). Anyway, I think this is no longer a WIP material :).

@eskultety
Copy link
Member

eskultety commented Nov 18, 2024

I don't see BUNDLE_DEPLOYMENT being dropped anywhere in any commit. I also think that commit 2 and 3's order should be swapped (first make changes, the lift the restriction). Anyway, I think this is no longer a WIP material :).

I wonder whether I just forgot that I had BUNDLE_DEPLOYMENT set during my final testing stages or there was something else about my environment. Anyway, my latest tests again in a fresh environment show the reason why you didn't incorporate dropping of the variable - bundler is still trying to connect online that way!

However, I'm still not a fan of forcing our users to do vendoring, although we do document it here: https://github.com/containerbuildsystem/cachi2/blob/main/docs/bundler.md#bundle_deployment. I am not sure if people are able to connect the dots given the extremely copy-paste (from the docs) explanation of the flag. It is only after further digging in the docs/blogs or read the definition BUNDLE_PATH to learn that it creates a local vendor directory. That may not be aligned with user's expectation wrt their Dockerfiles, because BUNDLE_DEPLOYMENT default path cannot be overriden by anything other (apparently) than BUNDLE_PATH. So, I'm wondering if we should introduce a new input JSON option for bundler install_path to count for the forced deployment; IOW we'd set BUNDLE_PATH=<user_install_path> if specified and that way the deployment would be completely transparent to the user. If not set, a vendor directory would be created and the user has to cope with that in their Dockerfile. Naturally, this would be a follow-up material.

That all said, the deployment conundrum made spend some more unplanned time on this figuring out what is bundler unhappy about:

$ bundler install --verbose
Running `bundle install --verbose` with bundler 2.5.22
Found no changes, using resolution from the lockfile
...
The definition is missing ["racc-1.8.1", ...]

for all dependencies. So I did run deployment to see what the vendor directory hierarchy looks like and tried copying over just the .gemspecs under the specifications directory

$ ls /var/tmp/bundle/specifications
...
-rw-r--r--. 1 root root 2613 Nov 18 09:15 sprockets-4.2.1.gemspec
-rw-r--r--. 1 root root 1351 Nov 18 09:15 sprockets-rails-3.5.2.gemspec
...
$ GEM_PATH=/var/tmp/bundle bundle install

That didn't get bundler any further as it still complained about missing definitions.
So I tried other directories that I found inside the vendor directory and found out that specifications is generally enough for most gems unless bundler wants some dependencies to be re-compiled for the local architecture, e.g. racc-1.8.1 . That creates an extensions directory next to specifications and if I create it as an empty directory, bundler then proceeds to a different error message:

$ GEM_PATH=/var/tmp/bundle bundler install --verbose
Running `bundle install --verbose` with bundler 2.5.22                                                                                        
Found no changes, using resolution from the lockfile 
Source locally installed gems is ignoring #<Bundler::StubSpecification name=racc version=1.8.1 platform=ruby> because it is missing extensions
Source locally installed gems is ignoring #<Bundler::StubSpecification name=date version=3.3.4 platform=ruby> because it is missing extensions
Source locally installed gems is ignoring #<Bundler::StubSpecification name=racc version=1.8.1 platform=ruby> because it is missing extensions
Source locally installed gems is ignoring #<Bundler::StubSpecification name=date version=3.3.4 platform=ruby> because it is missing extensions

I think it could be solved by forcing the Ruby platform in the build, making some deps to be recompiled during the build as a side effect, however, that requires changes to the lockfile, so it's out of question/reach. Compiling the extensions ourselves is also out of question because we don't know the target architecture. In summary, unpacking the gems and creating an extra directory hierarchy by us for bundler to consult to find gem specs before consulting the internet isn't a general enough solution, so this whole process made me accept the fact that we may not have another choice but to keep using BUNDLE_DEPLOYMENT.

That said, I think the user-facing docs could be improved on that front and also that we could extend our CLI input JSON such that we could set the install path for the user in order for them to avoid making undesirable manual cachi2-only changes to their Dockerfiles.

@a-ovchinnikov a-ovchinnikov marked this pull request as ready for review November 18, 2024 16:14
@a-ovchinnikov a-ovchinnikov changed the title wip: making bundler behave Making bundler respect hermetic requirement Nov 18, 2024
@eskultety
Copy link
Member

FWIW I just opened ruby/rubygems#8265 to request the --local installation flag to be exposed as a configuration setting, mentioning it here just for completeness, I will follow up with the docs update.

Copy link
Member

@eskultety eskultety left a comment

Choose a reason for hiding this comment

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

One commit msg nitpick and I still believe commits 2 and 3 should be swapped. With that addressed -> ACK.

@a-ovchinnikov a-ovchinnikov force-pushed the bundler_containment_procedure_1411 branch 2 times, most recently from a4c3ae6 to 1ca23fb Compare November 19, 2024 15:34
Copy link
Member

@eskultety eskultety left a comment

Choose a reason for hiding this comment

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

@a-ovchinnikov Sorry for a late notice, I know you have 2 ACKs, but I just noticed something in the design doc which we should IMO fix here, it's a trivial change, see my comment.

@eskultety
Copy link
Member

@a-ovchinnikov Sorry for a late notice, I know you have 2 ACKs, but I just noticed something in the design doc which we should IMO fix here, it's a trivial change, see my comment.

Disregard, it's better I'll do that in my docs patches which I'll rebase onto this work, so re-approving, sorry for the noise.

@a-ovchinnikov a-ovchinnikov force-pushed the bundler_containment_procedure_1411 branch from 1ca23fb to d85a9ee Compare November 21, 2024 15:35
It turned out that due to a yet unknown change somewhere
in the ecosystem bundler started ignoring instructions
to not access the web during a build when a git dependency
was present.

This change adds a workaround that explicitly forbids
consulting remotes for branches and references and also
pins a path to local repository in a config.

Signed-off-by: Alexey Ovchinnikov <aovchinn@redhat.com>
This change adds
 BUNDLE_ALLOW_OFFLINE_INSTALL
 BUNDLE_DISABLE_VERSION_CHECK
to flags to make it less likely that bundler would try accessing
the web while performing a hermetic build.

Signed-off-by: Alexey Ovchinnikov <aovchinn@redhat.com>
This reverts commit cea5779.

Signed-off-by: Alexey Ovchinnikov <aovchinn@redhat.com>
@a-ovchinnikov a-ovchinnikov force-pushed the bundler_containment_procedure_1411 branch from d85a9ee to d061c72 Compare November 21, 2024 15:38
@a-ovchinnikov a-ovchinnikov added this pull request to the merge queue Nov 21, 2024
Merged via the queue into hermetoproject:main with commit 74d5df6 Nov 21, 2024
16 checks passed
@a-ovchinnikov a-ovchinnikov deleted the bundler_containment_procedure_1411 branch November 21, 2024 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants