From 99b0b74ac87c77b5f39e21c65141d8fcc6753ca2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Isma=C3=ABl=20Bouya?= Date: Wed, 6 Mar 2019 16:43:44 +0100 Subject: [PATCH] Add taskwarrior-web Fixes https://git.immae.eu/mantisbt/view.php?id=67 --- nixops/modules/task/Gemfile.lock | 139 ++++++ nixops/modules/task/default.nix | 224 +++++++-- nixops/modules/task/fixes.patch | 56 +++ nixops/modules/task/gemset.nix | 567 +++++++++++++++++++++++ nixops/modules/task/taskwarrior-web.json | 15 + nixops/modules/task/taskwarrior-web.nix | 24 + nixops/modules/task/thin.patch | 23 + 7 files changed, 1005 insertions(+), 43 deletions(-) create mode 100644 nixops/modules/task/Gemfile.lock create mode 100644 nixops/modules/task/fixes.patch create mode 100644 nixops/modules/task/gemset.nix create mode 100644 nixops/modules/task/taskwarrior-web.json create mode 100644 nixops/modules/task/taskwarrior-web.nix create mode 100644 nixops/modules/task/thin.patch diff --git a/nixops/modules/task/Gemfile.lock b/nixops/modules/task/Gemfile.lock new file mode 100644 index 0000000..1b2f5ba --- /dev/null +++ b/nixops/modules/task/Gemfile.lock @@ -0,0 +1,139 @@ +PATH + remote: . + specs: + taskwarrior-web (1.1.12) + activesupport (~> 3) + json (~> 1.8) + parseconfig + rack-flash3 + rinku + sinatra + sinatra-simple-navigation + vegas + versionomy + +GEM + remote: http://rubygems.org/ + specs: + activesupport (3.2.22.5) + i18n (~> 0.6, >= 0.6.4) + multi_json (~> 1.0) + blockenspiel (0.5.0) + coderay (1.1.2) + concurrent-ruby (1.1.4) + daemons (1.3.1) + diff-lcs (1.3) + docile (1.3.1) + eventmachine (1.2.7) + ffi (1.10.0) + formatador (0.2.5) + growl (1.0.3) + guard (2.15.0) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (>= 1.0.12, < 2.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.9.12) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-bundler (2.2.1) + bundler (>= 1.3.0, < 3) + guard (~> 2.2) + guard-compat (~> 1.1) + guard-compat (1.2.1) + guard-rspec (4.7.3) + guard (~> 2.1) + guard-compat (~> 1.1) + rspec (>= 2.99.0, < 4.0) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + json (1.8.6) + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) + lumberjack (1.0.13) + method_source (0.9.2) + mini_portile2 (2.4.0) + multi_json (1.13.1) + mustermann (1.0.3) + nenv (0.3.0) + nokogiri (1.10.1) + mini_portile2 (~> 2.4.0) + notiffany (0.1.1) + nenv (~> 0.1) + shellany (~> 0.0) + parseconfig (1.0.8) + pry (0.12.2) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + rack (2.0.6) + rack-flash3 (1.0.5) + rack + rack-protection (2.0.5) + rack + rack-test (1.1.0) + rack (>= 1.0, < 3) + rake (10.5.0) + rb-fsevent (0.10.3) + rb-inotify (0.10.0) + ffi (~> 1.0) + rinku (2.0.5) + rspec (2.99.0) + rspec-core (~> 2.99.0) + rspec-expectations (~> 2.99.0) + rspec-mocks (~> 2.99.0) + rspec-core (2.99.2) + rspec-expectations (2.99.2) + diff-lcs (>= 1.1.3, < 2.0) + rspec-html-matchers (0.5.0) + nokogiri (~> 1) + rspec (~> 2, >= 2.11.0) + rspec-mocks (2.99.4) + ruby_dep (1.5.0) + shellany (0.0.1) + simple-navigation (4.0.5) + activesupport (>= 2.3.2) + simplecov (0.16.1) + docile (~> 1.1) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.2) + sinatra (2.0.5) + mustermann (~> 1.0) + rack (~> 2.0) + rack-protection (= 2.0.5) + tilt (~> 2.0) + sinatra-simple-navigation (4.1.0) + simple-navigation (~> 4.0) + sinatra (>= 1.0, < 3.0) + thin (1.7.2) + daemons (~> 1.0, >= 1.0.9) + eventmachine (~> 1.0, >= 1.0.4) + rack (>= 1, < 3) + thor (0.20.3) + tilt (2.0.9) + vegas (0.1.11) + rack (>= 1.0.0) + versionomy (0.5.0) + blockenspiel (~> 0.5) + +PLATFORMS + ruby + +DEPENDENCIES + growl + guard-bundler + guard-rspec + rack-test + rake (< 11) + rb-fsevent + rspec (~> 2) + rspec-html-matchers + simplecov + taskwarrior-web! + thin + +BUNDLED WITH + 1.16.2 diff --git a/nixops/modules/task/default.nix b/nixops/modules/task/default.nix index 3dc3299..2fd61aa 100644 --- a/nixops/modules/task/default.nix +++ b/nixops/modules/task/default.nix @@ -6,6 +6,81 @@ let user = config.services.taskserver.user; env = myconfig.env.tools.task; group = config.services.taskserver.group; + taskserver-user-certs = pkgs.runCommand "taskserver-user-certs" {} '' + mkdir -p $out/bin + cat > $out/bin/taskserver-user-certs <<"EOF" + #!/usr/bin/env bash + + user=$1 + + silent_certtool() { + if ! output="$("${pkgs.gnutls.bin}/bin/certtool" "$@" 2>&1)"; then + echo "GNUTLS certtool invocation failed with output:" >&2 + echo "$output" >&2 + fi + } + + silent_certtool -p \ + --bits 4096 \ + --outfile "${vardir}/userkeys/$user.key.pem" + ${pkgs.gnused}/bin/sed -i -n -e '/^-----BEGIN RSA PRIVATE KEY-----$/,$p' "${vardir}/userkeys/$user.key.pem" + + silent_certtool -c \ + --template "${pkgs.writeText "taskserver-ca.template" '' + tls_www_client + encryption_key + signing_key + expiration_days = 3650 + ''}" \ + --load-ca-certificate "${vardir}/keys/ca.cert" \ + --load-ca-privkey "${vardir}/keys/ca.key" \ + --load-privkey "${vardir}/userkeys/$user.key.pem" \ + --outfile "${vardir}/userkeys/$user.cert.pem" + EOF + chmod a+x $out/bin/taskserver-user-certs + patchShebangs $out/bin/taskserver-user-certs + ''; + taskwarrior-web = pkgs.callPackage ./taskwarrior-web.nix { + inherit (mylibs) fetchedGithub; + inherit env; + }; + taskwebPages = let + uidPages = lib.attrsets.zipAttrs ( + lib.lists.flatten + (lib.attrsets.mapAttrsToList (k: c: map (v: { "${v}" = k; }) c.uid) env.taskwarrior-web) + ); + pages = lib.attrsets.mapAttrs (uid: items: + if lib.lists.length items == 1 then + '' + + + + + + + '' + else + '' + + + To-do list disponibles + + + + + + + + '' + ) uidPages; + in + pkgs.runCommand "taskwerver-pages" {} '' + mkdir -p $out/ + ${builtins.concatStringsSep "\n" (lib.attrsets.mapAttrsToList (k: v: "cp ${pkgs.writeText k v} $out/${k}.html") pages)} + echo "Please login" > $out/index.html + ''; in { options.services.myTasks = { enable = lib.mkEnableOption "my tasks service"; @@ -13,7 +88,7 @@ in { config = lib.mkIf cfg.enable { security.acme.certs."eldiron".extraDomains.${fqdn} = null; - services.myWebsites.tools.modules = [ "proxy_fcgi" ]; + services.myWebsites.tools.modules = [ "proxy_fcgi" "sed" ]; services.myWebsites.tools.vhostConfs.task = { certName = "eldiron"; hosts = [ "task.immae.eu" ]; @@ -34,7 +109,48 @@ in { SetEnv TASKD_LDAP_BASE "${env.ldap.base}" SetEnv TASKD_LDAP_FILTER "${env.ldap.search}" - '' ]; + '' + '' + + ProxyPass "unix://${taskwarrior-web.socketsDir}/%{folderName}.sock|http://localhost-%{folderName}/" + ProxyPassReverse "unix://${taskwarrior-web.socketsDir}/%{folderName}.sock|http://localhost-%{folderName}/" + ProxyPassReverse http://${fqdn}/ + + SetOutputFilter Sed + OutputSed "s|/ajax|/taskweb/%{folderName}/ajax|g" + OutputSed "s|\([^x]\)/tasks|\1/taskweb/%{folderName}/tasks|g" + OutputSed "s|\([^x]\)/projects|\1/taskweb/%{folderName}/projects|g" + OutputSed "s|http://${fqdn}/|/taskweb/%{folderName}/|g" + OutputSed "s|/img/relax.jpg|/taskweb/%{folderName}/img/relax.jpg|g" + + '' + '' + Alias /taskweb ${taskwebPages} + + DirectoryIndex index.html + Require all granted + + + RewriteEngine on + RewriteRule ^/taskweb$ /taskweb/ [R=301,L] + RedirectMatch permanent ^/taskweb/([^/]+)$ /taskweb/$1/ + + RewriteCond %{LA-U:REMOTE_USER} !="" + RewriteCond ${taskwebPages}/%{LA-U:REMOTE_USER}.html -f + RewriteRule ^/taskweb/?$ ${taskwebPages}/%{LA-U:REMOTE_USER}.html [L] + + + Use LDAPConnect + Require ldap-group cn=users,cn=taskwarrior,ou=services,dc=immae,dc=eu + + '' + ] ++ (lib.attrsets.mapAttrsToList (k: v: '' + + ${builtins.concatStringsSep "\n" (map (uid: "Require ldap-attribute uid=${uid}") v.uid)} + + Use Taskwarrior ${k} + + '') env.taskwarrior-web); }; services.myPhpfpm.poolConfigs = { tasks = '' @@ -69,47 +185,7 @@ in { ''; }; - users.users.${user}.packages = [ - (pkgs.runCommand "taskserver-user-certs" {} '' - mkdir -p $out/bin - cat > $out/bin/taskserver-user-certs <<"EOF" - #!/usr/bin/env bash - - user=$1 - - silent_certtool() { - if ! output="$("${pkgs.gnutls.bin}/bin/certtool" "$@" 2>&1)"; then - echo "GNUTLS certtool invocation failed with output:" >&2 - echo "$output" >&2 - fi - } - - silent_certtool -p \ - --bits 4096 \ - --outfile "${vardir}/userkeys/$user.key.pem" - ${pkgs.gnused}/bin/sed -i -n -e '/^-----BEGIN RSA PRIVATE KEY-----$/,$p' "${vardir}/userkeys/$user.key.pem" - - silent_certtool -c \ - --template "${pkgs.writeText "taskserver-ca.template" '' - tls_www_client - encryption_key - signing_key - expiration_days = 3650 - ''}" \ - --load-ca-certificate "${vardir}/keys/ca.cert" \ - --load-ca-privkey "${vardir}/keys/ca.key" \ - --load-privkey "${vardir}/userkeys/$user.key.pem" \ - --outfile "${vardir}/userkeys/$user.cert.pem" - EOF - chmod a+x $out/bin/taskserver-user-certs - patchShebangs $out/bin/taskserver-user-certs - '') - ]; - - systemd.services.taskserver-ca.postStart = '' - chown :${group} "${vardir}/keys/ca.key" - chmod g+r "${vardir}/keys/ca.key" - ''; + users.users.${user}.packages = [ taskserver-user-certs ]; system.activationScripts.taskserver = { deps = [ "users" ]; @@ -127,5 +203,67 @@ in { listenHost = "::"; requestLimit = 104857600; }; + + system.activationScripts.taskwarrior-web = { + deps = [ "users" ]; + text = '' + install -m 0755 -o ${user} -g ${group} -d ${taskwarrior-web.socketsDir} + install -m 0750 -o ${user} -g ${group} -d ${taskwarrior-web.varDir} + ${builtins.concatStringsSep "\n" (lib.attrsets.mapAttrsToList + (k: v: "install -m 0750 -o ${user} -g ${group} -d ${taskwarrior-web.varDir}/${k}") + env.taskwarrior-web + )} + if [ ! -f ${vardir}/userkeys/taskwarrior-web.cert.pem ]; then + ${taskserver-user-certs}/bin/taskserver-user-certs taskwarrior-web + chown taskd:taskd ${vardir}/userkeys/taskwarrior-web.cert.pem ${vardir}/userkeys/taskwarrior-web.key.pem + fi + ''; + }; + + systemd.services = (lib.attrsets.mapAttrs' (name: userConfig: + let + credentials = "${userConfig.org}/${name}/${userConfig.key}"; + dateFormat = userConfig.date; + taskrc = pkgs.writeText "taskrc" '' + data.location=${taskwarrior-web.varDir}/${name} + taskd.certificate=${vardir}/userkeys/taskwarrior-web.cert.pem + taskd.key=${vardir}/userkeys/taskwarrior-web.key.pem + taskd.ca=${vardir}/keys/server.cert + taskd.server=${fqdn}:${toString config.services.taskserver.listenPort} + taskd.credentials=${credentials} + dateformat=${dateFormat} + ''; + in lib.attrsets.nameValuePair "taskwarrior-web-${name}" { + description = "Taskwarrior webapp for ${name}"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + path = [ pkgs.taskwarrior ]; + + environment.TASKRC = taskrc; + environment.BUNDLE_PATH = "${taskwarrior-web.gems}/lib/ruby/gems/2.5.0"; + environment.BUNDLE_GEMFILE = "${taskwarrior-web.gems.confFiles}/Gemfile"; + environment.LC_ALL = "fr_FR.UTF-8"; + + script = '' + exec ${taskwarrior-web.gems}/lib/ruby/gems/2.5.0/bin/bundle exec thin start -R config.ru -S ${taskwarrior-web.socketsDir}/${name}.sock + ''; + + serviceConfig = { + User = user; + PrivateTmp = true; + Restart = "always"; + TimeoutSec = 60; + Type = "simple"; + WorkingDirectory = taskwarrior-web.rubyRoot; + }; + + unitConfig.RequiresMountsFor = taskwarrior-web.varDir; + }) env.taskwarrior-web) // { + taskserver-ca.postStart = '' + chown :${group} "${vardir}/keys/ca.key" + chmod g+r "${vardir}/keys/ca.key" + ''; + }; + }; } diff --git a/nixops/modules/task/fixes.patch b/nixops/modules/task/fixes.patch new file mode 100644 index 0000000..851f9f0 --- /dev/null +++ b/nixops/modules/task/fixes.patch @@ -0,0 +1,56 @@ +diff --git a/lib/taskwarrior-web/helpers.rb b/lib/taskwarrior-web/helpers.rb +index 212aed7..94c57df 100644 +--- a/lib/taskwarrior-web/helpers.rb ++++ b/lib/taskwarrior-web/helpers.rb +@@ -1,6 +1,8 @@ + require 'active_support/core_ext/date/calculations' + + module TaskwarriorWeb::App::Helpers ++ include ERB::Util ++ + def format_date(timestamp) + format = TaskwarriorWeb::Config.dateformat || '%-m/%-d/%Y' + Time.parse(timestamp).localtime.strftime(format) +diff --git a/lib/taskwarrior-web/services/builder/base.rb b/lib/taskwarrior-web/services/builder/base.rb +index 58d246e..8f716ac 100644 +--- a/lib/taskwarrior-web/services/builder/base.rb ++++ b/lib/taskwarrior-web/services/builder/base.rb +@@ -10,7 +10,7 @@ module TaskwarriorWeb::CommandBuilder::Base + :complete => ':id done', + :annotate => ':id annotate', + :denotate => ':id denotate', +- :projects => '_projects', ++ :projects => '_unique project', + :tags => '_tags', + :sync => 'sync' + } +diff --git a/lib/taskwarrior-web/views/tasks/_form.erb b/lib/taskwarrior-web/views/tasks/_form.erb +index 789e7a1..fa08698 100644 +--- a/lib/taskwarrior-web/views/tasks/_form.erb ++++ b/lib/taskwarrior-web/views/tasks/_form.erb +@@ -1,14 +1,14 @@ +
+ +
+- ++ +
+
+ +
+ +
+- ++ +
+
+ +@@ -45,7 +45,7 @@ +
+ +
+- ++ + Enter tags separated by commas or spaces (e.g. each, word will,be a tag) +
+
diff --git a/nixops/modules/task/gemset.nix b/nixops/modules/task/gemset.nix new file mode 100644 index 0000000..35d13c6 --- /dev/null +++ b/nixops/modules/task/gemset.nix @@ -0,0 +1,567 @@ +{ + activesupport = { + dependencies = ["i18n" "multi_json"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0fyxqkkws4px4lzkbcqzp0bwai7nn7jk4p0bgfy0dny9cwm0qc9r"; + type = "gem"; + }; + version = "3.2.22.5"; + }; + blockenspiel = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1h701s45n5qprvcpc7fnr45n88p56x07pznkxqnhz1dbdbhb7xx8"; + type = "gem"; + }; + version = "0.5.0"; + }; + coderay = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "15vav4bhcc2x3jmi3izb11l4d9f3xv8hp2fszb7iqmpsccv1pz4y"; + type = "gem"; + }; + version = "1.1.2"; + }; + concurrent-ruby = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1ixcx9pfissxrga53jbdpza85qd5f6b5nq1sfqa9rnfq82qnlbp1"; + type = "gem"; + }; + version = "1.1.4"; + }; + daemons = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0l5gai3vd4g7aqff0k1mp41j9zcsvm2rbwmqn115a325k9r7pf4w"; + type = "gem"; + }; + version = "1.3.1"; + }; + diff-lcs = { + groups = ["default" "development" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "18w22bjz424gzafv6nzv98h0aqkwz3d9xhm7cbr1wfbyas8zayza"; + type = "gem"; + }; + version = "1.3"; + }; + docile = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "04d2izkna3ahfn6fwq4xrcafa715d3bbqczxm16fq40fqy87xn17"; + type = "gem"; + }; + version = "1.3.1"; + }; + eventmachine = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0wh9aqb0skz80fhfn66lbpr4f86ya2z5rx6gm5xlfhd05bj1ch4r"; + type = "gem"; + }; + version = "1.2.7"; + }; + ffi = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0j8pzj8raxbir5w5k6s7a042sb5k02pg0f8s4na1r5lan901j00p"; + type = "gem"; + }; + version = "1.10.0"; + }; + formatador = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1gc26phrwlmlqrmz4bagq1wd5b7g64avpx0ghxr9xdxcvmlii0l0"; + type = "gem"; + }; + version = "0.2.5"; + }; + growl = { + groups = ["local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0s0y7maljnalpbv2q1j5j5hvb4wcc31y9af0n7x1q2l0fzxgc9n9"; + type = "gem"; + }; + version = "1.0.3"; + }; + guard = { + dependencies = ["formatador" "listen" "lumberjack" "nenv" "notiffany" "pry" "shellany" "thor"]; + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0h84ja6qvii3hx86w9l4vjpbgl4m8ma8fbawwp7s8l791cgkdcmk"; + type = "gem"; + }; + version = "2.15.0"; + }; + guard-bundler = { + dependencies = ["guard" "guard-compat"]; + groups = ["local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0lji8f8w7y4prmpr2lqmlljvkqgkgnlsiwqgwvq7b1y3sxlsvy62"; + type = "gem"; + }; + version = "2.2.1"; + }; + guard-compat = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1zj6sr1k8w59mmi27rsii0v8xyy2rnsi09nqvwpgj1q10yq1mlis"; + type = "gem"; + }; + version = "1.2.1"; + }; + guard-rspec = { + dependencies = ["guard" "guard-compat" "rspec"]; + groups = ["local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1jkm5xp90gm4c5s51pmf92i9hc10gslwwic6mvk72g0yplya0yx4"; + type = "gem"; + }; + version = "4.7.3"; + }; + i18n = { + dependencies = ["concurrent-ruby"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "038qvz7kd3cfxk8bvagqhakx68pfbnmghpdkx7573wbf0maqp9a3"; + type = "gem"; + }; + version = "0.9.5"; + }; + json = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0qmj7fypgb9vag723w1a49qihxrcf5shzars106ynw2zk352gbv5"; + type = "gem"; + }; + version = "1.8.6"; + }; + listen = { + dependencies = ["rb-fsevent" "rb-inotify" "ruby_dep"]; + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "01v5mrnfqm6sgm8xn2v5swxsn1wlmq7rzh2i48d4jzjsc7qvb6mx"; + type = "gem"; + }; + version = "3.1.5"; + }; + lumberjack = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "06im7gcg42x77yhz2w5da2ly9xz0n0c36y5ks7xs53v0l9g0vf5n"; + type = "gem"; + }; + version = "1.0.13"; + }; + method_source = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1pviwzvdqd90gn6y7illcdd9adapw8fczml933p5vl739dkvl3lq"; + type = "gem"; + }; + version = "0.9.2"; + }; + mini_portile2 = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "15zplpfw3knqifj9bpf604rb3wc1vhq6363pd6lvhayng8wql5vy"; + type = "gem"; + }; + version = "2.4.0"; + }; + multi_json = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1rl0qy4inf1mp8mybfk56dfga0mvx97zwpmq5xmiwl5r770171nv"; + type = "gem"; + }; + version = "1.13.1"; + }; + mustermann = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0lycgkmnyy0bf29nnd2zql5a6pcf8sp69g9v4xw0gcfcxgpwp7i1"; + type = "gem"; + }; + version = "1.0.3"; + }; + nenv = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0r97jzknll9bhd8yyg2bngnnkj8rjhal667n7d32h8h7ny7nvpnr"; + type = "gem"; + }; + version = "0.3.0"; + }; + nokogiri = { + dependencies = ["mini_portile2"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "09zll7c6j7xr6wyvh5mm5ncj6pkryp70ybcsxdbw1nyphx5dh184"; + type = "gem"; + }; + version = "1.10.1"; + }; + notiffany = { + dependencies = ["nenv" "shellany"]; + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0x838fa5il0dd9zbm3lxkpbfxcf5fxv9556mayc2mxsdl5ghv8nx"; + type = "gem"; + }; + version = "0.1.1"; + }; + parseconfig = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0br2g9k6zc4ygah52aa8cwvpnnkszia29bnvnr8bhpk3rdzi2vmq"; + type = "gem"; + }; + version = "1.0.8"; + }; + pry = { + dependencies = ["coderay" "method_source"]; + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "00rm71x0r1jdycwbs83lf9l6p494m99asakbvqxh8rz7zwnlzg69"; + type = "gem"; + }; + version = "0.12.2"; + }; + rack = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1pcgv8dv4vkaczzlix8q3j68capwhk420cddzijwqgi2qb4lm1zm"; + type = "gem"; + }; + version = "2.0.6"; + }; + rack-flash3 = { + dependencies = ["rack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0rim9afrns6s8zc4apiymncysyvijpdg18k57kdpz66p55jf4mqz"; + type = "gem"; + }; + version = "1.0.5"; + }; + rack-protection = { + dependencies = ["rack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "15167q25rmxipqwi6hjqj3i1byi9iwl3xq9b7mdar7qiz39pmjsk"; + type = "gem"; + }; + version = "2.0.5"; + }; + rack-test = { + dependencies = ["rack"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0rh8h376mx71ci5yklnpqqn118z3bl67nnv5k801qaqn1zs62h8m"; + type = "gem"; + }; + version = "1.1.0"; + }; + rake = { + groups = ["development"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0jcabbgnjc788chx31sihc5pgbqnlc1c75wakmqlbjdm8jns2m9b"; + type = "gem"; + }; + version = "10.5.0"; + }; + rb-fsevent = { + groups = ["local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1lm1k7wpz69jx7jrc92w3ggczkjyjbfziq5mg62vjnxmzs383xx8"; + type = "gem"; + }; + version = "0.10.3"; + }; + rb-inotify = { + dependencies = ["ffi"]; + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1fs7hxm9g6ywv2yih83b879klhc4fs8i0p9166z795qmd77dk0a4"; + type = "gem"; + }; + version = "0.10.0"; + }; + rinku = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1smkk299v18brk98gqbdnqrfwm3143kikl30scidqb5j3pzlbz91"; + type = "gem"; + }; + version = "2.0.5"; + }; + rspec = { + dependencies = ["rspec-core" "rspec-expectations" "rspec-mocks"]; + groups = ["development" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "14q3hxvngk4ks8h41yw50d5fqbf2dhzwi9rz5ccxvh5a53ak2as3"; + type = "gem"; + }; + version = "2.99.0"; + }; + rspec-core = { + groups = ["default" "development" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1wwz21lcz2lwd2jcp2pvq7n1677v23acf7wxsyszp8msb47mw38i"; + type = "gem"; + }; + version = "2.99.2"; + }; + rspec-expectations = { + dependencies = ["diff-lcs"]; + groups = ["default" "development" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "11a5pph3anp4xr591dnlcy8xfkdf54qi2lvg4ykpqhxk37si1py3"; + type = "gem"; + }; + version = "2.99.2"; + }; + rspec-html-matchers = { + dependencies = ["nokogiri" "rspec"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "148grzvk0cvh24avhl0shjzz7ldhj138svf48pc5h1fdsb0pnqcv"; + type = "gem"; + }; + version = "0.5.0"; + }; + rspec-mocks = { + groups = ["default" "development" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0bzhqahbiswq41nqi6y2dka1k42n0hl14jb6bldb206zp4hikz8r"; + type = "gem"; + }; + version = "2.99.4"; + }; + ruby_dep = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1c1bkl97i9mkcvkn1jks346ksnvnnp84cs22gwl0vd7radybrgy5"; + type = "gem"; + }; + version = "1.5.0"; + }; + shellany = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1ryyzrj1kxmnpdzhlv4ys3dnl2r5r3d2rs2jwzbnd1v96a8pl4hf"; + type = "gem"; + }; + version = "0.0.1"; + }; + simple-navigation = { + dependencies = ["activesupport"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "08a2s18an3br3xj5j86r33q0hrkai0y157xg67h1khdskb08yylk"; + type = "gem"; + }; + version = "4.0.5"; + }; + simplecov = { + dependencies = ["docile" "json" "simplecov-html"]; + groups = ["local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1sfyfgf7zrp2n42v7rswkqgk3bbwk1bnsphm24y7laxv3f8z0947"; + type = "gem"; + }; + version = "0.16.1"; + }; + simplecov-html = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1lihraa4rgxk8wbfl77fy9sf0ypk31iivly8vl3w04srd7i0clzn"; + type = "gem"; + }; + version = "0.10.2"; + }; + sinatra = { + dependencies = ["mustermann" "rack" "rack-protection" "tilt"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1gasgn5f15myv08k10i16p326pchxjsy37pgqfw0xm66kcc5d7ry"; + type = "gem"; + }; + version = "2.0.5"; + }; + sinatra-simple-navigation = { + dependencies = ["simple-navigation" "sinatra"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1gishxd23qw6bwsk7fkagkfc7ihqyvvvb98j9bmwc6wwpsfs4prs"; + type = "gem"; + }; + version = "4.1.0"; + }; + taskwarrior-web = { + dependencies = ["activesupport" "json" "parseconfig" "rack-flash3" "rinku" "sinatra" "sinatra-simple-navigation" "vegas" "versionomy"]; + groups = ["default"]; + platforms = []; + bundledByPath = true; + path = ./.; + source = { + path = ./.; + type = "path"; + }; + version = "1.1.12"; + }; + thin = { + dependencies = ["daemons" "eventmachine" "rack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0nagbf9pwy1vg09k6j4xqhbjjzrg5dwzvkn4ffvlj76fsn6vv61f"; + type = "gem"; + }; + version = "1.7.2"; + }; + thor = { + groups = ["default" "local"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "1yhrnp9x8qcy5vc7g438amd5j9sw83ih7c30dr6g6slgw9zj3g29"; + type = "gem"; + }; + version = "0.20.3"; + }; + tilt = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0ca4k0clwf0rkvy7726x4nxpjxkpv67w043i39saxgldxd97zmwz"; + type = "gem"; + }; + version = "2.0.9"; + }; + vegas = { + dependencies = ["rack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0kzv0v1zb8vvm188q4pqwahb6468bmiamn6wpsbiq6r5i69s1bs5"; + type = "gem"; + }; + version = "0.1.11"; + }; + versionomy = { + dependencies = ["blockenspiel"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["http://rubygems.org"]; + sha256 = "0i0l4pzrl1vyp4lpg2cxhgkk56spki3lld943d6h7168fj8qyv33"; + type = "gem"; + }; + version = "0.5.0"; + }; +} diff --git a/nixops/modules/task/taskwarrior-web.json b/nixops/modules/task/taskwarrior-web.json new file mode 100644 index 0000000..70f396d --- /dev/null +++ b/nixops/modules/task/taskwarrior-web.json @@ -0,0 +1,15 @@ +{ + "tag": "a79cfe2-master", + "meta": { + "name": "taskwarrior-web", + "url": "https://github.com/theunraveler/taskwarrior-web", + "branch": "master" + }, + "github": { + "owner": "theunraveler", + "repo": "taskwarrior-web", + "rev": "a79cfe2b42791b62364118e58b21b892fff6ded8", + "sha256": "028rb4wry2an19707bvy4n305f3s0hipg214224p1m0mb61c3cq4", + "fetchSubmodules": true + } +} diff --git a/nixops/modules/task/taskwarrior-web.nix b/nixops/modules/task/taskwarrior-web.nix new file mode 100644 index 0000000..49d6946 --- /dev/null +++ b/nixops/modules/task/taskwarrior-web.nix @@ -0,0 +1,24 @@ +{ env, ruby_2_5, bundlerEnv, defaultGemConfig, fetchedGithub, stdenv, writeText, pkgs }: +let + varDir = "/var/lib/taskwarrior-web"; + socketsDir = "/run/taskwarrior-web"; + rubyRoot = stdenv.mkDerivation (fetchedGithub ./taskwarrior-web.json // rec { + phases = [ "unpackPhase" "patchPhase" "installPhase" ]; + patches = [ ./fixes.patch ./thin.patch ]; + installPhase = '' + cp -a . $out + cp ${./Gemfile.lock} $out/Gemfile.lock + ''; + }); + gems = bundlerEnv { + name = "taskwarrior-web-env"; + ruby = ruby_2_5; + pname = "taskwarrior-web"; + gemset = ./gemset.nix; + gemdir = rubyRoot.out; + groups = [ "default" "local" "development" ]; + }; +in + { + inherit gems varDir socketsDir rubyRoot; + } diff --git a/nixops/modules/task/thin.patch b/nixops/modules/task/thin.patch new file mode 100644 index 0000000..a7df3e3 --- /dev/null +++ b/nixops/modules/task/thin.patch @@ -0,0 +1,23 @@ +diff --git a/Gemfile b/Gemfile +index 8544e15..9c4279c 100644 +--- a/Gemfile ++++ b/Gemfile +@@ -3,6 +3,8 @@ source "http://rubygems.org" + # Specify your gem's dependencies in taskwarrior-web.gemspec + gemspec + ++gem 'thin' ++ + group :local do + gem 'rb-fsevent', :require => false + gem 'growl', :require => false +diff --git a/config.ru b/config.ru +index c3050c6..52387d8 100644 +--- a/config.ru ++++ b/config.ru +@@ -1,5 +1,4 @@ + require File.join(File.dirname(__FILE__), 'lib', 'taskwarrior-web') + +-disable :run + TaskwarriorWeb::App.set({ :environment => :production }) + run TaskwarriorWeb::App -- 2.41.0