freebsd.source: Use hashes from `git archive`

An in-tree dependency of FreeBSD uses an `export-ignore` directive
to hide certain files from the git export.
Unfortunately, that means that `fetchFromGitHub` has different outputs
when `forceFetchGit = true` and `forceFetchGit = false`.

We cannot download source with git during native FreeBSD bootstrap due
to a circular dependency,
so change the update script to output archives matching GitHub.

+42 -51
+4 -8
pkgs/os-specific/bsd/freebsd/pkgs/source.nix
··· 1 { fetchFromGitHub, sourceData }: 2 3 - # Using fetchFromGitHub from their mirror because it's a lot faster than their git server 4 - # If you want you could fetchgit from "https://git.FreeBSD.org/src.git" instead. 5 # The update script still pulls directly from git.freebsd.org 6 fetchFromGitHub { 7 owner = "freebsd"; 8 repo = "freebsd-src"; 9 inherit (sourceData) rev hash; 10 - 11 - # The GitHub export excludes some files in the git source 12 - # that were marked `export-ignore`. 13 - # A normal git checkout will keep those files, 14 - # matching the update script 15 - forceFetchGit = true; 16 }
··· 1 { fetchFromGitHub, sourceData }: 2 3 + # Using fetchFromGitHub from their mirror because we cannot use git during bootstrap 4 + # If you want you could fetchurl from "https://cgit.FreeBSD.org/src" instead. 5 # The update script still pulls directly from git.freebsd.org 6 + # Note that hashes with `forceFetchGit = true` may be different due to `export-ignore` 7 + # directives in gitattributes files. 8 fetchFromGitHub { 9 owner = "freebsd"; 10 repo = "freebsd-src"; 11 inherit (sourceData) rev hash; 12 }
+28 -33
pkgs/os-specific/bsd/freebsd/update.py
··· 11 import re 12 import subprocess 13 import sys 14 import tempfile 15 import typing 16 import urllib.request 17 18 _QUERY_VERSION_PATTERN = re.compile('^([A-Z]+)="(.+)"$') 19 - _RELEASE_PATCH_PATTERN = re.compile('^RELEASE-p([0-9]+)$') 20 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 21 MIN_VERSION = packaging.version.Version("13.0.0") 22 MAIN_BRANCH = "main" ··· 32 33 def request_supported_refs() -> list[str]: 34 # Looks pretty shady but I think this should work with every version of the page in the last 20 years 35 - r = re.compile("^h\d$", re.IGNORECASE) 36 soup = bs4.BeautifulSoup( 37 urllib.request.urlopen("https://www.freebsd.org/security"), features="lxml" 38 ) ··· 45 return list(df["Branch"]) 46 47 48 - def query_version(repo: git.Repo) -> dict[str, typing.Any]: 49 # This only works on FreeBSD 13 and later 50 text = ( 51 subprocess.check_output( 52 - ["bash", os.path.join(repo.working_dir, "sys", "conf", "newvers.sh"), "-v"] 53 ) 54 .decode("utf-8") 55 .strip() ··· 86 print(f"{ref_name}: revision still {rev.hexsha}, skipping") 87 return old_versions[ref_name] 88 89 - repo.git.checkout(rev) 90 - print(f"{ref_name}: checked out {rev.hexsha}") 91 92 - full_hash = ( 93 - subprocess.check_output(["nix", "hash", "path", "--sri", repo.working_dir]) 94 - .decode("utf-8") 95 - .strip() 96 - ) 97 - print(f"{ref_name}: hash is {full_hash}") 98 99 - version = query_version(repo) 100 - print(f"{ref_name}: version is {version['version']}") 101 102 return { 103 "rev": rev.hexsha, ··· 115 print(f"Selected temporary directory {temp_dir.name}") 116 117 if len(sys.argv) >= 2: 118 - orig_repo = git.Repo(sys.argv[1]) 119 - print(f"Fetching updates on {orig_repo.git_dir}") 120 - orig_repo.remote("origin").fetch() 121 else: 122 print("Cloning source repo") 123 - orig_repo = git.Repo.clone_from( 124 - "https://git.FreeBSD.org/src.git", to_path=os.path.join(temp_dir.name, "orig") 125 ) 126 127 supported_refs = request_supported_refs() 128 print(f"Supported refs are: {' '.join(supported_refs)}") 129 130 - print("Doing git crimes, do not run `git worktree prune` until after script finishes!") 131 - workdir = os.path.join(temp_dir.name, "work") 132 - git.cmd.Git(orig_repo.git_dir).worktree("add", "--orphan", workdir) 133 - 134 - # Have to create object before removing .git otherwise it will complain 135 - repo = git.Repo(workdir) 136 - repo.git.set_persistent_git_options(git_dir=repo.git_dir) 137 - # Remove so that nix hash doesn't see the file 138 - os.remove(os.path.join(workdir, ".git")) 139 - 140 - print(f"Working in directory {repo.working_dir} with git directory {repo.git_dir}") 141 - 142 143 try: 144 with open(os.path.join(BASE_DIR, "versions.json"), "r") as f: ··· 191 ) 192 versions[fullname] = result 193 194 - 195 with open(os.path.join(BASE_DIR, "versions.json"), "w") as out: 196 json.dump(versions, out, sort_keys=True, indent=2) 197 out.write("\n") 198 199 - if __name__ == '__main__': 200 main()
··· 11 import re 12 import subprocess 13 import sys 14 + import tarfile 15 import tempfile 16 import typing 17 import urllib.request 18 19 _QUERY_VERSION_PATTERN = re.compile('^([A-Z]+)="(.+)"$') 20 + _RELEASE_PATCH_PATTERN = re.compile("^RELEASE-p([0-9]+)$") 21 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 22 MIN_VERSION = packaging.version.Version("13.0.0") 23 MAIN_BRANCH = "main" ··· 33 34 def request_supported_refs() -> list[str]: 35 # Looks pretty shady but I think this should work with every version of the page in the last 20 years 36 + r = re.compile(r"^h\d$", re.IGNORECASE) 37 soup = bs4.BeautifulSoup( 38 urllib.request.urlopen("https://www.freebsd.org/security"), features="lxml" 39 ) ··· 46 return list(df["Branch"]) 47 48 49 + def query_version(work_dir: str) -> dict[str, typing.Any]: 50 # This only works on FreeBSD 13 and later 51 text = ( 52 subprocess.check_output( 53 + ["bash", os.path.join(work_dir, "sys", "conf", "newvers.sh"), "-v"] 54 ) 55 .decode("utf-8") 56 .strip() ··· 87 print(f"{ref_name}: revision still {rev.hexsha}, skipping") 88 return old_versions[ref_name] 89 90 + tar_content = io.BytesIO() 91 + repo.archive(tar_content, rev, format="tar") 92 + tar_content.seek(0) 93 + 94 + with tempfile.TemporaryDirectory(dir="/tmp") as work_dir: 95 + file = tarfile.TarFile(fileobj=tar_content) 96 + file.extractall(path=work_dir, filter="data") 97 98 + full_hash = ( 99 + subprocess.check_output(["nix", "hash", "path", "--sri", work_dir]) 100 + .decode("utf-8") 101 + .strip() 102 + ) 103 + print(f"{ref_name}: hash is {full_hash}") 104 105 + version = query_version(work_dir) 106 + print(f"{ref_name}: version is {version['version']}") 107 108 return { 109 "rev": rev.hexsha, ··· 121 print(f"Selected temporary directory {temp_dir.name}") 122 123 if len(sys.argv) >= 2: 124 + repo = git.Repo(sys.argv[1]) 125 + print(f"Fetching updates on {repo.git_dir}") 126 + repo.remote("origin").fetch() 127 else: 128 print("Cloning source repo") 129 + repo = git.Repo.clone_from( 130 + "https://git.FreeBSD.org/src.git", to_path=temp_dir.name 131 ) 132 133 supported_refs = request_supported_refs() 134 print(f"Supported refs are: {' '.join(supported_refs)}") 135 136 + print(f"git directory {repo.git_dir}") 137 138 try: 139 with open(os.path.join(BASE_DIR, "versions.json"), "r") as f: ··· 186 ) 187 versions[fullname] = result 188 189 with open(os.path.join(BASE_DIR, "versions.json"), "w") as out: 190 json.dump(versions, out, sort_keys=True, indent=2) 191 out.write("\n") 192 193 + 194 + if __name__ == "__main__": 195 main()
+10 -10
pkgs/os-specific/bsd/freebsd/versions.json
··· 1 { 2 "main": { 3 - "hash": "sha256-xsgY5Ex/B5ngOTa5OZRauSaSYvET5lWI7veJRrSq1oY=", 4 "ref": "main", 5 "refType": "branch", 6 - "rev": "c5773d366ecc5271b9bd6e5506c00fb3520f19ae", 7 "supported": false, 8 "version": { 9 "branch": "CURRENT", 10 "major": 15, 11 "minor": 0, 12 - "reldate": "1500035", 13 "release": "15.0-CURRENT", 14 "revision": "15.0", 15 "type": "FreeBSD", ··· 161 } 162 }, 163 "release/14.2.0": { 164 - "hash": "sha256-qZkeuUZbuPOvXZBgP5x6Hii1YN7XdDJzwZeYacIR5BI=", 165 "ref": "release/14.2.0", 166 "refType": "tag", 167 "rev": "c8918d6c7412fce87922e9bd7e4f5c7d7ca96eb7", ··· 308 "ref": "releng/14.1", 309 "refType": "branch", 310 "rev": "f389e68ca980b7e053a34d9eddde89b4c2a1ee6c", 311 - "supported": true, 312 "version": { 313 "branch": "RELEASE-p8", 314 "major": 14, ··· 322 } 323 }, 324 "releng/14.2": { 325 - "hash": "sha256-XP8BFnXvziaC9wOJj8q31UZXFqCUE7WQ5FdJHEZWGbg=", 326 "ref": "releng/14.2", 327 "refType": "branch", 328 "rev": "ac2cbb46b5f1efa7f7b5d4eb15631337329ec5b2", ··· 340 } 341 }, 342 "stable/13": { 343 - "hash": "sha256-J9SJKeR6Den3Sep2o4r0cqIDd2V5gbY0Ow9eP69Ny0o=", 344 "ref": "stable/13", 345 "refType": "branch", 346 - "rev": "a8431b47adae8f8b731206dc38d82b2245ad245e", 347 "supported": true, 348 "version": { 349 "branch": "STABLE", ··· 357 } 358 }, 359 "stable/14": { 360 - "hash": "sha256-tleB6J5Cg1SIN2LCfvV3Cfp4Lxx65UHmiILpin6UYGY=", 361 "ref": "stable/14", 362 "refType": "branch", 363 - "rev": "6e510d8fbaf8d91da235fe28250cd48124edda9f", 364 "supported": true, 365 "version": { 366 "branch": "STABLE",
··· 1 { 2 "main": { 3 + "hash": "sha256-f69U2FX+3GQimdUJunWApFseeKJhzjgNw4h26ZBPiT0=", 4 "ref": "main", 5 "refType": "branch", 6 + "rev": "9357c694e8dca627c25b15529e8435b2ab3dd48b", 7 "supported": false, 8 "version": { 9 "branch": "CURRENT", 10 "major": 15, 11 "minor": 0, 12 + "reldate": "1500036", 13 "release": "15.0-CURRENT", 14 "revision": "15.0", 15 "type": "FreeBSD", ··· 161 } 162 }, 163 "release/14.2.0": { 164 + "hash": "sha256-q5/0pKRlmzZUN+VMwUImkve+NTT1+O68YlwgXp2/aQM=", 165 "ref": "release/14.2.0", 166 "refType": "tag", 167 "rev": "c8918d6c7412fce87922e9bd7e4f5c7d7ca96eb7", ··· 308 "ref": "releng/14.1", 309 "refType": "branch", 310 "rev": "f389e68ca980b7e053a34d9eddde89b4c2a1ee6c", 311 + "supported": false, 312 "version": { 313 "branch": "RELEASE-p8", 314 "major": 14, ··· 322 } 323 }, 324 "releng/14.2": { 325 + "hash": "sha256-iSeTif/cEkqhIQ5hSNF+Rx7dORU13Bc0Dk8Zv4TYWtA=", 326 "ref": "releng/14.2", 327 "refType": "branch", 328 "rev": "ac2cbb46b5f1efa7f7b5d4eb15631337329ec5b2", ··· 340 } 341 }, 342 "stable/13": { 343 + "hash": "sha256-rex3CUXyyNDz/TouNqlzZFo6DAwSOKXTdC5HaRQoKKc=", 344 "ref": "stable/13", 345 "refType": "branch", 346 + "rev": "64f5a71c1cb79c09e50a37ddbe958224bb64add4", 347 "supported": true, 348 "version": { 349 "branch": "STABLE", ··· 357 } 358 }, 359 "stable/14": { 360 + "hash": "sha256-s+pj8LttAnKNNohUsJNOJRFmLg6x06tlkJn3xQnFQiY=", 361 "ref": "stable/14", 362 "refType": "branch", 363 + "rev": "e6a470ffcbd708cf404472bb871c2cb76eaa7b39", 364 "supported": true, 365 "version": { 366 "branch": "STABLE",