Open burke opened 5 years ago
Hm, I refined this to:
let
hostnameFromURL = url: # String -> String
builtins.elemAt (
builtins.match "https?://([^/]+)/.*" url # [ "packages.shopify.io" ]
) 0; # "packages.shopify.io"
bundlerVarFromHostname = hostname: # String -> String
with import <nixpkgs> { }; "BUNDLE_" + lib.toUpper (
builtins.replaceStrings ["."] ["__"] hostname # "packages__shopify__io"
); # "BUNDLE_PACKAGES__SHOPIFY__IO"
lookUpBundlerConfig = var: # String -> String
if builtins.getEnv var != ""
then builtins.getEnv var
else builtins.elemAt (
builtins.match ".*\n${var}: ([^\n]+)\n.*" (
builtins.readFile ((builtins.getEnv "HOME") + "/.bundle/config")
)
) 0;
injectAuth = url: # String -> String
let
hostname = hostnameFromURL url;
var = bundlerVarFromHostname hostname;
token = lookUpBundlerConfig var;
in
builtins.replaceStrings ["://"] ["://${token}@"] url;
in
{
abc = {
dependencies = ["def"];
groups = ["development" "test"];
platforms = [];
source = {
remotes = [(injectAuth "https://packages.shopify.io/shopify/gems")];
sha256 = "0000000000000000000000000000000000000000000000000001";
type = "gem";
};
version = "0.0.1";
};
}
This is probably progress in the right direction, but this feels like a weird place for this code to live.
One issue with this approach is that the secrets will be written to the /nix/store
which is readable by all the users on the machine. What some people do is rotate the token frequently to limit the window of attack.
Another approach would be to change the fetchers to use buitlins.fetchurl
and builtins.fetchgit
instead. Those are executed at evaluation time and also read from the user's ~/.netrc by default. To do that you will probably have to introduce an extension to <nixpkgs/pkgs/development/ruby-modules/gem/default.nix>
to allow to pass custom fetchers.
Thanks. I like that idea. I'll play with that when I get a chance.
I've got a Gemfile with private repos accessed over https. In a normal flow, I would just set bundler to use a personal access token like so:
bundle config GITHUB__COM <token>:x-oauth-basic
This of course doesn't work with bundix. I'm highly interested in finding a solution.
So a few months back, I added support for bundix to look up bundler credentials to fetch gems requiring authentication. Today I took a run at teaching nix to do this without the runtime assistance of bundix, and this is what I came up with. It's pretty rough but Technically Works™.
Anyone know how I could do this better? Is there a form I could shape this into that would make sense to merge into bundix?
I'm happy to pour a bunch of work into this if someone can point me in the right direction.
I'm going to want to come up with similar solutions for gems fetched from private git remotes.