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 return $info; 373 } 374 375 376 # Wait for a systemd unit to reach the "active" state. 377 sub waitForUnit {
··· 372 return $info; 373 } 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 + } 386 387 # Wait for a systemd unit to reach the "active" state. 388 sub waitForUnit {
+42 -12
nixos/modules/services/monitoring/graphite.nix
··· 7 writeTextOrNull = f: t: mapNullable (pkgs.writeTextDir f) t; 8 9 dataDir = cfg.dataDir; 10 11 graphiteApiConfig = pkgs.writeText "graphite-api.yaml" '' 12 time_zone: ${config.time.timeZone} ··· 93 description = "Graphite web frontend port."; 94 default = 8080; 95 type = types.int; 96 }; 97 }; 98 ··· 460 ]; 461 }; 462 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}"; 466 DJANGO_SETTINGS_MODULE = "graphite.settings"; 467 GRAPHITE_CONF_DIR = configDir; 468 GRAPHITE_STORAGE_DIR = dataDir; ··· 470 }; 471 serviceConfig = { 472 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''; 476 User = "graphite"; 477 Group = "graphite"; 478 PermissionsStartOnly = true; ··· 482 mkdir -p ${dataDir}/{whisper/,log/webapp/} 483 chmod 0700 ${dataDir}/{whisper/,log/webapp/} 484 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 490 491 - chown -R graphite:graphite ${cfg.dataDir} 492 493 touch ${dataDir}/db-created 494 fi 495 ''; 496 };
··· 7 writeTextOrNull = f: t: mapNullable (pkgs.writeTextDir f) t; 8 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 + ); 23 24 graphiteApiConfig = pkgs.writeText "graphite-api.yaml" '' 25 time_zone: ${config.time.timeZone} ··· 106 description = "Graphite web frontend port."; 107 default = 8080; 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 + ''; 118 }; 119 }; 120 ··· 482 ]; 483 }; 484 penvPack = "${penv}/${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 + ]; 492 DJANGO_SETTINGS_MODULE = "graphite.settings"; 493 GRAPHITE_CONF_DIR = configDir; 494 GRAPHITE_STORAGE_DIR = dataDir; ··· 496 }; 497 serviceConfig = { 498 ExecStart = '' 499 + ${pkgs.python27Packages.waitress-django}/bin/waitress-serve-django \ 500 + --host=${cfg.web.listenAddress} --port=${toString cfg.web.port} 501 + ''; 502 User = "graphite"; 503 Group = "graphite"; 504 PermissionsStartOnly = true; ··· 508 mkdir -p ${dataDir}/{whisper/,log/webapp/} 509 chmod 0700 ${dataDir}/{whisper/,log/webapp/} 510 511 + ${pkgs.pythonPackages.django_1_8}/bin/django-admin.py migrate --noinput 512 513 + chown -R graphite:graphite ${dataDir} 514 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" 524 fi 525 ''; 526 };
+1
nixos/release.nix
··· 257 tests.gnome3 = callTest tests/gnome3.nix {}; 258 tests.gnome3-gdm = callTest tests/gnome3-gdm.nix {}; 259 tests.grafama = callTest tests/grafana.nix {}; 260 tests.hardened = callTest tests/hardened.nix { }; 261 tests.hibernate = callTest tests/hibernate.nix {}; 262 tests.hound = callTest tests/hound.nix {};
··· 257 tests.gnome3 = callTest tests/gnome3.nix {}; 258 tests.gnome3-gdm = callTest tests/gnome3-gdm.nix {}; 259 tests.grafama = callTest tests/grafana.nix {}; 260 + tests.graphite = callTest tests/graphite.nix {}; 261 tests.hardened = callTest tests/hardened.nix { }; 262 tests.hibernate = callTest tests/hibernate.nix {}; 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 61 buildPythonApplication = args: buildPythonPackage ({namePrefix="";} // args ); 62 63 - graphiteVersion = "0.9.15"; 64 65 fetchPypi = makeOverridable( {format ? "setuptools", ... } @attrs: 66 let ··· 8286 8287 django_tagging = callPackage ../development/python-modules/django_tagging { }; 8288 8289 - django_tagging_0_3 = self.django_tagging.overrideAttrs (attrs: rec { 8290 - name = "django-tagging-0.3.6"; 8291 8292 src = pkgs.fetchurl { 8293 url = "mirror://pypi/d/django-tagging/${name}.tar.gz"; 8294 - sha256 = "03zlbq13rydfh28wh0jk3x3cjk9x6jjmqnx1i3ngjmfwbxf8x6j1"; 8295 }; 8296 - propagatedBuildInputs = with self; [ django ]; 8297 }); 8298 8299 django_classytags = buildPythonPackage rec { ··· 22250 }; 22251 22252 waitress = buildPythonPackage rec { 22253 - name = "waitress-0.8.9"; 22254 22255 src = pkgs.fetchurl { 22256 url = "mirror://pypi/w/waitress/${name}.tar.gz"; 22257 - sha256 = "826527dc9d334ed4ed76cdae672fdcbbccf614186657db71679ab58df869458a"; 22258 }; 22259 22260 doCheck = false; ··· 22264 platforms = platforms.all; 22265 }; 22266 }; 22267 22268 webassets = buildPythonPackage rec { 22269 name = "webassets-${version}"; ··· 23457 23458 src = pkgs.fetchurl { 23459 url = "mirror://pypi/w/whisper/${name}.tar.gz"; 23460 - sha256 = "1chkphxwnwvy2cs7jc2h2i0lqqvi9jx6vqj3ly88lwk7m35r4ss2"; 23461 }; 23462 23463 # error: invalid command 'test' ··· 23524 23525 src = pkgs.fetchurl { 23526 url = "mirror://pypi/c/carbon/${name}.tar.gz"; 23527 - sha256 = "f01db6d37726c6fc0a8aaa66a7bf14436b0dd0d62ef3c20ecb31605a4d365d2e"; 23528 }; 23529 23530 propagatedBuildInputs = with self; [ whisper txamqp zope_interface twisted ]; ··· 23739 23740 src = pkgs.fetchurl rec { 23741 url = "mirror://pypi/g/graphite-web/${name}.tar.gz"; 23742 - sha256 = "1c0kclbv8shv9nvjx19wqm4asia58s3qmd9fapchc6y9fjpjax6q"; 23743 }; 23744 23745 - propagatedBuildInputs = with self; [ django django_tagging_0_3 whisper pycairo ldap memcached pytz ]; 23746 23747 postInstall = '' 23748 wrapProgram $out/bin/run-graphite-devel-server.py \ ··· 23750 ''; 23751 23752 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' 23757 ''; 23758 23759 # error: invalid command 'test'
··· 60 61 buildPythonApplication = args: buildPythonPackage ({namePrefix="";} // args ); 62 63 + graphiteVersion = "1.0.2"; 64 65 fetchPypi = makeOverridable( {format ? "setuptools", ... } @attrs: 66 let ··· 8286 8287 django_tagging = callPackage ../development/python-modules/django_tagging { }; 8288 8289 + django_tagging_0_4_3 = self.django_tagging.overrideAttrs (attrs: rec { 8290 + name = "django-tagging-0.4.3"; 8291 8292 src = pkgs.fetchurl { 8293 url = "mirror://pypi/d/django-tagging/${name}.tar.gz"; 8294 + sha256 = "0617azpmp6jpg3d88v2ir97qrc9aqcs2s9gyvv9bgf2cp55khxhs"; 8295 }; 8296 + propagatedBuildInputs = with self; [ django_1_8 ]; 8297 }); 8298 8299 django_classytags = buildPythonPackage rec { ··· 22250 }; 22251 22252 waitress = buildPythonPackage rec { 22253 + name = "waitress-1.0.2"; 22254 22255 src = pkgs.fetchurl { 22256 url = "mirror://pypi/w/waitress/${name}.tar.gz"; 22257 + sha256 = "0pw6yyxi348r2xpq3ykqnf7gwi881azv2422d2ixb0xi5jws2ky7"; 22258 }; 22259 22260 doCheck = false; ··· 22264 platforms = platforms.all; 22265 }; 22266 }; 22267 + 22268 + waitress-django = callPackage ../development/python-modules/waitress-django { }; 22269 22270 webassets = buildPythonPackage rec { 22271 name = "webassets-${version}"; ··· 23459 23460 src = pkgs.fetchurl { 23461 url = "mirror://pypi/w/whisper/${name}.tar.gz"; 23462 + sha256 = "1v1bi3fl1i6p4z4ki692bykrkw6907dn3mfq0151f70lvi3zpns3"; 23463 }; 23464 23465 # error: invalid command 'test' ··· 23526 23527 src = pkgs.fetchurl { 23528 url = "mirror://pypi/c/carbon/${name}.tar.gz"; 23529 + sha256 = "142smpmgbnjinvfb6s4ijazish4vfgzyd8zcmdkh55y051fkixkn"; 23530 }; 23531 23532 propagatedBuildInputs = with self; [ whisper txamqp zope_interface twisted ]; ··· 23741 23742 src = pkgs.fetchurl rec { 23743 url = "mirror://pypi/g/graphite-web/${name}.tar.gz"; 23744 + sha256 = "0q8bwlj75jqyzmazfsi5sa26xl58ssa8wdxm2l4j0jqyn8xpfnmc"; 23745 }; 23746 23747 + propagatedBuildInputs = with self; [ 23748 + django_1_8 django_tagging_0_4_3 whisper pycairo cairocffi 23749 + ldap memcached pytz urllib3 scandir 23750 + ]; 23751 23752 postInstall = '' 23753 wrapProgram $out/bin/run-graphite-devel-server.py \ ··· 23755 ''; 23756 23757 preConfigure = '' 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')" 23772 ''; 23773 23774 # error: invalid command 'test'