Skip to content

Commit

Permalink
Images: add Debian auto-update script
Browse files Browse the repository at this point in the history
It's parsing the webpages, it's very MEH. There's sadly no API/JSON to
figure out what the latest release is. We do have to parse that HTML…
  • Loading branch information
picnoir committed Mar 28, 2024
1 parent 981035a commit b8d5011
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 6 deletions.
4 changes: 2 additions & 2 deletions debian/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
let
imagesJSON = lib.importJSON ./images.json;
fetchImage = image: pkgs.fetchurl {
inherit (image) hash;
url = "https://cloud.debian.org/images/cloud/${image.name}";
sha256 = image.hash;
url = image.name;
};
images = lib.mapAttrs (k: v: fetchImage v) imagesJSON.${system};
makeVmTestForImage = image: { testScript, sharedDirs, diskSize ? null }: generic.makeVmTest {
Expand Down
18 changes: 14 additions & 4 deletions debian/images.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
{
"aarch64-linux": {
"12": {
"hash": "0sckj4cpa9knd4dqab2l6z79gms7p5jq983408dvrfmb7dpz7p54",
"name": "https://cloud.debian.org/images/cloud/bookworm/20240211-1654/debian-12-generic-arm64-20240211-1654.qcow2"
},
"13": {
"hash": "0l6lh2b54n9pkdc7b12qpj7qbw8ql84a0cf4c97ml22d9wxjmydk",
"name": "https://cloud.debian.org/images/cloud/trixie/daily/20240328-1700/debian-13-generic-arm64-daily-20240328-1700.qcow2"
}
},
"x86_64-linux": {
"12": {
"name": "bookworm/20240211-1654/debian-12-generic-amd64-20240211-1654.qcow2",
"hash": "sha256-M9B0CoAUtHvu4vvftqAlrmOrnAMH3pwX9Lr0ir9nB8M="
"hash": "1hq7cyzqmx5syhbrrph70ffanqxf4nhbdpzvwbp7pd0lh0579l1k",
"name": "https://cloud.debian.org/images/cloud/bookworm/20240211-1654/debian-12-generic-amd64-20240211-1654.qcow2"
},
"13": {
"name": "trixie/daily/20240220-1663/debian-13-generic-amd64-daily-20240220-1663.qcow2",
"hash": "sha256-JBoGFc68zgsiH6bZ9MmgXzBFAozfBct6Bajjnn08s3g="
"hash": "1p12msg0b2cnw9pp01n5dpzk2gc6pxm6y2m50dzzf0s8gwp4p7md",
"name": "https://cloud.debian.org/images/cloud/trixie/daily/20240328-1700/debian-13-generic-amd64-daily-20240328-1700.qcow2"
}
}
}
72 changes: 72 additions & 0 deletions scripts/update-images.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#! /usr/bin/env nix-shell
#! nix-shell -i python3 -p python3 python3Packages.beautifulsoup4 python3Packages.requests nix-prefetch

import re
import requests
import subprocess
import json
from bs4 import BeautifulSoup
from datetime import datetime


def nix_hash(url):
print(f"[+] Calculating Nix hash for {url}")
res = subprocess.run(["nix-prefetch-url", url], stdout=subprocess.PIPE)
return res.stdout.rstrip().decode("utf-8")

def get_latest_debian_image(url):
print(f"[+] Parsing debian index {url}")
# Step 1: retrieve the latest entry
page = requests.get(url)
soup = BeautifulSoup(page.content, "html.parser")
rows = soup.find_all("tr")
l = [row.a["href"] for row in rows if row.a]
# Filtering out non-datetime entries such as "daily" or "latest"
l = [s for s in l if re.compile("^[0-9]{8}-[0-9]{4}/$").match(s)]
# Parsing date part of the string
parsed_l = [(datetime.strptime(s[:8], '%Y%m%d'), s) for s in l]
latest = max(parsed_l)
url = f"{url}/{latest[1]}"
print(f"[+] Parsing latest entry: {url}")

# Step 2: parse entry
page = requests.get(url)
soup = BeautifulSoup(page.content, "html.parser")
rows = soup.find_all("tr")
l = [row.a["href"] for row in rows if row.a]
res = {}
for s in l:
if re.compile("^.*-generic-.*\.qcow2$").match(s):
if "amd64" in s:
res["x86_64-linux"] = f"{url}{s}"
elif "arm64" in s:
res["aarch64-linux"] = f"{url}{s}"
return res

"""
Parse the debian cloudimages
"""
def debian_parse():
bookworm_url = "https://cloud.debian.org/images/cloud/bookworm"
trixie_url = "https://cloud.debian.org/images/cloud/trixie/daily"
bookworm = get_latest_debian_image(bookworm_url)
trixie = get_latest_debian_image(trixie_url)
res = {}
for arch in bookworm.keys():
res[arch] = {
"12": {
"name": bookworm[arch],
"hash": nix_hash(bookworm[arch])

},
"13": {
"name": trixie[arch],
"hash": nix_hash(trixie[arch])
}
}
return json.dumps(res)

if __name__ == '__main__':
debian_json = debian_parse()
with open("debian.json", "w") as f:
f.write(debian_json)

0 comments on commit b8d5011

Please sign in to comment.