Add the replace-dependency build support function.
The use case is to do a deep replacement of a dependency without rebuilding the entire tree.
For example, suppose a security hole is found in glibc and a patch released. Ideally, you'd
just rebuild everything, but that takes time, space, and CPU that you might not have, so in
the mean time you could build a safe version of, say, firefox with:
firefox-safe = replace-dependency { drv = firefox; old-dependency = glibc; new-dependency = patched-glibc; };
Building firefox-safe will rebuild glibc, but only do a simple copy/string replacement on all other dependencies
of firefox. On my system (MBP 13" mid-2012), after a new glibc had been build building firefox took around 11 seconds.
See the comments in the file for more details.
2013-01-11 19:42:09 +00:00
|
|
|
{ runCommand, nix, lib }:
|
|
|
|
|
|
|
|
# Replace a single dependency in the requisites tree of drv, propagating
|
|
|
|
# the change all the way up the tree, without a full rebuild. This can be
|
|
|
|
# useful, for example, to patch a security hole in libc and still use your
|
|
|
|
# system safely without rebuilding the world. This should be a short term
|
|
|
|
# solution, as soon as a rebuild can be done the properly rebuild derivation
|
|
|
|
# should be used. The old dependency and new dependency MUST have the same-length
|
|
|
|
# name, and ideally should have close-to-identical directory layout.
|
|
|
|
#
|
2013-01-13 16:15:01 +00:00
|
|
|
# Example: safeFirefox = replaceDependency {
|
Add the replace-dependency build support function.
The use case is to do a deep replacement of a dependency without rebuilding the entire tree.
For example, suppose a security hole is found in glibc and a patch released. Ideally, you'd
just rebuild everything, but that takes time, space, and CPU that you might not have, so in
the mean time you could build a safe version of, say, firefox with:
firefox-safe = replace-dependency { drv = firefox; old-dependency = glibc; new-dependency = patched-glibc; };
Building firefox-safe will rebuild glibc, but only do a simple copy/string replacement on all other dependencies
of firefox. On my system (MBP 13" mid-2012), after a new glibc had been build building firefox took around 11 seconds.
See the comments in the file for more details.
2013-01-11 19:42:09 +00:00
|
|
|
# drv = firefox;
|
2013-01-13 16:15:01 +00:00
|
|
|
# oldDependency = glibc;
|
|
|
|
# newDependency = overrideDerivation glibc (attrs: {
|
Add the replace-dependency build support function.
The use case is to do a deep replacement of a dependency without rebuilding the entire tree.
For example, suppose a security hole is found in glibc and a patch released. Ideally, you'd
just rebuild everything, but that takes time, space, and CPU that you might not have, so in
the mean time you could build a safe version of, say, firefox with:
firefox-safe = replace-dependency { drv = firefox; old-dependency = glibc; new-dependency = patched-glibc; };
Building firefox-safe will rebuild glibc, but only do a simple copy/string replacement on all other dependencies
of firefox. On my system (MBP 13" mid-2012), after a new glibc had been build building firefox took around 11 seconds.
See the comments in the file for more details.
2013-01-11 19:42:09 +00:00
|
|
|
# patches = attrs.patches ++ [ ./fix-glibc-hole.patch ];
|
|
|
|
# });
|
|
|
|
# };
|
|
|
|
# This will rebuild glibc with your security patch, then copy over firefox
|
|
|
|
# (and all of its dependencies) without rebuilding further.
|
2015-11-16 00:52:30 +00:00
|
|
|
{ drv, oldDependency, newDependency, verbose ? true }:
|
Add the replace-dependency build support function.
The use case is to do a deep replacement of a dependency without rebuilding the entire tree.
For example, suppose a security hole is found in glibc and a patch released. Ideally, you'd
just rebuild everything, but that takes time, space, and CPU that you might not have, so in
the mean time you could build a safe version of, say, firefox with:
firefox-safe = replace-dependency { drv = firefox; old-dependency = glibc; new-dependency = patched-glibc; };
Building firefox-safe will rebuild glibc, but only do a simple copy/string replacement on all other dependencies
of firefox. On my system (MBP 13" mid-2012), after a new glibc had been build building firefox took around 11 seconds.
See the comments in the file for more details.
2013-01-11 19:42:09 +00:00
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
2015-11-16 00:52:30 +00:00
|
|
|
warn = if verbose then builtins.trace else (x:y:y);
|
Add the replace-dependency build support function.
The use case is to do a deep replacement of a dependency without rebuilding the entire tree.
For example, suppose a security hole is found in glibc and a patch released. Ideally, you'd
just rebuild everything, but that takes time, space, and CPU that you might not have, so in
the mean time you could build a safe version of, say, firefox with:
firefox-safe = replace-dependency { drv = firefox; old-dependency = glibc; new-dependency = patched-glibc; };
Building firefox-safe will rebuild glibc, but only do a simple copy/string replacement on all other dependencies
of firefox. On my system (MBP 13" mid-2012), after a new glibc had been build building firefox took around 11 seconds.
See the comments in the file for more details.
2013-01-11 19:42:09 +00:00
|
|
|
references = import (runCommand "references.nix" { exportReferencesGraph = [ "graph" drv ]; } ''
|
|
|
|
(echo {
|
|
|
|
while read path
|
|
|
|
do
|
|
|
|
echo " \"$path\" = ["
|
|
|
|
read count
|
|
|
|
read count
|
|
|
|
while [ "0" != "$count" ]
|
|
|
|
do
|
|
|
|
read ref_path
|
|
|
|
if [ "$ref_path" != "$path" ]
|
|
|
|
then
|
|
|
|
echo " (builtins.storePath $ref_path)"
|
|
|
|
fi
|
|
|
|
count=$(($count - 1))
|
|
|
|
done
|
|
|
|
echo " ];"
|
|
|
|
done < graph
|
|
|
|
echo }) > $out
|
|
|
|
'').outPath;
|
|
|
|
|
|
|
|
discard = builtins.unsafeDiscardStringContext;
|
|
|
|
|
2013-01-13 16:15:01 +00:00
|
|
|
oldStorepath = builtins.storePath (discard (toString oldDependency));
|
Add the replace-dependency build support function.
The use case is to do a deep replacement of a dependency without rebuilding the entire tree.
For example, suppose a security hole is found in glibc and a patch released. Ideally, you'd
just rebuild everything, but that takes time, space, and CPU that you might not have, so in
the mean time you could build a safe version of, say, firefox with:
firefox-safe = replace-dependency { drv = firefox; old-dependency = glibc; new-dependency = patched-glibc; };
Building firefox-safe will rebuild glibc, but only do a simple copy/string replacement on all other dependencies
of firefox. On my system (MBP 13" mid-2012), after a new glibc had been build building firefox took around 11 seconds.
See the comments in the file for more details.
2013-01-11 19:42:09 +00:00
|
|
|
|
2015-11-16 10:42:27 +00:00
|
|
|
referencesOf = drv: references.${discard (toString drv)};
|
Add the replace-dependency build support function.
The use case is to do a deep replacement of a dependency without rebuilding the entire tree.
For example, suppose a security hole is found in glibc and a patch released. Ideally, you'd
just rebuild everything, but that takes time, space, and CPU that you might not have, so in
the mean time you could build a safe version of, say, firefox with:
firefox-safe = replace-dependency { drv = firefox; old-dependency = glibc; new-dependency = patched-glibc; };
Building firefox-safe will rebuild glibc, but only do a simple copy/string replacement on all other dependencies
of firefox. On my system (MBP 13" mid-2012), after a new glibc had been build building firefox took around 11 seconds.
See the comments in the file for more details.
2013-01-11 19:42:09 +00:00
|
|
|
|
2014-09-28 14:39:39 +01:00
|
|
|
dependsOnOldMemo = listToAttrs (map
|
|
|
|
(drv: { name = discard (toString drv);
|
|
|
|
value = elem oldStorepath (referencesOf drv) ||
|
|
|
|
any dependsOnOld (referencesOf drv);
|
|
|
|
}) (builtins.attrNames references));
|
|
|
|
|
2015-11-16 10:42:27 +00:00
|
|
|
dependsOnOld = drv: dependsOnOldMemo.${discard (toString drv)};
|
Add the replace-dependency build support function.
The use case is to do a deep replacement of a dependency without rebuilding the entire tree.
For example, suppose a security hole is found in glibc and a patch released. Ideally, you'd
just rebuild everything, but that takes time, space, and CPU that you might not have, so in
the mean time you could build a safe version of, say, firefox with:
firefox-safe = replace-dependency { drv = firefox; old-dependency = glibc; new-dependency = patched-glibc; };
Building firefox-safe will rebuild glibc, but only do a simple copy/string replacement on all other dependencies
of firefox. On my system (MBP 13" mid-2012), after a new glibc had been build building firefox took around 11 seconds.
See the comments in the file for more details.
2013-01-11 19:42:09 +00:00
|
|
|
|
2013-01-13 16:15:01 +00:00
|
|
|
drvName = drv:
|
Add the replace-dependency build support function.
The use case is to do a deep replacement of a dependency without rebuilding the entire tree.
For example, suppose a security hole is found in glibc and a patch released. Ideally, you'd
just rebuild everything, but that takes time, space, and CPU that you might not have, so in
the mean time you could build a safe version of, say, firefox with:
firefox-safe = replace-dependency { drv = firefox; old-dependency = glibc; new-dependency = patched-glibc; };
Building firefox-safe will rebuild glibc, but only do a simple copy/string replacement on all other dependencies
of firefox. On my system (MBP 13" mid-2012), after a new glibc had been build building firefox took around 11 seconds.
See the comments in the file for more details.
2013-01-11 19:42:09 +00:00
|
|
|
discard (substring 33 (stringLength (builtins.baseNameOf drv)) (builtins.baseNameOf drv));
|
|
|
|
|
2013-01-13 16:15:01 +00:00
|
|
|
rewriteHashes = drv: hashes: runCommand (drvName drv) { nixStore = "${nix}/bin/nix-store"; } ''
|
Add the replace-dependency build support function.
The use case is to do a deep replacement of a dependency without rebuilding the entire tree.
For example, suppose a security hole is found in glibc and a patch released. Ideally, you'd
just rebuild everything, but that takes time, space, and CPU that you might not have, so in
the mean time you could build a safe version of, say, firefox with:
firefox-safe = replace-dependency { drv = firefox; old-dependency = glibc; new-dependency = patched-glibc; };
Building firefox-safe will rebuild glibc, but only do a simple copy/string replacement on all other dependencies
of firefox. On my system (MBP 13" mid-2012), after a new glibc had been build building firefox took around 11 seconds.
See the comments in the file for more details.
2013-01-11 19:42:09 +00:00
|
|
|
$nixStore --dump ${drv} | sed 's|${baseNameOf drv}|'$(basename $out)'|g' | sed -e ${
|
|
|
|
concatStringsSep " -e " (mapAttrsToList (name: value:
|
|
|
|
"'s|${baseNameOf name}|${baseNameOf value}|g'"
|
2013-01-11 21:16:20 +00:00
|
|
|
) hashes)
|
Add the replace-dependency build support function.
The use case is to do a deep replacement of a dependency without rebuilding the entire tree.
For example, suppose a security hole is found in glibc and a patch released. Ideally, you'd
just rebuild everything, but that takes time, space, and CPU that you might not have, so in
the mean time you could build a safe version of, say, firefox with:
firefox-safe = replace-dependency { drv = firefox; old-dependency = glibc; new-dependency = patched-glibc; };
Building firefox-safe will rebuild glibc, but only do a simple copy/string replacement on all other dependencies
of firefox. On my system (MBP 13" mid-2012), after a new glibc had been build building firefox took around 11 seconds.
See the comments in the file for more details.
2013-01-11 19:42:09 +00:00
|
|
|
} | $nixStore --restore $out
|
|
|
|
'';
|
|
|
|
|
2013-01-13 16:15:01 +00:00
|
|
|
rewrittenDeps = listToAttrs [ {name = discard (toString oldDependency); value = newDependency;} ];
|
2013-01-11 21:09:07 +00:00
|
|
|
|
2014-09-28 14:39:39 +01:00
|
|
|
rewriteMemo = listToAttrs (map
|
|
|
|
(drv: { name = discard (toString drv);
|
|
|
|
value = rewriteHashes (builtins.storePath drv)
|
|
|
|
(filterAttrs (n: v: builtins.elem (builtins.storePath (discard (toString n))) (referencesOf drv)) rewriteMemo);
|
|
|
|
})
|
|
|
|
(filter dependsOnOld (builtins.attrNames references))) // rewrittenDeps;
|
Add the replace-dependency build support function.
The use case is to do a deep replacement of a dependency without rebuilding the entire tree.
For example, suppose a security hole is found in glibc and a patch released. Ideally, you'd
just rebuild everything, but that takes time, space, and CPU that you might not have, so in
the mean time you could build a safe version of, say, firefox with:
firefox-safe = replace-dependency { drv = firefox; old-dependency = glibc; new-dependency = patched-glibc; };
Building firefox-safe will rebuild glibc, but only do a simple copy/string replacement on all other dependencies
of firefox. On my system (MBP 13" mid-2012), after a new glibc had been build building firefox took around 11 seconds.
See the comments in the file for more details.
2013-01-11 19:42:09 +00:00
|
|
|
|
2015-11-16 22:44:03 +00:00
|
|
|
drvHash = discard (toString drv);
|
2013-01-13 16:15:01 +00:00
|
|
|
in assert (stringLength (drvName (toString oldDependency)) == stringLength (drvName (toString newDependency)));
|
2015-11-16 22:52:12 +00:00
|
|
|
rewriteMemo.${drvHash} or (warn "replace-dependency.nix: Derivation ${drvHash} does not depend on ${discard (toString oldDependency)}" drv)
|