From 0127bbefcd549c518e59ebdd78b42cf78241f0ba Mon Sep 17 00:00:00 2001 From: stuebinm Date: Mon, 22 Feb 2021 15:20:07 +0100 Subject: [PATCH 1/5] Add wink (Wo ist meine Winkekatze?) for hacc-voc This adds an instance of wink for the hacc-voc to hainich. Unfortunately, neither the actual package nor the container itself look very nixy, and e.g. cannot be configured declaratively. On the other hand, it does not appear the wink *has* any kind of config, so I guess there's that. Wink itself runs in a nixos container, but I've exposed its database to /var/lib/wink-db on the host, just to make it easier to access. After deployment, we still need to migrate our current database to this instance by hand (i.e. take the current database, rename it "development.sqlite3", and move it into the wink-db directory). Any improvements to this mess are welcome. --- hosts/hainich/configuration.nix | 1 + hosts/hainich/services/wink.nix | 52 ++ pkgs/default.nix | 3 + pkgs/wink/default.nix | 96 +++ pkgs/wink/gemset.nix | 994 ++++++++++++++++++++++++++++++++ 5 files changed, 1146 insertions(+) create mode 100644 hosts/hainich/services/wink.nix create mode 100644 pkgs/wink/default.nix create mode 100644 pkgs/wink/gemset.nix diff --git a/hosts/hainich/configuration.nix b/hosts/hainich/configuration.nix index 5cc94e0..1195b7f 100644 --- a/hosts/hainich/configuration.nix +++ b/hosts/hainich/configuration.nix @@ -16,6 +16,7 @@ ./services/gitlab-runner.nix ./services/lantifa.nix ./services/hasenloch.nix + ./services/wink.nix ./services/syncthing.nix ./services/monitoring.nix ./services/workadventure.nix diff --git a/hosts/hainich/services/wink.nix b/hosts/hainich/services/wink.nix new file mode 100644 index 0000000..5ef3bdb --- /dev/null +++ b/hosts/hainich/services/wink.nix @@ -0,0 +1,52 @@ +# for documentation on how this container works, have a look at +# https://wiki.infra4future.de/books/voc-infra/page/wink-65b + +{ pkgs, config, ...}: + +{ + containers.wink = { + autoStart = true; + privateNetwork = true; + hostAddress = "192.168.100.10"; + localAddress = "192.168.100.11"; + + # expose the wink database for easier backups / migrations + bindMounts."/var/lib/wink/db" = { + hostPath = "/var/lib/wink-db"; + isReadOnly = false; + }; + + config = {pkgs, config, ...}: { + networking.firewall.allowedTCPPorts = [ 3000 ]; + environment.systemPackages = [ pkgs.wink pkgs.v8 ]; + + systemd.services.wink = { + enable = true; + description = "Wo ist meine Winkekatze?"; + wantedBy = [ "multi-user.target" ]; + serviceConfig.type = "simple"; + environment.HOME = "/var/lib/wink/home"; + path = [ pkgs.wink pkgs.v8 ]; + script = '' + mkdir -p /var/lib/wink/home + cd /var/lib/wink + cp -r ${pkgs.wink.outPath}/* . + if [ ! -f database.exists ] + then + rails-wrapped db:migrate db:seed RAILS_ENV=development + touch database.exists + fi + rails-wrapped server -b [::] -p 3000 + ''; + }; + }; + }; + + + services.nginx.virtualHosts."wink.hacc.space" = { + locations."/".proxyPass = "http://${config.containers.wink.localAddress}:3000"; + forceSSL = true; + enableACME = true; + }; + +} diff --git a/pkgs/default.nix b/pkgs/default.nix index 193f443..94100c2 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -34,7 +34,10 @@ let ''; }); + wink = callPackage ./wink {}; + inherit (unstable) bottom; + }; in pkgs.extend(_: _: newpkgs) diff --git a/pkgs/wink/default.nix b/pkgs/wink/default.nix new file mode 100644 index 0000000..3561042 --- /dev/null +++ b/pkgs/wink/default.nix @@ -0,0 +1,96 @@ + +# high-level notes: +# - wink uses the execjs gem, which needs some javascript runtime +# to be available. Wink usually uses the mini_racer gem for this, +# which unfortunately refuses to work on nix, so instead we have +# to patch it out of wink's dependencies and replace it with +# something else +# - execjs actually just takes any compatible js runtime it can find; +# this packages uses v8 by default, but you can easily override it +# with e.g. nodejs and wink should still work. + +{ stdenv +, bundlerEnv +, fetchFromGitHub +, zlib +, sqlite +, ruby +, makeWrapper +# v8 may be replaced with e.g. nodejs — see docs for execjs for a list +# of accaptable backends, all of which should all work out of the box +, v8 +, ... }: + +let + sources-patched = stdenv.mkDerivation { + name = "wink-sources-patched"; + + # wink sources from the c3VOC + src = fetchFromGitHub { + owner = "voc"; + repo = "wink"; + rev = "9f1d312b7bf6457fc23aaa9348a43c3900046a6c"; + sha256 = "1xyb4n4ys93mzyj779mdd6ngiials38xfql3ivddxc1l5rk11hbi"; + }; + + phases = [ "patchPhase" "installPhase" ]; + + # remove mini_racer and libv8 (its sole dependency) from wink's deps + patchPhase = '' + cp -r $src/* . + sed -i "s/gem 'mini_racer', platforms: :ruby/#removed mini_racer/g" Gemfile + sed -i "s/mini_racer (0.2.0)/ /g" Gemfile.lock + sed -i "s/libv8 (>= 6.3)/ /g" Gemfile.lock + ''; + + installPhase = '' + mkdir -p $out + cp -r * $out/ + ''; + }; + + # use the patched dependencies to generate derivations for all the + # ruby dependencies (using a `gemset.nix` generated with bundix) + gems = bundlerEnv { + name = "wink-gems"; + inherit ruby; + gemConfig = { + nokogiri = attrs: { + buildInputs = [ zlib ]; + }; + sqlite3 = attr: { + buildInputs = [ sqlite ]; + }; + }; + gemfile = sources-patched.outPath + "/Gemfile"; + lockfile = sources-patched.outPath + "/Gemfile.lock"; + + # Open question: we could generate this dynamically, would that be + # a good idea? + gemset = ./gemset.nix; + }; +in + stdenv.mkDerivation { + name = "wink-without-wrapping"; + + src = sources-patched.outPath; + + buildInputs = [ + gems + ruby + makeWrapper + v8 + ]; + + # need to wrap the executables so ruby can find its gems + installPhase = + let gempath = "${gems.outPath}/lib/ruby/gems/2.6.0"; + in '' + mkdir -p $out + cp -r * $out + + makeWrapper $out/bin/rails $out/bin/rails-wrapped --set GEM_PATH ${gempath} + makeWrapper $out/bin/rake $out/bin/rake-wrapped --set GEM_PATH ${gempath} + ''; + + } diff --git a/pkgs/wink/gemset.nix b/pkgs/wink/gemset.nix new file mode 100644 index 0000000..f9aea01 --- /dev/null +++ b/pkgs/wink/gemset.nix @@ -0,0 +1,994 @@ +{ + actioncable = { + dependencies = ["actionpack" "nio4r" "websocket-driver"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "17vdxn0afi5rfnbs09nl0m0cyj7yvpi445bmi8pkmzbaqzqkq3ff"; + type = "gem"; + }; + version = "5.2.1"; + }; + actionmailer = { + dependencies = ["actionpack" "actionview" "activejob" "mail" "rails-dom-testing"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0h1nqg47jap0wzp0dhlnck4xjijfvdfw49aipjp8y2ihdpvyqrx6"; + type = "gem"; + }; + version = "5.2.1"; + }; + actionpack = { + dependencies = ["actionview" "activesupport" "rack" "rack-test" "rails-dom-testing" "rails-html-sanitizer"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "19zv9ix9iwpd8dxi5hyxgwrc1gh0fvx0a2vjhmic8dn8six41f4f"; + type = "gem"; + }; + version = "5.2.1"; + }; + actionview = { + dependencies = ["activesupport" "builder" "erubi" "rails-dom-testing" "rails-html-sanitizer"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0dxanjs7ngpny4ig7dg93ywmg9ljswzg8risdlff6ag8fzvsnidf"; + type = "gem"; + }; + version = "5.2.1"; + }; + active_link_to = { + dependencies = ["actionpack" "addressable"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1firn5hw8dkqlz1c2plprrzja5f0xs606qpwx7qrsn0l7mxq8c28"; + type = "gem"; + }; + version = "1.0.5"; + }; + activejob = { + dependencies = ["activesupport" "globalid"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1m4l7z08cx1lybfswfggy7y1rxnwr6gi15h0g9kkkkvmmn6klf3r"; + type = "gem"; + }; + version = "5.2.1"; + }; + activemodel = { + dependencies = ["activesupport"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "043nnxaf3cfq8jijls0jh1bg3a8v5zd9slc62zc2acp2n2wkjnd4"; + type = "gem"; + }; + version = "5.2.1"; + }; + activerecord = { + dependencies = ["activemodel" "activesupport" "arel"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0pc7cycvhzjpw0swil2inka6c0fvcxhln793czp52pidg0654g7g"; + type = "gem"; + }; + version = "5.2.1"; + }; + activestorage = { + dependencies = ["actionpack" "activerecord" "marcel"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0wncr3h94jsjmmqqmmips9vgy2kf1zhb96rlv5fbrgqplfhvpyag"; + type = "gem"; + }; + version = "5.2.1"; + }; + activesupport = { + dependencies = ["concurrent-ruby" "i18n" "minitest" "tzinfo"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0ziy6xk31k4fs115cdkba1ys4i8nzcyri7a2jig7nx7k5h7li6l2"; + type = "gem"; + }; + version = "5.2.1"; + }; + addressable = { + dependencies = ["public_suffix"]; + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0viqszpkggqi8hq87pqp0xykhvz60g99nwmkwsb0v45kc2liwxvk"; + type = "gem"; + }; + version = "2.5.2"; + }; + archive-zip = { + dependencies = ["io-like"]; + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1h9fc1ry1cgpzi6rn1r46znawvwgpn38m1ya6v8d7g7id35d41q6"; + type = "gem"; + }; + version = "0.11.0"; + }; + arel = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1jk7wlmkr61f6g36w9s2sn46nmdg6wn2jfssrhbhirv5x9n95nk0"; + type = "gem"; + }; + version = "9.0.0"; + }; + bindex = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1wvhf4v8sk5x8li03pcc0v0wglmyv7ikvvg05bnms83dfy7s4k8i"; + type = "gem"; + }; + version = "0.5.0"; + }; + bootsnap = { + dependencies = ["msgpack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1i3llrdqkndxzhv1a7a2yjpavmdabyq5ps296vmb32hv8fy95xk9"; + type = "gem"; + }; + version = "1.3.1"; + }; + builder = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0qibi5s67lpdv1wgcj66wcymcr04q6j4mzws6a479n0mlrmh5wr1"; + type = "gem"; + }; + version = "3.2.3"; + }; + byebug = { + groups = ["development" "test"]; + platforms = [{ + engine = "maglev"; + } { + engine = "mingw"; + } { + engine = "mingw"; + } { + engine = "ruby"; + }]; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "10znc1hjv8n686hhpl08f3m2g6h08a4b83nxblqwy2kqamkxcqf8"; + type = "gem"; + }; + version = "10.0.2"; + }; + capybara = { + dependencies = ["addressable" "mini_mime" "nokogiri" "rack" "rack-test" "xpath"]; + groups = ["test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1pn7jijww60kpcgf9g6yk430hqi867mwkxz89lzj694xrn87gzbc"; + type = "gem"; + }; + version = "3.6.0"; + }; + childprocess = { + dependencies = ["ffi"]; + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0a61922kmvcxyj5l70fycapr87gz1dzzlkfpq85rfqk5vdh3d28p"; + type = "gem"; + }; + version = "0.9.0"; + }; + chromedriver-helper = { + dependencies = ["archive-zip" "nokogiri"]; + groups = ["test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0x1inglq11k0ab1n33xzvqcxybcsgn6psj6si2gnls6yh0zx14h3"; + type = "gem"; + }; + version = "1.2.0"; + }; + coffee-rails = { + dependencies = ["coffee-script" "railties"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0jp81gjcid66ialk5n242y27p3payy0cz6c6i80ik02nx54mq2h8"; + type = "gem"; + }; + version = "4.2.2"; + }; + coffee-script = { + dependencies = ["coffee-script-source" "execjs"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0rc7scyk7mnpfxqv5yy4y5q1hx3i7q3ahplcp4bq2g5r24g2izl2"; + type = "gem"; + }; + version = "2.4.1"; + }; + coffee-script-source = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1907v9q1zcqmmyqzhzych5l7qifgls2rlbnbhy5vzyr7i7yicaz1"; + type = "gem"; + }; + version = "1.12.2"; + }; + concurrent-ruby = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "183lszf5gx84kcpb779v6a2y0mx9sssy8dgppng1z9a505nj1qcf"; + type = "gem"; + }; + version = "1.0.5"; + }; + crass = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0bpxzy6gjw9ggjynlxschbfsgmx8lv3zw1azkjvnb8b9i895dqfi"; + type = "gem"; + }; + version = "1.0.4"; + }; + diff-lcs = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "18w22bjz424gzafv6nzv98h0aqkwz3d9xhm7cbr1wfbyas8zayza"; + type = "gem"; + }; + version = "1.3"; + }; + docile = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "04d2izkna3ahfn6fwq4xrcafa715d3bbqczxm16fq40fqy87xn17"; + type = "gem"; + }; + version = "1.3.1"; + }; + erubi = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0bws86na9k565raiz0kk61yy5pxxp0fmwyzpibdwjkq0xzx8q6q1"; + type = "gem"; + }; + version = "1.7.1"; + }; + execjs = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1yz55sf2nd3l666ms6xr18sm2aggcvmb8qr3v53lr4rir32y1yp1"; + type = "gem"; + }; + version = "2.7.0"; + }; + ffi = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0jpm2dis1j7zvvy3lg7axz9jml316zrn7s0j59vyq3qr127z0m7q"; + type = "gem"; + }; + version = "1.9.25"; + }; + globalid = { + dependencies = ["activesupport"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "02smrgdi11kziqi9zhnsy9i6yr2fnxrqlv3lllsvdjki3cd4is38"; + type = "gem"; + }; + version = "0.4.1"; + }; + haml = { + dependencies = ["temple" "tilt"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1q0a9fvqh8kn6wm97fcks6qzbjd400bv8bx748w8v87m7p4klhac"; + type = "gem"; + }; + version = "5.0.4"; + }; + i18n = { + dependencies = ["concurrent-ruby"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0ppvmla21hssvrfm8g1n2fnb4lxn4yhy9qmmba0imanflgldrjmr"; + type = "gem"; + }; + version = "1.1.0"; + }; + io-like = { + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "04nn0s2wmgxij3k760h3r8m1dgih5dmd9h4v1nn085yi824i5z6k"; + type = "gem"; + }; + version = "0.3.0"; + }; + jbuilder = { + dependencies = ["activesupport" "multi_json"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1n3myqk2hdnidzzbgcdz2r1y4cr5vpz5nkfzs0lz4y9gkjbjyh2j"; + type = "gem"; + }; + version = "2.7.0"; + }; + jquery-rails = { + dependencies = ["rails-dom-testing" "railties" "thor"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "02ii77vwxc49f2lrkbdzww2168bp5nihwzakc9mqyrsbw394w7ki"; + type = "gem"; + }; + version = "4.3.1"; + }; + jquery-ui-rails = { + dependencies = ["railties"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1mbwwbbwzp836l7mc21amnaqmf5wbrw5hzls48hscrcgh0vig812"; + type = "gem"; + }; + version = "6.0.1"; + }; + json = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "01v6jjpvh3gnq6sgllpfqahlgxzj50ailwhj9b3cd20hi2dx0vxp"; + type = "gem"; + }; + version = "2.1.0"; + }; + listen = { + dependencies = ["rb-fsevent" "rb-inotify" "ruby_dep"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "01v5mrnfqm6sgm8xn2v5swxsn1wlmq7rzh2i48d4jzjsc7qvb6mx"; + type = "gem"; + }; + version = "3.1.5"; + }; + loofah = { + dependencies = ["crass" "nokogiri"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0yjs6wbcj3n06d3xjqpy3qbpx0bfa12h3x2rbpc2k33ldjlkx6zy"; + type = "gem"; + }; + version = "2.2.2"; + }; + mail = { + dependencies = ["mini_mime"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "10dyifazss9mgdzdv08p47p344wmphp5pkh5i73s7c04ra8y6ahz"; + type = "gem"; + }; + version = "2.7.0"; + }; + marcel = { + dependencies = ["mimemagic"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0v1kncmyh0yn9h28zri6hkfdqzr8bf26ar9bvglhgzy0chqr9dp8"; + type = "gem"; + }; + version = "0.3.2"; + }; + method_source = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0xqj21j3vfq4ldia6i2akhn2qd84m0iqcnsl49kfpq3xk6x0dzgn"; + type = "gem"; + }; + version = "0.9.0"; + }; + mimemagic = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "00ibc1mhvdfyfyl103xwb45621nwyqxf124cni5hyfhag0fn1c3q"; + type = "gem"; + }; + version = "0.3.2"; + }; + mini_mime = { + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1q4pshq387lzv9m39jv32vwb8wrq3wc4jwgl4jk209r4l33v09d3"; + type = "gem"; + }; + version = "1.0.1"; + }; + mini_portile2 = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "13d32jjadpjj6d2wdhkfpsmy68zjx90p49bgf8f7nkpz86r1fr11"; + type = "gem"; + }; + version = "2.3.0"; + }; + minitest = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0icglrhghgwdlnzzp4jf76b0mbc71s80njn5afyfjn4wqji8mqbq"; + type = "gem"; + }; + version = "5.11.3"; + }; + mqtt = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0d1khsry5mf63y03r6v91f4vrbn88277ksv7d69z3xmqs9sgpri9"; + type = "gem"; + }; + version = "0.5.0"; + }; + msgpack = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "09xy1wc4wfbd1jdrzgxwmqjzfdfxbz0cqdszq2gv6rmc3gv1c864"; + type = "gem"; + }; + version = "1.2.4"; + }; + multi_json = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1rl0qy4inf1mp8mybfk56dfga0mvx97zwpmq5xmiwl5r770171nv"; + type = "gem"; + }; + version = "1.13.1"; + }; + nio4r = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1a41ca1kpdmrypjp9xbgvckpy8g26zxphkja9vk7j5wl4n8yvlyr"; + type = "gem"; + }; + version = "2.3.1"; + }; + nokogiri = { + dependencies = ["mini_portile2"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1h9nml9h3m0mpvmh8jfnqvblnz5n5y3mmhgfc38avfmfzdrq9bgc"; + type = "gem"; + }; + version = "1.8.4"; + }; + public_suffix = { + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1x5h1dh1i3gwc01jbg01rly2g6a1qwhynb1s8a30ic507z1nh09s"; + type = "gem"; + }; + version = "3.0.2"; + }; + puma = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1k7dqxnq0dnf5rxkgs9rknclkn3ah7lsdrk6nrqxla8qzy31wliq"; + type = "gem"; + }; + version = "3.12.0"; + }; + rack = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "158hbn7rlc3czp2vivvam44dv6vmzz16qrh5dbzhfxbfsgiyrqw1"; + type = "gem"; + }; + version = "2.0.5"; + }; + rack-test = { + dependencies = ["rack"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0rh8h376mx71ci5yklnpqqn118z3bl67nnv5k801qaqn1zs62h8m"; + type = "gem"; + }; + version = "1.1.0"; + }; + rails = { + dependencies = ["actioncable" "actionmailer" "actionpack" "actionview" "activejob" "activemodel" "activerecord" "activestorage" "activesupport" "railties" "sprockets-rails"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1307cv1p6cj350hq2mi00dfgjb77rzvlhrr3h0bjz5s0a6jgwv3p"; + type = "gem"; + }; + version = "5.2.1"; + }; + rails-dom-testing = { + dependencies = ["activesupport" "nokogiri"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1lfq2a7kp2x64dzzi5p4cjcbiv62vxh9lyqk2f0rqq3fkzrw8h5i"; + type = "gem"; + }; + version = "2.0.3"; + }; + rails-html-sanitizer = { + dependencies = ["loofah"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1gv7vr5d9g2xmgpjfq4nxsqr70r9pr042r9ycqqnfvw5cz9c7jwr"; + type = "gem"; + }; + version = "1.0.4"; + }; + railties = { + dependencies = ["actionpack" "activesupport" "method_source" "rake" "thor"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "19y343dvb7vih82q2ssyhp1cirmp5sp1vpw4k5zmd1bxxkjix9qv"; + type = "gem"; + }; + version = "5.2.1"; + }; + rake = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1idi53jay34ba9j68c3mfr9wwkg3cd9qh0fn9cg42hv72c6q8dyg"; + type = "gem"; + }; + version = "12.3.1"; + }; + rb-fsevent = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1lm1k7wpz69jx7jrc92w3ggczkjyjbfziq5mg62vjnxmzs383xx8"; + type = "gem"; + }; + version = "0.10.3"; + }; + rb-inotify = { + dependencies = ["ffi"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0yfsgw5n7pkpyky6a9wkf1g9jafxb0ja7gz0qw0y14fd2jnzfh71"; + type = "gem"; + }; + version = "0.9.10"; + }; + rspec-core = { + dependencies = ["rspec-support"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1p1s5bnbqp3sxk67y0fh0x884jjym527r0vgmhbm81w7aq6b7l4p"; + type = "gem"; + }; + version = "3.8.0"; + }; + rspec-expectations = { + dependencies = ["diff-lcs" "rspec-support"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0vfqqcjmhdq25jrc8rd7nx4n8xid7s1ynv65ph06bk2xafn3rgll"; + type = "gem"; + }; + version = "3.8.1"; + }; + rspec-mocks = { + dependencies = ["diff-lcs" "rspec-support"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "06y508cjqycb4yfhxmb3nxn0v9xqf17qbd46l1dh4xhncinr4fyp"; + type = "gem"; + }; + version = "3.8.0"; + }; + rspec-rails = { + dependencies = ["actionpack" "activesupport" "railties" "rspec-core" "rspec-expectations" "rspec-mocks" "rspec-support"]; + groups = ["development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0bm1md49c6skjvqmi6p7jd036ikn8sgiy9lj2pvjmm8ibslpflg7"; + type = "gem"; + }; + version = "3.8.0"; + }; + rspec-support = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0p3m7drixrlhvj2zpc38b11x145bvm311x6f33jjcxmvcm0wq609"; + type = "gem"; + }; + version = "3.8.0"; + }; + ruby_dep = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1c1bkl97i9mkcvkn1jks346ksnvnnp84cs22gwl0vd7radybrgy5"; + type = "gem"; + }; + version = "1.5.0"; + }; + rubyzip = { + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "06js4gznzgh8ac2ldvmjcmg9v1vg9llm357yckkpylaj6z456zqz"; + type = "gem"; + }; + version = "1.2.1"; + }; + sass = { + dependencies = ["sass-listen"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1sy7xsbgpcy90j5ynbq967yplffp74pvph3r8ivn2sv2b44q6i61"; + type = "gem"; + }; + version = "3.5.7"; + }; + sass-listen = { + dependencies = ["rb-fsevent" "rb-inotify"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0xw3q46cmahkgyldid5hwyiwacp590zj2vmswlll68ryvmvcp7df"; + type = "gem"; + }; + version = "4.0.0"; + }; + sass-rails = { + dependencies = ["railties" "sass" "sprockets" "sprockets-rails" "tilt"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1wa63sbsimrsf7nfm8h0m1wbsllkfxvd7naph5d1j6pbc555ma7s"; + type = "gem"; + }; + version = "5.0.7"; + }; + selenium-webdriver = { + dependencies = ["childprocess" "rubyzip"]; + groups = ["test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0mv8c667sfdd01dcc1z1yh4fgmrr3fj57sgiv44r85kbhqr5j1aa"; + type = "gem"; + }; + version = "3.14.0"; + }; + simplecov = { + dependencies = ["docile" "json" "simplecov-html"]; + groups = ["development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1sfyfgf7zrp2n42v7rswkqgk3bbwk1bnsphm24y7laxv3f8z0947"; + type = "gem"; + }; + version = "0.16.1"; + }; + simplecov-html = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1lihraa4rgxk8wbfl77fy9sf0ypk31iivly8vl3w04srd7i0clzn"; + type = "gem"; + }; + version = "0.10.2"; + }; + spring = { + dependencies = ["activesupport"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "168yz9c1fv21wc5i8q7n43b9nk33ivg3ws1fn6x0afgryz3ssx75"; + type = "gem"; + }; + version = "2.0.2"; + }; + spring-watcher-listen = { + dependencies = ["listen" "spring"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1ybz9nsngfz4psvgnbr3gdk5ibqqhq47lsjkwh5yq4f8brpr10yz"; + type = "gem"; + }; + version = "2.0.1"; + }; + sprockets = { + dependencies = ["concurrent-ruby" "rack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "182jw5a0fbqah5w9jancvfmjbk88h8bxdbwnl4d3q809rpxdg8ay"; + type = "gem"; + }; + version = "3.7.2"; + }; + sprockets-rails = { + dependencies = ["actionpack" "activesupport" "sprockets"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0ab42pm8p5zxpv3sfraq45b9lj39cz9mrpdirm30vywzrwwkm5p1"; + type = "gem"; + }; + version = "3.2.1"; + }; + sqlite3 = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "01ifzp8nwzqppda419c9wcvr8n82ysmisrs0hph9pdmv1lpa4f5i"; + type = "gem"; + }; + version = "1.3.13"; + }; + temple = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "00nxf610nzi4n1i2lkby43nrnarvl89fcl6lg19406msr0k3ycmq"; + type = "gem"; + }; + version = "0.8.0"; + }; + thor = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0nmqpyj642sk4g16nkbq6pj856adpv91lp4krwhqkh2iw63aszdl"; + type = "gem"; + }; + version = "0.20.0"; + }; + thread_safe = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0nmhcgq6cgz44srylra07bmaw99f5271l0dpsvl5f75m44l0gmwy"; + type = "gem"; + }; + version = "0.3.6"; + }; + tilt = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0020mrgdf11q23hm1ddd6fv691l51vi10af00f137ilcdb2ycfra"; + type = "gem"; + }; + version = "2.0.8"; + }; + turbolinks = { + dependencies = ["turbolinks-source"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "16zy97lw64hf1gwh5kakx86dngyc5zvwpn0wzh6m9np48bsq8drj"; + type = "gem"; + }; + version = "5.1.1"; + }; + turbolinks-source = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "17jqbf7h3s40js4zjlpjw1knpydi27hinhjfsxhlrjcrz5a15gkw"; + type = "gem"; + }; + version = "5.1.0"; + }; + tzinfo = { + dependencies = ["thread_safe"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1fjx9j327xpkkdlxwmkl3a8wqj7i4l4jwlrv3z13mg95z9wl253z"; + type = "gem"; + }; + version = "1.2.5"; + }; + uglifier = { + dependencies = ["execjs"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "14r283lkhisq2sdccv8ngf10f2f18ly4nc3chz3kliw5nylbgznw"; + type = "gem"; + }; + version = "4.1.18"; + }; + web-console = { + dependencies = ["actionview" "activemodel" "bindex" "railties"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0brz15hzn3yi9x2ccc8asin0xv5cvsf98x8xbgk0vsinmfcka6ri"; + type = "gem"; + }; + version = "3.6.2"; + }; + websocket-driver = { + dependencies = ["websocket-extensions"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1551k3fs3kkb3ghqfj3n5lps0ikb9pyrdnzmvgfdxy8574n4g1dn"; + type = "gem"; + }; + version = "0.7.0"; + }; + websocket-extensions = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "034sdr7fd34yag5l6y156rkbhiqgmy395m231dwhlpcswhs6d270"; + type = "gem"; + }; + version = "0.1.3"; + }; + xpath = { + dependencies = ["nokogiri"]; + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1y61ijvv04bwga802s8py5xd7fcxci6478wgr9wkd35p45x20jzi"; + type = "gem"; + }; + version = "3.1.0"; + }; +} From e4c5f5a6bababe466a09f20a13e0ea05c10bb951 Mon Sep 17 00:00:00 2001 From: stuebinm Date: Sat, 13 Mar 2021 14:54:12 +0100 Subject: [PATCH 2/5] wink: init oauth2-proxy configuration. Since there was a desire for some kind of authentication in front of wink, here is a barebones config using oauth2-proxy. It is as yet untested, since I didn't want to deploy things right now / fiddle with the keycloak settings. See the comments in the documentation for what must still be done to make this work. I acknowledge that I said I wouldn't do this, but no one else seems to care. --- hosts/hainich/services/wink.nix | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/hosts/hainich/services/wink.nix b/hosts/hainich/services/wink.nix index 5ef3bdb..f279632 100644 --- a/hosts/hainich/services/wink.nix +++ b/hosts/hainich/services/wink.nix @@ -48,5 +48,30 @@ forceSSL = true; enableACME = true; }; - + + services.oauth2_proxy = + let keycloakurl = "https://auth.infra4future.de/auth/realms/forfuture/protocol/openid-connect"; + in { + enable = true; + nginx.virtualHosts = [ "wink.hacc.space" ]; + + # for the keycloak side of the configuration, see the documentation at + # https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider#keycloak-auth-provider + provider = "keycloak"; + clientID = ""; # TODO + loginURL = "${keycloakurl}/auth"; + redeemURL = "${keycloakurl}/token"; + profileURL = "${keycloakurl}/userinfo"; + validateURL = "${keycloakurl}/userinfo"; + + # must contain OAUTH2_PROXY_COOKIE_SECRET and OAUTH2_PROXY_CLIENT_SECRET + keyFile = "/var/lib/oauth2_proxy/secrets"; + + extraConfig = { + # log format (default would also log ip addresses / users) + auth_logging_format = "[{{.Timestamp}}] [{{.Status}}] {{.Message}}"; + allowed_group = "hacc"; + }; + }; + } From d707ba5ef3187ff742ec28cff2635518992713f5 Mon Sep 17 00:00:00 2001 From: stuebinm Date: Fri, 19 Mar 2021 15:24:03 +0100 Subject: [PATCH 3/5] wink: oauth2_proxy half-working MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For the record: this is the last state before nftables broke yesterday. As far as I know, all that is missing from this to make the authentication for wink actually work is internet access for the container (as was also the case for hasenloch); the snippets for coredns and NAT copied from that container led to the aforementioned firewall problem — or at least they are the only thing I changed between deployments. Apart from that: this moves the proxy into the container, mostly to make keeping track of its state (esp. the secrets file) easier should we ever decide to move this somewhere else / delete the container, since that will just delete any additional state of the proxy with it. --- hosts/hainich/services/wink.nix | 71 +++++++++++++++++---------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/hosts/hainich/services/wink.nix b/hosts/hainich/services/wink.nix index f279632..689be72 100644 --- a/hosts/hainich/services/wink.nix +++ b/hosts/hainich/services/wink.nix @@ -9,15 +9,10 @@ privateNetwork = true; hostAddress = "192.168.100.10"; localAddress = "192.168.100.11"; - - # expose the wink database for easier backups / migrations - bindMounts."/var/lib/wink/db" = { - hostPath = "/var/lib/wink-db"; - isReadOnly = false; - }; + config = {pkgs, config, ...}: { - networking.firewall.allowedTCPPorts = [ 3000 ]; + networking.firewall.allowedTCPPorts = [ 8000 ]; environment.systemPackages = [ pkgs.wink pkgs.v8 ]; systemd.services.wink = { @@ -39,39 +34,47 @@ rails-wrapped server -b [::] -p 3000 ''; }; + + services.oauth2_proxy = + let keycloakurl = "https://auth.infra4future.de/auth/realms/forfuture/protocol/openid-connect"; + in { + enable = true; + #nginx.virtualHosts = [ "matrix.hacc.space" ]; + upstream = "http://localhost:3000"; + httpAddress = "http//0.0.0.0:8000"; + + email.domains = [ "*" ]; + + # for the keycloak side of the configuration, see the documentation at + # https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider#keycloak-auth-provider + provider = "keycloak"; + clientID = "winktest"; # TODO + loginURL = "${keycloakurl}/auth"; + redeemURL = "${keycloakurl}/token"; + profileURL = "${keycloakurl}/userinfo"; + validateURL = "${keycloakurl}/userinfo"; + + # must contain OAUTH2_PROXY_COOKIE_SECRET and OAUTH2_PROXY_CLIENT_SECRET + keyFile = "/var/lib/oauth2_proxy/secrets"; + + extraConfig = { + # log format (default would also log ip addresses / users) + auth-logging-format = "[{{.Timestamp}}] [{{.Status}}] {{.Message}}"; + #allowed_group = "hacc"; + }; + }; + + }; }; - - - services.nginx.virtualHosts."wink.hacc.space" = { - locations."/".proxyPass = "http://${config.containers.wink.localAddress}:3000"; + + + services.nginx.virtualHosts."matrix.hacc.space" = { + locations."/".proxyPass = "http://${config.containers.wink.localAddress}:8000"; forceSSL = true; enableACME = true; }; - services.oauth2_proxy = - let keycloakurl = "https://auth.infra4future.de/auth/realms/forfuture/protocol/openid-connect"; - in { - enable = true; - nginx.virtualHosts = [ "wink.hacc.space" ]; - # for the keycloak side of the configuration, see the documentation at - # https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider#keycloak-auth-provider - provider = "keycloak"; - clientID = ""; # TODO - loginURL = "${keycloakurl}/auth"; - redeemURL = "${keycloakurl}/token"; - profileURL = "${keycloakurl}/userinfo"; - validateURL = "${keycloakurl}/userinfo"; - - # must contain OAUTH2_PROXY_COOKIE_SECRET and OAUTH2_PROXY_CLIENT_SECRET - keyFile = "/var/lib/oauth2_proxy/secrets"; - - extraConfig = { - # log format (default would also log ip addresses / users) - auth_logging_format = "[{{.Timestamp}}] [{{.Status}}] {{.Message}}"; - allowed_group = "hacc"; - }; - }; } From 432acb31e9a163d1e772821816340cbb0c28727c Mon Sep 17 00:00:00 2001 From: stuebinm Date: Sun, 21 Mar 2021 02:45:31 +0100 Subject: [PATCH 4/5] wink: add nat and coredns to container This should let it talk to the outside network (i.e. the internet), and thereby enable the oauth2-proxy to redeem codes to authenticate clients. --- hosts/hainich/services/wink.nix | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/hosts/hainich/services/wink.nix b/hosts/hainich/services/wink.nix index 689be72..b211f3e 100644 --- a/hosts/hainich/services/wink.nix +++ b/hosts/hainich/services/wink.nix @@ -64,7 +64,14 @@ }; }; - + services.coredns = { + enable = true; + config = '' + .:53 { + forward . 1.1.1.1 + } + ''; + }; }; }; @@ -75,6 +82,9 @@ enableACME = true; }; + networking.nat.enable = true; + networking.nat.internalInterfaces = ["ve-wink"]; + networking.nat.externalInterface = "enp6s0"; } From 1ddf9c4ba8833a6dd3f35d6a1cb73591fb73e389 Mon Sep 17 00:00:00 2001 From: stuebinm Date: Mon, 22 Mar 2021 23:46:24 +0100 Subject: [PATCH 5/5] wink: add cookie domain in oauth2-proxy In theory, this should work without that option (by getting the correct domain from the nginx reverse proxy via IP header), but apparently it doesn't. Also, I moved wink to wink2.hacc.space --- hosts/hainich/services/wink.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hosts/hainich/services/wink.nix b/hosts/hainich/services/wink.nix index b211f3e..9d7e3b1 100644 --- a/hosts/hainich/services/wink.nix +++ b/hosts/hainich/services/wink.nix @@ -44,6 +44,7 @@ httpAddress = "http//0.0.0.0:8000"; email.domains = [ "*" ]; + cookie.domain = "wink2.hacc.space"; # for the keycloak side of the configuration, see the documentation at # https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider#keycloak-auth-provider @@ -76,7 +77,7 @@ }; - services.nginx.virtualHosts."matrix.hacc.space" = { + services.nginx.virtualHosts."wink2.hacc.space" = { locations."/".proxyPass = "http://${config.containers.wink.localAddress}:8000"; forceSSL = true; enableACME = true;