Merge pull request #30166 from LumiGuide/graphite-1.0.2

Fix graphite crash by upgrading from 0.9.15 -> 1.0.2

authored by

Peter Simons and committed by
GitHub
757a7590 7d5c5eb2

+144 -27
+11
nixos/lib/test-driver/Machine.pm
··· 372 372 return $info; 373 373 } 374 374 375 + # Fail if the given systemd unit is not in the "active" state. 376 + sub requireActiveUnit { 377 + my ($self, $unit) = @_; 378 + $self->nest("checking if unit ‘$unit’ has reached state 'active'", sub { 379 + my $info = $self->getUnitInfo($unit); 380 + my $state = $info->{ActiveState}; 381 + if ($state ne "active") { 382 + die "Expected unit ‘$unit’ to to be in state 'active' but it is in state ‘$state’\n"; 383 + }; 384 + }); 385 + } 375 386 376 387 # Wait for a systemd unit to reach the "active" state. 377 388 sub waitForUnit {
+42 -12
nixos/modules/services/monitoring/graphite.nix
··· 7 7 writeTextOrNull = f: t: mapNullable (pkgs.writeTextDir f) t; 8 8 9 9 dataDir = cfg.dataDir; 10 + staticDir = cfg.dataDir + "/static"; 11 + 12 + graphiteLocalSettingsDir = pkgs.runCommand "graphite_local_settings" 13 + {inherit graphiteLocalSettings;} '' 14 + mkdir -p $out 15 + ln -s $graphiteLocalSettings $out/graphite_local_settings.py 16 + ''; 17 + 18 + graphiteLocalSettings = pkgs.writeText "graphite_local_settings.py" ( 19 + "STATIC_ROOT = '${staticDir}'\n" + 20 + optionalString (! isNull config.time.timeZone) "TIME_ZONE = '${config.time.timeZone}'\n" 21 + + cfg.web.extraConfig 22 + ); 10 23 11 24 graphiteApiConfig = pkgs.writeText "graphite-api.yaml" '' 12 25 time_zone: ${config.time.timeZone} ··· 93 106 description = "Graphite web frontend port."; 94 107 default = 8080; 95 108 type = types.int; 109 + }; 110 + 111 + extraConfig = mkOption { 112 + type = types.str; 113 + default = ""; 114 + description = '' 115 + Graphite webapp settings. See: 116 + <link xlink:href="http://graphite.readthedocs.io/en/latest/config-local-settings.html"/> 117 + ''; 96 118 }; 97 119 }; 98 120 ··· 460 482 ]; 461 483 }; 462 484 penvPack = "${penv}/${pkgs.python.sitePackages}"; 463 - # opt/graphite/webapp contains graphite/settings.py 464 - # explicitly adding pycairo in path because it cannot be imported via buildEnv 465 - in "${penvPack}/opt/graphite/webapp:${penvPack}:${pkgs.pythonPackages.pycairo}/${pkgs.python.sitePackages}"; 485 + in concatStringsSep ":" [ 486 + "${graphiteLocalSettingsDir}" 487 + "${penvPack}/opt/graphite/webapp" 488 + "${penvPack}" 489 + # explicitly adding pycairo in path because it cannot be imported via buildEnv 490 + "${pkgs.pythonPackages.pycairo}/${pkgs.python.sitePackages}" 491 + ]; 466 492 DJANGO_SETTINGS_MODULE = "graphite.settings"; 467 493 GRAPHITE_CONF_DIR = configDir; 468 494 GRAPHITE_STORAGE_DIR = dataDir; ··· 470 496 }; 471 497 serviceConfig = { 472 498 ExecStart = '' 473 - ${pkgs.python27Packages.waitress}/bin/waitress-serve \ 474 - --host=${cfg.web.listenAddress} --port=${toString cfg.web.port} \ 475 - --call django.core.handlers.wsgi:WSGIHandler''; 499 + ${pkgs.python27Packages.waitress-django}/bin/waitress-serve-django \ 500 + --host=${cfg.web.listenAddress} --port=${toString cfg.web.port} 501 + ''; 476 502 User = "graphite"; 477 503 Group = "graphite"; 478 504 PermissionsStartOnly = true; ··· 482 508 mkdir -p ${dataDir}/{whisper/,log/webapp/} 483 509 chmod 0700 ${dataDir}/{whisper/,log/webapp/} 484 510 485 - # populate database 486 - ${pkgs.python27Packages.graphite_web}/bin/manage-graphite.py syncdb --noinput 487 - 488 - # create index 489 - ${pkgs.python27Packages.graphite_web}/bin/build-index.sh 511 + ${pkgs.pythonPackages.django_1_8}/bin/django-admin.py migrate --noinput 490 512 491 - chown -R graphite:graphite ${cfg.dataDir} 513 + chown -R graphite:graphite ${dataDir} 492 514 493 515 touch ${dataDir}/db-created 516 + fi 517 + 518 + # Only collect static files when graphite_web changes. 519 + if ! [ "${dataDir}/current_graphite_web" -ef "${pkgs.python27Packages.graphite_web}" ]; then 520 + mkdir -p ${staticDir} 521 + ${pkgs.pythonPackages.django_1_8}/bin/django-admin.py collectstatic --noinput --clear 522 + chown -R graphite:graphite ${staticDir} 523 + ln -sfT "${pkgs.python27Packages.graphite_web}" "${dataDir}/current_graphite_web" 494 524 fi 495 525 ''; 496 526 };
+1
nixos/release.nix
··· 257 257 tests.gnome3 = callTest tests/gnome3.nix {}; 258 258 tests.gnome3-gdm = callTest tests/gnome3-gdm.nix {}; 259 259 tests.grafama = callTest tests/grafana.nix {}; 260 + tests.graphite = callTest tests/graphite.nix {}; 260 261 tests.hardened = callTest tests/hardened.nix { }; 261 262 tests.hibernate = callTest tests/hibernate.nix {}; 262 263 tests.hound = callTest tests/hound.nix {};
+26
nixos/tests/graphite.nix
··· 1 + import ./make-test.nix ({ pkgs, ...} : 2 + { 3 + name = "graphite"; 4 + nodes = { 5 + one = 6 + { config, pkgs, ... }: { 7 + services.graphite = { 8 + web = { 9 + enable = true; 10 + }; 11 + carbon = { 12 + enableCache = true; 13 + }; 14 + }; 15 + }; 16 + }; 17 + 18 + testScript = '' 19 + startAll; 20 + $one->waitForUnit("default.target"); 21 + $one->requireActiveUnit("graphiteWeb.service"); 22 + $one->requireActiveUnit("carbonCache.service"); 23 + $one->succeed("echo \"foo 1 `date +%s`\" | nc -q0 localhost 2003"); 24 + $one->waitUntilSucceeds("curl 'http://localhost:8080/metrics/find/?query=foo&format=treejson' --silent | grep foo") 25 + ''; 26 + })
+8
pkgs/development/python-modules/waitress-django/default.nix
··· 1 + { buildPythonPackage, django_1_8, waitress }: 2 + buildPythonPackage { 3 + name = "waitress-django"; 4 + src = ./.; 5 + pythonPath = [ django_1_8 waitress ]; 6 + doCheck = false; 7 + meta.description = "A waitress WSGI server serving django"; 8 + }
+12
pkgs/development/python-modules/waitress-django/setup.py
··· 1 + #!/usr/bin/env python 2 + 3 + from distutils.core import setup 4 + 5 + setup( name = "waitress-django" 6 + , version = "0.0.0" 7 + , description = "A waitress WSGI server serving django" 8 + , author = "Bas van Dijk" 9 + , author_email = "v.dijk.bas@gmail.com" 10 + , package_dir = {"" : "src"} 11 + , scripts = ["src/waitress-serve-django"] 12 + )
+14
pkgs/development/python-modules/waitress-django/src/waitress-serve-django
··· 1 + #!/usr/bin/env python 2 + import sys 3 + from waitress import serve 4 + from waitress.adjustments import Adjustments 5 + import django 6 + from django.core.handlers.wsgi import WSGIHandler 7 + from django.contrib.staticfiles.handlers import StaticFilesHandler 8 + 9 + if __name__ == "__main__": 10 + kw, args = Adjustments.parse_args(sys.argv[1:]) 11 + django.setup() 12 + # These arguments are specific to the runner, not waitress itself. 13 + del kw['call'], kw['help'] 14 + serve(StaticFilesHandler(WSGIHandler()), **kw)
+30 -15
pkgs/top-level/python-packages.nix
··· 60 60 61 61 buildPythonApplication = args: buildPythonPackage ({namePrefix="";} // args ); 62 62 63 - graphiteVersion = "0.9.15"; 63 + graphiteVersion = "1.0.2"; 64 64 65 65 fetchPypi = makeOverridable( {format ? "setuptools", ... } @attrs: 66 66 let ··· 8286 8286 8287 8287 django_tagging = callPackage ../development/python-modules/django_tagging { }; 8288 8288 8289 - django_tagging_0_3 = self.django_tagging.overrideAttrs (attrs: rec { 8290 - name = "django-tagging-0.3.6"; 8289 + django_tagging_0_4_3 = self.django_tagging.overrideAttrs (attrs: rec { 8290 + name = "django-tagging-0.4.3"; 8291 8291 8292 8292 src = pkgs.fetchurl { 8293 8293 url = "mirror://pypi/d/django-tagging/${name}.tar.gz"; 8294 - sha256 = "03zlbq13rydfh28wh0jk3x3cjk9x6jjmqnx1i3ngjmfwbxf8x6j1"; 8294 + sha256 = "0617azpmp6jpg3d88v2ir97qrc9aqcs2s9gyvv9bgf2cp55khxhs"; 8295 8295 }; 8296 - propagatedBuildInputs = with self; [ django ]; 8296 + propagatedBuildInputs = with self; [ django_1_8 ]; 8297 8297 }); 8298 8298 8299 8299 django_classytags = buildPythonPackage rec { ··· 22250 22250 }; 22251 22251 22252 22252 waitress = buildPythonPackage rec { 22253 - name = "waitress-0.8.9"; 22253 + name = "waitress-1.0.2"; 22254 22254 22255 22255 src = pkgs.fetchurl { 22256 22256 url = "mirror://pypi/w/waitress/${name}.tar.gz"; 22257 - sha256 = "826527dc9d334ed4ed76cdae672fdcbbccf614186657db71679ab58df869458a"; 22257 + sha256 = "0pw6yyxi348r2xpq3ykqnf7gwi881azv2422d2ixb0xi5jws2ky7"; 22258 22258 }; 22259 22259 22260 22260 doCheck = false; ··· 22264 22264 platforms = platforms.all; 22265 22265 }; 22266 22266 }; 22267 + 22268 + waitress-django = callPackage ../development/python-modules/waitress-django { }; 22267 22269 22268 22270 webassets = buildPythonPackage rec { 22269 22271 name = "webassets-${version}"; ··· 23457 23459 23458 23460 src = pkgs.fetchurl { 23459 23461 url = "mirror://pypi/w/whisper/${name}.tar.gz"; 23460 - sha256 = "1chkphxwnwvy2cs7jc2h2i0lqqvi9jx6vqj3ly88lwk7m35r4ss2"; 23462 + sha256 = "1v1bi3fl1i6p4z4ki692bykrkw6907dn3mfq0151f70lvi3zpns3"; 23461 23463 }; 23462 23464 23463 23465 # error: invalid command 'test' ··· 23524 23526 23525 23527 src = pkgs.fetchurl { 23526 23528 url = "mirror://pypi/c/carbon/${name}.tar.gz"; 23527 - sha256 = "f01db6d37726c6fc0a8aaa66a7bf14436b0dd0d62ef3c20ecb31605a4d365d2e"; 23529 + sha256 = "142smpmgbnjinvfb6s4ijazish4vfgzyd8zcmdkh55y051fkixkn"; 23528 23530 }; 23529 23531 23530 23532 propagatedBuildInputs = with self; [ whisper txamqp zope_interface twisted ]; ··· 23739 23741 23740 23742 src = pkgs.fetchurl rec { 23741 23743 url = "mirror://pypi/g/graphite-web/${name}.tar.gz"; 23742 - sha256 = "1c0kclbv8shv9nvjx19wqm4asia58s3qmd9fapchc6y9fjpjax6q"; 23744 + sha256 = "0q8bwlj75jqyzmazfsi5sa26xl58ssa8wdxm2l4j0jqyn8xpfnmc"; 23743 23745 }; 23744 23746 23745 - propagatedBuildInputs = with self; [ django django_tagging_0_3 whisper pycairo ldap memcached pytz ]; 23747 + propagatedBuildInputs = with self; [ 23748 + django_1_8 django_tagging_0_4_3 whisper pycairo cairocffi 23749 + ldap memcached pytz urllib3 scandir 23750 + ]; 23746 23751 23747 23752 postInstall = '' 23748 23753 wrapProgram $out/bin/run-graphite-devel-server.py \ ··· 23750 23755 ''; 23751 23756 23752 23757 preConfigure = '' 23753 - substituteInPlace webapp/graphite/thirdparty/pytz/__init__.py --replace '/usr/share/zoneinfo' '/etc/zoneinfo' 23754 - substituteInPlace webapp/graphite/settings.py --replace "join(WEBAPP_DIR, 'content')" "join('$out', 'webapp', 'content')" 23755 - cp webapp/graphite/manage.py bin/manage-graphite.py 23756 - substituteInPlace bin/manage-graphite.py --replace 'settings' 'graphite.settings' 23758 + # graphite is configured by storing a local_settings.py file inside the 23759 + # graphite python package. Since that package is stored in the immutable 23760 + # Nix store we can't modify it. So how do we configure graphite? 23761 + # 23762 + # First of all we rename "graphite.local_settings" to 23763 + # "graphite_local_settings" so that the settings are not looked up in the 23764 + # graphite package anymore. Secondly we place a directory containing a 23765 + # graphite_local_settings.py on the PYTHONPATH in the graphite module 23766 + # <nixpkgs/nixos/modules/services/monitoring/graphite.nix>. 23767 + substituteInPlace webapp/graphite/settings.py \ 23768 + --replace "graphite.local_settings" " graphite_local_settings" 23769 + 23770 + substituteInPlace webapp/graphite/settings.py \ 23771 + --replace "join(WEBAPP_DIR, 'content')" "join('$out', 'webapp', 'content')" 23757 23772 ''; 23758 23773 23759 23774 # error: invalid command 'test'