Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions architecture.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<meta name="twitter:title" content="Keel Linux architecture: composition on a mesh">
<meta name="twitter:description" content="Overlays, appliances and applications; the manifest and the spec; IPv6-first networking and signed layers.">
<meta name="twitter:image" content="https://keellinux.org/assets/keel-social.png">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="style.css?v=2026093001">
<script>
(function () {
var root = document.documentElement;
Expand All @@ -38,7 +38,7 @@
}
})();
</script>
<script defer src="assets/js/site.js"></script>
<script defer src="assets/js/site.js?v=2026093001"></script>
<script defer data-domain="keellinux.org" src="https://analytics.pop.coop/js/script.file-downloads.hash.outbound-links.pageview-props.revenue.tagged-events.js"></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
</head>
Expand Down
4 changes: 2 additions & 2 deletions cloud.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<meta name="twitter:title" content="Keel Linux: cloud and replication">
<meta name="twitter:description" content="From one box to a private cloud on the same image: the mesh, the registry, failover, replication and backup.">
<meta name="twitter:image" content="https://keellinux.org/assets/keel-social.png">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="style.css?v=2026093001">
<script>
(function () {
var root = document.documentElement;
Expand All @@ -38,7 +38,7 @@
}
})();
</script>
<script defer src="assets/js/site.js"></script>
<script defer src="assets/js/site.js?v=2026093001"></script>
<script defer data-domain="keellinux.org" src="https://analytics.pop.coop/js/script.file-downloads.hash.outbound-links.pageview-props.revenue.tagged-events.js"></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
</head>
Expand Down
4 changes: 2 additions & 2 deletions guidelines.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<meta name="twitter:title" content="Keel Linux guidelines">
<meta name="twitter:description" content="How the repositories are organised, what every change must meet, and how to use the mark.">
<meta name="twitter:image" content="https://keellinux.org/assets/keel-social.png">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="style.css?v=2026093001">
<script>
(function () {
var root = document.documentElement;
Expand All @@ -38,7 +38,7 @@
}
})();
</script>
<script defer src="assets/js/site.js"></script>
<script defer src="assets/js/site.js?v=2026093001"></script>
<script defer data-domain="keellinux.org" src="https://analytics.pop.coop/js/script.file-downloads.hash.outbound-links.pageview-props.revenue.tagged-events.js"></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
</head>
Expand Down
10 changes: 5 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<meta name="twitter:title" content="Keel Linux: composable, mesh-native appliances on Debian">
<meta name="twitter:description" content="IPv6-first, declarative appliances that run alone or join a private cloud over a WireGuard mesh.">
<meta name="twitter:image" content="https://keellinux.org/assets/keel-social.png">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="style.css?v=2026093001">
<script>
(function () {
var root = document.documentElement;
Expand All @@ -38,7 +38,7 @@
}
})();
</script>
<script defer src="assets/js/site.js"></script>
<script defer src="assets/js/site.js?v=2026093001"></script>
<script defer data-domain="keellinux.org" src="https://analytics.pop.coop/js/script.file-downloads.hash.outbound-links.pageview-props.revenue.tagged-events.js"></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
</head>
Expand Down Expand Up @@ -91,7 +91,7 @@ <h1 id="hero-title">Composable, <span class="accent">mesh-native</span> applianc
<a class="btn btn-ghost" href="roadmap.html">See the roadmap</a>
</div>
</div>
<figure class="mesh-panel" data-module="mesh" data-src="assets/js/mesh.js" style="margin:0">
<figure class="mesh-panel" data-module="mesh" data-src="assets/js/mesh.js?v=2026093001" style="margin:0">
<div class="panel-bar">
<span class="dots" aria-hidden="true"><i></i><i></i><i></i></span>
<span>wg0 · mesh · IPv6</span>
Expand Down Expand Up @@ -257,7 +257,7 @@ <h3>Advanced, cloud advanced</h3>
<h2 id="security-title">Three gates before the application</h2>
<p class="lead">In an advanced installation, a request meets CrowdSec first, then Nginx with the WAF inline, then Anubis, and only then the application. <span class="badge badge-decided">Decided, 0030</span></p>
</div>
<figure class="pipeline" data-module="pipeline" data-src="assets/js/pipeline.js" style="margin:0" data-reveal>
<figure class="pipeline" data-module="pipeline" data-src="assets/js/pipeline.js?v=2026093001" style="margin:0" data-reveal>
<div class="pipeline-stage"><canvas aria-hidden="true"></canvas></div>
<ol class="pipeline-steps">
<li><strong>Internet</strong>A request arrives, over IPv6 first.</li>
Expand Down Expand Up @@ -292,7 +292,7 @@ <h2 id="declarative-title">Declared in one file, converged by one command</h2>
</ul>
</div>
<div data-reveal data-reveal-delay="1">
<div class="terminal" data-module="terminal" data-src="assets/js/terminal.js">
<div class="terminal" data-module="terminal" data-src="assets/js/terminal.js?v=2026093001">
<div class="panel-bar">
<span class="dots" aria-hidden="true"><i></i><i></i><i></i></span>
<span>root@blog: ~</span>
Expand Down
4 changes: 2 additions & 2 deletions roadmap.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<meta name="twitter:title" content="Keel Linux roadmap">
<meta name="twitter:description" content="Eight phases, one layer at a time, each done only when it holds on a built image.">
<meta name="twitter:image" content="https://keellinux.org/assets/keel-social.png">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="style.css?v=2026093001">
<script>
(function () {
var root = document.documentElement;
Expand All @@ -38,7 +38,7 @@
}
})();
</script>
<script defer src="assets/js/site.js"></script>
<script defer src="assets/js/site.js?v=2026093001"></script>
<script defer data-domain="keellinux.org" src="https://analytics.pop.coop/js/script.file-downloads.hash.outbound-links.pageview-props.revenue.tagged-events.js"></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
</head>
Expand Down
6 changes: 3 additions & 3 deletions security.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<meta name="twitter:title" content="Keel Linux security: secure by default">
<meta name="twitter:description" content="No shared keys in images, CrowdSec, a WAF and Anubis, and every port declared loopback, mesh or public.">
<meta name="twitter:image" content="https://keellinux.org/assets/keel-social.png">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="style.css?v=2026093001">
<script>
(function () {
var root = document.documentElement;
Expand All @@ -38,7 +38,7 @@
}
})();
</script>
<script defer src="assets/js/site.js"></script>
<script defer src="assets/js/site.js?v=2026093001"></script>
<script defer data-domain="keellinux.org" src="https://analytics.pop.coop/js/script.file-downloads.hash.outbound-links.pageview-props.revenue.tagged-events.js"></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
</head>
Expand Down Expand Up @@ -112,7 +112,7 @@ <h2 id="identity-title">Keys and identity: none in the image</h2>
<section id="pipeline" aria-labelledby="pipeline-title">
<h2 id="pipeline-title">The request pipeline</h2>
<p>Keel Web is an appliance of its own and the base of every web appliance: Nginx, the Coraza WAF and Anubis. In an advanced installation a request passes them in a fixed order. <span class="badge badge-decided">Decided, 0029 and 0030; Phases 1 and 3</span></p>
<figure class="pipeline" data-module="pipeline" data-src="assets/js/pipeline.js" style="margin:1.5rem 0">
<figure class="pipeline" data-module="pipeline" data-src="assets/js/pipeline.js?v=2026093001" style="margin:1.5rem 0">
<div class="pipeline-stage"><canvas aria-hidden="true"></canvas></div>
<ol class="pipeline-steps">
<li><strong>Internet</strong>A request arrives, over IPv6 first.</li>
Expand Down
12 changes: 12 additions & 0 deletions tests/test_sitecheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,18 @@ def test_a_fragment_of_an_asset_is_reported(self):
],
)

def test_a_version_query_names_the_same_asset(self):
text = page('<a href="assets/a.svg?v=2026093001">x</a>')
self.assertEqual(
sitecheck.check({"index.html": text}, {"assets/a.svg"}), []
)

def test_a_version_query_on_a_missing_asset_is_reported(self):
text = page('<a href="assets/b.svg?v=1">x</a>')
self.assertEqual(
len(sitecheck.check({"index.html": text}, {"assets/a.svg"})), 2
)

def test_an_empty_id_attribute_is_not_a_target(self):
text = page('<a href="#x">x</a><section id=""></section>')
self.assertEqual(len(sitecheck.check({"index.html": text})), 1)
Expand Down
8 changes: 6 additions & 2 deletions tools/sitecheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,13 @@ def from_site_origin(reference: str) -> str:


def split_fragment(reference: str) -> tuple[str, str]:
"""A reference as (path, fragment); either part may be empty"""
"""A reference as (path, fragment); either part may be empty

A query, such as the version that busts a browser's cache of
style.css?v=2026093001, names the same file and is dropped.
"""
path, _, fragment = reference.partition("#")
return path, fragment
return path.partition("?")[0], fragment


def check(
Expand Down
Loading