├── .github
└── workflows
│ └── tests.yml
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── biome.json
├── build.sh
├── cmd
└── wasm
│ └── main.go
├── go.mod
├── go.sum
├── helm
└── tardis
│ ├── .helmignore
│ ├── Chart.yaml
│ ├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── tests
│ │ └── test-connection.yaml
│ └── values.yaml
├── img
├── sugiyama.png
├── tardis.png
└── zherebko.png
├── index.html
├── jest.config.js
├── package.json
├── public
├── favicon.svg
├── gmsl.wasm
└── wasm_exec.js
├── shims
└── synapse
│ ├── .dockerignore
│ ├── Dockerfile
│ ├── README.md
│ ├── build.sh
│ ├── requirements-freeze.txt
│ ├── requirements.txt
│ └── shim.py
├── src
├── auth_dag.ts
├── cache.ts
├── debugger.ts
├── event_list.ts
├── graph.ts
├── index.ts
├── preloaded_scenarios.ts
├── scenario.ts
├── state_resolver.test.ts
└── state_resolver.ts
├── style.css
├── tsconfig.json
└── yarn.lock
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 |
3 | on:
4 | push:
5 | branches: ["main"]
6 | pull_request:
7 |
8 | permissions:
9 | packages: read
10 | # Note: from https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
11 | # > If you specify the access for any of these scopes, all of those that are not specified are set to none.
12 |
13 | jobs:
14 | check-signoff:
15 | if: "github.event_name == 'pull_request'"
16 | uses: "matrix-org/backend-meta/.github/workflows/sign-off.yml@v2"
17 |
18 | tests:
19 | runs-on: ubuntu-latest
20 |
21 | steps:
22 | - uses: actions/checkout@v3
23 |
24 | - uses: actions/setup-node@v4
25 | with:
26 | node-version: 20
27 |
28 | - name: Install
29 | run: yarn install
30 |
31 | - name: Build
32 | run: yarn build
33 |
34 | - name: Lint
35 | run: yarn lint ./src
36 |
37 | - name: Test
38 | run: yarn test
39 |
40 | - name: Docker Build
41 | run: docker build -t tardis .
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .zed/
2 | dist/
3 | node_modules/
4 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:lts
2 |
3 | WORKDIR /app
4 | COPY yarn.lock package.json ./
5 | RUN yarn install
6 |
7 | COPY . .
8 | EXPOSE 5173
9 | CMD ["yarn", "start", "--host", "0.0.0.0", "--port", "5173"]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## TARDIS - Time Agnostic Room DAG Inspection Service
2 |
3 | TARDIS is a time-travelling debugger for Matrix room DAGs, which reads a plaintext file
4 | to graphically visualise a room using [d3-dag](https://github.com/erikbrinkman/d3-dag) for
5 | debugging purposes. It can then perform state resolution at any given event on the DAG via
6 | a shim server. TARDIS comes with a Synapse shim server, which needs to be run in addition
7 | to TARDIS. See `shims/synapse`.
8 |
9 | ## Generates stuff like this:
10 |
11 | 
12 |
13 | ### To use:
14 |
15 | Requires node 20+ for global crypto variables.
16 | ```
17 | yarn install
18 | yarn run start
19 | ```
20 | or:
21 | ```
22 | docker build -t tardis .
23 | docker run --rm -p 5173:5173 tardis
24 | ```
25 |
26 | ## Loading events
27 |
28 | ### ..via existing events in a database
29 | Provide a new-line delimited JSON file which contains events to render in the full federation format (with `prev_events`, etc).
30 | To get such a file _for Synapse installations on Postgres_, run the following (assuming `matrix` is the name of your DB):
31 | ```
32 | $ psql matrix
33 | matrix=> \t
34 | Tuples only is on.
35 | matrix=> \o the-file.ndjson
36 | matrix=> select jsonb_insert(json::JSONB, '{event_id}', ('"' || event_id || '"')::JSONB) from event_json where event_id in
37 | (select event_id from events where
38 | room_id='!THE_ROOM_ID' and
39 | stream_ordering < (select stream_ordering from events where event_id='$LATEST_EVENT_ID') and
40 | stream_ordering > (select stream_ordering from events where event_id='$EARLIEST_EVENT_ID')
41 | order by stream_ordering asc
42 | );
43 | ```
44 |
45 | For SQLite3 use `select '{"event_id":"' || event_id || '",' || substr(json, 2) from event_json`.
46 |
47 | You can drop the `stream_ordering` clauses if the room is small and you want to see the entire thing.
48 |
49 | It is important that the events are sorted in causal order. To do this with [jq](https://jqlang.github.io/jq/): just do:
50 | ```
51 | cat the-file.ndjson | jq -s 'sort_by(.depth)' > sorted-file.ndjson
52 | ```
53 | The file created by these commands can be dropped **as-is** into TARDIS.
54 |
55 | ### ..via scenario JSON5 files
56 | Provide a JSON5 file which contains the scenario to run. See the `examples` directory for examples on
57 | the keys available.
58 |
59 | ## Developing
60 |
61 |
62 | ### Building WASM
63 | Sometimes we want to create mock scenarios which don't exist in databases. We use placeholder event IDs in this case. However, state
64 | resolution demands that they are actual event IDs. Tardis uses the same code paths as Dendrite (via wasm) to generate the correct event IDs.
65 | To build the wasm, you need [tinygo](https://tinygo.org/) installed and then:
66 | ```
67 | GOOS=js GOARCH=wasm tinygo build -o ./public/gmsl.wasm --no-debug ./cmd/wasm/main.go
68 | ```
69 | A working version is already supplied with this repository.
70 |
--------------------------------------------------------------------------------
/biome.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
3 | "vcs": {
4 | "enabled": true,
5 | "clientKind": "git",
6 | "useIgnoreFile": true
7 | },
8 | "organizeImports": {
9 | "enabled": true
10 | },
11 | "formatter": {
12 | "enabled": true,
13 | "indentStyle": "space",
14 | "indentWidth": 4,
15 | "lineWidth": 120
16 | },
17 | "linter": {
18 | "enabled": true,
19 | "rules": {
20 | "recommended": true,
21 | "style": {
22 | "noNonNullAssertion": "off"
23 | }
24 | }
25 | },
26 | "files": {
27 | "maxSize": 2097152,
28 | "ignoreUnknown": true,
29 | "ignore": ["shims/*", "public/*"]
30 | },
31 | "json": {
32 | "formatter": {
33 | "indentWidth": 2
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -eu
2 | yarn build # dumps to ./dist
3 | git checkout gh-pages # we gitignore ./dist so the directory is carried over to this branch
4 | git ls-files -z | xargs -0 rm -f # remove previous release
5 | cp -r ./dist/* . # dump dist files at the root
6 | git add assets/ index.html # add them
7 | git status # show the user so they can commit
--------------------------------------------------------------------------------
/cmd/wasm/main.go:
--------------------------------------------------------------------------------
1 | // Includes functions useful for tardis, written in Go.
2 | // Compiled using TinyGo to keep .wasm file sizes small.
3 | package main
4 |
5 | import (
6 | "crypto/sha256"
7 | "encoding/base64"
8 | "encoding/json"
9 | "fmt"
10 | "syscall/js"
11 |
12 | "github.com/matrix-org/gomatrixserverlib"
13 | "github.com/matrix-org/gomatrixserverlib/spec"
14 | )
15 |
16 | // This function is exported to JS, and returns the event ID for the input event JSON and
17 | // room version using the same code paths as Dendrite.
18 | func eventIDForEvent(this js.Value, args []js.Value) any {
19 | if len(args) != 2 {
20 | fmt.Println("eventIDForEvent: must be called with (event, roomVer)")
21 | return ""
22 | }
23 | eventJSON := args[0].String()
24 | roomVerStr := args[1].String()
25 | roomVersion := gomatrixserverlib.RoomVersion(roomVerStr)
26 | verImpl, err := gomatrixserverlib.GetRoomVersion(roomVersion)
27 | if err != nil {
28 | return ""
29 | }
30 | redactedJSON, err := verImpl.RedactEventJSON([]byte(eventJSON))
31 | if err != nil {
32 | return ""
33 | }
34 |
35 | var event map[string]spec.RawJSON
36 | if err = json.Unmarshal(redactedJSON, &event); err != nil {
37 | return ""
38 | }
39 |
40 | delete(event, "signatures")
41 | delete(event, "unsigned")
42 | existingEventID := event["event_id"]
43 | delete(event, "event_id")
44 |
45 | hashableEventJSON, err := json.Marshal(event)
46 | if err != nil {
47 | return ""
48 | }
49 |
50 | hashableEventJSON, err = gomatrixserverlib.CanonicalJSON(hashableEventJSON)
51 | if err != nil {
52 | return ""
53 | }
54 |
55 | sha256Hash := sha256.Sum256(hashableEventJSON)
56 | var eventID string
57 |
58 | eventFormat := verImpl.EventFormat()
59 | eventIDFormat := verImpl.EventIDFormat()
60 |
61 | switch eventFormat {
62 | case gomatrixserverlib.EventFormatV1:
63 | if err = json.Unmarshal(existingEventID, &eventID); err != nil {
64 | return ""
65 | }
66 | case gomatrixserverlib.EventFormatV2:
67 | var encoder *base64.Encoding
68 | switch eventIDFormat {
69 | case gomatrixserverlib.EventIDFormatV2:
70 | encoder = base64.RawStdEncoding.WithPadding(base64.NoPadding)
71 | case gomatrixserverlib.EventIDFormatV3:
72 | encoder = base64.RawURLEncoding.WithPadding(base64.NoPadding)
73 | default:
74 | return ""
75 | }
76 | eventID = "$" + encoder.EncodeToString(sha256Hash[:])
77 | default:
78 | return ""
79 | }
80 |
81 | return eventID
82 | }
83 |
84 | func main() {
85 | wait := make(chan struct{}, 0)
86 | js.Global().Set("gmslEventIDForEvent", js.FuncOf(eventIDForEvent))
87 | <-wait
88 | }
89 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/matrix-org/tardis
2 |
3 | go 1.23.1
4 |
5 | require (
6 | github.com/matrix-org/gomatrixserverlib v0.0.0-20240910190622-2c764912ce93 // indirect
7 | github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 // indirect
8 | github.com/sirupsen/logrus v1.9.0 // indirect
9 | github.com/tidwall/gjson v1.14.3 // indirect
10 | github.com/tidwall/match v1.1.1 // indirect
11 | github.com/tidwall/pretty v1.2.0 // indirect
12 | github.com/tidwall/sjson v1.2.5 // indirect
13 | golang.org/x/crypto v0.17.0 // indirect
14 | golang.org/x/sys v0.15.0 // indirect
15 | )
16 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
4 | github.com/matrix-org/gomatrixserverlib v0.0.0-20240910190622-2c764912ce93 h1:FbyZ/xkeBVYHi2xfwAVaNmDhP+4HNbt9e6ucOR+jvBk=
5 | github.com/matrix-org/gomatrixserverlib v0.0.0-20240910190622-2c764912ce93/go.mod h1:HZGsVJ3bUE+DkZtufkH9H0mlsvbhEGK5CpX0Zlavylg=
6 | github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 h1:eCEHXWDv9Rm335MSuB49mFUK44bwZPFSDde3ORE3syk=
7 | github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
8 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
9 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
10 | github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
11 | github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
12 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
13 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
14 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
15 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
16 | github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
17 | github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
18 | github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
19 | github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
20 | github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
21 | github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
22 | github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
23 | github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
24 | github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
25 | golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
26 | golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
27 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
28 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
29 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
30 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
31 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
32 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
33 |
--------------------------------------------------------------------------------
/helm/tardis/.helmignore:
--------------------------------------------------------------------------------
1 | # Patterns to ignore when building packages.
2 | # This supports shell glob matching, relative path matching, and
3 | # negation (prefixed with !). Only one pattern per line.
4 | .DS_Store
5 | # Common VCS dirs
6 | .git/
7 | .gitignore
8 | .bzr/
9 | .bzrignore
10 | .hg/
11 | .hgignore
12 | .svn/
13 | # Common backup files
14 | *.swp
15 | *.bak
16 | *.tmp
17 | *.orig
18 | *~
19 | # Various IDEs
20 | .project
21 | .idea/
22 | *.tmproj
23 | .vscode/
24 |
--------------------------------------------------------------------------------
/helm/tardis/Chart.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v2
2 | name: tardis
3 | description: A Helm chart for shim servers for tardis
4 |
5 | # A chart can be either an 'application' or a 'library' chart.
6 | #
7 | # Application charts are a collection of templates that can be packaged into versioned archives
8 | # to be deployed.
9 | #
10 | # Library charts provide useful utilities or functions for the chart developer. They're included as
11 | # a dependency of application charts to inject those utilities and functions into the rendering
12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed.
13 | type: application
14 |
15 | # This is the chart version. This version number should be incremented each time you make changes
16 | # to the chart and its templates, including the app version.
17 | # Versions are expected to follow Semantic Versioning (https://semver.org/)
18 | version: 0.1.0
19 |
20 | # This is the version number of the application being deployed. This version number should be
21 | # incremented each time you make changes to the application. Versions are not expected to
22 | # follow Semantic Versioning. They should reflect the version the application is using.
23 | # It is recommended to use it with quotes.
24 | appVersion: "v0.0.1"
25 |
--------------------------------------------------------------------------------
/helm/tardis/templates/NOTES.txt:
--------------------------------------------------------------------------------
1 | 1. Get the application URL by running these commands:
2 | {{- if .Values.ingress.enabled }}
3 | {{- range $host := .Values.ingress.hosts }}
4 | {{- range .paths }}
5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
6 | {{- end }}
7 | {{- end }}
8 | {{- else if contains "NodePort" .Values.service.type }}
9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "tardis.fullname" . }})
10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
11 | echo http://$NODE_IP:$NODE_PORT
12 | {{- else if contains "LoadBalancer" .Values.service.type }}
13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available.
14 | You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "tardis.fullname" . }}'
15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "tardis.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
16 | echo http://$SERVICE_IP:{{ .Values.service.port }}
17 | {{- else if contains "ClusterIP" .Values.service.type }}
18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "tardis.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
19 | export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
20 | echo "Visit http://127.0.0.1:8080 to use your application"
21 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
22 | {{- end }}
23 |
--------------------------------------------------------------------------------
/helm/tardis/templates/_helpers.tpl:
--------------------------------------------------------------------------------
1 | {{/*
2 | Expand the name of the chart.
3 | */}}
4 | {{- define "tardis.name" -}}
5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6 | {{- end }}
7 |
8 | {{/*
9 | Create a default fully qualified app name.
10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
11 | If release name contains chart name it will be used as a full name.
12 | */}}
13 | {{- define "tardis.fullname" -}}
14 | {{- if .Values.fullnameOverride }}
15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
16 | {{- else }}
17 | {{- $name := default .Chart.Name .Values.nameOverride }}
18 | {{- if contains $name .Release.Name }}
19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }}
20 | {{- else }}
21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
22 | {{- end }}
23 | {{- end }}
24 | {{- end }}
25 |
26 | {{/*
27 | Create chart name and version as used by the chart label.
28 | */}}
29 | {{- define "tardis.chart" -}}
30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
31 | {{- end }}
32 |
33 | {{/*
34 | Common labels
35 | */}}
36 | {{- define "tardis.labels" -}}
37 | helm.sh/chart: {{ include "tardis.chart" . }}
38 | {{ include "tardis.selectorLabels" . }}
39 | {{- if .Chart.AppVersion }}
40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
41 | {{- end }}
42 | app.kubernetes.io/managed-by: {{ .Release.Service }}
43 | {{- end }}
44 |
45 | {{/*
46 | Selector labels
47 | */}}
48 | {{- define "tardis.selectorLabels" -}}
49 | app.kubernetes.io/name: {{ include "tardis.name" . }}
50 | app.kubernetes.io/instance: {{ .Release.Name }}
51 | {{- end }}
52 |
53 | {{/*
54 | Create the name of the service account to use
55 | */}}
56 | {{- define "tardis.serviceAccountName" -}}
57 | {{- if .Values.serviceAccount.create }}
58 | {{- default (include "tardis.fullname" .) .Values.serviceAccount.name }}
59 | {{- else }}
60 | {{- default "default" .Values.serviceAccount.name }}
61 | {{- end }}
62 | {{- end }}
63 |
--------------------------------------------------------------------------------
/helm/tardis/templates/deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: {{ include "tardis.fullname" . }}
5 | labels:
6 | {{- include "tardis.labels" . | nindent 4 }}
7 | spec:
8 | {{- if not .Values.autoscaling.enabled }}
9 | replicas: {{ .Values.replicaCount }}
10 | {{- end }}
11 | selector:
12 | matchLabels:
13 | {{- include "tardis.selectorLabels" . | nindent 6 }}
14 | template:
15 | metadata:
16 | {{- with .Values.podAnnotations }}
17 | annotations:
18 | {{- toYaml . | nindent 8 }}
19 | {{- end }}
20 | labels:
21 | {{- include "tardis.labels" . | nindent 8 }}
22 | {{- with .Values.podLabels }}
23 | {{- toYaml . | nindent 8 }}
24 | {{- end }}
25 | spec:
26 | {{- with .Values.imagePullSecrets }}
27 | imagePullSecrets:
28 | {{- toYaml . | nindent 8 }}
29 | {{- end }}
30 | serviceAccountName: {{ include "tardis.serviceAccountName" . }}
31 | securityContext:
32 | {{- toYaml .Values.podSecurityContext | nindent 8 }}
33 | containers:
34 | - name: {{ .Chart.Name }}
35 | securityContext:
36 | {{- toYaml .Values.securityContext | nindent 12 }}
37 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
38 | imagePullPolicy: {{ .Values.image.pullPolicy }}
39 | ports:
40 | - name: http
41 | containerPort: 1234
42 | protocol: TCP
43 | livenessProbe:
44 | {{- toYaml .Values.livenessProbe | nindent 12 }}
45 | readinessProbe:
46 | {{- toYaml .Values.readinessProbe | nindent 12 }}
47 | resources:
48 | {{- toYaml .Values.resources | nindent 12 }}
49 | {{- with .Values.volumeMounts }}
50 | volumeMounts:
51 | {{- toYaml . | nindent 12 }}
52 | {{- end }}
53 | {{- with .Values.volumes }}
54 | volumes:
55 | {{- toYaml . | nindent 8 }}
56 | {{- end }}
57 | {{- with .Values.nodeSelector }}
58 | nodeSelector:
59 | {{- toYaml . | nindent 8 }}
60 | {{- end }}
61 | {{- with .Values.affinity }}
62 | affinity:
63 | {{- toYaml . | nindent 8 }}
64 | {{- end }}
65 | {{- with .Values.tolerations }}
66 | tolerations:
67 | {{- toYaml . | nindent 8 }}
68 | {{- end }}
69 |
--------------------------------------------------------------------------------
/helm/tardis/templates/hpa.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.autoscaling.enabled }}
2 | apiVersion: autoscaling/v2
3 | kind: HorizontalPodAutoscaler
4 | metadata:
5 | name: {{ include "tardis.fullname" . }}
6 | labels:
7 | {{- include "tardis.labels" . | nindent 4 }}
8 | spec:
9 | scaleTargetRef:
10 | apiVersion: apps/v1
11 | kind: Deployment
12 | name: {{ include "tardis.fullname" . }}
13 | minReplicas: {{ .Values.autoscaling.minReplicas }}
14 | maxReplicas: {{ .Values.autoscaling.maxReplicas }}
15 | metrics:
16 | {{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
17 | - type: Resource
18 | resource:
19 | name: cpu
20 | target:
21 | type: Utilization
22 | averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
23 | {{- end }}
24 | {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
25 | - type: Resource
26 | resource:
27 | name: memory
28 | target:
29 | type: Utilization
30 | averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
31 | {{- end }}
32 | {{- end }}
33 |
--------------------------------------------------------------------------------
/helm/tardis/templates/ingress.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.ingress.enabled -}}
2 | {{- $fullName := include "tardis.fullname" . -}}
3 | {{- $svcPort := .Values.service.port -}}
4 | {{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
5 | {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
6 | {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
7 | {{- end }}
8 | {{- end }}
9 | {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
10 | apiVersion: networking.k8s.io/v1
11 | {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
12 | apiVersion: networking.k8s.io/v1beta1
13 | {{- else -}}
14 | apiVersion: extensions/v1beta1
15 | {{- end }}
16 | kind: Ingress
17 | metadata:
18 | name: {{ $fullName }}
19 | labels:
20 | {{- include "tardis.labels" . | nindent 4 }}
21 | {{- with .Values.ingress.annotations }}
22 | annotations:
23 | {{- toYaml . | nindent 4 }}
24 | {{- end }}
25 | spec:
26 | {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
27 | ingressClassName: {{ .Values.ingress.className }}
28 | {{- end }}
29 | {{- if .Values.ingress.tls }}
30 | tls:
31 | {{- range .Values.ingress.tls }}
32 | - hosts:
33 | {{- range .hosts }}
34 | - {{ . | quote }}
35 | {{- end }}
36 | secretName: {{ .secretName }}
37 | {{- end }}
38 | {{- end }}
39 | rules:
40 | {{- range .Values.ingress.hosts }}
41 | - host: {{ .host | quote }}
42 | http:
43 | paths:
44 | {{- range .paths }}
45 | - path: {{ .path }}
46 | {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
47 | pathType: {{ .pathType }}
48 | {{- end }}
49 | backend:
50 | {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
51 | service:
52 | name: {{ $fullName }}
53 | port:
54 | number: {{ $svcPort }}
55 | {{- else }}
56 | serviceName: {{ $fullName }}
57 | servicePort: {{ $svcPort }}
58 | {{- end }}
59 | {{- end }}
60 | {{- end }}
61 | {{- end }}
62 |
--------------------------------------------------------------------------------
/helm/tardis/templates/service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: {{ include "tardis.fullname" . }}
5 | labels:
6 | {{- include "tardis.labels" . | nindent 4 }}
7 | spec:
8 | type: {{ .Values.service.type }}
9 | ports:
10 | - port: {{ .Values.service.port }}
11 | targetPort: http
12 | protocol: TCP
13 | name: http
14 | selector:
15 | {{- include "tardis.selectorLabels" . | nindent 4 }}
16 |
--------------------------------------------------------------------------------
/helm/tardis/templates/serviceaccount.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.serviceAccount.create -}}
2 | apiVersion: v1
3 | kind: ServiceAccount
4 | metadata:
5 | name: {{ include "tardis.serviceAccountName" . }}
6 | labels:
7 | {{- include "tardis.labels" . | nindent 4 }}
8 | {{- with .Values.serviceAccount.annotations }}
9 | annotations:
10 | {{- toYaml . | nindent 4 }}
11 | {{- end }}
12 | automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
13 | {{- end }}
14 |
--------------------------------------------------------------------------------
/helm/tardis/templates/tests/test-connection.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Pod
3 | metadata:
4 | name: "{{ include "tardis.fullname" . }}-test-connection"
5 | labels:
6 | {{- include "tardis.labels" . | nindent 4 }}
7 | annotations:
8 | "helm.sh/hook": test
9 | spec:
10 | containers:
11 | - name: wget
12 | image: busybox
13 | command: ['wget']
14 | args: ['{{ include "tardis.fullname" . }}:{{ .Values.service.port }}']
15 | restartPolicy: Never
16 |
--------------------------------------------------------------------------------
/helm/tardis/values.yaml:
--------------------------------------------------------------------------------
1 | # Default values for tardis.
2 | # This is a YAML-formatted file.
3 | # Declare variables to be passed into your templates.
4 |
5 | replicaCount: 1
6 |
7 | image:
8 | repository: ghcr.io/matrix-org/tardis-synapse
9 | pullPolicy: IfNotPresent
10 | # Overrides the image tag whose default is the chart appVersion.
11 | tag: ""
12 |
13 | imagePullSecrets: []
14 | nameOverride: ""
15 | fullnameOverride: ""
16 |
17 | serviceAccount:
18 | # Specifies whether a service account should be created
19 | create: true
20 | # Automatically mount a ServiceAccount's API credentials?
21 | automount: true
22 | # Annotations to add to the service account
23 | annotations: {}
24 | # The name of the service account to use.
25 | # If not set and create is true, a name is generated using the fullname template
26 | name: ""
27 |
28 | podAnnotations: {}
29 | podLabels: {}
30 |
31 | podSecurityContext: {}
32 | # fsGroup: 2000
33 |
34 | securityContext: {}
35 | # capabilities:
36 | # drop:
37 | # - ALL
38 | # readOnlyRootFilesystem: true
39 | # runAsNonRoot: true
40 | # runAsUser: 1000
41 |
42 | service:
43 | type: ClusterIP
44 | port: 80
45 |
46 | ingress:
47 | enabled: false
48 | className: ""
49 | annotations: {}
50 | # kubernetes.io/ingress.class: nginx
51 | # kubernetes.io/tls-acme: "true"
52 | hosts:
53 | - host: chart-example.local
54 | paths:
55 | - path: /
56 | pathType: ImplementationSpecific
57 | tls: []
58 | # - secretName: chart-example-tls
59 | # hosts:
60 | # - chart-example.local
61 |
62 | resources: {}
63 | # We usually recommend not to specify default resources and to leave this as a conscious
64 | # choice for the user. This also increases chances charts run on environments with little
65 | # resources, such as Minikube. If you do want to specify resources, uncomment the following
66 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
67 | # limits:
68 | # cpu: 100m
69 | # memory: 128Mi
70 | # requests:
71 | # cpu: 100m
72 | # memory: 128Mi
73 |
74 | livenessProbe:
75 | tcpSocket:
76 | port: http
77 | readinessProbe:
78 | tcpSocket:
79 | port: http
80 |
81 | autoscaling:
82 | enabled: false
83 | minReplicas: 1
84 | maxReplicas: 100
85 | targetCPUUtilizationPercentage: 80
86 | # targetMemoryUtilizationPercentage: 80
87 |
88 | # Additional volumes on the output Deployment definition.
89 | volumes: []
90 | # - name: foo
91 | # secret:
92 | # secretName: mysecret
93 | # optional: false
94 |
95 | # Additional volumeMounts on the output Deployment definition.
96 | volumeMounts: []
97 | # - name: foo
98 | # mountPath: "/etc/foo"
99 | # readOnly: true
100 |
101 | nodeSelector: {}
102 |
103 | tolerations: []
104 |
105 | affinity: {}
106 |
--------------------------------------------------------------------------------
/img/sugiyama.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matrix-org/tardis/1c10b1b2a6503f7814c102d16fa428d159862c60/img/sugiyama.png
--------------------------------------------------------------------------------
/img/tardis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matrix-org/tardis/1c10b1b2a6503f7814c102d16fa428d159862c60/img/tardis.png
--------------------------------------------------------------------------------
/img/zherebko.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matrix-org/tardis/1c10b1b2a6503f7814c102d16fa428d159862c60/img/zherebko.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | TARDIS - Time Agnostic Room DAG Inspection Service
7 |
8 |
9 |
10 |
11 |