6 ms·
How does this relate to what NixOS is doing? I've been casually following it. I know they build everything from source and then build results get hashed. The ha
by rdtsc 9y ago
How does this relate to what NixOS is doing? I've been casually following it. I know they build everything from source and then build results get hashed. The hash is not just the output, but also contains all input of the build. The assumption is that once a package and its dependencies are built, it will end up producing the same output.
Is the difference then that reproducible Arch or say Debian would ensure that the source when compiled would produce the same binary output on _any_ the machine of the same type. As opposed to say maybe NixOS would just make the output different if it runs on a machine with a hard drive mounted on a different directory or the cpu has more cores?
- aseipp 9y agoYou're close. For NixOS, I distinguish between "determinism" and "reproducible": - Deterministic: the same input always gives the same output source, no exceptions. - Reproducible: The steps to *create* some build result are always the same, but the results might not be bit-for-bit identical. (Please note that for most people they use "Reproducible" to refer to what I call "Determinism", but this is only in the context of NixOS, so just go with me.) NixOS is always reproducible. Any build can be exactly reproduced by another person, and the build will run the exact same steps. But it is not always deterministic. This seems strange but it really isn't. For example, although I may always take the same steps to compile some software (let's say "./configure; make; make install"), that does not guarantee determinism -- for example, perhaps the 'make' stage will run `date` and then embed the date in the source (e.g. `gcc -DBUILD_DATE="$(date)"` or something). That breaks determinism. However, Nix is always reproducible. If you run 'nix-build' today, tomorrow, or 5 years from now -- if you have the same description of the package, the build always proceeds the same way. In practice, this means "You need to have the same git revision of the nixpkgs source code". But if you have that -- nothing should ever change. Of course you can monkey-wrench this and make up various weird counter examples to this ("My build system only compiles stuff when rand() % 4 == 10, hah!"), but that's the general idea. NixOS will always take the exact same steps -- down to the letter -- in order to build your software. But that doesn't guarantee its deterministic. Most other systems are, in a sense, also reproducible, because you could just "run all the commands the same way, every time" -- but not in the highly automated way Nix is. In general a single hash identifies everything, to the point that I can literally recreate exact copies of a machine with a single command. I can reformat my laptop and have it back to the exact same software in 10 minutes, etc. It is also more nuanced than that: on something like Arch Linux, you and I may be running two Arch machines. They may feel identical. We might even both run './configure; make; make install' and the software will work similarly. But if I haven't run 'pacman -Syu' in week, and you ran it yesterday -- that isn't the same thing! Our environments are not reproductions of each other; they are only vaguely similar. Maybe you got a bugfixed glibc for example that I did not. If that was the case in NixOS, it would cause a rebuild (because one of the inputs -- some of the steps you must take to create something, including installing its prerequisites -- have changed). In this case, "reproducible" does not mean "this piece of software is obtained by running this exact set of steps", that's too narrow. It means "this result is obtained by running the exact set of steps, for every single thing this result has ever depended on, all the way up the chain". > As opposed to say maybe NixOS would just make the output different if it runs on a machine with a hard drive mounted on a different directory or the cpu has more cores? No, this won't happen. CPU cores and the "location" of the source code are not included in the hash[1], they are not part of the input "source" to a build result. [1] What actually happens is that the source code is copied into a location inside the "Nix store", and it is built from there. Same source code? Same destination. So in other words the first thing Nix really does is "create an build result from the input source code", i.e. a directory containing a copy of all the code, and that is given as the input to another step that actually builds the results, using the source as input. You could think of "building software" as two packages: one package, which is built by unzipping the source code and keeping the results, and another that is created by building the previously unzipped code. So it uses the same mechanism as it always does: source code is just an input to something we want to "build", in this case, the executables. It's no different than "zlib" the library an input to "libpng" the library (because zlib needs libpng). It is just an "input" in an abstract sense.
- rdtsc 9y agoThanks for explaining. Great answer. Along with catern's sibling comment it cleared the confusion for me.
- nextos 9y agoWhat do you think of NixOS vs GuixSD?
- anthmcc 9y ago> Please note that for most people they use "Reproducible" to refer to what I call "Determinism" Which I would argue makes fall more sense. actually I think a better definition would be that determinism is bit-for-bit identical under controlled inputs. A reproducible build is the act of controlling those inputs to feed into a deterministic build. I'm curious why you chose the definition you did, as proving a build is reproducible sounds impossible hard. Of course I've always looked at it from the standpoint of "reproduce this binary from source, thus proving your source code (modulo compiler trust of course)".
- catern 9y agoNix allows you to perfectly reproduce the on-disk inputs going in to a build, and also completely isolate the build by heavily sandboxing it. But build processes, being a large and complicated function, may not give you bit-for-bit identical output even if all their on-disk inputs are bit-for-bit identical. So it's a good start, but not enough. Distributions like Debian and Arch need to put in a fair bit of effort to reach the same level as Nix. But, in a sense, reaching that level is the "easy" part - it's an interesting technical challenge. The hard part of the reproducible builds effort, the part which Nix doesn't give you, and the part which developers from Debian, Nix, and other distros are still actively working on, is ensuring that bit-for-bit identical on-disk inputs, along with sandboxing, will give you bit-for-bit identical outputs. That is a task which requires cleaning up the build process of the entire open source world.
- baldfat 9y agoWe are all still living on 30 year old package management systems and we need a modern approach. I still have hope for flatpak. I want a system where the folder is the application and deleting the folder is the way you remove applications. The devil though is in the details of how or what is shared. Sadly flatpak and snap don't seem to have much in community support. MacOS and OSX seem to be the closest to this idea of the folder being the application. Trying Nix it is just impractical, but I liked the idea.
- jerf 9y ago"We are all still living on 30 year old package management systems and we need a modern approach.... Trying Nix it is just impractical, but I liked the idea." There's a causal connection between those two things....
- ufo 9y agoContainers are orthogonal to what the parent poster was talking about. Reproduceable builds are a build system problem, not a package distribution or package interoperability problem. Even with containers, being able to reproducibly rebuild the containerized application from its sources if desired is still a challenge.
- tempay 9y ago> The hash is not just the output, but also contains all input of the build. The hash doesn’t contain the output at all, it only contains the inputs. As such you know the hash of all packages before you start building anything. It would be difficult to do anything different as the package may contain an absolute path to itself.
- rdtsc 9y agoAh you're right, of course.
- civodul 9y agoThe main difference between the Arch/Debian approach and that of Nix and Guix is that Nix and Guix "normalize" the build environment using containers, whereas Arch, Debian, and others aim to achieve bit-reproducibility in spite of differences in the build environment. Thus some of the issues that apply to Arch or Debian do not apply to Guix and Nix, but many apply to both (timestamps are an obvious example.) For Guix we are currently at ~80% reproducible packages: https://gnu.org/software/guix/news/reproducible-builds-a-status-update.html https://gnu.org/software/guix/news/reproducible-builds-a-sta... . That's not an entirely fair comparison because, for example, Python packages in Guix include .pyc files whereas on Debian they don't (not sure about Arch).