Merge "WORKSPACE: use nix for python/go if available"
diff --git a/bgpwtf/speedtest/BUILD.bazel b/bgpwtf/speedtest/BUILD.bazel
index cc431d0..7b5af44 100644
--- a/bgpwtf/speedtest/BUILD.bazel
+++ b/bgpwtf/speedtest/BUILD.bazel
@@ -1,4 +1,4 @@
-load("@io_bazel_rules_docker//container:container.bzl", "container_image")
+load("@io_bazel_rules_docker//container:container.bzl", "container_image", "container_push")
 load("@io_bazel_rules_go//go:def.bzl", "go_library")
 load("@io_bazel_rules_go//extras:embed_data.bzl", "go_embed_data")
 
@@ -24,19 +24,11 @@
     entrypoint = ["/hscloud/backend"],
 )
 
-genrule(
-    name = "push_latest",
-    srcs = [":latest"],
-    outs = ["version.sh"],
-    executable = True,
-    cmd = """
-        local=bazel/bgpwtf/speedtest:latest
-        tag=$$(date +%s)
-        remote=registry.k0.hswaw.net/bgpwtf/speedtest:$$tag
-
-        docker tag $$local $$remote
-        docker push $$remote
-        echo -ne "#!/bin/sh\necho Pushed $$remote\n" > $(OUTS)
-    """,
+container_push(
+    name = "push",
+    image = ":latest",
+    format = "Docker",
+    registry = "registry.k0.hswaw.net",
+    repository = "q3k/speedetst",
+    tag = "{BUILD_TIMESTAMP}-{STABLE_GIT_COMMIT}",
 )
-
diff --git a/bgpwtf/speedtest/backend/main.go b/bgpwtf/speedtest/backend/main.go
index 7d4aece..3473352 100644
--- a/bgpwtf/speedtest/backend/main.go
+++ b/bgpwtf/speedtest/backend/main.go
@@ -134,9 +134,11 @@
 		w.Write(static.Data["bgpwtf/speedtest/index.html"])
 	})
 	http.HandleFunc("/speedtest.js", func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Add("Content-Type", "text/javascript")
 		w.Write(static.Data["bgpwtf/speedtest/speedtest.js"])
 	})
 	http.HandleFunc("/speedtest_worker.js", func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Add("Content-Type", "text/javascript")
 		w.Write(static.Data["bgpwtf/speedtest/speedtest_worker.js"])
 	})
 
