Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • privatestorage/PrivateStorageio
  • tomprince/PrivateStorageio
2 results
Show changes
Showing
with 545 additions and 112 deletions
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"description": "Watching the watchers",
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": 22,
"links": [],
"panels": [
{
"alert": {
"alertRuleTags": {},
"conditions": [
{
"evaluator": {
"params": [
0
],
"type": "gt"
},
"operator": {
"type": "and"
},
"query": {
"params": [
"A",
"5m",
"now"
]
},
"reducer": {
"params": [],
"type": "avg"
},
"type": "query"
}
],
"executionErrorState": "alerting",
"for": "5m",
"frequency": "1m",
"handler": 1,
"name": "Scraping down",
"noDataState": "ok",
"notifications": []
},
"aliasColors": {},
"bars": true,
"dashLength": 10,
"dashes": false,
"datasource": null,
"description": "Is Prometheus having problems scraping our instances? Should be zero.",
"fieldConfig": {
"defaults": {},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 6,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": false,
"linewidth": 1,
"nullPointMode": "null as zero",
"options": {
"alertThreshold": false
},
"percentage": false,
"pluginVersion": "7.5.10",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": true,
"steppedLine": false,
"targets": [
{
"exemplar": true,
"expr": "count by (job, instance) (up == 0)",
"hide": false,
"interval": "",
"legendFormat": "{{job}}/{{instance}}",
"refId": "A"
}
],
"thresholds": [
{
"colorMode": "critical",
"fill": false,
"line": false,
"op": "gt",
"value": 0,
"visible": true
}
],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Scraping failures",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"decimals": 0,
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"refresh": false,
"schemaVersion": 27,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-30m",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Meta monitoring",
"uid": "MetaMonitoring",
"version": 1
}
......@@ -41,7 +41,7 @@
"description": "Some of our software runs in a single thread, so this shows max CPU per core (instead of averaged over all cores)",
"fieldConfig": {
"defaults": {
"custom": {}
"links": []
},
"overrides": []
},
......@@ -49,7 +49,7 @@
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 8,
"w": 6,
"x": 0,
"y": 1
},
......@@ -68,11 +68,10 @@
"linewidth": 1,
"nullPointMode": "null",
"options": {
"alertThreshold": true,
"dataLinks": []
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.3.5",
"pluginVersion": "7.5.10",
"pointradius": 2,
"points": false,
"renderer": "flot",
......@@ -173,8 +172,8 @@
"datasource": null,
"fieldConfig": {
"defaults": {
"custom": {},
"displayName": "${__field.labels.instance}"
"displayName": "${__field.labels.instance}",
"links": []
},
"overrides": [
{
......@@ -194,8 +193,8 @@
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 8,
"x": 8,
"w": 6,
"x": 6,
"y": 1
},
"hiddenSeries": false,
......@@ -213,11 +212,10 @@
"linewidth": 1,
"nullPointMode": "null",
"options": {
"alertThreshold": true,
"dataLinks": []
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.3.5",
"pluginVersion": "7.5.10",
"pointradius": 2,
"points": false,
"renderer": "flot",
......@@ -241,7 +239,7 @@
"line": true,
"op": "gt",
"value": 1,
"yaxis": "left"
"visible": true
}
],
"timeFrom": null,
......@@ -328,7 +326,7 @@
"description": "How much RAM is in use? Relative to available system memory.",
"fieldConfig": {
"defaults": {
"custom": {}
"links": []
},
"overrides": []
},
......@@ -336,8 +334,8 @@
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 8,
"x": 16,
"w": 6,
"x": 12,
"y": 1
},
"hiddenSeries": false,
......@@ -356,11 +354,10 @@
"linewidth": 1,
"nullPointMode": "null",
"options": {
"alertThreshold": true,
"dataLinks": []
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.3.5",
"pluginVersion": "7.5.10",
"pointradius": 2,
"points": false,
"renderer": "flot",
......@@ -384,7 +381,7 @@
"line": true,
"op": "gt",
"value": 0.8,
"yaxis": "left"
"visible": true
}
],
"timeFrom": null,
......@@ -428,6 +425,152 @@
"alignLevel": null
}
},
{
"alert": {
"alertRuleTags": {},
"conditions": [
{
"evaluator": {
"params": [
0.1
],
"type": "gt"
},
"operator": {
"type": "and"
},
"query": {
"params": [
"A",
"5m",
"now"
]
},
"reducer": {
"params": [],
"type": "avg"
},
"type": "query"
}
],
"executionErrorState": "alerting",
"for": "5m",
"frequency": "1m",
"handler": 1,
"name": "Swap usage alert",
"noDataState": "no_data",
"notifications": []
},
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": null,
"description": "How much Swap is in use? Relative to available swap.",
"fieldConfig": {
"defaults": {},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 6,
"x": 18,
"y": 1
},
"hiddenSeries": false,
"id": 30,
"legend": {
"alignAsTable": false,
"avg": false,
"current": false,
"hideEmpty": false,
"hideZero": false,
"max": false,
"min": false,
"rightSide": false,
"show": false,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.5.10",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"exemplar": true,
"expr": "1 - node_memory_SwapFree_bytes / node_memory_SwapTotal_bytes",
"interval": "",
"intervalFactor": 1,
"legendFormat": "{{instance}}",
"refId": "A"
}
],
"thresholds": [
{
"colorMode": "critical",
"fill": true,
"line": true,
"op": "gt",
"value": 0.1,
"visible": true
}
],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Swap used %",
"tooltip": {
"shared": true,
"sort": 2,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"$$hashKey": "object:98",
"format": "percentunit",
"label": null,
"logBase": 1,
"max": "1",
"min": "0",
"show": true
},
{
"$$hashKey": "object:99",
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": false
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"collapsed": false,
"datasource": null,
......@@ -448,10 +591,10 @@
"dashLength": 10,
"dashes": false,
"datasource": null,
"description": "Shows most saturated network link for every node. Baseline is the reported NIC link speed - that might not be the actual limit.",
"description": "Shows most saturated network link for every node. Bit/s.",
"fieldConfig": {
"defaults": {
"custom": {}
"links": []
},
"overrides": []
},
......@@ -478,11 +621,10 @@
"linewidth": 1,
"nullPointMode": "null",
"options": {
"alertThreshold": true,
"dataLinks": []
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.3.5",
"pluginVersion": "7.5.10",
"pointradius": 2,
"points": false,
"renderer": "flot",
......@@ -492,14 +634,14 @@
"steppedLine": false,
"targets": [
{
"expr": "max by (instance) (rate(node_network_transmit_bytes_total{device!~\"lo|monitoringvpn\"}[5m]) / node_network_speed_bytes)",
"expr": "max by (instance) (rate(node_network_transmit_bytes_total{device!~\"lo|monitoringvpn\"}[5m]) * 8)",
"interval": "",
"intervalFactor": 4,
"legendFormat": "{{instance}} out",
"refId": "A"
},
{
"expr": "- max by (instance) (rate(node_network_receive_bytes_total{device!~\"lo|monitoringvpn\"}[5m]) / node_network_speed_bytes)",
"expr": "- max by (instance) (rate(node_network_receive_bytes_total{device!~\"lo|monitoringvpn\"}[5m]) * 8)",
"interval": "",
"intervalFactor": 4,
"legendFormat": "{{instance}} in",
......@@ -510,7 +652,7 @@
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Throughput %",
"title": "Throughput",
"tooltip": {
"shared": false,
"sort": 2,
......@@ -527,15 +669,17 @@
},
"yaxes": [
{
"$$hashKey": "object:226",
"decimals": null,
"format": "percentunit",
"format": "bps",
"label": null,
"logBase": 1,
"max": "1",
"min": "-1",
"max": null,
"min": null,
"show": true
},
{
"$$hashKey": "object:227",
"format": "short",
"label": null,
"logBase": 1,
......@@ -558,7 +702,7 @@
"description": "Packet and error count. Positive values mean transmit, negative receive.",
"fieldConfig": {
"defaults": {
"custom": {}
"links": []
},
"overrides": []
},
......@@ -585,11 +729,10 @@
"linewidth": 1,
"nullPointMode": "null as zero",
"options": {
"alertThreshold": true,
"dataLinks": []
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.3.5",
"pluginVersion": "7.5.10",
"pointradius": 2,
"points": false,
"renderer": "flot",
......@@ -602,28 +745,28 @@
"expr": "- rate(node_network_receive_packets_total{device!~\"lo|monitoringvpn\"}[5m])",
"interval": "",
"intervalFactor": 4,
"legendFormat": "{{instance}} {{device}}",
"legendFormat": "{{instance}} in",
"refId": "A"
},
{
"expr": "- rate(node_network_receive_errs_total{device!~\"lo|monitoringvpn\"}[5m])",
"interval": "",
"intervalFactor": 4,
"legendFormat": "{{instance}} {{device}}",
"legendFormat": "{{instance}} in err",
"refId": "B"
},
{
"expr": "rate(node_network_transmit_packets_total{device!~\"lo|monitoringvpn\"}[5m])",
"interval": "",
"intervalFactor": 4,
"legendFormat": "{{instance}} {{device}}",
"legendFormat": "{{instance}} out",
"refId": "C"
},
{
"expr": "rate(node_network_transmit_errs_total{device!~\"lo|monitoringvpn\"}[5m])",
"interval": "",
"intervalFactor": 4,
"legendFormat": "{{instance}} {{device}}",
"legendFormat": "{{instance}} out err",
"refId": "D"
}
],
......@@ -647,7 +790,7 @@
},
"yaxes": [
{
"format": "short",
"format": "pps",
"label": null,
"logBase": 1,
"max": null,
......@@ -781,7 +924,7 @@
"description": "Network errors, drops etc. Should all be 0.",
"fieldConfig": {
"defaults": {
"custom": {}
"links": []
},
"overrides": []
},
......@@ -808,11 +951,10 @@
"linewidth": 1,
"nullPointMode": "null",
"options": {
"alertThreshold": true,
"dataLinks": []
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.3.5",
"pluginVersion": "7.5.10",
"pointradius": 2,
"points": false,
"renderer": "flot",
......@@ -852,7 +994,8 @@
"fill": true,
"line": true,
"op": "gt",
"value": 10
"value": 10,
"visible": true
}
],
"timeFrom": null,
......@@ -953,7 +1096,7 @@
"description": "Watch filesystems filling up. Shows only mounts over 10 % of available bytes used.",
"fieldConfig": {
"defaults": {
"custom": {},
"links": [],
"unit": "percentunit"
},
"overrides": []
......@@ -981,11 +1124,10 @@
"linewidth": 1,
"nullPointMode": "null",
"options": {
"alertThreshold": true,
"dataLinks": []
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.3.5",
"pluginVersion": "7.5.10",
"pointradius": 2,
"points": false,
"renderer": "flot",
......@@ -1012,7 +1154,7 @@
"line": true,
"op": "gt",
"value": 0.8,
"yaxis": "left"
"visible": true
}
],
"timeFrom": null,
......@@ -1035,6 +1177,7 @@
},
"yaxes": [
{
"$$hashKey": "object:131",
"format": "percentunit",
"label": null,
"logBase": 1,
......@@ -1043,6 +1186,7 @@
"show": true
},
{
"$$hashKey": "object:132",
"format": "short",
"label": null,
"logBase": 1,
......@@ -1065,7 +1209,7 @@
"description": "Input Output Operations per second. Positive values mean read, negative write.",
"fieldConfig": {
"defaults": {
"custom": {}
"links": []
},
"overrides": []
},
......@@ -1092,11 +1236,10 @@
"linewidth": 1,
"nullPointMode": "null as zero",
"options": {
"alertThreshold": true,
"dataLinks": []
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.3.5",
"pluginVersion": "7.5.10",
"pointradius": 2,
"points": false,
"renderer": "flot",
......@@ -1170,7 +1313,7 @@
"description": "Max average storage latency per node. Positive values mean read, negative write.",
"fieldConfig": {
"defaults": {
"custom": {}
"links": []
},
"overrides": []
},
......@@ -1197,11 +1340,10 @@
"linewidth": 1,
"nullPointMode": "null as zero",
"options": {
"alertThreshold": true,
"dataLinks": []
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.3.5",
"pluginVersion": "7.5.10",
"pointradius": 2,
"points": false,
"renderer": "flot",
......@@ -1268,14 +1410,14 @@
}
],
"refresh": "30s",
"schemaVersion": 20,
"schemaVersion": 27,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"from": "now-3h",
"to": "now"
},
"timepicker": {},
......
......@@ -67,17 +67,14 @@ in {
default = false;
description = ''
Enables the slack alerter. Expects a file that contains
the definition of an environment variable named SLACKURL
pointing to the secret Slack Web Hook URL in
grafanaSlackUrlFile (see below).
the secret Slack Web Hook URL in grafanaSlackUrlFile (see below).
'';
};
grafanaSlackUrlFile = lib.mkOption
{ type = lib.types.path;
default = /run/keys/grafana-slack-url;
description = ''
Where to find the Grafana Systemd EnvironmentFile that
sets the secret SLACKURL environment variable.
Where to find the file that containts the slack URL.
'';
};
};
......@@ -86,12 +83,6 @@ in {
# Port 80 for ACME ssl retrieval only. 443 for nginx -> grafana.
networking.firewall.allowedTCPPorts = [ 80 443 ];
# We pass the secret Slack URL using an environment variable.
systemd.services.grafana.serviceConfig.EnvironmentFile =
if cfg.enableSlackAlert
then [ cfg.grafanaSlackUrlFile ]
else [ ];
services.grafana = {
enable = true;
domain = cfg.domain;
......@@ -157,7 +148,9 @@ in {
uploadImage = true;
};
secure_settings = {
url = "$SLACKURL";
# `$__file{}` reads the value from the named file.
# See https://grafana.com/docs/grafana/latest/administration/configuration/#file-provider
url = "$__file{${toString cfg.grafanaSlackUrlFile}}";
};
}]);
};
......
......@@ -127,6 +127,16 @@ in
# Want a regex instead? try locations."~ /v\d+/"
proxyPass = "http://unix:${cfg.unixSocket}";
};
locations."/metrics" = {
proxyPass = "http://unix:${cfg.unixSocket}";
# Only allow our monitoringvpn subnet
extraConfig = ''
allow 172.23.23.0/24;
allow 127.0.0.1;
allow ::1;
deny all;
'';
};
locations."/" = {
# Return a 404 error for any paths not specified above.
extraConfig = ''
......@@ -135,5 +145,11 @@ in
};
};
};
# Open 80 and 443 for nginx
networking.firewall.allowedTCPPorts = [
80
443
];
};
}
......@@ -19,7 +19,8 @@ let
};
in
{
zkapissuer = callPackage ./zkapissuer {};
inherit (ourpkgs) privatestorage;
leasereport = callPackage ./leasereport {};
zkap-spending-service = callPackage ./zkap-spending-service {};
inherit (ourpkgs) privatestorage leasereport;
zkapissuer = callPackage ./zkapissuer {};
}
{ callPackage, fetchFromGitLab, lib }:
let
repo-data = lib.importJSON ./repo.json;
repo = fetchFromGitLab (builtins.removeAttrs repo-data [ "branch" ]);
LeaseReport = (import "${repo}/nix").LeaseReport;
in
LeaseReport.components.exes.LeaseReport
{
"owner": "privatestorage",
"repo": "LeaseReport",
"branch": "main",
"domain": "whetstone.privatestorage.io",
"rev": "3739ffde14e698f56118a444e6946edb736b6983",
"outputHashAlgo": "sha512",
"outputHash": "37b4hrhjghvza0bqvmngcdapqfjjjiv0gx90y0i4wvj72nf1xsh7g2kwpvjm4prpb5s7fxb50x971xfw4sqpwwsk2zdll4nbl5764ij"
}
{
"owner": "privatestorage",
"repo": "zkap-spending-service",
"rev": "e0d63b79213d16f2de6629167ea8f1236ba22e14",
"rev": "cbf7509f429ffd6e6cf37a73e4ff84a9c5ce1141",
"branch": "main",
"domain": "whetstone.privatestorage.io",
"outputHash": "30abb0g9xxn4lp493kj5wmz8kj5q2iqvw40m8llqvb3zamx60gd8cy451ii7z15qbrbx9xmjdfw0k4gviij46fkx1s8nbich5c8qx57",
"outputHash": "04g7pcykc2525cg3z7wg5834s7vqn82xaqjvf52l6dnxv3mb9xr93kk505dvxcwhgfbqpim5i479s9kqd8gi7q3lq5wn5fq7rf7lkrj",
"outputHashAlgo": "sha512"
}
{ callPackage }:
{ callPackage, fetchFromGitHub, lib }:
let
repo = callPackage ./repo.nix { };
repo-data = lib.importJSON ./repo.json;
repo = fetchFromGitHub (builtins.removeAttrs repo-data [ "branch" ]);
PaymentServer = (import "${repo}/nix").PaymentServer;
in
PaymentServer.components.exes."PaymentServer-exe"
{
"owner": "PrivateStorageio",
"repo": "PaymentServer",
"rev": "e080beb14ec58ffe8e55c35e6dddd46c5082887f",
"branch": "main",
"outputHashAlgo": "sha256",
"outputHash": "1zck9kawbs2lkr3qjipira9gawa4gxlqijqqjrmlvvyp9mr0fgxm"
}
{ fetchFromGitHub }:
fetchFromGitHub {
owner = "PrivateStorageio";
repo = "PaymentServer";
rev = "ff30e85c231a3b5ad76426bbf8801f8f76884367";
sha256 = "1spz19f5z96shmfpazj0rv6877xvchf3gl49a4xahjbbsz39x34x";
}
# The overall system test suite for PrivateStorageio NixOS configuration.
let
pkgs = import ../nixpkgs-2105.nix { };
in {
{ pkgs }:
{
private-storage = pkgs.nixosTest ./tests/private-storage.nix;
spending = pkgs.nixosTest ./tests/spending.nix;
tahoe = pkgs.nixosTest ./tests/tahoe.nix;
......
......@@ -11,10 +11,14 @@
services.private-storage-spending.enable = true;
services.private-storage-spending.domain = "localhost";
};
external = { ... }: {
# A node that has no particular configuration, for testing access rules
# for external hosts.
};
};
testScript = { nodes }: let
revision = nodes.spending.config.passthru.ourpkgs.zkap-spending-service.meta.rev;
curl = "${pkgs.curl}/bin/curl -sSf";
curl = "${pkgs.curl}/bin/curl -sSf --max-time 5";
in
''
import json
......@@ -25,8 +29,17 @@
with subtest("Ensure we can ping the spending service"):
output = spending.succeed("${curl} http://localhost/v1/_ping")
assert json.loads(output)["status"] == "ok", "Could not ping spending service."
with subtest("Ensure external hosts can ping the spending service"):
output = external.succeed("${curl} http://spending/v1/_ping")
assert json.loads(output)["status"] == "ok", "Could not ping spending service."
with subtest("Ensure that the spending service version matches the expected version"):
output = spending.succeed("${curl} http://localhost/v1/_version")
assert json.loads(output)["revision"] == "${revision}", "Spending service revision does not match."
with subtest("Ensure that the spending service generates metrics"):
# TODO: We should pass "-H 'accept: application/openmetrics-text'" here.
# See https://github.com/prometheus/prometheus/issues/8932
output = spending.succeed("${curl} http://localhost/metrics | ${pkgs.prometheus}/bin/promtool check metrics")
with subtest("Ensure that the metrics are not accesible from other machines"):
output = external.fail("${curl} http://spending/metrics")
'';
}
# The overall unit test suite for PrivateStorageio NixOS configuration.
{ pkgs }:
let
pkgs = import <nixpkgs> { };
# Total the numbers in a list.
sum = builtins.foldl' (a: b: a + b) 0;
......
{
"name": "release2105",
"url": "https://releases.nixos.org/nixos/21.05/nixos-21.05.3367.fd8a7fd07da/nixexprs.tar.xz",
"sha256": "12p7v805xj5as2fbdh30i0b9iwy8y24sk256rgqfqylxj1784mn8"
"url": "https://releases.nixos.org/nixos/21.05/nixos-21.05.3740.ce7a1190a0f/nixexprs.tar.xz",
"sha256": "112drvixj81vscj8cncmks311rk2ik5gydpd03d3r0yc939zjskg"
}
{ stdenv, lib, graphviz, python3Packages }:
stdenv.mkDerivation rec {
version = "0.0";
name = "privatestorageio-${version}";
src = lib.cleanSource ./.;
depsBuildBuild = [
graphviz
];
buildPhase = ''
${python3Packages.sphinx}/bin/sphinx-build -W docs/source docs/build
'';
installPhase = ''
mkdir $out
mv docs/build $out/docs
'';
}
......@@ -16,6 +16,7 @@ let
python-commands = [
./update-nixpkgs
./update-gitlab-repo
./update-github-repo
];
in
# This derivation creates a package that wraps our tools to setup an environment
......
#!/usr/bin/env python
"""
Update a pinned github repository.
Pass this path to a JSON file and it will update it to the latest
version of the branch it specifies. You can also pass a different
branch or repository owner, which will update the file to point at
the new branch/repository, and update to the latest version.
"""
import argparse
import json
from pathlib import Path
import httpx
from ps_tools import get_url_hash
HASH_TYPE = "sha512"
ARCHIVE_TEMPLATE = "https://api.github.com/repos/{owner}/{repo}/tarball/{rev}"
BRANCH_TEMPLATE = (
"https://api.github.com/repos/{owner}/{repo}/commits/{branch}"
)
def get_github_commit(config):
response = httpx.get(BRANCH_TEMPLATE.format(**config))
response.raise_for_status()
return response.json()["sha"]
def get_github_archive_url(config):
return ARCHIVE_TEMPLATE.format(**config)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"repo_file",
metavar="repo-file",
type=Path,
help="JSON file with pinned configuration.",
)
parser.add_argument(
"--branch",
type=str,
help="Branch to update to.",
)
parser.add_argument(
"--owner",
type=str,
help="Repository owner to update to.",
)
parser.add_argument(
"--rev",
type=str,
help="Revision to pin.",
)
parser.add_argument(
"--dry-run",
action="store_true",
)
args = parser.parse_args()
repo_file = args.repo_file
config = json.loads(repo_file.read_text())
for key in ["owner", "branch"]:
if getattr(args, key) is not None:
config[key] = getattr(args, key)
if args.rev is not None:
config["rev"] = args.rev
else:
config["rev"] = get_github_commit(config)
archive_url = get_github_archive_url(config)
config.update(get_url_hash(HASH_TYPE, "source", archive_url))
output = json.dumps(config, indent=2)
if args.dry_run:
print(output)
else:
repo_file.write_text(output)
if __name__ == "__main__":
main()