Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ocis-bin: support more architectures and add update script #326809

Merged
merged 1 commit into from
Jul 15, 2024
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
59 changes: 43 additions & 16 deletions pkgs/by-name/oc/ocis-bin/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,46 @@
autoPatchelfHook,
}:

let
arch =
{
i686-linux = "386";
x86_64-linux = "amd64";
aarch64-linux = "arm64";
armv7l-linux = "arm";
x86_64-darwin = "amd64";
aarch64-darwin = "arm64";
}
."${stdenv.hostPlatform.system}" or (throw "Unsupported system: ${stdenv.hostPlatform.system}");

os =
if stdenv.isLinux then
"linux"
else if stdenv.isDarwin then
"darwin"
else
throw "Unsupported OS";

hash =
{
hash_386-linux = "sha256-4yEgg0Ve8tjNn2weH9d91tfRaU1TE569VvZLxzuzXsw=";
hash_amd64-linux = "sha256-YAIhtHv/cO4yFpkWoRNMf6t4+ifMtGPTcYu84ZMvfD4=";
hash_arm64-linux = "sha256-OdtT9NOhh0Fkk+8CDic0NWWbGflk3FcuKB60OycJU5E=";
hash_arm-linux = "sha256-foMsZ8Nq+Q5lqt2XZCDvQ+/sFM8/1/rPfogzsyrQHqs=";
hash_amd64-darwin = "sha256-6jaX9iqyqztykeXZX3YqwRV/silFiyfeB9gJyreAfF8=";
hash_arm64-darwin = "sha256-KJqMJct7YWocE4eVjMF36adqTIf7WcutZlG3QEoMhCI=";
}
."hash_${arch}-${os}";
in
stdenv.mkDerivation (finalAttrs: {
pname = "ocis-bin";
version = "5.0.5";
system =
if stdenv.isLinux && stdenv.isx86_64 then
"linux-amd64"
else if stdenv.isLinux && stdenv.isAarch64 then
"linux-arm64"
else
"";

src = fetchurl {
url = "https://github.com/owncloud/ocis/releases/download/v${finalAttrs.version}/ocis-${finalAttrs.version}-${finalAttrs.system}";

hash =
if stdenv.isLinux && stdenv.isAarch64 then
"sha256-OdtT9NOhh0Fkk+8CDic0NWWbGflk3FcuKB60OycJU5E="
else if stdenv.isLinux && stdenv.isx86_64 then
"sha256-YAIhtHv/cO4yFpkWoRNMf6t4+ifMtGPTcYu84ZMvfD4="
else
builtins.throw "Unsupported platform, please contact Nixpkgs maintainers for ocis package";
url = "https://github.com/owncloud/ocis/releases/download/v${finalAttrs.version}/ocis-${finalAttrs.version}-${os}-${arch}";
inherit hash;
};

dontUnpack = true;

nativeBuildInputs = [ autoPatchelfHook ];
Expand All @@ -37,6 +55,8 @@ stdenv.mkDerivation (finalAttrs: {
runHook postInstall
'';

passthru.updateScript = ./update.py;

meta = with lib; {
description = "ownCloud Infinite Scale Stack ";
homepage = "https://owncloud.dev/ocis/";
Expand All @@ -50,6 +70,13 @@ stdenv.mkDerivation (finalAttrs: {
danth
ramblurr
];

platforms =
(lib.intersectLists platforms.linux (
lib.platforms.arm ++ lib.platforms.aarch64 ++ lib.platforms.x86
))
++ (lib.intersectLists platforms.darwin (lib.platforms.aarch64 ++ lib.platforms.x86_64));

sourceProvenance = [ sourceTypes.binaryNativeCode ];
mainProgram = "ocis";
};
Expand Down
215 changes: 215 additions & 0 deletions pkgs/by-name/oc/ocis-bin/update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
#!/usr/bin/env nix-shell
##!nix-shell -I nixpkgs=./. -i python3 -p common-updater-scripts gnused nix coreutils python312
"""
Updater script for the ocis-bin package.

This script fetches an HTML table from a specified URL and parses it to determine the release type
(either "Rolling" or "Production") of a given software version. It uses the built-in urllib.request
for fetching the HTML content and the built-in html.parser for parsing the HTML. By relying only on
standard library modules, we avoid dependencies on third-party libraries, which simplifies deployment
and improves portability.
"""
import urllib.request
import os
import subprocess
import json
import sys
from datetime import datetime
from html.parser import HTMLParser

TRACKING_CHANNEL = "Production" # Either Rolling or Production

GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", None)


class TableParser(HTMLParser):
def __init__(self, version):
super().__init__()
self.version = version
self.in_td = False
self.current_row = []
self.release_type = None
self.in_target_row = False

def handle_starttag(self, tag, attrs):
if tag == "td":
self.in_td = True

if tag == "a":
href = dict(attrs).get("href", "")
if self.version in href:
self.in_target_row = True

def handle_endtag(self, tag):
if tag == "td":
self.in_td = False

if tag == "tr" and self.in_target_row:
self.release_type = self.current_row[1]
self.in_target_row = False

if tag == "tr":
self.current_row = []

def handle_data(self, data):
if self.in_td:
self.current_row.append(data.strip())


def get_release_type(content, version):
parser = TableParser(version)
parser.feed(content)
return parser.release_type


def get_latest_version():
url = "https://api.github.com/repos/owncloud/ocis/releases?per_page=1"
req = urllib.request.Request(url)

if GITHUB_TOKEN:
req.add_header("Authorization", f"Bearer {GITHUB_TOKEN}")

with urllib.request.urlopen(req) as response:
if response.status != 200:
raise Exception(f"HTTP request failed with status {response.status}")

data = response.read()
releases = json.loads(data)
latest_version = releases[0]["tag_name"].lstrip("v")

return latest_version


def get_all_versions():
url = "https://api.github.com/repos/owncloud/ocis/releases"
req = urllib.request.Request(url)

if GITHUB_TOKEN:
req.add_header("Authorization", f"Bearer {GITHUB_TOKEN}")

with urllib.request.urlopen(req) as response:
if response.status != 200:
raise Exception(f"HTTP request failed with status {response.status}")

data = response.read()
releases = json.loads(data)

versions = []
for release in releases:
version = release["tag_name"].lstrip("v")
published_date = datetime.strptime(
release["published_at"], "%Y-%m-%dT%H:%M:%SZ"
)
versions.append({"version": version, "published_date": published_date})

return versions


def get_current_version():
result = subprocess.run(
[
"nix-instantiate",
"--eval",
"-E",
"with import ./. {}; ocis-bin.version or (lib.getVersion ocis-bin)",
],
capture_output=True,
text=True,
)
result.check_returncode()
return result.stdout.strip().strip('"')


def get_hash(os_name, arch, version):
url = f"https://github.com/owncloud/ocis/releases/download/v{version}/ocis-{version}-{os_name}-{arch}"
result = subprocess.run(
["nix-prefetch-url", "--type", "sha256", url], capture_output=True, text=True
)
result.check_returncode()
pkg_hash = result.stdout.strip()
result = subprocess.run(
["nix", "hash", "to-sri", f"sha256:{pkg_hash}"], capture_output=True, text=True
)
result.check_returncode()
return result.stdout.strip()


def update_source_version(pkg_name, version, hash_value, system):
subprocess.run(
[
"update-source-version",
pkg_name,
version,
hash_value,
f"--system={system}",
"--ignore-same-version",
],
check=True,
)


def main():
all_versions = get_all_versions()
latest_version = all_versions[0]
nix_current_version = get_current_version()

current_version = None
for version in all_versions:
if nix_current_version == version["version"]:
current_version = version
break

if not current_version:
print(
f"error: cannot find github release for current nix version of ocis-bin {nix_current_version}"
)
sys.exit(1)

if current_version == latest_version:
print(f"ocis-bin is up-to-date: {current_version}")
return

roadmap_url = "https://owncloud.dev/ocis/release_roadmap/"
response = urllib.request.urlopen(roadmap_url)
content = response.read().decode("utf-8")
latest_version_channel = get_release_type(content, latest_version["version"])
current_version_channel = get_release_type(content, current_version["version"])

target_version = None
if latest_version_channel == TRACKING_CHANNEL:
target_version = latest_version
elif latest_version_channel != TRACKING_CHANNEL:
for version in all_versions:
channel = get_release_type(content, version["version"])
if (
channel == TRACKING_CHANNEL
and version["published_date"] > current_version["published_date"]
):
target_version = version
print(
f"ocis-bin found newer version {version['version']} in channel {TRACKING_CHANNEL}"
)
break

if not target_version:
print(
f"ocis-bin could not find newer version in {TRACKING_CHANNEL} than the current {current_version['version']}"
)
return

systems = [
("darwin", "arm64", "aarch64-darwin"),
("darwin", "amd64", "x86_64-darwin"),
("linux", "arm64", "aarch64-linux"),
("linux", "arm", "armv7l-linux"),
("linux", "amd64", "x86_64-linux"),
("linux", "386", "i686-linux"),
]

for os_name, arch, system in systems:
hash_value = get_hash(os_name, arch, target_version["version"])
update_source_version("ocis-bin", target_version["version"], hash_value, system)


if __name__ == "__main__":
main()