Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at netboot-syslinux-multiplatform 415 lines 12 kB view raw
1{ stdenv 2, pkgs 3, makeWrapper 4, runCommand 5, lib 6, writeShellScript 7, fetchFromGitHub 8, bundlerEnv 9, callPackage 10 11, ruby_3_2 12, replace 13, gzip 14, gnutar 15, git 16, cacert 17, util-linux 18, gawk 19, nettools 20, imagemagick 21, optipng 22, pngquant 23, libjpeg 24, jpegoptim 25, gifsicle 26, jhead 27, oxipng 28, libpsl 29, redis 30, postgresql 31, which 32, brotli 33, procps 34, rsync 35, icu 36, fetchYarnDeps 37, yarn 38, fixup_yarn_lock 39, nodePackages 40, nodejs_16 41, dart-sass-embedded 42 43, plugins ? [] 44}@args: 45 46let 47 version = "3.1.0.beta4"; 48 49 src = fetchFromGitHub { 50 owner = "discourse"; 51 repo = "discourse"; 52 rev = "v${version}"; 53 sha256 = "sha256-22GXFYPjPYL20amR4xFB4L/dCp32H4Z3uf0GLGEghUE="; 54 }; 55 56 ruby = ruby_3_2; 57 58 runtimeDeps = [ 59 # For backups, themes and assets 60 rubyEnv.wrappedRuby 61 rsync 62 gzip 63 gnutar 64 git 65 brotli 66 67 # Misc required system utils 68 which 69 procps # For ps and kill 70 util-linux # For renice 71 gawk 72 nettools # For hostname 73 74 # Image optimization 75 imagemagick 76 optipng 77 oxipng 78 pngquant 79 libjpeg 80 jpegoptim 81 gifsicle 82 nodePackages.svgo 83 jhead 84 ]; 85 86 runtimeEnv = { 87 HOME = "/run/discourse/home"; 88 RAILS_ENV = "production"; 89 UNICORN_LISTENER = "/run/discourse/sockets/unicorn.sock"; 90 }; 91 92 mkDiscoursePlugin = 93 { name ? null 94 , pname ? null 95 , version ? null 96 , meta ? null 97 , bundlerEnvArgs ? {} 98 , preserveGemsDir ? false 99 , src 100 , ... 101 }@args: 102 let 103 rubyEnv = bundlerEnv (bundlerEnvArgs // { 104 inherit name pname version ruby; 105 }); 106 in 107 stdenv.mkDerivation (builtins.removeAttrs args [ "bundlerEnvArgs" ] // { 108 pluginName = if name != null then name else "${pname}-${version}"; 109 dontConfigure = true; 110 dontBuild = true; 111 installPhase = '' 112 runHook preInstall 113 mkdir -p $out 114 cp -r * $out/ 115 '' + lib.optionalString (bundlerEnvArgs != {}) ( 116 if preserveGemsDir then '' 117 cp -r ${rubyEnv}/lib/ruby/gems/* $out/gems/ 118 '' 119 else '' 120 if [[ -e $out/gems ]]; then 121 echo "Warning: The repo contains a 'gems' directory which will be removed!" 122 echo " If you need to preserve it, set 'preserveGemsDir = true'." 123 rm -r $out/gems 124 fi 125 ln -sf ${rubyEnv}/lib/ruby/gems $out/gems 126 '' + '' 127 runHook postInstall 128 ''); 129 }); 130 131 rake = runCommand "discourse-rake" { 132 nativeBuildInputs = [ makeWrapper ]; 133 } '' 134 mkdir -p $out/bin 135 makeWrapper ${rubyEnv}/bin/rake $out/bin/discourse-rake \ 136 ${lib.concatStrings (lib.mapAttrsToList (name: value: "--set ${name} '${value}' ") runtimeEnv)} \ 137 --prefix PATH : ${lib.makeBinPath runtimeDeps} \ 138 --set RAKEOPT '-f ${discourse}/share/discourse/Rakefile' \ 139 --chdir '${discourse}/share/discourse' 140 ''; 141 142 rubyEnv = bundlerEnv { 143 name = "discourse-ruby-env-${version}"; 144 inherit version ruby; 145 gemdir = ./rubyEnv; 146 gemset = 147 let 148 gems = import ./rubyEnv/gemset.nix; 149 in 150 gems // { 151 mini_racer = gems.mini_racer // { 152 buildInputs = [ icu ]; 153 dontBuild = false; 154 NIX_LDFLAGS = "-licui18n"; 155 }; 156 libv8-node = 157 let 158 noopScript = writeShellScript "noop" "exit 0"; 159 linkFiles = writeShellScript "link-files" '' 160 cd ../.. 161 162 mkdir -p vendor/v8/${stdenv.hostPlatform.system}/libv8/obj/ 163 ln -s "${nodejs_16.libv8}/lib/libv8.a" vendor/v8/${stdenv.hostPlatform.system}/libv8/obj/libv8_monolith.a 164 165 ln -s ${nodejs_16.libv8}/include vendor/v8/include 166 167 mkdir -p ext/libv8-node 168 echo '--- !ruby/object:Libv8::Node::Location::Vendor {}' >ext/libv8-node/.location.yml 169 ''; 170 in gems.libv8-node // { 171 dontBuild = false; 172 postPatch = '' 173 cp ${noopScript} libexec/build-libv8 174 cp ${noopScript} libexec/build-monolith 175 cp ${noopScript} libexec/download-node 176 cp ${noopScript} libexec/extract-node 177 cp ${linkFiles} libexec/inject-libv8 178 ''; 179 }; 180 mini_suffix = gems.mini_suffix // { 181 propagatedBuildInputs = [ libpsl ]; 182 dontBuild = false; 183 # Use our libpsl instead of the vendored one, which isn't 184 # available for aarch64. It has to be called 185 # libpsl.x86_64.so or it isn't found. 186 postPatch = '' 187 cp $(readlink -f ${libpsl}/lib/libpsl.so) vendor/libpsl.x86_64.so 188 ''; 189 }; 190 sass-embedded = gems.sass-embedded // { 191 dontBuild = false; 192 # `sass-embedded` depends on `dart-sass-embedded` and tries to 193 # fetch that as `.tar.gz` from GitHub releases. That `.tar.gz` 194 # can also be specified via `SASS_EMBEDDED`. But instead of 195 # compressing our `dart-sass-embedded` just to decompress it 196 # again, we simply patch the Rakefile to symlink that path. 197 patches = [ 198 ./rubyEnv/sass-embedded-static.patch 199 ]; 200 postPatch = '' 201 export SASS_EMBEDDED=${dart-sass-embedded}/bin 202 ''; 203 }; 204 }; 205 206 groups = [ 207 "default" "assets" "development" "test" 208 ]; 209 }; 210 211 assets = stdenv.mkDerivation { 212 pname = "discourse-assets"; 213 inherit version src; 214 215 yarnOfflineCache = fetchYarnDeps { 216 yarnLock = src + "/app/assets/javascripts/yarn.lock"; 217 sha256 = "0a20kns4irdpzzx2dvdjbi0m3s754gp737q08z5nlcnffxqvykrk"; 218 }; 219 220 nativeBuildInputs = runtimeDeps ++ [ 221 postgresql 222 redis 223 nodePackages.uglify-js 224 nodePackages.terser 225 nodePackages.patch-package 226 yarn 227 nodejs_16 228 ]; 229 230 outputs = [ "out" "javascripts" ]; 231 232 patches = [ 233 # Use the Ruby API version in the plugin gem path, to match the 234 # one constructed by bundlerEnv 235 ./plugin_gem_api_version.patch 236 237 # Change the path to the auto generated plugin assets, which 238 # defaults to the plugin's directory and isn't writable at the 239 # time of asset generation 240 ./auto_generated_path.patch 241 242 # Fix the rake command used to recursively execute itself in the 243 # assets precompilation task. 244 ./assets_rake_command.patch 245 246 # `app/assets/javascripts/discourse/package.json`'s postinstall 247 # hook tries to call `../node_modules/.bin/patch-package`, which 248 # hasn't been `patchShebangs`-ed yet. So instead we just use 249 # `patch-package` from `nativeBuildInputs`. 250 ./asserts_patch-package_from_path.patch 251 ]; 252 253 # We have to set up an environment that is close enough to 254 # production ready or the assets:precompile task refuses to 255 # run. This means that Redis and PostgreSQL has to be running and 256 # database migrations performed. 257 preBuild = '' 258 # Yarn wants a real home directory to write cache, config, etc to 259 export HOME=$NIX_BUILD_TOP/fake_home 260 261 # Make yarn install packages from our offline cache, not the registry 262 yarn config --offline set yarn-offline-mirror $yarnOfflineCache 263 264 # Fixup "resolved"-entries in yarn.lock to match our offline cache 265 ${fixup_yarn_lock}/bin/fixup_yarn_lock app/assets/javascripts/yarn.lock 266 267 export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt 268 269 yarn install --offline --cwd app/assets/javascripts/discourse 270 271 patchShebangs app/assets/javascripts/node_modules/ 272 273 redis-server >/dev/null & 274 275 initdb -A trust $NIX_BUILD_TOP/postgres >/dev/null 276 postgres -D $NIX_BUILD_TOP/postgres -k $NIX_BUILD_TOP >/dev/null & 277 export PGHOST=$NIX_BUILD_TOP 278 279 echo "Waiting for Redis and PostgreSQL to be ready.." 280 while ! redis-cli --scan >/dev/null || ! psql -l >/dev/null; do 281 sleep 0.1 282 done 283 284 psql -d postgres -tAc 'CREATE USER "discourse"' 285 psql -d postgres -tAc 'CREATE DATABASE "discourse" OWNER "discourse"' 286 psql 'discourse' -tAc "CREATE EXTENSION IF NOT EXISTS pg_trgm" 287 psql 'discourse' -tAc "CREATE EXTENSION IF NOT EXISTS hstore" 288 289 # Create a temporary home dir to stop bundler from complaining 290 mkdir $NIX_BUILD_TOP/tmp_home 291 export HOME=$NIX_BUILD_TOP/tmp_home 292 293 ${lib.concatMapStringsSep "\n" (p: "ln -sf ${p} plugins/${p.pluginName or ""}") plugins} 294 295 export RAILS_ENV=production 296 297 bundle exec rake db:migrate >/dev/null 298 chmod -R +w tmp 299 ''; 300 301 buildPhase = '' 302 runHook preBuild 303 304 bundle exec rake assets:precompile 305 306 runHook postBuild 307 ''; 308 309 installPhase = '' 310 runHook preInstall 311 312 mv public/assets $out 313 314 rm -r app/assets/javascripts/plugins 315 mv app/assets/javascripts $javascripts 316 ln -sf /run/discourse/assets/javascripts/plugins $javascripts/plugins 317 318 runHook postInstall 319 ''; 320 }; 321 322 discourse = stdenv.mkDerivation { 323 pname = "discourse"; 324 inherit version src; 325 326 buildInputs = [ 327 rubyEnv rubyEnv.wrappedRuby rubyEnv.bundler 328 ]; 329 330 patches = [ 331 # Load a separate NixOS site settings file 332 ./nixos_defaults.patch 333 334 # Add a noninteractive admin creation task 335 ./admin_create.patch 336 337 # Add the path to the CA cert bundle to make TLS work 338 ./action_mailer_ca_cert.patch 339 340 # Log Unicorn messages to the journal and make request timeout 341 # configurable 342 ./unicorn_logging_and_timeout.patch 343 344 # Use the Ruby API version in the plugin gem path, to match the 345 # one constructed by bundlerEnv 346 ./plugin_gem_api_version.patch 347 348 # Change the path to the auto generated plugin assets, which 349 # defaults to the plugin's directory and isn't writable at the 350 # time of asset generation 351 ./auto_generated_path.patch 352 353 # Make sure the notification email setting applies 354 ./notification_email.patch 355 ]; 356 357 postPatch = '' 358 # Always require lib-files and application.rb through their store 359 # path, not their relative state directory path. This gets rid of 360 # warnings and means we don't have to link back to lib from the 361 # state directory. 362 find config -type f -name "*.rb" -execdir \ 363 sed -Ei "s,(\.\./)+(lib|app)/,$out/share/discourse/\2/," {} \; 364 find config -maxdepth 1 -type f -name "*.rb" -execdir \ 365 sed -Ei "s,require_relative (\"|')([[:alnum:]].*)(\"|'),require_relative '$out/share/discourse/config/\2'," {} \; 366 ''; 367 368 buildPhase = '' 369 runHook preBuild 370 371 mv config config.dist 372 mv public public.dist 373 374 runHook postBuild 375 ''; 376 377 installPhase = '' 378 runHook preInstall 379 380 mkdir -p $out/share 381 cp -r . $out/share/discourse 382 rm -r $out/share/discourse/log 383 ln -sf /var/log/discourse $out/share/discourse/log 384 ln -sf /var/lib/discourse/tmp $out/share/discourse/tmp 385 ln -sf /run/discourse/config $out/share/discourse/config 386 ln -sf /run/discourse/public $out/share/discourse/public 387 ln -sf ${assets} $out/share/discourse/public.dist/assets 388 rm -r $out/share/discourse/app/assets/javascripts 389 ln -sf ${assets.javascripts} $out/share/discourse/app/assets/javascripts 390 ${lib.concatMapStringsSep "\n" (p: "ln -sf ${p} $out/share/discourse/plugins/${p.pluginName or ""}") plugins} 391 392 runHook postInstall 393 ''; 394 395 meta = with lib; { 396 homepage = "https://www.discourse.org/"; 397 platforms = platforms.linux; 398 maintainers = with maintainers; [ talyz ]; 399 license = licenses.gpl2Plus; 400 description = "Discourse is an open source discussion platform"; 401 }; 402 403 passthru = { 404 inherit rubyEnv runtimeEnv runtimeDeps rake mkDiscoursePlugin assets; 405 enabledPlugins = plugins; 406 plugins = callPackage ./plugins/all-plugins.nix { inherit mkDiscoursePlugin; }; 407 ruby = rubyEnv.wrappedRuby; 408 tests = import ../../../../nixos/tests/discourse.nix { 409 inherit (stdenv) system; 410 inherit pkgs; 411 package = pkgs.discourse.override args; 412 }; 413 }; 414 }; 415in discourse