Hi, On Tue, 28 Feb 2023 at 22:13, Jonathan Frederickson <jonat...@terracrypt.net> wrote:
> I recently had a discussion in #spritely on Libera.Chat about Guix and > Nix, and in particular a (relatively) new feature of Nix called flakes > that Guix doesn't currently have an analogue for. Well, even after several readings of Nix documentation about Flakes, I am still not sure to understand how the concept would apply for Guix. :-) > But the package you end up with each time you do that... depends on > which revision of Guix you're running when you run ~guix shell~! So if > I point someone to a project with a ~guix.scm~ file, they might not be > able to use it if their Guix revision is too old. (Or too new, if > packages have been renamed or removed.) More generally, it means that > they do not end up with the same dependency graph that I do. This > makes troubleshooting potentially tricky, because if something breaks > you have to check the resulting profile to see which versions of your > package's dependencies (and transitive dependencies) are actually > installed. That’s why “guix time-machine” is really cool! :-) Basically, I have my current Guix revision and I run “guix pull” every… indecent duration. However, I run many many “guix time-machine”, well each time I am working on a project, so daily. Even, I only run “guix pull” against the default Savannah Guix channel. Then, depending on the projects, they can require the channels guix-science, guix-cran or others. The graph I need for a specific project is controlled by the file channels.scm and I run, from the directory of that project: guix time-machine -C channels.scm -- shell This channels.scm file can be part of the Git repository of that project. And sometimes, I have several files for testing revision variants. On the top of that, for some cases, I have specific packages for one project. Therefore, I have a folder, say guix/extra containing one or more files which define new or variant packages. Somehow, my typical line looks like: guix time-machine -C state-1.scm -- shell -L guix/extra -m manifest-A.scm guix time-machine -C state-2.scm -- shell -L guix/extra -f guix-B.scm etc. (Although, I should admit that I barely use the option -f. ;-)) > For those who haven't used Nix, it has a solution to this called > flakes. Flakes let you specify git repositories explicitly as inputs for > your project[1]. (It also maintains a flake.lock file so you can lock to > a specific revision automatically while still using a named branch in > your inputs directly, but I believe you could in theory refer to a > specific rev in your inputs.) Effectively, the channels you're using for > dependencies are specified by the project you're building, not whatever > happens to be configured on your local machine. >From my understanding, what I describe above seems providing these Nix flakes, no? Or could you explain on a concrete example what you can do with Nix flakes that you cannot do with Guix? Well, UI and how easy to use can also be considered part of “can do”. :-) I mean, maybe the current Guix way could be improved on the light of the Nix flakes. > I think something like this would be useful for Guix for many of the > same reasons it's useful in Nix. But there's a bit of a security > conundrum here. Loading Guix package definitions involves code > execution, which as far as I can tell isn't currently sandboxed at all! > And that's a problem. When you load package definitions from a channel > that you've configured on your system, you've explicitly trusted that > channel's maintainers. But with a flake-like system... even if you might > be okay depending on someone else's code, that doesn't necessarily mean > you fully trust them. You might ultimately choose to sandbox the > resulting binary, but that's moot if you can't fetch its dependencies > without running arbitrary code with all of your user's authority. I am not sure to understand this sandbox part. For instance, guix time-machine -C channels.scm -- shell --container provides you an isolated environment where you can run untrusted packages coming from untrusted channels. Even, the option ’-F, --emulate-fhs’ combined with the option ’-C, --container’ allow to run untrusted binaries coming from elsewhere (not built by Guix); you need some care with the options -E and --expose though. Do you think something is missing? What could we improve in this area? Do you mean evaluate the Guile files provided by the untrusted channels in a sandbox? > I think there is a solution to this, though. Right now when you > evaluate Guix package definitions, you're basically running arbitrary > Guile code. This of course can do anything you can do. But it doesn't > have to! If you're familiar with Christine Lemmer-Webber's work on > Spritely, you'll probably know what I'm getting at here: I think using > object capabilities[2] would fix this. I recommend reading the linked > blog post for a good explainer on what object capabilities are, as I > won't do it justice here, but to perhaps oversimplify: code in a > capability system only has access to the things you give it, and no > more. It's like lexical scope, but taken very seriously. Hum, I should have missed some details – since I am not familiar with “object capability”. Thanks for the pointer. Is it another way to view “contract” [a]? a: <https://docs.racket-lang.org/reference/contracts.html> > If you think about what a typical package definition needs to be able to > do to your system directly, I think it's not actually that much? My > (admittedly basic, possibly flawed) understanding of how Guix works is > that most of the heavy lifting is done by ~guix-daemon~, which itself is > pretty heavily sandboxed, and that most of what the ~guix~ subcommands > are doing is building derivations which instruct ~guix-daemon~ to > perform build actions. So while you're building these derivations, > unless I'm misunderstanding: > > - You don't need network access > - You don't need (much) filesystem access >From my understanding, Guix and guix-daemon already works that way, no? Do you mean evaluate the user-side Guile part of “guix foo -f file.scm” inside a sandboxed environment? On Wed, 01 Mar 2023 at 10:56, Josselin Poiret <d...@jpoiret.xyz> wrote: > Now my personal opinion: you should note that it's a very bad idea in > general to rely on specific versions of dependencies. Downstream > consumers of your software should be able to use it with up-to-date > dependencies, because they can provide security benefits, bugfixes, > etc. Having version pinning like in go leads to dependency hell, and > should be frowned upon. Well, it depends on what you want, IMHO. :-) Sometimes, you want to reproduce the exact same computational environment, including all the defects. >From my personal opinion, channels.scm and manifests.scm, probably considering also transformations, these features allow – putting more than less efforts – to achieve a fine control with flexibility. Cheers, simon