diff options
Diffstat (limited to 'nixpkgs/pkgs/applications/networking/browsers/ungoogled-chromium/update.nix')
-rw-r--r-- | nixpkgs/pkgs/applications/networking/browsers/ungoogled-chromium/update.nix | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/applications/networking/browsers/ungoogled-chromium/update.nix b/nixpkgs/pkgs/applications/networking/browsers/ungoogled-chromium/update.nix new file mode 100644 index 00000000000..6dff17c69dd --- /dev/null +++ b/nixpkgs/pkgs/applications/networking/browsers/ungoogled-chromium/update.nix @@ -0,0 +1,271 @@ +let maybePkgs = import ../../../../../. {}; in + +{ stdenv ? maybePkgs.stdenv +, runCommand ? maybePkgs.runCommand +, fetchurl ? maybePkgs.fetchurl +, writeText ? maybePkgs.writeText +, curl ? maybePkgs.curl +, cacert ? maybePkgs.cacert +, nix ? maybePkgs.nix +}: + +let + inherit (stdenv) lib; + + sources = if builtins.pathExists ./upstream-info.nix + then import ./upstream-info.nix + else {}; + + bucketURL = "https://commondatastorage.googleapis.com/" + + "chromium-browser-official"; + + mkVerURL = version: "${bucketURL}/chromium-${version}.tar.xz"; + + debURL = "https://dl.google.com/linux/chrome/deb/pool/main/g"; + + getDebURL = channelName: version: arch: mirror: let + packageSuffix = if channelName == "dev" then "unstable" else channelName; + packageName = "google-chrome-${packageSuffix}"; + in "${mirror}/${packageName}/${packageName}_${version}-1_${arch}.deb"; + + # Untrusted mirrors, don't try to update from them! + debMirrors = [ + "http://95.31.35.30/chrome/pool/main/g" + "http://mirror.pcbeta.com/google/chrome/deb/pool/main/g" + "http://repo.fdzh.org/chrome/deb/pool/main/g" + ]; + +in { + getChannel = channel: let + chanAttrs = builtins.getAttr channel sources; + in { + inherit channel; + inherit (chanAttrs) version; + + main = fetchurl { + url = mkVerURL chanAttrs.version; + inherit (chanAttrs) sha256; + }; + + binary = fetchurl (let + mkUrls = arch: let + mkURLForMirror = getDebURL channel chanAttrs.version arch; + in map mkURLForMirror ([ debURL ] ++ debMirrors); + in if stdenv.is64bit && chanAttrs ? sha256bin64 then { + urls = mkUrls "amd64"; + sha256 = chanAttrs.sha256bin64; + } else if !stdenv.is64bit && chanAttrs ? sha256bin32 then { + urls = mkUrls "i386"; + sha256 = chanAttrs.sha256bin32; + } else throw "No Chrome plugins are available for your architecture."); + }; + + update = let + csv2nix = name: src: import (runCommand "${name}.nix" { + src = builtins.fetchurl src; + } '' + esc() { echo "\"$(echo "$1" | sed -e 's/"\\$/\\&/')\""; } # ohai emacs " + IFS=, read -r -a headings <<< "$(head -n1 "$src")" + echo "[" > "$out" + tail -n +2 "$src" | while IFS=, read -r -a line; do + echo " {" + for idx in "''${!headings[@]}"; do + echo " $(esc "''${headings[idx]}") = $(esc ''${line[$idx]});" + done + echo " }" + done >> "$out" + echo "]" >> "$out" + ''); + + channels = lib.fold lib.recursiveUpdate {} (map (attrs: { + ${attrs.os}.${attrs.channel} = attrs // { + history = let + drvName = "omahaproxy-${attrs.os}.${attrs.channel}-info"; + history = csv2nix drvName "http://omahaproxy.appspot.com/history"; + cond = h: attrs.os == h.os && attrs.channel == h.channel + && lib.versionOlder h.version attrs.current_version; + # Note that this is a *reverse* sort! + sorter = a: b: lib.versionOlder b.version a.version; + sorted = builtins.sort sorter (lib.filter cond history); + in map (lib.flip removeAttrs ["os" "channel"]) sorted; + version = attrs.current_version; + }; + }) (csv2nix "omahaproxy-info" "http://omahaproxy.appspot.com/all?csv=1")); + + /* + XXX: This is essentially the same as: + + builtins.tryEval (builtins.fetchurl url) + + ... except that tryEval on fetchurl isn't working and doesn't catch + errors for fetchurl, so we go for a different approach. + + We only have fixed-output derivations that can have networking access, so + we abuse SHA1 and its weaknesses to forge a fixed-output derivation which + is not so fixed, because it emits different contents that have the same + SHA1 hash. + + Using this method, we can distinguish whether the URL is available or + whether it's not based on the actual content. + + So let's use tryEval as soon as it's working with fetchurl in Nix. + */ + tryFetch = url: let + # SHA1 hash collisions from https://shattered.io/static/shattered.pdf: + collisions = runCommand "sha1-collisions" { + outputs = [ "out" "good" "bad" ]; + base64 = '' + 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 + NC/4ct6rQkPkQHMcV/8XckU4UJCy+VeTA== + ''; + } '' + echo "$base64" | base64 -d | tar xj + mv good.pdf "$good" + mv bad.pdf "$bad" + touch "$out" + ''; + + cacheVal = let + urlHash = builtins.hashString "sha256" url; + timeSlice = builtins.currentTime / 600; + in "${urlHash}-${toString timeSlice}"; + + in { + success = import (runCommand "check-success" { + result = stdenv.mkDerivation { + name = "tryfetch-${cacheVal}"; + inherit url; + + outputHash = "d00bbe65d80f6d53d5c15da7c6b4f0a655c5a86a"; + outputHashMode = "flat"; + outputHashAlgo = "sha1"; + + nativeBuildInputs = [ curl ]; + preferLocalBuild = true; + + inherit (collisions) good bad; + + buildCommand = '' + if SSL_CERT_FILE="${cacert}/etc/ssl/certs/ca-bundle.crt" \ + curl -s -L -f -I "$url" > /dev/null; then + cp "$good" "$out" + else + cp "$bad" "$out" + fi + ''; + + impureEnvVars = lib.fetchers.proxyImpureEnvVars; + }; + inherit (collisions) good; + } '' + if cmp -s "$result" "$good"; then + echo true > "$out" + else + echo false > "$out" + fi + ''); + value = builtins.fetchurl url; + }; + + fetchLatest = channel: let + result = tryFetch (mkVerURL channel.version); + in if result.success then result.value else fetchLatest (channel // { + version = if channel.history != [] + then (lib.head channel.history).version + else throw "Unfortunately there's no older version than " + + "${channel.version} available for channel " + + "${channel.channel} on ${channel.os}."; + history = lib.tail channel.history; + }); + + getHash = path: import (runCommand "gethash.nix" { + inherit path; + nativeBuildInputs = [ nix ]; + } '' + sha256="$(nix-hash --flat --base32 --type sha256 "$path")" + echo "\"$sha256\"" > "$out" + ''); + + isLatest = channel: version: let + ourVersion = sources.${channel}.version or null; + in if ourVersion == null then false + else lib.versionOlder version sources.${channel}.version + || version == sources.${channel}.version; + + # We only support GNU/Linux right now. + linuxChannels = let + genLatest = channelName: channel: let + newUpstream = { + inherit (channel) version; + sha256 = getHash (fetchLatest channel); + }; + keepOld = let + oldChannel = sources.${channelName}; + in { + inherit (oldChannel) version sha256; + } // lib.optionalAttrs (oldChannel ? sha256bin32) { + inherit (oldChannel) sha256bin32; + } // lib.optionalAttrs (oldChannel ? sha256bin64) { + inherit (oldChannel) sha256bin64; + }; + in if isLatest channelName channel.version then keepOld else newUpstream; + in lib.mapAttrs genLatest channels.linux; + + getLinuxFlash = channelName: channel: let + inherit (channel) version; + fetchArch = arch: tryFetch (getDebURL channelName version arch debURL); + packages = lib.genAttrs ["i386" "amd64"] fetchArch; + isNew = arch: attr: !(builtins.hasAttr attr channel) + && packages.${arch}.success; + in channel // lib.optionalAttrs (isNew "i386" "sha256bin32") { + sha256bin32 = getHash (packages.i386.value); + } // lib.optionalAttrs (isNew "amd64" "sha256bin64") { + sha256bin64 = getHash (packages.amd64.value); + }; + + newChannels = lib.mapAttrs getLinuxFlash linuxChannels; + + dumpAttrs = indent: attrs: let + mkVal = val: if lib.isAttrs val then dumpAttrs (indent + 1) val + else "\"${lib.escape ["$" "\\" "\""] (toString val)}\""; + mkIndent = level: lib.concatStrings (builtins.genList (_: " ") level); + mkAttr = key: val: "${mkIndent (indent + 1)}${key} = ${mkVal val};\n"; + attrLines = lib.mapAttrsToList mkAttr attrs; + in "{\n" + (lib.concatStrings attrLines) + (mkIndent indent) + "}"; + in writeText "chromium-new-upstream-info.nix" '' + # This file is autogenerated from update.sh in the same directory. + ${dumpAttrs 0 newChannels} + ''; +} |