Unverified Commit 0ee8715a authored by github-actions[bot]'s avatar github-actions[bot] Committed by GitHub
Browse files

Merge master into staging-next

parents 195ccf5b ec88b0d0
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -7899,6 +7899,11 @@
    githubId = 31008330;
    name = "Jann Marc Villablanca";
  };
  jgarcia = {
    github = "chewblacka";
    githubId = 18430320;
    name = "John Garcia";
  };
  jgart = {
    email = "jgart@dismail.de";
    github = "jgarte";
+106 −77
Original line number Diff line number Diff line
@@ -4,20 +4,20 @@
# - maintainers/scripts/update-luarocks-packages

# format:
# $ nix run nixpkgs.python3Packages.black -c black update.py
# $ nix run nixpkgs#black maintainers/scripts/pluginupdate.py
# type-check:
# $ nix run nixpkgs.python3Packages.mypy -c mypy update.py
# $ nix run nixpkgs#python3.pkgs.mypy maintainers/scripts/pluginupdate.py
# linted:
# $ nix run nixpkgs.python3Packages.flake8 -c flake8 --ignore E501,E265 update.py
# $ nix run nixpkgs#python3.pkgs.flake8 -- --ignore E501,E265 maintainers/scripts/pluginupdate.py

import argparse
import csv
import functools
import http
import json
import logging
import os
import subprocess
import logging
import sys
import time
import traceback
@@ -25,14 +25,14 @@ import urllib.error
import urllib.parse
import urllib.request
import xml.etree.ElementTree as ET
from dataclasses import asdict, dataclass
from datetime import datetime
from functools import wraps
from multiprocessing.dummy import Pool
from pathlib import Path
from typing import Dict, List, Optional, Tuple, Union, Any, Callable
from urllib.parse import urljoin, urlparse
from tempfile import NamedTemporaryFile
from dataclasses import dataclass, asdict
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
from urllib.parse import urljoin, urlparse

import git

@@ -41,12 +41,13 @@ ATOM_LINK = "{http://www.w3.org/2005/Atom}link" # "
ATOM_UPDATED = "{http://www.w3.org/2005/Atom}updated"  # "

LOG_LEVELS = {
    logging.getLevelName(level): level for level in [
        logging.DEBUG, logging.INFO, logging.WARN, logging.ERROR ]
    logging.getLevelName(level): level
    for level in [logging.DEBUG, logging.INFO, logging.WARN, logging.ERROR]
}

log = logging.getLogger()


def retry(ExceptionToCheck: Any, tries: int = 4, delay: float = 3, backoff: float = 2):
    """Retry calling the decorated function using an exponential backoff.
    http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
@@ -77,6 +78,7 @@ def retry(ExceptionToCheck: Any, tries: int = 4, delay: float = 3, backoff: floa

    return deco_retry


@dataclass
class FetchConfig:
    proc: int
@@ -91,22 +93,21 @@ def make_request(url: str, token=None) -> urllib.request.Request:


# a dictionary of plugins and their new repositories
Redirects = Dict['PluginDesc', 'Repo']
Redirects = Dict["PluginDesc", "Repo"]


class Repo:
    def __init__(
        self, uri: str, branch: str
    ) -> None:
    def __init__(self, uri: str, branch: str) -> None:
        self.uri = uri
        '''Url to the repo'''
        """Url to the repo"""
        self._branch = branch
        # Redirect is the new Repo to use
        self.redirect: Optional['Repo'] = None
        self.redirect: Optional["Repo"] = None
        self.token = "dummy_token"

    @property
    def name(self):
        return self.uri.split('/')[-1]
        return self.uri.split("/")[-1]

    @property
    def branch(self):
@@ -114,6 +115,7 @@ class Repo:

    def __str__(self) -> str:
        return f"{self.uri}"

    def __repr__(self) -> str:
        return f"Repo({self.name}, {self.uri})"

@@ -125,9 +127,9 @@ class Repo:
    def latest_commit(self) -> Tuple[str, datetime]:
        log.debug("Latest commit")
        loaded = self._prefetch(None)
        updated = datetime.strptime(loaded['date'], "%Y-%m-%dT%H:%M:%S%z")
        updated = datetime.strptime(loaded["date"], "%Y-%m-%dT%H:%M:%S%z")

        return loaded['rev'], updated
        return loaded["rev"], updated

    def _prefetch(self, ref: Optional[str]):
        cmd = ["nix-prefetch-git", "--quiet", "--fetch-submodules", self.uri]
@@ -144,23 +146,23 @@ class Repo:
        return loaded["sha256"]

    def as_nix(self, plugin: "Plugin") -> str:
        return f'''fetchgit {{
        return f"""fetchgit {{
      url = "{self.uri}";
      rev = "{plugin.commit}";
      sha256 = "{plugin.sha256}";
    }}'''
    }}"""


class RepoGitHub(Repo):
    def __init__(
        self, owner: str, repo: str, branch: str
    ) -> None:
    def __init__(self, owner: str, repo: str, branch: str) -> None:
        self.owner = owner
        self.repo = repo
        self.token = None
        '''Url to the repo'''
        """Url to the repo"""
        super().__init__(self.url(""), branch)
        log.debug("Instantiating github repo owner=%s and repo=%s", self.owner, self.repo)
        log.debug(
            "Instantiating github repo owner=%s and repo=%s", self.owner, self.repo
        )

    @property
    def name(self):
@@ -213,7 +215,6 @@ class RepoGitHub(Repo):
            new_repo = RepoGitHub(owner=new_owner, repo=new_name, branch=self.branch)
            self.redirect = new_repo


    def prefetch(self, commit: str) -> str:
        if self.has_submodules():
            sha256 = super().prefetch(commit)
@@ -233,12 +234,12 @@ class RepoGitHub(Repo):
        else:
            submodule_attr = ""

        return f'''fetchFromGitHub {{
        return f"""fetchFromGitHub {{
      owner = "{self.owner}";
      repo = "{self.repo}";
      rev = "{plugin.commit}";
      sha256 = "{plugin.sha256}";{submodule_attr}
    }}'''
    }}"""


@dataclass(frozen=True)
@@ -258,15 +259,14 @@ class PluginDesc:
        return self.repo.name < other.repo.name

    @staticmethod
    def load_from_csv(config: FetchConfig, row: Dict[str, str]) -> 'PluginDesc':
    def load_from_csv(config: FetchConfig, row: Dict[str, str]) -> "PluginDesc":
        branch = row["branch"]
        repo = make_repo(row['repo'], branch.strip())
        repo = make_repo(row["repo"], branch.strip())
        repo.token = config.github_token
        return PluginDesc(repo, branch.strip(), row["alias"])


    @staticmethod
    def load_from_string(config: FetchConfig, line: str) -> 'PluginDesc':
    def load_from_string(config: FetchConfig, line: str) -> "PluginDesc":
        branch = "HEAD"
        alias = None
        uri = line
@@ -279,6 +279,7 @@ class PluginDesc:
        repo.token = config.github_token
        return PluginDesc(repo, branch.strip(), alias)


@dataclass
class Plugin:
    name: str
@@ -302,22 +303,38 @@ class Plugin:
        return copy


def load_plugins_from_csv(config: FetchConfig, input_file: Path,) -> List[PluginDesc]:
def load_plugins_from_csv(
    config: FetchConfig,
    input_file: Path,
) -> List[PluginDesc]:
    log.debug("Load plugins from csv %s", input_file)
    plugins = []
    with open(input_file, newline='') as csvfile:
    with open(input_file, newline="") as csvfile:
        log.debug("Writing into %s", input_file)
        reader = csv.DictReader(csvfile,)
        reader = csv.DictReader(
            csvfile,
        )
        for line in reader:
            plugin = PluginDesc.load_from_csv(config, line)
            plugins.append(plugin)

    return plugins


def run_nix_expr(expr):
    with CleanEnvironment():
        cmd = ["nix", "eval", "--extra-experimental-features",
                "nix-command", "--impure", "--json", "--expr", expr]
    with CleanEnvironment() as nix_path:
        cmd = [
            "nix",
            "eval",
            "--extra-experimental-features",
            "nix-command",
            "--impure",
            "--json",
            "--expr",
            expr,
            "--nix-path",
            nix_path,
        ]
        log.debug("Running command %s", " ".join(cmd))
        out = subprocess.check_output(cmd)
        data = json.loads(out)
@@ -348,7 +365,7 @@ class Editor:
        self.nixpkgs_repo = None

    def add(self, args):
        '''CSV spec'''
        """CSV spec"""
        log.debug("called the 'add' command")
        fetch_config = FetchConfig(args.proc, args.github_token)
        editor = self
@@ -357,22 +374,26 @@ class Editor:
            pdesc = PluginDesc.load_from_string(fetch_config, plugin_line)
            log.debug("loaded as pdesc", pdesc)
            append = [pdesc]
            editor.rewrite_input(fetch_config, args.input_file, editor.deprecated, append=append)
            plugin, _ = prefetch_plugin(pdesc, )
            editor.rewrite_input(
                fetch_config, args.input_file, editor.deprecated, append=append
            )
            plugin, _ = prefetch_plugin(
                pdesc,
            )
            autocommit = not args.no_commit
            if autocommit:
                commit(
                    editor.nixpkgs_repo,
                    "{drv_name}: init at {version}".format(
                        drv_name=editor.get_drv_name(plugin.normalized_name),
                        version=plugin.version
                        version=plugin.version,
                    ),
                    [args.outfile, args.input_file],
                )

    # Expects arguments generated by 'update' subparser
    def update(self, args):
        '''CSV spec'''
        """CSV spec"""
        print("the update member function should be overriden in subclasses")

    def get_current_plugins(self) -> List[Plugin]:
@@ -385,11 +406,11 @@ class Editor:
        return plugins

    def load_plugin_spec(self, config: FetchConfig, plugin_file) -> List[PluginDesc]:
        '''CSV spec'''
        """CSV spec"""
        return load_plugins_from_csv(config, plugin_file)

    def generate_nix(self, _plugins, _outfile: str):
        '''Returns nothing for now, writes directly to outfile'''
        """Returns nothing for now, writes directly to outfile"""
        raise NotImplementedError()

    def get_update(self, input_file: str, outfile: str, config: FetchConfig):
@@ -413,7 +434,6 @@ class Editor:

        return update


    @property
    def attr_path(self):
        return self.name + "Plugins"
@@ -427,10 +447,11 @@ class Editor:
    def create_parser(self):
        common = argparse.ArgumentParser(
            add_help=False,
            description=(f"""
            description=(
                f"""
                Updates nix derivations for {self.name} plugins.\n
                By default from {self.default_in} to {self.default_out}"""
            )
            ),
        )
        common.add_argument(
            "--input-names",
@@ -463,26 +484,33 @@ class Editor:
            Uses GITHUB_API_TOKEN environment variables as the default value.""",
        )
        common.add_argument(
            "--no-commit", "-n", action="store_true", default=False,
            help="Whether to autocommit changes"
            "--no-commit",
            "-n",
            action="store_true",
            default=False,
            help="Whether to autocommit changes",
        )
        common.add_argument(
            "--debug", "-d", choices=LOG_LEVELS.keys(),
            "--debug",
            "-d",
            choices=LOG_LEVELS.keys(),
            default=logging.getLevelName(logging.WARN),
            help="Adjust log level"
            help="Adjust log level",
        )

        main = argparse.ArgumentParser(
            parents=[common],
            description=(f"""
            description=(
                f"""
                Updates nix derivations for {self.name} plugins.\n
                By default from {self.default_in} to {self.default_out}"""
            )
            ),
        )

        subparsers = main.add_subparsers(dest="command", required=False)
        padd = subparsers.add_parser(
            "add", parents=[],
            "add",
            parents=[],
            description="Add new plugin",
            add_help=False,
        )
@@ -502,10 +530,12 @@ class Editor:
        pupdate.set_defaults(func=self.update)
        return main

    def run(self,):
        '''
    def run(
        self,
    ):
        """
        Convenience function
        '''
        """
        parser = self.create_parser()
        args = parser.parse_args()
        command = args.command or "update"
@@ -518,17 +548,15 @@ class Editor:
        getattr(self, command)(args)




class CleanEnvironment(object):
    def __enter__(self) -> None:
    def __enter__(self) -> str:
        self.old_environ = os.environ.copy()
        local_pkgs = str(Path(__file__).parent.parent.parent)
        os.environ["NIX_PATH"] = f"localpkgs={local_pkgs}"
        self.empty_config = NamedTemporaryFile()
        self.empty_config.write(b"{}")
        self.empty_config.flush()
        os.environ["NIXPKGS_CONFIG"] = self.empty_config.name
        return f"localpkgs={local_pkgs}"

    def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
        os.environ.update(self.old_environ)
@@ -570,14 +598,15 @@ def print_download_error(plugin: PluginDesc, ex: Exception):
    ]
    print("\n".join(tb_lines))


def check_results(
    results: List[Tuple[PluginDesc, Union[Exception, Plugin], Optional[Repo]]]
) -> Tuple[List[Tuple[PluginDesc, Plugin]], Redirects]:
    ''' '''
    """ """
    failures: List[Tuple[PluginDesc, Exception]] = []
    plugins = []
    redirects: Redirects = {}
    for (pdesc, result, redirect) in results:
    for pdesc, result, redirect in results:
        if isinstance(result, Exception):
            failures.append((pdesc, result))
        else:
@@ -594,17 +623,18 @@ def check_results(
    else:
        print(f", {len(failures)} plugin(s) could not be downloaded:\n")

        for (plugin, exception) in failures:
        for plugin, exception in failures:
            print_download_error(plugin, exception)

        sys.exit(1)


def make_repo(uri: str, branch) -> Repo:
    '''Instantiate a Repo with the correct specialization depending on server (gitub spec)'''
    """Instantiate a Repo with the correct specialization depending on server (gitub spec)"""
    # dumb check to see if it's of the form owner/repo (=> github) or https://...
    res = urlparse(uri)
    if res.netloc in ["github.com", ""]:
        res = res.path.strip('/').split('/')
        res = res.path.strip("/").split("/")
        repo = RepoGitHub(res[0], res[1], branch)
    else:
        repo = Repo(uri.strip(), branch)
@@ -675,7 +705,6 @@ def prefetch(
        return (pluginDesc, e, None)



def rewrite_input(
    config: FetchConfig,
    input_file: Path,
@@ -684,12 +713,14 @@ def rewrite_input(
    redirects: Redirects = {},
    append: List[PluginDesc] = [],
):
    plugins = load_plugins_from_csv(config, input_file,)
    plugins = load_plugins_from_csv(
        config,
        input_file,
    )

    plugins.extend(append)

    if redirects:

        cur_date_iso = datetime.now().strftime("%Y-%m-%d")
        with open(deprecated, "r") as f:
            deprecations = json.load(f)
@@ -709,8 +740,8 @@ def rewrite_input(
    with open(input_file, "w") as f:
        log.debug("Writing into %s", input_file)
        # fields = dataclasses.fields(PluginDesc)
        fieldnames = ['repo', 'branch', 'alias']
        writer = csv.DictWriter(f, fieldnames, dialect='unix', quoting=csv.QUOTE_NONE)
        fieldnames = ["repo", "branch", "alias"]
        writer = csv.DictWriter(f, fieldnames, dialect="unix", quoting=csv.QUOTE_NONE)
        writer.writeheader()
        for plugin in sorted(plugins):
            writer.writerow(asdict(plugin))
@@ -726,7 +757,6 @@ def commit(repo: git.Repo, message: str, files: List[Path]) -> None:
        print("no changes in working tree to commit")



def update_plugins(editor: Editor, args):
    """The main entry function of this module. All input arguments are grouped in the `Editor`."""

@@ -751,4 +781,3 @@ def update_plugins(editor: Editor, args):
                f"{editor.attr_path}: resolve github repository redirects",
                [args.outfile, args.input_file, editor.deprecated],
            )
+23 −3
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ let

  cfg = config.services.gitea-actions-runner;

  settingsFormat = pkgs.formats.yaml { };

  # Check whether any runner instance label requires a container runtime
  # Empty label strings result in the upstream defined defaultLabels, which require docker
  # https://gitea.com/gitea/act_runner/src/tag/v0.1.5/internal/app/cmd/register.go#L93-L98
@@ -119,6 +121,18 @@ in
              that follows the filesystem hierarchy standard.
            '';
          };
          settings = mkOption {
            description = lib.mdDoc ''
              Configuration for `act_runner daemon`.
              See https://gitea.com/gitea/act_runner/src/branch/main/internal/pkg/config/config.example.yaml for an example configuration
            '';

            type = types.submodule {
              freeformType = settingsFormat.type;
            };

            default = { };
          };

          hostPackages = mkOption {
            type = listOf package;
@@ -169,6 +183,7 @@ in
        wantsHost = hasHostScheme instance;
        wantsDocker = wantsContainerRuntime && config.virtualisation.docker.enable;
        wantsPodman = wantsContainerRuntime && config.virtualisation.podman.enable;
        configFile = settingsFormat.generate "config.yaml" instance.settings;
      in
        nameValuePair "gitea-runner-${escapeSystemdPath name}" {
          inherit (instance) enable;
@@ -196,7 +211,12 @@ in
            User = "gitea-runner";
            StateDirectory = "gitea-runner";
            WorkingDirectory = "-/var/lib/gitea-runner/${name}";
            ExecStartPre = pkgs.writeShellScript "gitea-register-runner-${name}" ''

            # gitea-runner might fail when gitea is restarted during upgrade.
            Restart = "on-failure";
            RestartSec = 2;

            ExecStartPre = [(pkgs.writeShellScript "gitea-register-runner-${name}" ''
              export INSTANCE_DIR="$STATE_DIRECTORY/${name}"
              mkdir -vp "$INSTANCE_DIR"
              cd "$INSTANCE_DIR"
@@ -221,8 +241,8 @@ in
                echo "$LABELS_WANTED" > "$LABELS_FILE"
              fi

            '';
            ExecStart = "${cfg.package}/bin/act_runner daemon";
            '')];
            ExecStart = "${cfg.package}/bin/act_runner daemon --config ${configFile}";
            SupplementaryGroups = optionals (wantsDocker) [
              "docker"
            ] ++ optionals (wantsPodman) [
+4 −0
Original line number Diff line number Diff line
@@ -226,6 +226,10 @@ in
      serviceConfig = {
        ExecStart = "${pkgs.rustus}/bin/rustus";
        StateDirectory = "rustus";
        # User name is defined here to enable restoring a backup for example
        # You will run the backup restore command as sudo -u rustus in order
        # to have write permissions to /var/lib
        User = "rustus";
        DynamicUser = true;
        LoadCredential = lib.optionals isHybridS3 [
          "S3_ACCESS_KEY_PATH:${cfg.storage.s3_access_key_file}"
+3 −3
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@

stdenv.mkDerivation rec {
  pname = "squeekboard";
  version = "1.21.0";
  version = "1.22.0";

  src = fetchFromGitLab {
    domain = "gitlab.gnome.org";
@@ -32,7 +32,7 @@ stdenv.mkDerivation rec {
    owner = "Phosh";
    repo = pname;
    rev = "v${version}";
    hash = "sha256-Mn0E+R/UzBLHPvarQHlEN4JBpf4VAaXdKdWLsFEyQE4=";
    hash = "sha256-Rk6LOCZ5bhoo5ORAIIYWENrKUIVypd8bnKjyyBSbUYg=";
  };

  cargoDeps = rustPlatform.fetchCargoTarball {
@@ -42,7 +42,7 @@ stdenv.mkDerivation rec {
      cp Cargo.lock.newer Cargo.lock
    '';
    name = "${pname}-${version}";
    hash = "sha256-F2mef0HvD9WZRx05DEpQ1AO1skMwcchHZzJa74AHmsM=";
    hash = "sha256-DygWra4R/w8KzkFzIVm4+ePpUpjiYGaDx2NQm6o+tWQ=";
  };

  mesonFlags = [
Loading