diff --git a/bgpwtf/speedtest/kube/prod.jsonnet b/bgpwtf/speedtest/kube/prod.jsonnet
index fc6e083..9187f54 100644
--- a/bgpwtf/speedtest/kube/prod.jsonnet
+++ b/bgpwtf/speedtest/kube/prod.jsonnet
@@ -1,4 +1,4 @@
-local kube = import '../../../../kube/kube.libsonnet';
+local kube = import '../../../kube/kube.libsonnet';
 
 {
     local speedtest = self,
@@ -8,8 +8,7 @@
         appName: "speedtest",
         domain: "speedtest.hackerspace.pl",
 
-        tag: "1563032542",
-        image: "registry.k0.hswaw.net/bgpwtf/speedtest:" + cfg.tag,
+        image: "registry.k0.hswaw.net/q3k/speedetst:1601997887-f9d9c752ad8403c2b284bfeab23111b25f7e2214",
 
         resources: {
             requests: {
diff --git a/cluster/certs/etcd-dcr01s22.hswaw.net.cert b/cluster/certs/etcd-dcr01s22.hswaw.net.cert
index 69930ec..5380b73 100644
--- a/cluster/certs/etcd-dcr01s22.hswaw.net.cert
+++ b/cluster/certs/etcd-dcr01s22.hswaw.net.cert
@@ -1,9 +1,9 @@
 -----BEGIN CERTIFICATE-----
-MIIFHjCCBAagAwIBAgIUHMTWqXaNMC+JIbfJV/cXWiAQJiwwDQYJKoZIhvcNAQEL
+MIIFHjCCBAagAwIBAgIUU8/CIgYDnyPPidO4Tssmy1TjPqgwDQYJKoZIhvcNAQEL
 BQAweDELMAkGA1UEBhMCUEwxFDASBgNVBAgTC01hem93aWVja2llMQ8wDQYDVQQH
 EwZXYXJzYXcxGzAZBgNVBAoTEldhcnNhdyBIYWNrZXJzcGFjZTETMBEGA1UECxMK
-Y2x1c3RlcmNmZzEQMA4GA1UEAxMHZXRjZCBjYTAeFw0xOTEwMzAyMzAxMDBaFw0y
-MDEwMjkyMzAxMDBaMHgxCzAJBgNVBAYTAlBMMRQwEgYDVQQIEwtNYXpvd2llY2tp
+Y2x1c3RlcmNmZzEQMA4GA1UEAxMHZXRjZCBjYTAeFw0yMDEwMDMxNTMzMDBaFw0y
+MTEwMDMxNTMzMDBaMHgxCzAJBgNVBAYTAlBMMRQwEgYDVQQIEwtNYXpvd2llY2tp
 ZTEPMA0GA1UEBxMGV2Fyc2F3MSUwIwYDVQQLExxub2RlIGV0Y2Qgc2VydmVyIGNl
 cnRpZmljYXRlMRswGQYDVQQDExJkY3IwMXMyMi5oc3dhdy5uZXQwggIiMA0GCSqG
 SIb3DQEBAQUAA4ICDwAwggIKAoICAQDib61eHI9KxUqLPqI/KeUVB1VmNsuu+lxR
@@ -21,10 +21,10 @@
 BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUH4gHxXmo
 ZnxR/Tf2BJMylqE9YYAwHwYDVR0jBBgwFoAU8Vm4Zk0+w+dC7oGj1EZ/OVN1+Q8w
 HQYDVR0RBBYwFIISZGNyMDFzMjIuaHN3YXcubmV0MA0GCSqGSIb3DQEBCwUAA4IB
-AQCEm9hL/m9BTXnxILqq++2JjDzh+ZLjorgNQ/TdHEGhx9bm1SxaR/bT5uOLANEp
-I+pUTPC6W700F6FizD5IhHreOUwKICc9e341W7GrVPbBsi583PPcDVIYL/0EtEus
-Rs50oDaPiBeOf9Tix9YxcjtVtGHBKXkEtikxwS9XX26AGCLeBJOd3rIclm/vaCNJ
-R4Mn7NsjRAe2b0+JFmyQrdZXqGBYEzfIV5nb3+1O0S0ppVzmDWUJYTjtujzxvP6w
-xwAjCJ06ZFjqaYP2VksqFt+7kGKLOhhs8VnRz5EExkNtmzOszZvAn1M/o4vZX0pZ
-NU5Tt5/J8p6gNzvSRcjsJyI7
+AQAnL07txl6GnhEsgzZrZHlCqz/x4vsDwg0v9Zk4miJEmd0Qv2QJwrr4kl2ZhL0a
+93fpkrmMM8t/eWztjbQqXwW6YQGg23xByLTfNRs1CZ2lhgGuFid2GLEG96TqBj3I
+cO6wULazT40rwws5yHpGI8I1P5HlHyLOiM7V+5EosHz3lyKxBI2/qvETPxIsmt8G
+M1UUG3xlF1BWcW9/9EbOikBSiEzLVOEiOoaPI1zXBRmHI0fZDyMdCdOVob/fccmg
+ZGrxY6wnlrNPyhruk+2B3yFW6wwOt3/Fh51IBes3Oxu0EwO7qQhaik3xbL6pKH92
+6NPMYWG0QiC5WvJnoFobnHf+
 -----END CERTIFICATE-----
diff --git a/cluster/certs/etcd-dcr01s24.hswaw.net.cert b/cluster/certs/etcd-dcr01s24.hswaw.net.cert
index d8dccd2..e8711e8 100644
--- a/cluster/certs/etcd-dcr01s24.hswaw.net.cert
+++ b/cluster/certs/etcd-dcr01s24.hswaw.net.cert
@@ -1,9 +1,9 @@
 -----BEGIN CERTIFICATE-----
-MIIFHjCCBAagAwIBAgIUKe9dtX3sAAushUrH7/r7N3UoPdwwDQYJKoZIhvcNAQEL
+MIIFHjCCBAagAwIBAgIUSMVQ8VRSx+yQhCKL3lHv7taBIvgwDQYJKoZIhvcNAQEL
 BQAweDELMAkGA1UEBhMCUEwxFDASBgNVBAgTC01hem93aWVja2llMQ8wDQYDVQQH
 EwZXYXJzYXcxGzAZBgNVBAoTEldhcnNhdyBIYWNrZXJzcGFjZTETMBEGA1UECxMK
-Y2x1c3RlcmNmZzEQMA4GA1UEAxMHZXRjZCBjYTAeFw0xOTEwMzExNTE5MDBaFw0y
-MDEwMzAxNTE5MDBaMHgxCzAJBgNVBAYTAlBMMRQwEgYDVQQIEwtNYXpvd2llY2tp
+Y2x1c3RlcmNmZzEQMA4GA1UEAxMHZXRjZCBjYTAeFw0yMDEwMDMxNTM4MDBaFw0y
+MTEwMDMxNTM4MDBaMHgxCzAJBgNVBAYTAlBMMRQwEgYDVQQIEwtNYXpvd2llY2tp
 ZTEPMA0GA1UEBxMGV2Fyc2F3MSUwIwYDVQQLExxub2RlIGV0Y2Qgc2VydmVyIGNl
 cnRpZmljYXRlMRswGQYDVQQDExJkY3IwMXMyNC5oc3dhdy5uZXQwggIiMA0GCSqG
 SIb3DQEBAQUAA4ICDwAwggIKAoICAQCl0NRZ5k7SgPeq7v0L/yGjgW8ifJV/3HJQ
@@ -21,10 +21,10 @@
 BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUyyvX/j6W
 TiyCWhZjXwJavrVm+McwHwYDVR0jBBgwFoAU8Vm4Zk0+w+dC7oGj1EZ/OVN1+Q8w
 HQYDVR0RBBYwFIISZGNyMDFzMjQuaHN3YXcubmV0MA0GCSqGSIb3DQEBCwUAA4IB
-AQAzX8owYwbspNIfXBzs+xR2kkoJH5IHHo7lU40QJUYjmg4HqHHQVne842gaXkq4
-LA5k0xAeHIFf4AmwaJKmJUchfYf3Kdrz0bgQ+w7P6fXN1JmMJUV6lWdrmaZrWBKA
-dhfstlnBsaNBNx1FZ08/gWlnIw5Vpyz5F/5oxZqnvKCONFi35t5g/IwUxMNh8tu6
-7z3+KhyNkIHEX0OkOz5XnGcmn2jwEoqOoX3x84NWxTq5rUefBptRZMpgL0qmxOEp
-at0ftNY4DHYpEMG7MiHIPE6pElIzBHQpRRkg6VZBU4YUXCGrG5htjde8DxNMdcdA
-csgzP8tQpoQU3ZriCKrDYN7W
+AQB1oYVNWzed6MAzvnkeB/4oj14IMbJF+iF7uXc/lAAoOzeJ0JetOuq0HuMJGBq2
+Qrk4zva9gR+CbYzSTsc8MHxCI+/rf/ywHTdOJkGUmyF9K1grLuKNvM/zT0v5zGwq
+6u8+Nxbi0W0NmRjht2nQhkRBn8WEhyAAoqzITz8GRPcTPwzlsEh0FBt2rt/vQgkL
+Lny9/W6BIX+3UjhlgeludY3eFfhr79cSabWL33v+MJx89RPWKdDYW6tW+w8sqQsY
+K7wHUaZNB5crW6/EZIG0ICHHd+IVHCFOJ/OyubT/rjhP/5AnjJHQpZhATLVN8toY
+dkMnauFLQIdiSFaKsF5GEFv5
 -----END CERTIFICATE-----
diff --git a/cluster/certs/etcdpeer-dcr01s22.hswaw.net.cert b/cluster/certs/etcdpeer-dcr01s22.hswaw.net.cert
index fd535e5..f6bf5e0 100644
--- a/cluster/certs/etcdpeer-dcr01s22.hswaw.net.cert
+++ b/cluster/certs/etcdpeer-dcr01s22.hswaw.net.cert
@@ -1,9 +1,9 @@
 -----BEGIN CERTIFICATE-----
-MIIFITCCBAmgAwIBAgIUGIumkbssnFQwYrQT8xCHqhU2DJwwDQYJKoZIhvcNAQEL
+MIIFITCCBAmgAwIBAgIUWVNkuf6gx/r3S5q+rpSq4rMhffswDQYJKoZIhvcNAQEL
 BQAwfTELMAkGA1UEBhMCUEwxFDASBgNVBAgTC01hem93aWVja2llMQ8wDQYDVQQH
 EwZXYXJzYXcxGzAZBgNVBAoTEldhcnNhdyBIYWNrZXJzcGFjZTETMBEGA1UECxMK
-Y2x1c3RlcmNmZzEVMBMGA1UEAxMMZXRjZCBwZWVyIGNhMB4XDTE5MTAzMDIyNTQw
-MFoXDTIwMTAyOTIyNTQwMFowdjELMAkGA1UEBhMCUEwxFDASBgNVBAgTC01hem93
+Y2x1c3RlcmNmZzEVMBMGA1UEAxMMZXRjZCBwZWVyIGNhMB4XDTIwMTAwMzE1MzMw
+MFoXDTIxMTAwMzE1MzMwMFowdjELMAkGA1UEBhMCUEwxFDASBgNVBAgTC01hem93
 aWVja2llMQ8wDQYDVQQHEwZXYXJzYXcxIzAhBgNVBAsTGm5vZGUgZXRjZCBwZWVy
 IGNlcnRpZmljYXRlMRswGQYDVQQDExJkY3IwMXMyMi5oc3dhdy5uZXQwggIiMA0G
 CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC8CX6AHfDOCXrNacddsGApq2PZMQ5w
@@ -21,10 +21,10 @@
 BggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU1Yhk
 16mTklzv3gvOdw38WrodcA0wHwYDVR0jBBgwFoAULXuar2iqGaTMKoi++HbkvSen
 JA4wHQYDVR0RBBYwFIISZGNyMDFzMjIuaHN3YXcubmV0MA0GCSqGSIb3DQEBCwUA
-A4IBAQBXo4Yj2HN3TvQMy662Vm+hLyD/aL0L4FVA3dzTl47LX+7P5uL6e5OaES1A
-PSbiIJc75zcSmpdOZHQgUZTEfUZWjZVuE9Vobe7TgIdxB5kUrKvvgqR/d3t7t+B+
-3RayeTO6wlErVj/FffDuy664AVAhXsAC/38iDu7uyAnmNcORELn4kadwZ9FyjWUh
-x44o5+7AJXX0TldXMH1WHh4nwHdOlTeAf147iTUSvLp1QJu9X4EfaeF5MmfqXdGN
-lyjKfbs+Mzt93aNudpiOXolAUdI2t+jhTCo4BA/48QhKwtQZWdGbBWvCdsamZwHU
-7/lijK2qFFkN7xv4I0klSsxyS0Qs
+A4IBAQCV4L9ABnxG2salwBi+t17KvcxEUvo0oD0fs8tI+F5aQB3pHQ/NqRFd/jw2
+7yA1TXt0WG5VBDwbWzJU0psSH5IbPgN5DYVh0BDw71rFB92I3qtW+g5WJo0S7YPj
+GakvJaQmoXPc8ayYFE0n4aFkV9rUVQvcUNjmBsX+rX5su2SbVnE0ZXM6EKrepiFI
+l4HEGokkrOAHKs+1rpJcq/L2e+bRwPmGmTBpnmxlb3AFLST+nL57DZFqho90hFlC
+mifNsSJwXFfDy6lY0XIe+ZyuwfQghfKQLjzee1lgLZIAIdbkFbsP3wh2Z9hG08OL
+pHUSOfG21sh1AsHsQGBtdNHrZONd
 -----END CERTIFICATE-----
diff --git a/cluster/certs/etcdpeer-dcr01s24.hswaw.net.cert b/cluster/certs/etcdpeer-dcr01s24.hswaw.net.cert
index 98987fd..1f57a83 100644
--- a/cluster/certs/etcdpeer-dcr01s24.hswaw.net.cert
+++ b/cluster/certs/etcdpeer-dcr01s24.hswaw.net.cert
@@ -1,9 +1,9 @@
 -----BEGIN CERTIFICATE-----
-MIIFITCCBAmgAwIBAgIUZZUchWgXTldXCL5R+Ia9khASeHcwDQYJKoZIhvcNAQEL
+MIIFITCCBAmgAwIBAgIUWKSJE21a++cxOE0Z2DJosY76dDEwDQYJKoZIhvcNAQEL
 BQAwfTELMAkGA1UEBhMCUEwxFDASBgNVBAgTC01hem93aWVja2llMQ8wDQYDVQQH
 EwZXYXJzYXcxGzAZBgNVBAoTEldhcnNhdyBIYWNrZXJzcGFjZTETMBEGA1UECxMK
-Y2x1c3RlcmNmZzEVMBMGA1UEAxMMZXRjZCBwZWVyIGNhMB4XDTE5MTAzMTE1MTkw
-MFoXDTIwMTAzMDE1MTkwMFowdjELMAkGA1UEBhMCUEwxFDASBgNVBAgTC01hem93
+Y2x1c3RlcmNmZzEVMBMGA1UEAxMMZXRjZCBwZWVyIGNhMB4XDTIwMTAwMzE1Mzgw
+MFoXDTIxMTAwMzE1MzgwMFowdjELMAkGA1UEBhMCUEwxFDASBgNVBAgTC01hem93
 aWVja2llMQ8wDQYDVQQHEwZXYXJzYXcxIzAhBgNVBAsTGm5vZGUgZXRjZCBwZWVy
 IGNlcnRpZmljYXRlMRswGQYDVQQDExJkY3IwMXMyNC5oc3dhdy5uZXQwggIiMA0G
 CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDYaeLRNwXmdRabgLr4AxRpEHOfMtru
@@ -21,10 +21,10 @@
 BggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUI6hU
 9NpYy72mFYPrD2Rs8pEFR6cwHwYDVR0jBBgwFoAULXuar2iqGaTMKoi++HbkvSen
 JA4wHQYDVR0RBBYwFIISZGNyMDFzMjQuaHN3YXcubmV0MA0GCSqGSIb3DQEBCwUA
-A4IBAQAct/qxRCQQ7N9y6sgs7dnXyKhFVHDVMZKvCn5xtDQASTUZwMbVy6rVt74j
-5xX+dHwxgRwvDMP8V5TeVCaud2TlJbwsp9WkfD9wDPFIBmL/aQB6Ksq9hCdj/Is8
-zMLypHF9v9oP7jRy7OD/lyfsGpRESF5UVYKjlZZCIz9K9N/CT+GBPGn80CJ9D3MG
-MOCcu3FyzLjrZwFBCDghXXT0RtnmwRwGodsfeOHA2v4OU2J1HN2VyDIXKlOEYd/l
-D0tQsNR15s3RrlkqgnfRkCi/b3iRlsvNuLX8YbQTJDy+HnpFRKHp36qPDIoCXDQ9
-GreAdy9AaRpEpAIOt221OXX9qc+i
+A4IBAQA27E7NsihLZRJeoeNRA3EGLT1loZzYyCKZZ+uF2nrdVLXfDeHMusfJRacW
+XzyiOveNm2vc5EqZY7/yuALZMZqN75+Zm1/9xbWql9vPOD++5TaY3y9ethiCKzmw
+momYt06iR3qrEA5SN/uKt1+1ikRGGkT9SvWSu86tIHf5P2GP2cb//vGeFlygqZxN
+QCWaDe8sM9J4rozHwTS/shkiifMgkbcRNlAy3K6M9zC9DWoM1xe1mF/pSD/DoMUG
+19Mp52QREETHe+Cfj+wlXFWPqCg1RAEcHMdNfWdCkwY30VVy3OQgSEIgSdRZIlWG
+eWEAsxj9XldOG7/9hxl9RHnQHl6U
 -----END CERTIFICATE-----
diff --git a/cluster/certs/kube-apiserver.cert b/cluster/certs/kube-apiserver.cert
index 76e25a8..ca8df8c 100644
--- a/cluster/certs/kube-apiserver.cert
+++ b/cluster/certs/kube-apiserver.cert
@@ -1,9 +1,9 @@
 -----BEGIN CERTIFICATE-----
-MIIFOzCCBCOgAwIBAgIUFeoDxwVWSi1SvKTE4KnOIqE73ZkwDQYJKoZIhvcNAQEL
+MIIFOzCCBCOgAwIBAgIULKpBQwMbte2UAxQf/JOymdUwqFkwDQYJKoZIhvcNAQEL
 BQAwgYMxCzAJBgNVBAYTAlBMMRQwEgYDVQQIEwtNYXpvd2llY2tpZTEPMA0GA1UE
 BxMGV2Fyc2F3MRswGQYDVQQKExJXYXJzYXcgSGFja2Vyc3BhY2UxEzARBgNVBAsT
-CmNsdXN0ZXJjZmcxGzAZBgNVBAMTEmt1YmVybmV0ZXMgbWFpbiBDQTAeFw0xOTEw
-MzEwMDUwMDBaFw0yMDEwMzAwMDUwMDBaMGQxCzAJBgNVBAYTAlBMMRQwEgYDVQQI
+CmNsdXN0ZXJjZmcxGzAZBgNVBAMTEmt1YmVybmV0ZXMgbWFpbiBDQTAeFw0yMDEw
+MDMxNTI2MDBaFw0yMTEwMDMxNTI2MDBaMGQxCzAJBgNVBAYTAlBMMRQwEgYDVQQI
 EwtNYXpvd2llY2tpZTEPMA0GA1UEBxMGV2Fyc2F3MRcwFQYDVQQLEw5LdWJlcm5l
 dGVzIEFQSTEVMBMGA1UEAxMMazAuaHN3YXcubmV0MIICIjANBgkqhkiG9w0BAQEF
 AAOCAg8AMIICCgKCAgEAsx1dks+6hu3dWLizbUf5egqRfax9oaKJn7H2+F0ndoIX
@@ -21,10 +21,10 @@
 CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKBFe5T0rvllN4ZQuSFH
 UGOcke7SMB8GA1UdIwQYMBaAFJgyXQ5PMx77CemJJBMWQmqA0ZnQMEIGA1UdEQQ7
 MDmCDGswLmhzd2F3Lm5ldIIja3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5rMC5oc3dh
-dy5uZXSHBAoKDAEwDQYJKoZIhvcNAQELBQADggEBAA3tA/YcvwW0HMDLHiD1jSHW
-7LgzF7UjTEa2yfGy7sxR8yX/L0DO6vm6nPdQKzKt/7eDMpMRDJyuJljP5kGfNYgG
-UA34uoMTP98AKusCfv+xsA+V6NVanI0D4lLfX4FiCZXnjX1ZpbiOOZ2Sb0s4U/VY
-SG0v8hoWeMSBE1IlrClJuT2PCfh/TBUFErqPboDWIMlhc4Grbdno28KsBS0daeKY
-fndNhGTfRW03Kse1b0Z3/3u+igjbjVOHE010n9gFNySB5Eu0SRIxIKct/1b0Pwzw
-DoiL9QmuHH9UPDYdWeryJC6mxy21AhNWVRBJVDy5Przi9W+3yhyZsgv21sB9Ceo=
+dy5uZXSHBAoKDAEwDQYJKoZIhvcNAQELBQADggEBAK4JvvqER6qUuKIuAu/b+Zz1
+0B4qLePwgRgeanMPL6/sdwUT1MSWzhgOua4g5NeNPjZduFe6SDT+26/OSFJ4+oYd
++keYEQuzjR+Dv/V9zkgNxX7npplMg6LdrE1qJh6v62tJhy8z+aEh1cC9cLvP0M3a
+yhKbwLT/fl2q6BlS1cB7I6kilU/8D15LBJjqMo9jCmdmY0cxEQtLBs5UgRuMHf3G
+hISDdjoRCQuUM1VC89oiu8nAqgyzxUbVJtJwdRoxMlSHvzY60Uu9CwSTCUTYIlnW
+SVHsfhjRjR37gM+MXMrxgJG+hDU+67nVoAuA05CUrY6qwFKKyGK3smPCFw/TdAc=
 -----END CERTIFICATE-----
diff --git a/cluster/certs/kube-kubelet-dcr01s22.hswaw.net.cert b/cluster/certs/kube-kubelet-dcr01s22.hswaw.net.cert
index 0e8c29f..5ebff9a 100644
--- a/cluster/certs/kube-kubelet-dcr01s22.hswaw.net.cert
+++ b/cluster/certs/kube-kubelet-dcr01s22.hswaw.net.cert
@@ -1,9 +1,9 @@
 -----BEGIN CERTIFICATE-----
-MIIFWTCCBEGgAwIBAgIUMajhf+ol+qYrPkWO4cUmxAzERiIwDQYJKoZIhvcNAQEL
+MIIFWTCCBEGgAwIBAgIUNiys02uLuZgxUVPAVK3RS0AcKTYwDQYJKoZIhvcNAQEL
 BQAwgYMxCzAJBgNVBAYTAlBMMRQwEgYDVQQIEwtNYXpvd2llY2tpZTEPMA0GA1UE
 BxMGV2Fyc2F3MRswGQYDVQQKExJXYXJzYXcgSGFja2Vyc3BhY2UxEzARBgNVBAsT
-CmNsdXN0ZXJjZmcxGzAZBgNVBAMTEmt1YmVybmV0ZXMgbWFpbiBDQTAeFw0xOTEw
-MzAyMzAxMDBaFw0yMDEwMjkyMzAxMDBaMIGGMQswCQYDVQQGEwJQTDEUMBIGA1UE
+CmNsdXN0ZXJjZmcxGzAZBgNVBAMTEmt1YmVybmV0ZXMgbWFpbiBDQTAeFw0yMDEw
+MDMxNTMzMDBaFw0yMTEwMDMxNTMzMDBaMIGGMQswCQYDVQQGEwJQTDEUMBIGA1UE
 CBMLTWF6b3dpZWNraWUxDzANBgNVBAcTBldhcnNhdzEVMBMGA1UEChMMc3lzdGVt
 Om5vZGVzMRAwDgYDVQQLEwdLdWJlbGV0MScwJQYDVQQDEx5zeXN0ZW06bm9kZTpk
 Y3IwMXMyMi5oc3dhdy5uZXQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
@@ -22,10 +22,10 @@
 VR0TAQH/BAIwADAdBgNVHQ4EFgQUW/G38M+taLCcnLVTk/lfdpQDbrUwHwYDVR0j
 BBgwFoAUmDJdDk8zHvsJ6YkkExZCaoDRmdAwPQYDVR0RBDYwNIISZGNyMDFzMjIu
 aHN3YXcubmV0hh5zeXN0ZW06bm9kZTpkY3IwMXMyMi5oc3dhdy5uZXQwDQYJKoZI
-hvcNAQELBQADggEBAEMzvEAEpg/rJb03iDvfPXElD/YBezoOGhDP7aRWwnJh0NtW
-/gx4CvrTq922EmM3ZquuFDIFABt+cr09KZWDC7HsYQyxZuOZK+l08PWG1hW3/2T9
-tpJM274LEwQJE+rKFlq22YFg/b844DSzCvIC2EQZaSpaBt5UY1685sO84rG0YtCz
-5uqGoYU5A/9q3anxIQh3nP6KhlEDruMNxBaZRwm/MyB3J3PafqfbXRgZH6ESi2h6
-Y1E3hlkwkrBBqCfVOUbWs4echvPvL4ysPi2FNzo4L0eXYn7+Xiv0tfAoIhRgRMeY
-qY6wgjdRMORwXSEPfiUqOhTz2EUctXR7MQu3sfg=
+hvcNAQELBQADggEBAGgM2YokHvqZdziBEfzOTSxbmrUuGRIPsvL0uqq5N/sm28ti
+FzlrfwWO+HEVkRA6fMKpwA2nAn+JGg/PcTgH3UrNfSTDQIMUqEAQqbtwdtnEL/ND
+AXAs06wnnDZ3IvyQZAyGKDEzbmyjroTfVWtssXtUhMXDH+j/lm3Ga03QhqzbO9zS
+RloCTM8bBxNpPS6aNlT8GVF4jv/u/REuEtbRPrYUpjVub9QpDJxXcdLXd6Hmz9zR
+32j5TEY2s0ub8duc+y6Xaljkl2fnezUk71QaKxgYWRCuC8eF4ZGWrKsfP0Q1IdZX
+OaDf8ePgtVcOFBtLy2foJriECRbXX2/r96kwAGU=
 -----END CERTIFICATE-----
diff --git a/cluster/certs/kube-kubelet-dcr01s24.hswaw.net.cert b/cluster/certs/kube-kubelet-dcr01s24.hswaw.net.cert
index 353f4f1..38286fe 100644
--- a/cluster/certs/kube-kubelet-dcr01s24.hswaw.net.cert
+++ b/cluster/certs/kube-kubelet-dcr01s24.hswaw.net.cert
@@ -1,9 +1,9 @@
 -----BEGIN CERTIFICATE-----
-MIIFWTCCBEGgAwIBAgIUHPS7inpM8ExeIKErCehvZiwDUNgwDQYJKoZIhvcNAQEL
+MIIFWTCCBEGgAwIBAgIUD02W4qrbKIQLaBbi/rph4q6DkLQwDQYJKoZIhvcNAQEL
 BQAwgYMxCzAJBgNVBAYTAlBMMRQwEgYDVQQIEwtNYXpvd2llY2tpZTEPMA0GA1UE
 BxMGV2Fyc2F3MRswGQYDVQQKExJXYXJzYXcgSGFja2Vyc3BhY2UxEzARBgNVBAsT
-CmNsdXN0ZXJjZmcxGzAZBgNVBAMTEmt1YmVybmV0ZXMgbWFpbiBDQTAeFw0xOTEw
-MzExNTE5MDBaFw0yMDEwMzAxNTE5MDBaMIGGMQswCQYDVQQGEwJQTDEUMBIGA1UE
+CmNsdXN0ZXJjZmcxGzAZBgNVBAMTEmt1YmVybmV0ZXMgbWFpbiBDQTAeFw0yMDEw
+MDMxNTM4MDBaFw0yMTEwMDMxNTM4MDBaMIGGMQswCQYDVQQGEwJQTDEUMBIGA1UE
 CBMLTWF6b3dpZWNraWUxDzANBgNVBAcTBldhcnNhdzEVMBMGA1UEChMMc3lzdGVt
 Om5vZGVzMRAwDgYDVQQLEwdLdWJlbGV0MScwJQYDVQQDEx5zeXN0ZW06bm9kZTpk
 Y3IwMXMyNC5oc3dhdy5uZXQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
@@ -22,10 +22,10 @@
 VR0TAQH/BAIwADAdBgNVHQ4EFgQU98WJLNafrXaajcrVAVuoPlj3EhcwHwYDVR0j
 BBgwFoAUmDJdDk8zHvsJ6YkkExZCaoDRmdAwPQYDVR0RBDYwNIISZGNyMDFzMjQu
 aHN3YXcubmV0hh5zeXN0ZW06bm9kZTpkY3IwMXMyNC5oc3dhdy5uZXQwDQYJKoZI
-hvcNAQELBQADggEBAEiUHf5ZVv2R/jyDI25ctQQp7p9UqKygHKeWOPnvJKIRaQtl
-1PcVIuu0gfpvWgPQSPLUJV8GIN3zJCZLDyHeXZaer4Bo5ivRIX9a5Q+Ino8xLaoX
-6lxkvtBEipdZJ9Gc8GbXo80EinefUnMOlEmXKKC/KWSb9qK2VAbXZam8GGntN4np
-GDDBDbM/Frsz+o+xsLTiozO1gBsJYkl5M3K7vtpl16+hv/QqlK+mnE5ghEfxi6Ss
-hVAf/I9Zg4e45g3nVQwqKhw5nekad/lsnvN/hpuKZhZQdCudUOuuwbW1sc3540Ff
-L77u3ZR/jexJrxR4wzplKl1wtSxJ74x2LaOAIS8=
+hvcNAQELBQADggEBALb8pvxAMWf9CHyDmfj/iXwkDRqHCgNu+qaEzSp4foHgh5ch
+QOs416s8bLyCqIXhoL/vZGCnIRAHBuYunwbofVJnEqo27nLo0o2rH/ABSxCpukmA
+WEGrTv/0wp98gjTNNMX590ws71XrsLRTig4dOTch6NhxoJz5VMOY7vPIItiyFLe2
+Y/LutQA9Wwz3ki6hPs69SJcrLbmfzKOEpJNMKIHhHcwDqT2weTOiZOP7/CsoGPje
+v4dylmcJTMTq0YIQmTDRlKbSGPbE4uVhizytvb2CwODQb+taqQwQ4aRdT76HAdYK
+YbX163CxALNYVYQNkB6dhUR5JNbYnAUwon4h18U=
 -----END CERTIFICATE-----
diff --git a/cluster/nix/modules/kubernetes.nix b/cluster/nix/modules/kubernetes.nix
index 59e8b4f..10560cd 100644
--- a/cluster/nix/modules/kubernetes.nix
+++ b/cluster/nix/modules/kubernetes.nix
@@ -4,17 +4,17 @@
 let
   # Pin for k8s packages. This is so that upagrading the system will not upgrade the k8s control or data planes.
   k8spkgs = import (fetchGit {
-    # Now at 1.14.3
-    name = "nixos-unstable-2019-06-17";
+    # Now at 1.15.4
+    name = "nixos-unstable-2019-09-18";
     url = https://github.com/nixos/nixpkgs-channels/;
-    rev = "415e8e5820b7825fb74a6c7986bf6af725227eaa";
+    rev = "b21a3356f01b59992432a907f17e66abc77f17a0";
   }) {};
   # Pin for kubelet
   k8spkgsKubelet = import (fetchGit {
-    # Now at 1.14.3
-    name = "nixos-unstable-2019-06-17";
+    # Now at 1.15.4
+    name = "nixos-unstable-2019-09-18";
     url = https://github.com/nixos/nixpkgs-channels/;
-    rev = "415e8e5820b7825fb74a6c7986bf6af725227eaa";
+    rev = "b21a3356f01b59992432a907f17e66abc77f17a0";
   }) {};
 
 in rec {
diff --git a/ops/monitoring/README.md b/ops/monitoring/README.md
new file mode 100644
index 0000000..0594678
--- /dev/null
+++ b/ops/monitoring/README.md
@@ -0,0 +1,41 @@
+hscloud monitoring
+==================
+
+Quick links
+-----------
+
+ - *Old Global Dashboard*: [monitoring.hackerspace.pl](https://monitoring.hackerspace.pl) - old monitoring system, unrelated to this one, configured using Chef at management.hackerspace.pl (long since dead). This setup is supposed to replace it.
+
+Architecture
+------------
+
+The hscloud monitoring solution is two-tiered:
+
+ - at the *global* tier we run metrics aggregation, long-term storage, dashboard and alerting.
+ - at the *agent* tier we collect metrics from various sources (possibly even lower tiered agents).
+
+All agent-tier agents send metrics to all global instances.
+
+
+          .--------.     .--------.              '.
+          | global |     | global |               > - global tier
+          '--------'     '--------'              .'   (contains 'global instances')
+            |    '---. .---'    |
+            |         X         |
+            |    .---' '---.    |
+            |    |         |    |
+    .--------------.     .--------------------. '.
+    |   cluster    |     |    hswaw-proxy     |  |
+    | k0.hswaw.net |     | waw.hackerspace.pl |   > - agent tier
+    '--------------'     '--------------------' .'    (contains 'agents')
+
+
+Agent - cluster
+---------------
+
+Cluster agents are responsible from collecting Kubernetes cluster metrics. They run a prometheus server that scrapes kubelet/cadvisor/... metrics and send them off to global instances.
+
+Global Instances
+----------------
+
+Global agents run Victoria Metrics, ingest metrics from all agents, and perform long-term storage. In the future they will also run Grafana and AlertManager.
diff --git a/ops/monitoring/k0.jsonnet b/ops/monitoring/k0.jsonnet
index 028a463..62810c5 100644
--- a/ops/monitoring/k0.jsonnet
+++ b/ops/monitoring/k0.jsonnet
@@ -1,11 +1,39 @@
-local lib = import "lib.libsonnet";
+local cluster = import "lib/cluster.libsonnet";
+local global = import "lib/global.libsonnet";
+
+// Monitoring tiers set up on k0. See README for architectural background.
 
 {
-    cluster: lib.Cluster("k0") {
-        cfg+: {
-            storageClasses+: {
-                prometheus: "waw-hdd-redundant-3",
-            },
+    local k0 = self,
+    local cfg = {
+        storageClasses+: {
+            prometheus: "waw-hdd-redundant-3",
+            victoria: "waw-hdd-redundant-3",
         },
     },
+
+    // Cluster tier - prometheus.
+    cluster: cluster.Cluster("k0") {
+        cfg+: cfg {
+            username: "cluster-k0",
+            upstreams: [
+                { password: std.split(importstr "secrets/plain/global-agent-cluster-k0", "\n")[0], remote: k0.global.internalIngestURL  },
+            ],
+        },
+    },
+
+    // Global tier - victoria metrics.
+    global: global.Global("k0") {
+        cfg+: cfg {
+            hosts: {
+                globalAPI: "monitoring-global-api.k0.hswaw.net",
+            },
+            agents: [
+                // Ingestion from k0 cluster tier.
+                { username: k0.cluster.cfg.username, password: std.split(importstr "secrets/plain/global-agent-cluster-k0", "\n")[0], },
+                // Access from q3k's test Grafana.
+                { username: "grafana", password: std.split(importstr "secrets/plain/global-agent-grafana", "\n")[0], },
+            ],
+        }, 
+    },
 }
diff --git a/ops/monitoring/lib.libsonnet b/ops/monitoring/lib.libsonnet
deleted file mode 100644
index 61f49b4..0000000
--- a/ops/monitoring/lib.libsonnet
+++ /dev/null
@@ -1,5 +0,0 @@
-local cluster = import "lib/cluster.libsonnet";
-
-{
-    Cluster: cluster.Cluster,
-}
diff --git a/ops/monitoring/lib/cluster.libsonnet b/ops/monitoring/lib/cluster.libsonnet
index 9b64f05..511d426 100644
--- a/ops/monitoring/lib/cluster.libsonnet
+++ b/ops/monitoring/lib/cluster.libsonnet
@@ -2,8 +2,10 @@
 
 {
     // Cluster sets up all cluster-specific monitoring resources in their own namespace.
+    //
     // Currently this consists of a prometheus server that scrapes k8s nodes for kubelet
-    // and cAdvisor metrics.
+    // and cAdvisor metrics, and possibly ships over metrics to the global tier via set
+    // upstreams.
     Cluster(name):: {
         local cluster = self,
         local cfg = cluster.cfg,
@@ -18,6 +20,17 @@
             storageClasses: {
                 prometheus: error "storageClasses.prometheus must be set",
             },
+
+            // Username used to authenticate to upstreams.
+            username: error "username must be set",
+
+            // Global tier upstreams that this cluster should ship metrics off to.
+            // List of
+            //  {
+            //     remote: URL of upstream
+            //     password: password used to authenticate, in conjunction with cfg.username.
+            //  
+            upstreams: [],
         },
 
         namespace: kube.Namespace(cfg.namespace),
@@ -105,6 +118,17 @@
                         ],
                     },
                 ],
+
+                remote_write: [
+                    {
+                        url: u.remote,
+                        basic_auth: {
+                            username: cluster.cfg.username,
+                            password: u.password,
+                        },
+                    }
+                    for u in cluster.cfg.upstreams
+                ],
             },
 
             configmap: kube.ConfigMap("prometheus-cluster") {
@@ -152,9 +176,7 @@
                                         "/bin/prometheus",
                                         "--config.file=/etc/prometheus/prometheus.yml",
                                         "--storage.tsdb.path=/prometheus",
-                                        # TODO(q3k): reduce this once we have a long-term storage
-                                        # solution.
-                                        "--storage.tsdb.retention.time=120d",
+                                        "--storage.tsdb.retention.size=10GB",
                                         "--web.console.libraries=/usr/share/prometheus/console_libraries",
                                         "--web.console.templates=/usr/share/prometheus/consoles",
                                         "--web.enable-lifecycle",
@@ -198,7 +220,7 @@
                     accessModes: ["ReadWriteOnce"],
                     resources: {
                         requests: {
-                            storage: "32Gi",
+                            storage: "16Gi",
                         },
                     },
                 },
diff --git a/ops/monitoring/lib/global.libsonnet b/ops/monitoring/lib/global.libsonnet
new file mode 100644
index 0000000..dbdbebb
--- /dev/null
+++ b/ops/monitoring/lib/global.libsonnet
@@ -0,0 +1,149 @@
+local kube = import "../../../kube/kube.libsonnet";
+
+{
+    // Global sets up a global tier instance of the hscloud monitoring infrastructure.
+    //
+    // This currently consists of Victoria Metrics, to which the agent tier sends metrics data via
+    // the prometheus remote_write protocol.
+    // Victoria Metrics is here used as a long-term storage solution. However, right now, it
+    // just keeps data locally on disk. In the future, S3 snapshots/backups should be introduced.
+    Global(name):: {
+        local global = self,
+        local cfg = global.cfg,
+
+        cfg:: {
+            name: name,
+            namespace: "monitoring-global-%s" % [cfg.name],
+
+            images: {
+                victoria: "victoriametrics/victoria-metrics:v1.40.0",
+                vmauth: "victoriametrics/vmauth:v1.40.0",
+            },
+
+            hosts: {
+                // DNS hostname that this global tier will use. Ingress will run under it.
+                globalAPI: error "hosts.globalAPI must be set",
+            },
+
+            storageClasses: {
+                // Storage class used for main data retention.
+                victoria: error "storageClasses.victoria must be set",
+            },
+
+            // A list of agents that will push metrics to this instance.
+            // List of:
+            // {
+            //   username: the username that the agent will authenticate with
+            //   password: the password that the agent will authenticate with
+            // }
+            agents: [],
+        },
+
+        // Generated URLs that agents should use to ship metrics over. Both require HTTP basic
+        // auth, configured via cfg.agents.
+        // The internal URL should be used for agents colocated in the same Kubernetes cluster.
+        internalIngestURL:: "http://%s/api/v1/write" % [global.victoria.serviceAPI.host_colon_port],
+        // The glboal URL should be used for agents sending data over the internet.
+        globalIngestURL:: "https://%s/api/v1/write" % [cfg.hosts.globalAPI],
+
+        namespace: kube.Namespace(cfg.namespace),
+        local ns = global.namespace,
+
+        victoria: {
+            local victoria = self,
+
+            pvc: ns.Contain(kube.PersistentVolumeClaim("victoria-data")) {
+                spec+: {
+                    storageClassName: cfg.storageClasses.victoria,
+                    accessModes: ["ReadWriteOnce"],
+                    resources: {
+                        requests: {
+                            storage: "64Gi",
+                        },
+                    },
+                },
+            },
+
+            authSecret: ns.Contain(kube.Secret("vmauth")) {
+                data+: {
+                    "config.yaml": std.base64(std.manifestJson({
+                        users: [
+                            {
+                                username: a.username,
+                                password: a.password,
+                                url_prefix: "http://localhost:8428",
+                            }
+                            for a in cfg.agents
+                        ],
+                    }) + "\n")
+                },
+            },
+
+            deploy: ns.Contain(kube.Deployment("victoria")) {
+                spec+: {
+                    template+: {
+                        spec+: {
+                            containers_: {
+                                default: kube.Container("default") {
+                                    image: cfg.images.victoria,
+                                    volumeMounts_: {
+                                        data: { mountPath: "/victoria-metrics-data", },
+                                    },
+                                },
+                                vmauth: kube.Container("vmauth") {
+                                    image: cfg.images.vmauth,
+                                    command: [
+                                        "/vmauth-prod",
+                                        "-auth.config", "/mnt/secret/config.yaml",
+                                    ],
+                                    volumeMounts_: {
+                                        secret: { mountPath: "/mnt/secret", },
+                                    },
+                                    ports_: {
+                                        api: { containerPort: 8427 }
+                                    },
+                                }
+                            },
+                            volumes_: {
+                                data: kube.PersistentVolumeClaimVolume(victoria.pvc),
+                                secret: kube.SecretVolume(victoria.authSecret),
+                            },
+                        },
+                    },
+                },
+            },
+
+            serviceAPI: ns.Contain(kube.Service("victoria-api")) {
+                target_pod: victoria.deploy.spec.template,
+                spec+: {
+                    ports: [
+                        { name: "api", port: 8427, targetPort: 8427, protocol: "TCP" },
+                    ],
+                    type: "ClusterIP",
+                },
+            },
+
+            ingressAPI: ns.Contain(kube.Ingress("victoria-api")) {
+                metadata+: {
+                    annotations+: {
+                        "kubernetes.io/tls-acme": "true",
+                        "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
+                    },
+                },
+                spec+: {
+                    tls: [
+                        { hosts: [cfg.hosts.globalAPI], secretName: "ingress-tls" },
+                    ],
+                    rules: [
+                        {
+                            host: cfg.hosts.globalAPI,
+                            http: {
+                                paths: [ { path: "/", backend: { serviceName: victoria.serviceAPI.metadata.name, servicePort: 8427 } }, ],
+                            },
+                        }
+                    ],
+                },
+            },
+        },
+    }
+}
diff --git a/ops/monitoring/secrets/cipher/global-agent-cluster-k0 b/ops/monitoring/secrets/cipher/global-agent-cluster-k0
new file mode 100644
index 0000000..29e715b
--- /dev/null
+++ b/ops/monitoring/secrets/cipher/global-agent-cluster-k0
@@ -0,0 +1,40 @@
+-----BEGIN PGP MESSAGE-----
+
+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
+=e/F1
+-----END PGP MESSAGE-----
diff --git a/ops/monitoring/secrets/cipher/global-agent-grafana b/ops/monitoring/secrets/cipher/global-agent-grafana
new file mode 100644
index 0000000..fd501e6
--- /dev/null
+++ b/ops/monitoring/secrets/cipher/global-agent-grafana
@@ -0,0 +1,40 @@
+-----BEGIN PGP MESSAGE-----
+
+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
+xL1OhySubTvzg2yTCfUoEuMWZFL1rwgT9lrKVg==
+=Do8R
+-----END PGP MESSAGE-----
diff --git a/ops/monitoring/secrets/plain/.gitignore b/ops/monitoring/secrets/plain/.gitignore
new file mode 100644
index 0000000..72e8ffc
--- /dev/null
+++ b/ops/monitoring/secrets/plain/.gitignore
@@ -0,0 +1 @@
+*