├── .envrc ├── .github ├── passthru.nix └── workflows │ ├── doc.yml │ └── nix-github-actions.yml ├── .gitignore ├── .mergify.yml ├── .reuse └── dep5 ├── LICENSES ├── Apache-2.0.txt ├── CC-BY-SA-4.0.txt ├── CC0-1.0.txt ├── GPL-3.0-only.txt ├── LicenseRef-all-rights-reserved.txt └── MIT.txt ├── Procfile ├── README.md ├── assets ├── NGI0_tag.png ├── nlnet-banner.png └── tweag.png ├── checks ├── golangci-lint └── gomod2nix ├── dev └── treefmt.nix ├── examples-old ├── colmena │ ├── flake.nix │ └── secrets │ │ ├── log-priv │ │ └── log-pub ├── nixops-deployment.nix └── nixos-shell.nix ├── examples ├── 01_basic │ ├── configuration.nix │ └── secrets │ │ ├── log-priv │ │ └── log-pub └── 02_post_build │ ├── configuration.nix │ └── secrets │ ├── log-priv │ └── log-pub ├── flake.lock ├── flake.nix ├── nixos └── default.nix ├── packages ├── go-lib │ ├── README.md │ ├── executor │ │ ├── executor.go │ │ └── limited.go │ ├── go.mod │ ├── go.sum │ ├── gomod2nix.toml │ ├── safemap │ │ └── map.go │ └── set │ │ ├── set.go │ │ └── set_test.go ├── trustix-doc │ ├── .gitignore │ ├── Procfile │ ├── book.toml │ ├── default.nix │ ├── doc_old │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── comparison.md │ │ ├── numeric.csl │ │ ├── references.bib │ │ ├── shell.nix │ │ ├── trustix-gossip.puml │ │ ├── trustix-submission.puml │ │ └── trustix-substitution.puml │ └── src │ │ ├── SUMMARY.md │ │ ├── about.md │ │ ├── api.md │ │ ├── binarycache.md │ │ ├── hacking.md │ │ ├── howto-nix │ │ ├── binarycache.md │ │ ├── builder-colmena-nixos.md │ │ ├── index.md │ │ ├── post-build-hook.md │ │ ├── setup.md │ │ └── subscribing.md │ │ └── intro.md ├── trustix-nix-r13y-web │ ├── .eslintignore │ ├── .eslintrc.js │ ├── .gitignore │ ├── .prettierignore │ ├── .prettierrc.json │ ├── Procfile │ ├── README.md │ ├── default.nix │ ├── index.html │ ├── mk-proto │ ├── package-lock.json │ ├── package.json │ ├── postcss.config.js │ ├── src │ │ ├── App.tsx │ │ ├── about.tsx │ │ ├── api │ │ │ ├── api_connect.ts │ │ │ ├── api_connectweb.ts │ │ │ └── api_pb.ts │ │ ├── chart │ │ │ ├── README.md │ │ │ └── SolidChart.tsx │ │ ├── client.tsx │ │ ├── index.css │ │ ├── index.tsx │ │ ├── lib.tsx │ │ ├── pages │ │ │ ├── attrs.tsx │ │ │ ├── diff.tsx │ │ │ └── drv.tsx │ │ └── widgets.tsx │ ├── tailwind.config.js │ ├── tsconfig.json │ └── vite.config.ts ├── trustix-nix-r13y │ ├── .gitignore │ ├── Procfile │ ├── default.nix │ ├── examples │ │ └── config.toml │ ├── go.mod │ ├── go.sum │ ├── gomod2nix.toml │ ├── internal │ │ ├── cmd │ │ │ ├── db.go │ │ │ ├── index-logs.go │ │ │ ├── root.go │ │ │ └── serve.go │ │ ├── config │ │ │ ├── channels.go │ │ │ ├── config.go │ │ │ └── eval.go │ │ ├── cron │ │ │ └── cron.go │ │ ├── db │ │ │ ├── db.go │ │ │ ├── derivations.sql.go │ │ │ ├── eval.sql.go │ │ │ ├── logs.sql.go │ │ │ ├── models.go │ │ │ ├── reprod.sql.go │ │ │ └── suggest.sql.go │ │ ├── dbcache │ │ │ ├── db.go │ │ │ ├── diffoscope.sql.go │ │ │ └── models.go │ │ ├── derivation │ │ │ └── derivation.go │ │ ├── eval │ │ │ ├── config.go │ │ │ ├── eval.go │ │ │ ├── interface.go │ │ │ └── interface_test.go │ │ ├── future │ │ │ └── future.go │ │ ├── index │ │ │ ├── attrs.go │ │ │ ├── derivations.go │ │ │ ├── hydra │ │ │ │ ├── api.go │ │ │ │ └── import.go │ │ │ └── logs.go │ │ ├── lib │ │ │ └── lib.go │ │ ├── refcount │ │ │ └── refcount.go │ │ └── server │ │ │ ├── api.go │ │ │ └── diff.go │ ├── main.go │ ├── mk-proto │ ├── nixos │ │ └── default.nix │ ├── reprod-api │ │ ├── api.pb.go │ │ ├── api.proto │ │ └── reprod_apiconnect │ │ │ └── api.connect.go │ ├── sql-cache │ │ ├── fs.go │ │ ├── queries │ │ │ └── diffoscope.sql │ │ └── schema │ │ │ └── 20221005142925_initial.sql │ ├── sql │ │ ├── fs.go │ │ ├── queries │ │ │ ├── derivations.sql │ │ │ ├── eval.sql │ │ │ ├── logs.sql │ │ │ ├── reprod.sql │ │ │ └── suggest.sql │ │ └── schema │ │ │ ├── 20220818142927_initial.sql │ │ │ └── 20220904150640_logs.sql │ └── sqlc.yaml ├── trustix-nix │ ├── .gitignore │ ├── Procfile │ ├── cmd │ │ ├── auth.go │ │ ├── binary-cache-proxy.go │ │ ├── lib.go │ │ ├── post-build-hook.go │ │ ├── root.go │ │ └── submit-closure.go │ ├── default.nix │ ├── dev │ │ ├── cache-priv-key.pem │ │ └── cache-pub-key.pem │ ├── go.mod │ ├── go.sum │ ├── gomod2nix.toml │ ├── main.go │ ├── nar │ │ ├── nar.go │ │ └── nar_test.go │ ├── nixos │ │ ├── binarycache.nix │ │ ├── default.nix │ │ └── post-build-hook.nix │ └── schema │ │ └── narinfo.go ├── trustix-proto │ ├── .gitignore │ ├── Makefile │ ├── Procfile │ ├── api │ │ ├── api.pb.go │ │ ├── api.proto │ │ └── apiconnect │ │ │ └── api.connect.go │ ├── doc.md │ ├── go.mod │ ├── go.sum │ ├── gomod2nix.toml │ ├── protocols │ │ └── protocols.go │ ├── rpc │ │ ├── rpc.pb.go │ │ ├── rpc.proto │ │ └── rpcconnect │ │ │ └── rpc.connect.go │ └── schema │ │ ├── loghead.pb.go │ │ ├── loghead.proto │ │ ├── logleaf.pb.go │ │ ├── logleaf.proto │ │ ├── mapentry.pb.go │ │ ├── mapentry.proto │ │ ├── queue.pb.go │ │ └── queue.proto ├── trustix │ ├── .gitignore │ ├── Procfile │ ├── auth │ │ ├── auth.go │ │ └── token.go │ ├── client │ │ ├── client.go │ │ ├── conn.go │ │ ├── connect_logapi.go │ │ ├── connect_logrpc.go │ │ ├── connect_nodeapi.go │ │ └── connect_rpcapi.go │ ├── config.toml │ ├── default.nix │ ├── dev │ │ ├── priv │ │ ├── pub │ │ ├── token-priv │ │ └── token-pub │ ├── go.mod │ ├── go.sum │ ├── gomod2nix.toml │ ├── interfaces │ │ ├── api.go │ │ └── rpc.go │ ├── internal │ │ ├── api │ │ │ ├── kvstore_log.go │ │ │ ├── kvstore_node.go │ │ │ └── log.go │ │ ├── cmd │ │ │ ├── auth.go │ │ │ ├── daemon.go │ │ │ ├── decide.go │ │ │ ├── doc.go │ │ │ ├── flush.go │ │ │ ├── generatekey.go │ │ │ ├── generatetoken.go │ │ │ ├── printlogid.go │ │ │ ├── query.go │ │ │ ├── root.go │ │ │ ├── submit.go │ │ │ └── value.go │ │ ├── config │ │ │ ├── config.go │ │ │ ├── config_test.go │ │ │ ├── decider │ │ │ │ ├── js.go │ │ │ │ ├── logid.go │ │ │ │ ├── percentage.go │ │ │ │ └── selector.go │ │ │ ├── errors.go │ │ │ ├── fixtures │ │ │ │ └── example.toml │ │ │ ├── pubkey.go │ │ │ ├── publisher.go │ │ │ ├── signer │ │ │ │ └── signer.go │ │ │ ├── storage.go │ │ │ └── subscriber.go │ │ ├── constants │ │ │ └── constants.go │ │ ├── decider │ │ │ ├── agg.go │ │ │ ├── agg_test.go │ │ │ ├── js.go │ │ │ ├── js_test.go │ │ │ ├── logid.go │ │ │ ├── logid_test.go │ │ │ ├── main.go │ │ │ ├── percentage.go │ │ │ └── percentage_test.go │ │ ├── lib │ │ │ └── closer.go │ │ ├── log │ │ │ ├── leaf.go │ │ │ ├── lib.go │ │ │ ├── log.go │ │ │ ├── log_test.go │ │ │ ├── proof.go │ │ │ └── storage.go │ │ ├── pool │ │ │ └── pool.go │ │ ├── publisher │ │ │ ├── map.go │ │ │ └── pub.go │ │ ├── server │ │ │ ├── lib.go │ │ │ ├── log.go │ │ │ ├── logrpc.go │ │ │ ├── node.go │ │ │ └── rpc.go │ │ ├── signer │ │ │ ├── ed25519.go │ │ │ ├── ed25519_test.go │ │ │ ├── fixtures │ │ │ │ ├── priv │ │ │ │ └── pub │ │ │ ├── lib.go │ │ │ └── struct.go │ │ ├── sth │ │ │ └── sth.go │ │ ├── sthsync │ │ │ └── sync.go │ │ └── storage │ │ │ ├── bucket.go │ │ │ ├── errors.go │ │ │ ├── helpers.go │ │ │ ├── interface.go │ │ │ ├── memory.go │ │ │ └── native.go │ ├── main.go │ ├── nixos │ │ ├── default.nix │ │ └── test.nix │ └── tests │ │ ├── compare-fixtures │ │ ├── log-agg │ │ │ ├── config.toml │ │ │ ├── priv │ │ │ └── pub │ │ ├── log1 │ │ │ ├── config.toml │ │ │ ├── priv │ │ │ └── pub │ │ ├── log2 │ │ │ ├── config.toml │ │ │ ├── priv │ │ │ └── pub │ │ └── log3 │ │ │ ├── config.toml │ │ │ ├── priv │ │ │ └── pub │ │ ├── config-simple.toml │ │ ├── default.nix │ │ └── fixtures │ │ ├── priv │ │ └── pub └── unixtransport │ ├── .github │ └── workflows │ │ └── test.yaml │ ├── .gitignore │ ├── README.md │ ├── go.mod │ ├── register.go │ └── register_test.go ├── renovate.json └── tools ├── bump_go └── wait_for_file /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | watch_file flake.nix 3 | watch_file flake.lock 4 | -------------------------------------------------------------------------------- /.github/passthru.nix: -------------------------------------------------------------------------------- 1 | # Find all passthru.tests and return them as a list of full attribute paths 2 | builtins.toJSON ( 3 | let 4 | p = import ../. { }; 5 | in 6 | builtins.foldl' 7 | (acc: v: 8 | let 9 | tests = builtins.attrNames (p.${v}.passthru.tests or { }); 10 | in 11 | acc ++ map (t: "${v}.passthru.tests.${t}") tests) [ ] 12 | (builtins.attrNames p) 13 | ) 14 | -------------------------------------------------------------------------------- /.github/workflows/doc.yml: -------------------------------------------------------------------------------- 1 | name: Build/Deploy GH Pages 2 | 3 | on: 4 | push: 5 | branches: master 6 | 7 | jobs: 8 | docs: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | 13 | - uses: cachix/install-nix-action@v27 14 | with: 15 | nix_path: nixpkgs=channel:nixos-unstable 16 | 17 | - uses: cachix/cachix-action@v15 18 | with: 19 | name: nix-community 20 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 21 | 22 | # Docs 23 | - name: build-doc 24 | run: nix build -L .#trustix-doc 25 | 26 | - name: deploy-doc 27 | uses: peaceiris/actions-gh-pages@v4 28 | if: github.ref == 'refs/heads/master' 29 | with: 30 | github_token: ${{ secrets.GITHUB_TOKEN }} 31 | publish_dir: ./result 32 | -------------------------------------------------------------------------------- /.github/workflows/nix-github-actions.yml: -------------------------------------------------------------------------------- 1 | name: Nix Flake actions 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | - main 9 | 10 | jobs: 11 | nix-matrix: 12 | runs-on: ubuntu-latest 13 | outputs: 14 | matrix: ${{ steps.set-matrix.outputs.matrix }} 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: cachix/install-nix-action@v27 18 | - id: set-matrix 19 | name: Generate Nix Matrix 20 | run: | 21 | set -Eeu 22 | echo "matrix=$(nix eval --json '.#githubActions.matrix')" >> "$GITHUB_OUTPUT" 23 | 24 | nix-build: 25 | needs: nix-matrix 26 | runs-on: ${{ matrix.os }} 27 | strategy: 28 | matrix: ${{fromJSON(needs.nix-matrix.outputs.matrix)}} 29 | steps: 30 | - uses: actions/checkout@v4 31 | - uses: cachix/install-nix-action@v27 32 | - run: mkdir -p ~/.config/nix && echo "system-features = kvm nixos-test" >> ~/.config/nix/nix.conf 33 | - run: nix build -L ".#${{ matrix.attr }}" 34 | 35 | # Check gomod2nix up to date 36 | gomod2nix: 37 | runs-on: ubuntu-latest 38 | steps: 39 | - uses: actions/checkout@v4 40 | - uses: cachix/install-nix-action@v27 41 | with: 42 | nix_path: nixpkgs=channel:nixos-unstable 43 | - uses: cachix/cachix-action@v15 44 | with: 45 | name: nix-community 46 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 47 | - name: gomod2nix 48 | run: nix develop -c ./checks/gomod2nix 49 | 50 | golangci-lint: 51 | runs-on: ubuntu-latest 52 | steps: 53 | - uses: actions/checkout@v4 54 | - uses: cachix/install-nix-action@v27 55 | with: 56 | nix_path: nixpkgs=channel:nixos-unstable 57 | - uses: cachix/cachix-action@v15 58 | with: 59 | name: nix-community 60 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 61 | - name: golangci-lint 62 | run: nix develop -c ./checks/golangci-lint 63 | 64 | collect: 65 | runs-on: ubuntu-latest 66 | needs: 67 | - nix-build 68 | - gomod2nix 69 | - golangci-lint 70 | steps: 71 | - run: exit 0 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .direnv 2 | result* 3 | /state 4 | *.sqlite3 5 | __pycache__ 6 | nixos.qcow2 7 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: automatic merge for Renovate pull requests 3 | conditions: 4 | - author=renovate[bot] 5 | - check-success=collect 6 | actions: 7 | merge: 8 | method: rebase 9 | -------------------------------------------------------------------------------- /LICENSES/LicenseRef-all-rights-reserved.txt: -------------------------------------------------------------------------------- 1 | Copyright (C), All rights reserved 2 | -------------------------------------------------------------------------------- /LICENSES/MIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | trustix: bash -c "cd packages/trustix && hivemind" 2 | trustix-nix: bash -c "./tools/wait_for_file $TRUSTIX_RPC && cd packages/trustix-nix && hivemind" 3 | trustix-nix-r13y: bash -c "cd packages/trustix-nix-r13y && hivemind" 4 | trustix-nix-r13y-web: bash -c "cd packages/trustix-nix-r13y-web && hivemind" 5 | trustix-proto: bash -c "cd packages/trustix-proto && hivemind" 6 | trustix-doc: bash -c "cd packages/trustix-doc && hivemind" 7 | -------------------------------------------------------------------------------- /assets/NGI0_tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/trustix/e99677b9295d169b44e136e3b9fc3251c360295e/assets/NGI0_tag.png -------------------------------------------------------------------------------- /assets/nlnet-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/trustix/e99677b9295d169b44e136e3b9fc3251c360295e/assets/nlnet-banner.png -------------------------------------------------------------------------------- /assets/tweag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/trustix/e99677b9295d169b44e136e3b9fc3251c360295e/assets/tweag.png -------------------------------------------------------------------------------- /checks/golangci-lint: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright © 2020-2022 The Trustix Authors 4 | # 5 | # SPDX-License-Identifier: MIT 6 | 7 | set -euo pipefail 8 | 9 | args="./... --out-format github-actions" 10 | 11 | ls ./packages/*/go.mod | xargs dirname | while read pkgdir; do 12 | echo "Checking $pkgdir" 13 | bash -c "cd $pkgdir && golangci-lint run --timeout 15m0s $args" 14 | done 15 | -------------------------------------------------------------------------------- /checks/gomod2nix: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright © 2020-2022 The Trustix Authors 4 | # 5 | # SPDX-License-Identifier: MIT 6 | 7 | # Check if all gomod2nix.toml files are up to date 8 | set -euo pipefail 9 | 10 | ls ./packages/*/gomod2nix.toml | xargs dirname | while read pkgdir; do 11 | bash -c "cd $pkgdir && gomod2nix generate" 12 | done 13 | 14 | git diff --exit-code 15 | -------------------------------------------------------------------------------- /dev/treefmt.nix: -------------------------------------------------------------------------------- 1 | { 2 | # Used to find the project root 3 | projectRootFile = "flake.lock"; 4 | 5 | programs.nixpkgs-fmt.enable = true; 6 | programs.gofmt.enable = true; 7 | 8 | programs.clang-format.enable = true; 9 | settings.formatter.clang-format.includes = [ 10 | "*.proto" 11 | ]; 12 | } 13 | -------------------------------------------------------------------------------- /examples-old/colmena/secrets/log-priv: -------------------------------------------------------------------------------- 1 | D78e/VtuDLBdcJy65ekU8ZSNlyWbtWOUMh5ZRdp+tzi7pc4++cknt/D3RG4K3Whi9YEddbHFgFnvg3BeNkkWuA== -------------------------------------------------------------------------------- /examples-old/colmena/secrets/log-pub: -------------------------------------------------------------------------------- 1 | u6XOPvnJJ7fw90RuCt1oYvWBHXWxxYBZ74NwXjZJFrg= -------------------------------------------------------------------------------- /examples-old/nixops-deployment.nix: -------------------------------------------------------------------------------- 1 | { 2 | 3 | network.description = "Example Trustix NixOps deployment"; 4 | 5 | publisher_server = 6 | { resources, ... }: 7 | { 8 | 9 | # Add the root-level NixOS module 10 | imports = [ 11 | /path/to/trustix/git/checkout/nixos 12 | ]; 13 | 14 | services.trustix = { 15 | enable = true; 16 | 17 | signer.snakeoil = { 18 | type = "ed25519"; 19 | ed25519 = { 20 | # Keys from deployment.keys are stored under /run/ on a temporary filesystem and will not persist across a reboot. 21 | private-key-path = "/run/keys/trustix-priv"; 22 | }; 23 | }; 24 | 25 | publishers = [ 26 | { 27 | signer = "snakeoil"; 28 | protocol = "nix"; 29 | key = { 30 | type = "ed25519"; 31 | # Contents of the generated trustix-pub 32 | pub = "2uy8gNIOYEewTiV7iB7cUxBGpXxQtdlFepFoRvJTCJo="; 33 | }; 34 | } 35 | ]; 36 | }; 37 | 38 | # Push local builds via the post-build hook 39 | services.trustix-nix-build-hook.enable = true; 40 | 41 | deployment = { 42 | # Replace with your desired deployment target 43 | # For example ec2/gcp 44 | # 45 | # targetHost = "10.0.0.1"; 46 | 47 | # Upload keys to the remote 48 | keys = { 49 | trustix-priv.keyFile = "./trustix-priv"; 50 | }; 51 | }; 52 | }; 53 | 54 | subscriber_server = 55 | { resources, ... }: 56 | { 57 | 58 | services.trustix = { 59 | enable = true; 60 | 61 | subscribers = [ 62 | { 63 | protocol = "nix"; 64 | key = { 65 | type = "ed25519"; 66 | # Contents of the generated trustix-pub 67 | pub = "2uy8gNIOYEewTiV7iB7cUxBGpXxQtdlFepFoRvJTCJo="; 68 | }; 69 | } 70 | ]; 71 | 72 | # A remote can expose many logs and they are not neccesarily created by the remote in question 73 | remotes = [ 74 | "grpc+http://10.0.0.1" 75 | ]; 76 | 77 | }; 78 | 79 | deployment = { 80 | # Replace with your desired deployment target 81 | # For example ec2/gcp 82 | # 83 | # targetHost = "10.0.0.2"; 84 | }; 85 | 86 | }; 87 | 88 | } 89 | -------------------------------------------------------------------------------- /examples-old/nixos-shell.nix: -------------------------------------------------------------------------------- 1 | let 2 | pubKey = "fG7JEPzIsr2mlSx5Xeh02BbJ4uzGpm5IE3aSGhS1UKo="; 3 | in 4 | { config, pkgs, ... }: { 5 | imports = [ 6 | ../packages/trustix/nixos 7 | ../packages/trustix-nix/nixos 8 | ]; 9 | 10 | # # TODO: for some reason setting nixpkgs.pkgs directly causes problems with nixos-shell 11 | # # so instead we copy over the overlays and config, but the pinned nixpkgs does not carry over here 12 | # # nixpkgs.pkgs = import ../pkgs.nix {}; 13 | # nixpkgs = { 14 | # inherit (import ../pkgs.nix { }) overlays config; 15 | # }; 16 | 17 | services.trustix = { 18 | enable = true; 19 | 20 | signers.snakeoil = { 21 | type = "ed25519"; 22 | ed25519 = { 23 | # for testing this is fine, but in practice this should 24 | # be managed as a secret, and not put into the nix store 25 | private-key-path = pkgs.writeText "privkey" '' 26 | DyWQaOanQ64NU+k3dpp68/ABjFupTW941htRLRUCRdF8bskQ/MiyvaaVLHld6HTYFsni7MambkgTdpIaFLVQqg== 27 | ''; 28 | }; 29 | }; 30 | 31 | publishers = [{ 32 | signer = "snakeoil"; 33 | protocol = "nix"; 34 | publicKey.key = pubKey; 35 | }]; 36 | }; 37 | 38 | services.trustix-nix-build-hook = { 39 | enable = true; 40 | publisher = builtins.head config.services.trustix.publishers; 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /examples/01_basic/configuration.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, lib, ... }: 2 | { 3 | services.trustix = { 4 | enable = true; 5 | 6 | # Trustix differentiates between the concepts of a "signer" and a "publisher". 7 | # A signer refers to a private key implementation. 8 | # These can be file based or use hardware tokens. 9 | signers.my-signer = { 10 | type = "ed25519"; 11 | # Configuring the private key like this by path is bad practice because the key ends up world readable in /nix/store. 12 | # You should either: 13 | # - Put the key in a persistent path and reference it like: `ed25519.private-key-path = "/path/to/key"` 14 | # - Use a secrets management solution like sops-nix or agenix. 15 | ed25519.private-key-path = ./secrets/log-priv; 16 | }; 17 | 18 | publishers = [ 19 | { 20 | # Use the key configured above 21 | signer = "my-signer"; 22 | 23 | # Trustix is built first and foremost for Nix, but could also be used for verifying other package ecosystems. 24 | protocol = "nix"; 25 | 26 | # An arbitrary (string -> string) attrset with metadata about this log. 27 | # This isn't used by the Trustix logs but is used to inform the Nix binary cache proxy about possible substitution sources. 28 | meta = { 29 | upstream = "https://cache.nixos.org"; 30 | }; 31 | 32 | # The public key identifying this log. 33 | publicKey = { 34 | type = "ed25519"; 35 | key = builtins.readFile ./secrets/log-pub; 36 | }; 37 | } 38 | ]; 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /examples/01_basic/secrets/log-priv: -------------------------------------------------------------------------------- 1 | MOZW3HYsw97M+e+qqbgi0y8TYAMh4wSA53oWJildMX3lfzcO9D1HmNDAowACsG+lqj8tMAPY5YfrBBPtq1yz/g== -------------------------------------------------------------------------------- /examples/01_basic/secrets/log-pub: -------------------------------------------------------------------------------- 1 | 5X83DvQ9R5jQwKMAArBvpao/LTAD2OWH6wQT7atcs/4= -------------------------------------------------------------------------------- /examples/02_post_build/configuration.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, lib, ... }: 2 | { 3 | # Our basic Trustix configuration from before 4 | services.trustix = { 5 | enable = true; 6 | 7 | signers.my-signer = { 8 | type = "ed25519"; 9 | ed25519.private-key-path = ./secrets/log-priv; 10 | }; 11 | 12 | publishers = [ 13 | { 14 | signer = "my-signer"; 15 | protocol = "nix"; 16 | meta.upstream = "https://cache.nixos.org"; 17 | publicKey = { 18 | type = "ed25519"; 19 | key = builtins.readFile ./secrets/log-pub; 20 | }; 21 | } 22 | ]; 23 | }; 24 | 25 | # Enable the post build hook to push builds to the main Trustix daemon 26 | services.trustix-nix-build-hook = { 27 | enable = true; 28 | # Log id as returned by `trustix print-log-id --protocol nix --pubkey $(cat secrets/log-pub)` 29 | # This is your logs globally unique identifier and what clients will use to subscribe to your build results. 30 | logID = "0c7942343fa91b610704d531f552f3e785705dbd7d22c965bc0d58fa3ff2c87c"; 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /examples/02_post_build/secrets/log-priv: -------------------------------------------------------------------------------- 1 | MOZW3HYsw97M+e+qqbgi0y8TYAMh4wSA53oWJildMX3lfzcO9D1HmNDAowACsG+lqj8tMAPY5YfrBBPtq1yz/g== -------------------------------------------------------------------------------- /examples/02_post_build/secrets/log-pub: -------------------------------------------------------------------------------- 1 | 5X83DvQ9R5jQwKMAArBvpao/LTAD2OWH6wQT7atcs/4= -------------------------------------------------------------------------------- /nixos/default.nix: -------------------------------------------------------------------------------- 1 | flake: 2 | { config, lib, pkgs, ... }: 3 | 4 | { 5 | nixpkgs.overlays = [ 6 | (_: prev: builtins.removeAttrs (flake.packages.${prev.stdenv.targetPlatform.system} or { }) [ "default" ]) 7 | ]; 8 | 9 | imports = [ 10 | ../packages/trustix/nixos 11 | ../packages/trustix-nix/nixos 12 | ../packages/trustix-nix-r13y/nixos 13 | ]; 14 | } 15 | -------------------------------------------------------------------------------- /packages/go-lib/README.md: -------------------------------------------------------------------------------- 1 | # go-lib - A collection of useful Go utilities 2 | 3 | These utilities are in no way specific to Trustix but implements generally useful concepts. 4 | -------------------------------------------------------------------------------- /packages/go-lib/executor/executor.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 Tweag IO 2 | // Copyright © 2020-2022 The Trustix Authors 3 | // 4 | // SPDX-License-Identifier: MIT 5 | 6 | package executor 7 | 8 | import ( 9 | "sync" 10 | ) 11 | 12 | // ParallellExecutor - Execute callback functions in parallell 13 | type ParallellExecutor struct { 14 | errChan chan error 15 | wg *sync.WaitGroup 16 | mux *sync.Mutex 17 | 18 | // Error returned by Wait(), cached for other Wait() invocations 19 | err error 20 | done bool 21 | } 22 | 23 | func NewParallellExecutor() *ParallellExecutor { 24 | return &ParallellExecutor{ 25 | errChan: make(chan error), 26 | mux: new(sync.Mutex), 27 | wg: new(sync.WaitGroup), 28 | 29 | err: nil, 30 | done: false, 31 | } 32 | } 33 | 34 | func (e *ParallellExecutor) Add(fn func() error) error { 35 | if e.err != nil { 36 | return e.err 37 | } 38 | 39 | e.wg.Add(1) 40 | 41 | go func() { 42 | defer e.wg.Done() 43 | 44 | err := fn() 45 | if err != nil { 46 | e.errChan <- err 47 | } 48 | }() 49 | 50 | return nil 51 | } 52 | 53 | func (e *ParallellExecutor) Wait() error { 54 | e.mux.Lock() 55 | defer e.mux.Unlock() 56 | 57 | if e.done { 58 | return e.err 59 | } 60 | 61 | var err error 62 | 63 | // Ensure channel is closed 64 | go func() { 65 | e.wg.Wait() 66 | close(e.errChan) 67 | }() 68 | 69 | for err = range e.errChan { 70 | if err != nil { 71 | break 72 | } 73 | } 74 | 75 | e.done = true 76 | e.err = err 77 | 78 | return err 79 | } 80 | -------------------------------------------------------------------------------- /packages/go-lib/executor/limited.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020-2022 The Trustix Authors 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package executor 6 | 7 | import ( 8 | "sync" 9 | ) 10 | 11 | // LimitedParallellExecutor - Execute callback functions in parallell 12 | type LimitedParallellExecutor struct { 13 | wg *sync.WaitGroup 14 | mux *sync.Mutex 15 | guard chan struct{} 16 | 17 | // Error returned by Wait(), cached for other Wait() & Add() invocations 18 | err error 19 | done bool 20 | } 21 | 22 | func NewLimitedParallellExecutor(maxWorkers int) *LimitedParallellExecutor { 23 | e := &LimitedParallellExecutor{ 24 | mux: new(sync.Mutex), 25 | wg: new(sync.WaitGroup), 26 | guard: make(chan struct{}, maxWorkers), 27 | 28 | err: nil, 29 | done: false, 30 | } 31 | 32 | return e 33 | } 34 | 35 | func (e *LimitedParallellExecutor) Add(fn func() error) error { 36 | if e.err != nil { 37 | return e.err 38 | } 39 | 40 | e.wg.Add(1) 41 | 42 | e.guard <- struct{}{} // Block until a worker is available 43 | 44 | go func() { 45 | defer e.wg.Done() 46 | defer func() { 47 | <-e.guard 48 | }() 49 | 50 | err := fn() 51 | 52 | if err != nil && e.err == nil { 53 | e.mux.Lock() 54 | e.err = err 55 | e.mux.Unlock() 56 | } 57 | }() 58 | 59 | return nil 60 | } 61 | 62 | func (e *LimitedParallellExecutor) Wait() error { 63 | if e.done { 64 | return e.err 65 | } 66 | 67 | e.wg.Wait() 68 | 69 | e.done = true 70 | 71 | return e.err 72 | } 73 | -------------------------------------------------------------------------------- /packages/go-lib/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nix-community/trustix/packages/go-lib 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.0 7 | golang.org/x/exp v0.0.0-20231006140011-7918f672742d 8 | ) 9 | 10 | require ( 11 | github.com/davecgh/go-spew v1.1.1 // indirect 12 | github.com/pmezard/go-difflib v1.0.0 // indirect 13 | gopkg.in/yaml.v3 v3.0.1 // indirect 14 | ) 15 | -------------------------------------------------------------------------------- /packages/go-lib/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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 5 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 6 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 7 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 8 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 9 | github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= 10 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 11 | golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= 12 | golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= 13 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 14 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 15 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 16 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 17 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 18 | -------------------------------------------------------------------------------- /packages/go-lib/gomod2nix.toml: -------------------------------------------------------------------------------- 1 | schema = 3 2 | 3 | [mod] 4 | [mod."github.com/davecgh/go-spew"] 5 | version = "v1.1.1" 6 | hash = "sha256-nhzSUrE1fCkN0+RL04N4h8jWmRFPPPWbCuDc7Ss0akI=" 7 | [mod."github.com/pmezard/go-difflib"] 8 | version = "v1.0.0" 9 | hash = "sha256-/FtmHnaGjdvEIKAJtrUfEhV7EVo5A/eYrtdnUkuxLDA=" 10 | [mod."github.com/stretchr/testify"] 11 | version = "v1.8.0" 12 | hash = "sha256-LDxBAebK+A06y4vbH7cd1sVBOameIY81Xm8/9OPZh7o=" 13 | [mod."golang.org/x/exp"] 14 | version = "v0.0.0-20231006140011-7918f672742d" 15 | hash = "sha256-2SO1etTQ6UCUhADR5sgvDEDLHcj77pJKCIa/8mGDbAo=" 16 | [mod."gopkg.in/yaml.v3"] 17 | version = "v3.0.1" 18 | hash = "sha256-FqL9TKYJ0XkNwJFnq9j0VvJ5ZUU1RvH/52h/f5bkYAU=" 19 | -------------------------------------------------------------------------------- /packages/go-lib/safemap/map.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020-2022 The Trustix Authors 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package safemap 6 | 7 | import ( 8 | "errors" 9 | "sync" 10 | ) 11 | 12 | var ErrNotExist = errors.New("item does not exist") 13 | 14 | type SafeMap[K comparable, V any] struct { 15 | store map[K]V 16 | mux sync.RWMutex 17 | } 18 | 19 | func NewMap[K comparable, V any]() *SafeMap[K, V] { 20 | return &SafeMap[K, V]{ 21 | store: make(map[K]V), 22 | mux: sync.RWMutex{}, 23 | } 24 | } 25 | 26 | func (m *SafeMap[K, V]) Get(key K) (V, error) { 27 | m.mux.RLock() 28 | defer m.mux.RUnlock() 29 | 30 | value, ok := m.store[key] 31 | if !ok { 32 | return value, ErrNotExist 33 | } 34 | 35 | return value, nil 36 | } 37 | 38 | func (m *SafeMap[K, V]) Set(key K, value V) { 39 | m.mux.Lock() 40 | defer m.mux.Unlock() 41 | 42 | m.store[key] = value 43 | } 44 | 45 | func (m *SafeMap[K, V]) Has(key K) bool { 46 | m.mux.RLock() 47 | defer m.mux.RUnlock() 48 | 49 | _, ok := m.store[key] 50 | return ok 51 | } 52 | 53 | func (m *SafeMap[K, V]) Remove(key K) { 54 | m.mux.Lock() 55 | defer m.mux.Unlock() 56 | 57 | delete(m.store, key) 58 | } 59 | -------------------------------------------------------------------------------- /packages/go-lib/set/set_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020-2022 The Trustix Authors 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package set 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestAdd(t *testing.T) { 14 | set := NewSet[string]() 15 | set.Add("123") 16 | 17 | assert.NotNil(t, set.values["123"]) 18 | } 19 | 20 | func TestHas(t *testing.T) { 21 | set := NewSet[string]() 22 | set.Add("123") 23 | 24 | assert.Equal(t, set.Has("123"), true) 25 | assert.Equal(t, set.Has("1234"), false) 26 | } 27 | 28 | func TestRemove(t *testing.T) { 29 | set := NewSet[string]() 30 | 31 | set.Add("123") 32 | assert.Equal(t, set.Has("123"), true) 33 | 34 | set.Remove("123") 35 | assert.Equal(t, set.Has("123"), false) 36 | } 37 | 38 | func TestValues(t *testing.T) { 39 | set := NewSet[string]() 40 | 41 | // Add set members out of order to also test stable output order of Values() 42 | set.Add("321") 43 | set.Add("123") 44 | 45 | values := set.Values() 46 | 47 | assert.Equal(t, len(values), 2) 48 | assert.Equal(t, values[0], "123") 49 | assert.Equal(t, values[1], "321") 50 | } 51 | 52 | func TestUnion(t *testing.T) { 53 | a := NewSet[string]() 54 | a.Add("A") 55 | 56 | b := NewSet[string]() 57 | b.Add("B") 58 | 59 | u := a.Union(b) 60 | 61 | uv := u.Values() 62 | assert.Equal(t, len(uv), 2) 63 | 64 | assert.Equal(t, uv[0], "A") 65 | assert.Equal(t, uv[1], "B") 66 | } 67 | 68 | func TestDiff(t *testing.T) { 69 | a := NewSet[string]() 70 | a.Add("A") 71 | 72 | b := NewSet[string]() 73 | b.Add("A") 74 | b.Add("B") 75 | 76 | d := b.Diff(a) 77 | 78 | dv := d.Values() 79 | assert.Equal(t, len(dv), 1) 80 | 81 | assert.Equal(t, dv[0], "B") 82 | } 83 | 84 | func TestCopy(t *testing.T) { 85 | a := NewSet[string]() 86 | a.Add("A") 87 | a.Add("B") 88 | a.Add("C") 89 | 90 | b := a.Copy() 91 | 92 | assert.True(t, a != b) // Ensure different addr 93 | 94 | // Ensure no difference from copied set 95 | assert.Equal(t, len(a.Diff(b).Values()), 0) 96 | assert.Equal(t, len(b.Diff(a).Values()), 0) 97 | } 98 | 99 | func TestUpdate(t *testing.T) { 100 | a := NewSet[string]() 101 | a.Add("A") 102 | 103 | b := NewSet[string]() 104 | b.Add("B") 105 | b.Add("C") 106 | 107 | a.Update(b) 108 | 109 | values := a.Values() 110 | assert.Equal(t, len(values), 3) 111 | 112 | assert.Equal(t, values[0], "A") 113 | assert.Equal(t, values[1], "B") 114 | assert.Equal(t, values[2], "C") 115 | } 116 | -------------------------------------------------------------------------------- /packages/trustix-doc/.gitignore: -------------------------------------------------------------------------------- 1 | book 2 | -------------------------------------------------------------------------------- /packages/trustix-doc/Procfile: -------------------------------------------------------------------------------- 1 | serve: mdbook serve 2 | -------------------------------------------------------------------------------- /packages/trustix-doc/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["adisbladis"] 3 | language = "en" 4 | multilingual = false 5 | src = "src" 6 | title = "Trustix Doc" 7 | -------------------------------------------------------------------------------- /packages/trustix-doc/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs 2 | , lib 3 | }: 4 | 5 | pkgs.stdenv.mkDerivation { 6 | pname = "trustix-doc"; 7 | version = "dev"; 8 | 9 | src = ../..; 10 | 11 | nativeBuildInputs = [ 12 | pkgs.mdbook 13 | ]; 14 | 15 | buildPhase = '' 16 | runHook preBuild 17 | 18 | cd packages/trustix-doc 19 | mdbook build 20 | 21 | runHook postBuild 22 | ''; 23 | 24 | installPhase = '' 25 | mv book $out 26 | ''; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /packages/trustix-doc/doc_old/.gitignore: -------------------------------------------------------------------------------- 1 | *.pdf 2 | *.latex 3 | -------------------------------------------------------------------------------- /packages/trustix-doc/doc_old/Makefile: -------------------------------------------------------------------------------- 1 | all: build 2 | 3 | puml: 4 | plantuml *.puml -tlatex:nopreamble 5 | 6 | pdf: 7 | pandoc comparison.md -f markdown -t latex -o comparison.pdf --filter pandoc-citeproc --bibliography=references.bib --csl=numeric.csl 8 | 9 | build: pdf puml 10 | 11 | clean: 12 | rm -f *.tex *.pdf *.png *.svg 13 | -------------------------------------------------------------------------------- /packages/trustix-doc/doc_old/references.bib: -------------------------------------------------------------------------------- 1 | @book{dolstra2006purely, 2 | title={The purely functional software deployment model}, 3 | author={Dolstra, Eelco}, 4 | year={2006}, 5 | publisher={Utrecht University} 6 | } 7 | -------------------------------------------------------------------------------- /packages/trustix-doc/doc_old/shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import { } }: 2 | let 3 | tl = (pkgs.texlive.combine { 4 | inherit (pkgs.texlive) scheme-medium wrapfig ulem capt-of 5 | titlesec preprint enumitem paralist ctex environ svg 6 | beamer trimspaces zhnumber changepage framed pdfpages 7 | fvextra minted upquote ifplatform xstring; 8 | }); 9 | 10 | pythonEnv = pkgs.python3.withPackages (ps: [ 11 | ps.pygments 12 | ]); 13 | 14 | in 15 | pkgs.mkShell { 16 | buildInputs = [ 17 | pythonEnv 18 | pkgs.pandoc 19 | pkgs.haskellPackages.pandoc-citeproc 20 | pkgs.haskellPackages.pandoc-crossref 21 | pkgs.plantuml 22 | tl 23 | ]; 24 | } 25 | -------------------------------------------------------------------------------- /packages/trustix-doc/doc_old/trustix-gossip.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | skinparam sequenceMessageAlign center 3 | skinparam padding 2 4 | skinparam ParticipantPadding 10 5 | skinparam BoxPadding 20 6 | 7 | title Trustix gossip hub submission flow 8 | 9 | participant User 10 | participant Nix 11 | participant "Trustix Log" as Trustix 12 | participant "Gossip hub" as GossipHub 13 | 14 | User-->Nix: Instantiate `hello` from nixpkgs with git sha ff00ff 15 | User<--Nix: /nix/store/lzq1bv4y9zjr75rj7b4lixkf4l3ac0lr-hello-2.10.drv 16 | 17 | User-->Nix: Realise (substitute) /nix/store/lzq1bv4y9zjr75rj7b4lixkf4l3ac0lr-hello-2.10.drv\n (store hash 5rxgjmfa79psrfa6ynl7agywg3q1mavn) 18 | 19 | Nix-->User: Return OK 20 | 21 | User-->GossipHub: Push "I observed output hash for store hash 5rxgjmfa79psrfa6ynl7agywg3q1mavn" 22 | GossipHub-->GossipHub: Publish Signed Tree Head (STH) in Gossip Hub log 23 | 24 | @enduml 25 | -------------------------------------------------------------------------------- /packages/trustix-doc/doc_old/trustix-submission.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | skinparam sequenceMessageAlign center 3 | skinparam padding 2 4 | 5 | title Trustix log submission flow 6 | 7 | participant User 8 | participant Nix 9 | participant "Trustix post-build hook" as BuildHook 10 | participant "Trustix Log" as Trustix 11 | 12 | User-->Nix: Instantiate `hello` from nixpkgs with git sha ff00ff 13 | User<--Nix: /nix/store/lzq1bv4y9zjr75rj7b4lixkf4l3ac0lr-hello-2.10.drv 14 | 15 | User-->Nix: Realise (build) /nix/store/lzq1bv4y9zjr75rj7b4lixkf4l3ac0lr-hello-2.10.drv\n (store hash 5rxgjmfa79psrfa6ynl7agywg3q1mavn) 16 | 17 | Nix-->BuildHook: Submit 5rxgjmfa79psrfa6ynl7agywg3q1mavn 18 | 19 | BuildHook-->Trustix: Submit store hash 5rxgjmfa with output hash 0v1pkm7xg0gp5 20 | 21 | Trustix-->Trustix: Publish STH (sign log) 22 | 23 | Trustix-->BuildHook: OK 24 | BuildHook-->Nix: OK 25 | 26 | Nix-->User: Return OK 27 | 28 | @enduml 29 | -------------------------------------------------------------------------------- /packages/trustix-doc/doc_old/trustix-substitution.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | skinparam ParticipantPadding 0 3 | 4 | title Trustix user binary substitution flow 5 | 6 | participant User 7 | participant Nix 8 | participant Trustix 9 | participant "Trustix-builder1" as B1 10 | participant "Trustix-builder2" as B2 11 | participant "Trustix-builder3" as B3 12 | 13 | 14 | User-->Nix: Instantiate `hello` from nixpkgs with git sha ff00ff 15 | User<--Nix: /nix/store/lzq1bv4y9zjr75rj7b4lixkf4l3ac0lr-hello-2.10.drv 16 | 17 | User-->Nix: Realise (build) /nix/store/lzq1bv4y9zjr75rj7b4lixkf4l3ac0lr-hello-2.10.drv\n (store hash 5rxgjmfa79psrfa6ynl7agywg3q1mavn) 18 | 19 | Nix-->Trustix: Get narinfo for store hash 5rxgjmfa79psrfa6ynl7agywg3q1mavn 20 | 21 | Trustix-->B1: Give me the output hash of store hash 5rxgjmfa79psrfa6ynl7agywg3q1mavn 22 | B1-->Trustix: 201b6001a69044c84531db27ab6efb4d10ca2ef9b3976814666af90286043fa7 23 | deactivate B1 24 | 25 | Trustix-->B2: Give me the output hash of store hash 5rxgjmfa79psrfa6ynl7agywg3q1mavn 26 | B2-->Trustix: 201b6001a69044c84531db27ab6efb4d10ca2ef9b3976814666af90286043fa7 27 | deactivate B2 28 | 29 | Trustix-->B3: Give me the output hash of store hash 5rxgjmfa79psrfa6ynl7agywg3q1mavn 30 | B3-->Trustix: 201b6001a69044c84531db27ab6efb4d10ca2ef9b3976814666af90286043fa7 31 | deactivate B3 32 | 33 | Trustix-->Trustix: Is the hash 201b6001a69044c84531db27ab6efb4d10ca2ef9b3976814666af90286043fa7 \nreally the output for input hash 5rxgjmfa79psrfa6ynl7agywg3q1mavn ? 34 | 35 | alt Trustworthy build 36 | Trustix-->Nix: Return narinfo (NAR (Nix archive) meta information) including hash 37 | Nix-->Trustix: Download NAR 38 | Trustix-->B1: Download NAR 39 | Trustix-->Trustix: Verify NAR hash 40 | Trustix-->Nix: Return NAR 41 | Nix-->Nix: Install NAR into Nix store 42 | else Untrustworthy build 43 | Trustix-->Nix: Return 404 for narinfo 44 | Nix-->Nix: Build locally 45 | end 46 | 47 | Nix-->User: Return result 48 | 49 | @enduml 50 | -------------------------------------------------------------------------------- /packages/trustix-doc/src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [About](./about.md) 4 | 5 | - [Introduction](./intro.md) 6 | 7 | - [How to use Trustix with Nix](./howto-nix/index.md) 8 | - [Basic setup](./howto-nix/setup.md) 9 | - [Post build hook](./howto-nix/post-build-hook.md) 10 | - [Subscribing](./howto-nix/subscribing.md) 11 | - [Usage as a binary cache](./howto-nix/binarycache.md) 12 | 13 | - [Hacking](./hacking.md) 14 | 15 | - [API docs](./api.md) 16 | -------------------------------------------------------------------------------- /packages/trustix-doc/src/api.md: -------------------------------------------------------------------------------- 1 | {{#include ../../trustix-proto/doc.md}} 2 | -------------------------------------------------------------------------------- /packages/trustix-doc/src/binarycache.md: -------------------------------------------------------------------------------- 1 | # Usage as a binary cache 2 | -------------------------------------------------------------------------------- /packages/trustix-doc/src/howto-nix/binarycache.md: -------------------------------------------------------------------------------- 1 | # Trustix - Binary cache setup 2 | 3 | The easiest way to use Trustix is via the NixOS modules, though even they require some manual preparation in terms of generating keys. 4 | 5 | This document walks you through how to configure your local system as a binary cache. 6 | 7 | ## Requisites 8 | 9 | We are assuming you have already followed the steps to set up one or more subscribers to your local Trustix instance. 10 | 11 | - Generate a public/private keypair to use with your local binary cache. 12 | ``` sh 13 | $ nix-store --generate-binary-cache-key binarycache.example.com cache-priv-key.pem cache-pub-key.pem 14 | ``` 15 | 16 | - Move the keys somewhere persistent and safe 17 | Of course having keys around readable by anyone on the system is not a good idea, so we will move these somewhere safe. 18 | In this tutorial we are using `/var/trustix/keys` but you are free to use whatever you wish. 19 | A deployment tool like Colmena, Morph or NixOps is recommended to deal with secrets. 20 | 21 | `$ mv cache-priv-key.pem /var/trustix/keys/cache-priv-key.pem` 22 | 23 | ## Configuring 24 | 25 | - Add the binary cache to your `configuration.nix` 26 | ``` nix 27 | { pkgs, config, ... }: 28 | { 29 | 30 | # Enable the local binary cache server 31 | services.trustix-nix-cache = { 32 | enable = true; 33 | private-key = "/var/trustix/keys/cache-priv-key.pem"; 34 | port = 9001; 35 | }; 36 | 37 | # Configure Nix to use it 38 | nix = { 39 | binaryCaches = [ 40 | "http://localhost:9001" 41 | ]; 42 | binaryCachePublicKeys = [ 43 | "binarycache.example.com://06YZJreoL8n9IdDlhnA3t7uJmHUI/rIIy3uO4FHRY=" 44 | ]; 45 | }; 46 | 47 | # Configure your Trustix daemon with a decision making process on how 48 | # to determine if a build is trustworthy or not. 49 | # 50 | # In this case we configure it to have at least 2/3 majority to be substituted. 51 | # 52 | # Note that this configuration is incomplete and assumes you have already set up a subscriber. 53 | services.trustix = { 54 | deciders.nix = [ 55 | { 56 | engine = "percentage"; 57 | percentage.minimum = 66; 58 | } 59 | ]; 60 | }; 61 | 62 | } 63 | ``` 64 | 65 | You are now all set up to use Trustix as a substitution method! 66 | -------------------------------------------------------------------------------- /packages/trustix-doc/src/howto-nix/builder-colmena-nixos.md: -------------------------------------------------------------------------------- 1 | # Builder setup (using Colmena) 2 | -------------------------------------------------------------------------------- /packages/trustix-doc/src/howto-nix/index.md: -------------------------------------------------------------------------------- 1 | # Trustix - End to end Nix howto's 2 | 3 | Up until now we have talked about components in isolation, let's go through some practical examples of how to deploy your own Trustix nodes. 4 | -------------------------------------------------------------------------------- /packages/trustix-doc/src/howto-nix/post-build-hook.md: -------------------------------------------------------------------------------- 1 | # Trustix - Usage via Nix 2 | 3 | In the previous chapter we set up the main Trustix daemon. It's now time to actually start using it to publish build results. 4 | 5 | ## Requisites 6 | - A NixOS installation using Flakes 7 | - The basic setup from the previous chapter 8 | 9 | ## Setup 10 | - `configuration.nix`: 11 | ``` nix 12 | {{#include ../../../../examples/02_post_build/configuration.nix}} 13 | ``` 14 | 15 | ## Effect 16 | This sets up Nix with a post build hook that publishes any builds performed locally to your locally running log. 17 | -------------------------------------------------------------------------------- /packages/trustix-doc/src/howto-nix/setup.md: -------------------------------------------------------------------------------- 1 | # Trustix - Usage via Nix 2 | 3 | The easiest way to use Trustix is via the NixOS modules, though even they require some manual preparation in terms of generating keys. 4 | 5 | This document will guide you through the very basic NixOS setup required both by log clients and log publishers. 6 | 7 | How to actually publish/subscribe are laid out in other documents. 8 | 9 | ## Requisites 10 | - A NixOS installation using Flakes 11 | 12 | ## Create keys 13 | 14 | All Trustix build logs are first and foremost identified by their key pair, which will be the first thing we have to generate. 15 | 16 | Let's start by generating a key pair for our log: 17 | ``` 18 | $ mkdir secrets 19 | $ nix run github:nix-community/trustix#trustix -- generate-key --privkey secrets/log-priv --pubkey secrets/log-pub 20 | ``` 21 | 22 | Additionally logs are identified not just by their key, but how that key is used. 23 | If a key is used for multiple protocols (not just Nix) those logs will have a different ID. 24 | This ID is what _subscribers_ use to indicate what they want to subscribe to. 25 | 26 | To find out the log ID for the key pair you just generated: 27 | `$ nix run github:nix-community/trustix#trustix -- print-log-id --protocol nix --pubkey $(cat secrets/log-pub)` 28 | 29 | ## Flakes 30 | 31 | - `flake.nix` 32 | ``` nix 33 | { 34 | inputs = { 35 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 36 | 37 | trustix = { 38 | url = "github:nix-community/trustix"; 39 | inputs.nixpkgs.follows = "nixpkgs"; 40 | }; 41 | }; 42 | outputs = { nixpkgs, flake-utils, trustix, ... }: { 43 | nixosConfigurations.trustix-example = nixpkgs.lib.nixosSystem { 44 | system = "x86_64-linux"; 45 | modules = 46 | [ ({ pkgs, ... }: { 47 | # import trustix modules 48 | imports = [ 49 | trustix.nixosModules.trustix 50 | ./configuration.nix 51 | ]; 52 | }) 53 | ]; 54 | }; 55 | 56 | }; 57 | } 58 | ``` 59 | 60 | - `configuration.nix`: 61 | ``` nix 62 | {{#include ../../../../examples/01_basic/configuration.nix}} 63 | ``` 64 | 65 | ## Effect 66 | This will set up an instance of Trustix on your system. 67 | In the next chapter we will look at using the post build hook to publish results to our local log. 68 | -------------------------------------------------------------------------------- /packages/trustix-doc/src/howto-nix/subscribing.md: -------------------------------------------------------------------------------- 1 | # Trustix - Subscribing 2 | This document walks you through how to subscribe to an already published binary cache. 3 | 4 | ## Requisites 5 | - A local Trustix instance 6 | - A remote log's metadata 7 | - Public key 8 | - URL 9 | 10 | ## Configuring 11 | 12 | - Add log(s) to your `configuration.nix` 13 | ``` nix 14 | { pkgs, config, ... }: 15 | { 16 | 17 | services.trustix = { 18 | enable = true; 19 | 20 | subscribers = [ 21 | { 22 | protocol = "nix"; 23 | publicKey = { 24 | type = "ed25519"; 25 | key = "2uy8gNIOYEewTiV7iB7cUxBGpXxQtdlFepFoRvJTCJo="; 26 | }; 27 | } 28 | ]; 29 | 30 | # A remote can expose many logs and they are not neccesarily created by the remote in question 31 | remotes = [ 32 | "https://demo.trustix.dev" 33 | ]; 34 | 35 | }; 36 | 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist 2 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | module.exports = { 3 | env: { 4 | browser: true, 5 | es2021: true, 6 | }, 7 | extends: [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/recommended", 10 | "plugin:solid/recommended", 11 | "plugin:sonarjs/recommended", 12 | ], 13 | overrides: [], 14 | parser: "@typescript-eslint/parser", 15 | parserOptions: { 16 | ecmaVersion: "latest", 17 | sourceType: "module", 18 | }, 19 | plugins: ["@typescript-eslint", "solid", "sonarjs"], 20 | rules: {}, 21 | }; 22 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/.prettierignore: -------------------------------------------------------------------------------- 1 | build 2 | coverage 3 | dist 4 | result 5 | src/api/*.ts 6 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "all" 3 | } 4 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/Procfile: -------------------------------------------------------------------------------- 1 | serve: npm run dev 2 | proto: (proto_script=$(readlink -f ./mk-proto); cd ../trustix-nix-r13y/reprod-api && reflex -r '\.proto$' "$proto_script") 3 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/README.md: -------------------------------------------------------------------------------- 1 | ## Usage 2 | 3 | Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`. 4 | 5 | This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely be removed once you clone a template. 6 | 7 | ```bash 8 | $ npm install # or pnpm install or yarn install 9 | ``` 10 | 11 | ### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs) 12 | 13 | ## Available Scripts 14 | 15 | In the project directory, you can run: 16 | 17 | ### `npm dev` or `npm start` 18 | 19 | Runs the app in the development mode.
20 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 21 | 22 | The page will reload if you make edits.
23 | 24 | ### `npm run build` 25 | 26 | Builds the app for production to the `dist` folder.
27 | It correctly bundles Solid in production mode and optimizes the build for the best performance. 28 | 29 | The build is minified and the filenames include the hashes.
30 | Your app is ready to be deployed! 31 | 32 | ## Deployment 33 | 34 | You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.) 35 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, buildNodeModules, lib, nodejs, npmHooks }: 2 | 3 | stdenv.mkDerivation { 4 | pname = "trustix-nix-r13y-web"; 5 | version = "0.1.0"; 6 | 7 | src = ./.; 8 | 9 | nativeBuildInputs = [ 10 | buildNodeModules.hooks.npmConfigHook 11 | nodejs 12 | npmHooks.npmInstallHook 13 | ]; 14 | 15 | nodeModules = buildNodeModules.fetchNodeModules { 16 | packageRoot = ./.; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/index.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Trustix r13y - Reproducibility tracking 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/mk-proto: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | cd "$(dirname "$0")" 4 | exec protoc -I ../trustix-nix-r13y/reprod-api \ 5 | --es_out src/api \ 6 | --es_opt target=ts \ 7 | --connect-es_out src/api \ 8 | --connect-es_opt target=ts \ 9 | ../trustix-nix-r13y/reprod-api/*.proto 10 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "trustix-nix-r13y-web", 3 | "version": "0.0.0", 4 | "description": "", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "serve": "vite preview" 9 | }, 10 | "license": "GPL-3.0-only", 11 | "devDependencies": { 12 | "@bufbuild/protoc-gen-es": "^1.4.1", 13 | "@types/lodash.clonedeep": "^4.5.7", 14 | "@types/lodash.merge": "^4.6.7", 15 | "@typescript-eslint/eslint-plugin": "^8.0.0", 16 | "@typescript-eslint/eslint-plugin-tslint": "^7.0.0", 17 | "@typescript-eslint/parser": "^8.0.0", 18 | "autoprefixer": "^10.4.8", 19 | "daisyui": "^4.0.0", 20 | "eslint": "^8.25.0", 21 | "eslint-plugin-solid": "^0.14.0", 22 | "eslint-plugin-sonarjs": "^1.0.0", 23 | "postcss": "^8.4.16", 24 | "prettier": "3.3.3", 25 | "tailwindcss": "^3.3.5", 26 | "typescript": "^5.2.2", 27 | "vite": "^5.0.0", 28 | "vite-plugin-eslint": "^1.8.1", 29 | "vite-plugin-solid": "^2.7.2", 30 | "@connectrpc/protoc-gen-connect-es": "^1.1.2" 31 | }, 32 | "dependencies": { 33 | "@bufbuild/protobuf": "^1.4.1", 34 | "@solidjs/router": "^0.14.0", 35 | "chart.js": "^4.4.0", 36 | "google-palette": "^1.1.0", 37 | "lodash.clonedeep": "^4.5.0", 38 | "lodash.merge": "^4.6.2", 39 | "solid-icons": "^1.1.0", 40 | "solid-js": "^1.5.1", 41 | "theme-change": "^2.5.0", 42 | "@connectrpc/connect-web": "^1.1.3", 43 | "@connectrpc/connect": "^1.1.3" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/postcss.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | module.exports = { 3 | purge: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"], 4 | plugins: { 5 | tailwindcss: {}, 6 | autoprefixer: {}, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/src/chart/README.md: -------------------------------------------------------------------------------- 1 | # This is a fork of https://github.com/MrFoxPro/solid-chart.js 2 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/src/chart/SolidChart.tsx: -------------------------------------------------------------------------------- 1 | // Copyright © 2020-2022 The Trustix Authors 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-only 4 | 5 | import { Chart, registerables } from "chart.js"; 6 | import { ComponentProps, createEffect, createSignal } from "solid-js"; 7 | import merge from "lodash.merge"; 8 | import deepClone from "lodash.clonedeep"; 9 | 10 | export type SolidChartProps = { 11 | canvasOptions?: ComponentProps<"canvas">; 12 | replace?: boolean; // set this to true if merging properties is not suitable (i.e. when you need to remove items or properties) 13 | } & Chart.ChartConfiguration; 14 | 15 | Chart.register(...registerables); 16 | 17 | const replaceChartProps = (props: { src: SolidChartProps; dest: Chart }) => { 18 | /* eslint-disable solid/reactivity */ 19 | const { src, dest } = props; 20 | for (const key in src) { 21 | if (key in dest) { 22 | dest[key] = src[key]; 23 | } 24 | } 25 | }; 26 | 27 | export function SolidChart(props: SolidChartProps) { 28 | const [canvas, setCanvas] = createSignal(null); 29 | const [chart, setChart] = createSignal(null); 30 | createEffect(() => { 31 | const el = canvas(); 32 | if (!el) return; 33 | const _chart = chart(); 34 | if (!_chart) { 35 | setChart(new Chart(el, deepClone(props))); 36 | return; 37 | } 38 | 39 | if (props.replace) { 40 | replaceChartProps({ src: props, dest: _chart.config }); 41 | } else { 42 | merge(_chart.config, deepClone(props)); 43 | } 44 | _chart.update(); 45 | }); 46 | function createChart(canvas: HTMLCanvasElement) { 47 | setTimeout(() => setCanvas(canvas)); 48 | } 49 | 50 | /* eslint-disable solid/reactivity */ 51 | return ; 52 | } 53 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/src/client.tsx: -------------------------------------------------------------------------------- 1 | // Copyright © 2020-2022 The Trustix Authors 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-only 4 | 5 | import { ReproducibilityAPI } from "./api/api_connectweb"; 6 | import { 7 | createPromiseClient, 8 | } from "@connectrpc/connect"; 9 | import { 10 | createConnectTransport, 11 | } from "@connectrpc/connect-web"; 12 | 13 | const client = createPromiseClient( 14 | ReproducibilityAPI, 15 | createConnectTransport({ 16 | baseUrl: "/api", 17 | }), 18 | ); 19 | 20 | export default client; 21 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/src/index.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2020-2022 The Trustix Authors 3 | * 4 | * SPDX-License-Identifier: GPL-3.0-only 5 | */ 6 | 7 | @tailwind base; 8 | @tailwind components; 9 | @tailwind utilities; 10 | 11 | .drv-card { 12 | width: 52rem; 13 | } 14 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/src/index.tsx: -------------------------------------------------------------------------------- 1 | // Copyright © 2020-2022 The Trustix Authors 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-only 4 | 5 | /* @refresh reload */ 6 | import "./index.css"; 7 | import { render } from "solid-js/web"; 8 | import { Router } from "@solidjs/router"; 9 | 10 | import App from "./App"; 11 | 12 | render( 13 | () => ( 14 | 15 | 16 | 17 | ), 18 | document.getElementById("root") as HTMLElement, 19 | ); 20 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/src/lib.tsx: -------------------------------------------------------------------------------- 1 | // Copyright © 2020-2022 The Trustix Authors 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-only 4 | 5 | export class NameValuePair { 6 | public name: string; 7 | public value: T; 8 | 9 | constructor(name: string, value: T) { 10 | this.name = name; 11 | this.value = value; 12 | } 13 | 14 | // Turn a map of objects into an array of name value pairs 15 | public static fromMap(values: { [key: string]: T }): NameValuePair[] { 16 | const arr: Array = []; 17 | 18 | Object.keys(values).forEach((key) => { 19 | const value = values[key]; 20 | arr.push(new NameValuePair(key, value)); 21 | }); 22 | 23 | return arr; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/trustix-nix-r13y-web/src/pages/diff.tsx: -------------------------------------------------------------------------------- 1 | // Copyright © 2020-2022 The Trustix Authors 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-only 4 | 5 | import { Component, createResource, Show, Suspense } from "solid-js"; 6 | import { useSearchParams } from "@solidjs/router"; 7 | 8 | import { DiffResponse, DiffRequest } from "../api/api_pb"; 9 | 10 | import { loading } from "../widgets"; 11 | 12 | import client from "../client"; 13 | 14 | const fetchDiff = async (params): DiffResponse => { 15 | const req = new DiffRequest(params); 16 | return await client.diff(req); 17 | }; 18 | 19 | const Diff: Component = () => { 20 | const [searchParams] = useSearchParams(); 21 | 22 | const [diff] = createResource(() => { 23 | for (const param of ["a", "b"]) { 24 | if (searchParams[param] == undefined) { 25 | throw `Missing search parameter: ${param}`; 26 | } 27 | } 28 | 29 | return { 30 | OutputHash1: searchParams.a, 31 | OutputHash2: searchParams.b, 32 | }; 33 | }, fetchDiff); 34 | 35 | return ( 36 | <> 37 | 38 | 39 |
40 |
41 |

Diffoscope

42 | 43 | {(() => { 44 | const iframe = ( 45 |