選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

212 行
7.8 KiB

  1. # Checks derivation meta and attrs for problems (like brokenness,
  2. # licenses, etc).
  3. { lib, config, hostPlatform, meta }:
  4. let
  5. # See discussion at https://github.com/NixOS/nixpkgs/pull/25304#issuecomment-298385426
  6. # for why this defaults to false, but I (@copumpkin) want to default it to true soon.
  7. shouldCheckMeta = config.checkMeta or false;
  8. allowUnfree = config.allowUnfree or false || builtins.getEnv "NIXPKGS_ALLOW_UNFREE" == "1";
  9. whitelist = config.whitelistedLicenses or [];
  10. blacklist = config.blacklistedLicenses or [];
  11. onlyLicenses = list:
  12. lib.lists.all (license:
  13. let l = lib.licenses.${license.shortName or "BROKEN"} or false; in
  14. if license == l then true else
  15. throw ''‘${showLicense license}’ is not an attribute of lib.licenses''
  16. ) list;
  17. areLicenseListsValid =
  18. if lib.mutuallyExclusive whitelist blacklist then
  19. assert onlyLicenses whitelist; assert onlyLicenses blacklist; true
  20. else
  21. throw "whitelistedLicenses and blacklistedLicenses are not mutually exclusive.";
  22. hasLicense = attrs:
  23. attrs ? meta.license;
  24. hasWhitelistedLicense = assert areLicenseListsValid; attrs:
  25. hasLicense attrs && builtins.elem attrs.meta.license whitelist;
  26. hasBlacklistedLicense = assert areLicenseListsValid; attrs:
  27. hasLicense attrs && builtins.elem attrs.meta.license blacklist;
  28. allowBroken = config.allowBroken or false || builtins.getEnv "NIXPKGS_ALLOW_BROKEN" == "1";
  29. allowUnsupportedSystem = config.allowUnsupportedSystem or false;
  30. isUnfree = licenses: lib.lists.any (l:
  31. !l.free or true || l == "unfree" || l == "unfree-redistributable") licenses;
  32. # Alow granular checks to allow only some unfree packages
  33. # Example:
  34. # {pkgs, ...}:
  35. # {
  36. # allowUnfree = false;
  37. # allowUnfreePredicate = (x: pkgs.lib.hasPrefix "flashplayer-" x.name);
  38. # }
  39. allowUnfreePredicate = config.allowUnfreePredicate or (x: false);
  40. # Check whether unfree packages are allowed and if not, whether the
  41. # package has an unfree license and is not explicitely allowed by the
  42. # `allowUNfreePredicate` function.
  43. hasDeniedUnfreeLicense = attrs:
  44. !allowUnfree &&
  45. hasLicense attrs &&
  46. isUnfree (lib.lists.toList attrs.meta.license) &&
  47. !allowUnfreePredicate attrs;
  48. allowInsecureDefaultPredicate = x: builtins.elem x.name (config.permittedInsecurePackages or []);
  49. allowInsecurePredicate = x: (config.allowInsecurePredicate or allowInsecureDefaultPredicate) x;
  50. hasAllowedInsecure = attrs:
  51. (attrs.meta.knownVulnerabilities or []) == [] ||
  52. allowInsecurePredicate attrs ||
  53. builtins.getEnv "NIXPKGS_ALLOW_INSECURE" == "1";
  54. showLicense = license: license.shortName or "unknown";
  55. pos_str = meta.position or "«unknown-file»";
  56. remediation = {
  57. unfree = remediate_whitelist "Unfree";
  58. broken = remediate_whitelist "Broken";
  59. blacklisted = x: "";
  60. insecure = remediate_insecure;
  61. unknown-meta = x: "";
  62. };
  63. remediate_whitelist = allow_attr: attrs:
  64. ''
  65. a) For `nixos-rebuild` you can set
  66. { nixpkgs.config.allow${allow_attr} = true; }
  67. in configuration.nix to override this.
  68. b) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
  69. { allow${allow_attr} = true; }
  70. to ~/.config/nixpkgs/config.nix.
  71. '';
  72. remediate_insecure = attrs:
  73. ''
  74. Known issues:
  75. '' + (lib.concatStrings (map (issue: " - ${issue}\n") attrs.meta.knownVulnerabilities)) + ''
  76. You can install it anyway by whitelisting this package, using the
  77. following methods:
  78. a) for `nixos-rebuild` you can add ‘${attrs.name or "«name-missing»"}’ to
  79. `nixpkgs.config.permittedInsecurePackages` in the configuration.nix,
  80. like so:
  81. {
  82. nixpkgs.config.permittedInsecurePackages = [
  83. "${attrs.name or "«name-missing»"}"
  84. ];
  85. }
  86. b) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
  87. ‘${attrs.name or "«name-missing»"}’ to `permittedInsecurePackages` in
  88. ~/.config/nixpkgs/config.nix, like so:
  89. {
  90. permittedInsecurePackages = [
  91. "${attrs.name or "«name-missing»"}"
  92. ];
  93. }
  94. '';
  95. handleEvalIssue = attrs: { reason , errormsg ? "" }:
  96. let
  97. msg = ''
  98. Package ‘${attrs.name or "«name-missing»"}’ in ${pos_str} ${errormsg}, refusing to evaluate.
  99. '' + (builtins.getAttr reason remediation) attrs;
  100. handler = if config ? "handleEvalIssue"
  101. then config.handleEvalIssue reason
  102. else throw;
  103. in handler msg;
  104. metaTypes = with lib.types; rec {
  105. # These keys are documented
  106. description = str;
  107. longDescription = str;
  108. branch = str;
  109. homepage = either (listOf str) str;
  110. downloadPage = str;
  111. license = either (listOf lib.types.attrs) (either lib.types.attrs str);
  112. maintainers = listOf (attrsOf str);
  113. priority = int;
  114. platforms = listOf (either str lib.systems.parsed.types.system);
  115. hydraPlatforms = listOf str;
  116. broken = bool;
  117. # Weirder stuff that doesn't appear in the documentation?
  118. knownVulnerabilities = listOf str;
  119. name = str;
  120. version = str;
  121. tag = str;
  122. updateWalker = bool;
  123. executables = listOf str;
  124. outputsToInstall = listOf str;
  125. position = str;
  126. available = bool;
  127. repositories = attrsOf str;
  128. isBuildPythonPackage = platforms;
  129. schedulingPriority = int;
  130. downloadURLRegexp = str;
  131. isFcitxEngine = bool;
  132. isIbusEngine = bool;
  133. isGutenprint = bool;
  134. badPlatforms = platforms;
  135. };
  136. checkMetaAttr = k: v:
  137. if metaTypes?${k} then
  138. if metaTypes.${k}.check v then null else "key '${k}' has a value ${toString v} of an invalid type ${builtins.typeOf v}; expected ${metaTypes.${k}.description}"
  139. else "key '${k}' is unrecognized; expected one of: \n\t [${lib.concatMapStringsSep ", " (x: "'${x}'") (lib.attrNames metaTypes)}]";
  140. checkMeta = meta: if shouldCheckMeta then lib.remove null (lib.mapAttrsToList checkMetaAttr meta) else [];
  141. checkPlatform = attrs:
  142. (!(attrs ? meta.platforms) || lib.any (lib.meta.platformMatch hostPlatform) attrs.meta.platforms) &&
  143. (!(attrs ? meta.badPlatforms && lib.any (lib.meta.platformMatch hostPlatform) attrs.meta.badPlatforms));
  144. # Check if a derivation is valid, that is whether it passes checks for
  145. # e.g brokenness or license.
  146. #
  147. # Return { valid: Bool } and additionally
  148. # { reason: String; errormsg: String } if it is not valid, where
  149. # reason is one of "unfree", "blacklisted" or "broken".
  150. checkValidity = attrs:
  151. if hasDeniedUnfreeLicense attrs && !(hasWhitelistedLicense attrs) then
  152. { valid = false; reason = "unfree"; errormsg = "has an unfree license (‘${showLicense attrs.meta.license}’)"; }
  153. else if hasBlacklistedLicense attrs then
  154. { valid = false; reason = "blacklisted"; errormsg = "has a blacklisted license (‘${showLicense attrs.meta.license}’)"; }
  155. else if !allowBroken && attrs.meta.broken or false then
  156. { valid = false; reason = "broken"; errormsg = "is marked as broken"; }
  157. else if !allowUnsupportedSystem && !allowBroken && !(checkPlatform attrs) then
  158. { valid = false; reason = "broken"; errormsg = "is not supported on ‘${hostPlatform.config}’"; }
  159. else if !(hasAllowedInsecure attrs) then
  160. { valid = false; reason = "insecure"; errormsg = "is marked as insecure"; }
  161. else let res = checkMeta (attrs.meta or {}); in if res != [] then
  162. { valid = false; reason = "unknown-meta"; errormsg = "has an invalid meta attrset:${lib.concatMapStrings (x: "\n\t - " + x) res}"; }
  163. else { valid = true; };
  164. assertValidity = attrs: let
  165. validity = checkValidity attrs;
  166. in validity // {
  167. # Throw an error if trying to evaluate an non-valid derivation
  168. handled = if !validity.valid
  169. then handleEvalIssue attrs (removeAttrs validity ["valid"])
  170. else true;
  171. };
  172. in assertValidity