Compare commits

..

No commits in common. "raihan2000/pipinstall" and "dev" have entirely different histories.

92 changed files with 262 additions and 443 deletions

View file

@ -1,5 +0,0 @@
/venv
/build
__pycache__
.mypy_cache
*.xml

5
.gitignore vendored
View file

@ -1,8 +1,5 @@
*.kate-swp *.kate-swp
/venv venv/
/build
__pycache__/ __pycache__/
.coverage* .coverage*
*.xml *.xml
*.egg-info
dist

View file

@ -7,19 +7,15 @@ format:
stage: check stage: check
image: python image: python
before_script: before_script:
- python3 -m venv venv - pip install yapf autoflake --break-system-packages
- venv/bin/pip3 install yapf autoflake
script: script:
- source venv/bin/activate
- ./format.sh --check - ./format.sh --check
typecheck: typecheck:
stage: check stage: check
image: python image: python
before_script: before_script:
- python3 -m venv venv - pip install mypy --break-system-packages
- source venv/bin/activate
- pip install mypy
script: script:
- ./typecheck.sh --non-interactive --junit-xml mypy-report.xml - ./typecheck.sh --non-interactive --junit-xml mypy-report.xml
artifacts: artifacts:
@ -31,13 +27,12 @@ pytest:
image: archlinux image: archlinux
before_script: before_script:
- pacman -Sy --noconfirm --needed archlinux-keyring && pacman -Su --noconfirm python python-pip sudo git base-devel arch-install-scripts rsync - pacman -Sy --noconfirm --needed archlinux-keyring && pacman -Su --noconfirm python python-pip sudo git base-devel arch-install-scripts rsync
- python3 -m venv venv - pip install -r test_requirements.txt -r requirements.txt --break-system-packages
- venv/bin/pip3 install -r test_requirements.txt -r requirements.txt
- 'echo "kupfer ALL = (ALL) NOPASSWD: ALL" > /etc/sudoers.d/kupfer_all' - 'echo "kupfer ALL = (ALL) NOPASSWD: ALL" > /etc/sudoers.d/kupfer_all'
- useradd -m kupfer - useradd -m kupfer
- chmod 777 . - chmod 777 .
script: script:
- script -e -c 'su kupfer -s /bin/bash -c ". venv/bin/activate && INTEGRATION_TESTS_USE_GLOBAL_CONFIG=TRUE KUPFERBOOTSTRAP_WRAPPED=DOCKER ./pytest.sh --junit-xml=pytest-report.xml --cov-report=xml:coverage.xml integration_tests.py"' - script -e -c 'su kupfer -s /bin/bash -c "INTEGRATION_TESTS_USE_GLOBAL_CONFIG=TRUE KUPFERBOOTSTRAP_WRAPPED=DOCKER ./pytest.sh --junit-xml=pytest-report.xml --cov-report=xml:coverage.xml integration_tests.py"'
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/' coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
artifacts: artifacts:
reports: reports:
@ -56,7 +51,6 @@ build_docker:
DOCKER_TLS_CERTDIR: "" DOCKER_TLS_CERTDIR: ""
script: script:
- 'docker build --pull -t "${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}" -t "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}" .' - 'docker build --pull -t "${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}" -t "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}" .'
- 'echo "running sanity check" && docker run -it --rm "${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}" kupferbootstrap --help'
only: only:
- branches - branches
except: except:
@ -83,9 +77,7 @@ push_docker:
DOCS_MAKE_TARGET: "html" DOCS_MAKE_TARGET: "html"
DOCS_MAKE_THREADS: 6 DOCS_MAKE_THREADS: 6
before_script: &docs_before_script before_script: &docs_before_script
- python3 -m venv venv - pip install -r requirements.txt -r docs/requirements.txt --break-system-packages
- source venv/bin/activate
- pip install -r requirements.txt -r docs/requirements.txt
script: &docs_script script: &docs_script
- make -C docs -j$DOCS_MAKE_THREADS SPHINXARGS="$DOCS_SPHINXARGS" $DOCS_MAKE_TARGET - make -C docs -j$DOCS_MAKE_THREADS SPHINXARGS="$DOCS_SPHINXARGS" $DOCS_MAKE_TARGET
- mv "docs/$DOCS_MAKE_TARGET" public - mv "docs/$DOCS_MAKE_TARGET" public

View file

@ -17,14 +17,16 @@ RUN yes | pacman -Scc
RUN sed -i "s/SigLevel.*/SigLevel = Never/g" /etc/pacman.conf RUN sed -i "s/SigLevel.*/SigLevel = Never/g" /etc/pacman.conf
ENV KUPFERBOOTSTRAP_WRAPPED=DOCKER ENV KUPFERBOOTSTRAP_WRAPPED=DOCKER
ENV PATH=/app/bin:/app/local/bin:/app/venv/bin:$PATH ENV PATH=/app/bin:/app/local/bin:$PATH
WORKDIR /app WORKDIR /app
COPY . . COPY requirements.txt .
RUN python3 -m venv /app/venv # TODO: pip packaging so we don't need --break-system-packages
RUN /app/venv/bin/pip3 install -r requirements.txt RUN pip install -r requirements.txt --break-system-packages
RUN /app/venv/bin/python3 -c "from kupferbootstrap.distro import distro; distro.get_kupfer_local(arch=None,in_chroot=False).repos_config_snippet()" | tee -a /etc/pacman.conf COPY . .
RUN python -c "from distro import distro; distro.get_kupfer_local(arch=None,in_chroot=False).repos_config_snippet()" | tee -a /etc/pacman.conf
RUN useradd -m -g users kupfer RUN useradd -m -g users kupfer
RUN echo "kupfer ALL=(ALL) NOPASSWD: ALL" | tee /etc/sudoers.d/kupfer RUN echo "kupfer ALL=(ALL) NOPASSWD: ALL" | tee /etc/sudoers.d/kupfer

View file

@ -18,26 +18,14 @@ This will run a webserver on localhost:9999. Access it like `firefox http://loca
## Installation ## Installation
0. If you're not on ArchLinux (i.e. don't have `pacman`, `makepkg`, etc. available in your $PATH), install Docker and add yourself to the docker group. Install Docker, Python 3 with the libraries from `requirements.txt` and put `bin/` into your `PATH`.
1. Craate a python venv: `python3 -m venv venv` Then use `kupferbootstrap`.
1. Activate it: `source venv/bin/activate`
1. Install KBS: `pip3 install .`
Then run `kupferbootstrap`.
### Pro Tip:
- You can add a shell alias for `$(PWD)/venv/bin/kupferbootstrap` or create a symlink to it at `/usr/local/bin/kuperbootstrap` for quick access without needing to manually source the venv script every time.
- It is recommended to abbreviate `kupferbootstrap` to `kbs` for even less typing.
## Quickstart ## Quickstart
1. Initialize config with defaults, configure your device and flavour: `kupferbootstrap config init` 1. Initialize config with defaults, configure your device and flavour: `kupferbootstrap config init`
1. Initialize PKGBUILDs and caches: `kupferbootstrap packages init`
1. Build an image and packages along the way: `kupferbootstrap image build` 1. Build an image and packages along the way: `kupferbootstrap image build`
## Development ## Development
Put `dev` into `version.txt` to always rebuild kupferboostrap from this directory and use `kupferbootstrap` as normal.
### Docker
Put `BUILD` (the default) into `docker_version.txt` to always rebuild kupferboostrap from this directory; otherwise the image is pulled from `registry.gitlab.com/kupfer/kupferbootstrap:$VERSION`, where `$VERSION` is the contents of `docker_version.txt`.

4
bin/kupferbootstrap Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
# shellcheck disable=SC2068
python3 "$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")/main.py" $@

View file

@ -5,10 +5,10 @@ import logging
from typing import Optional from typing import Optional
from kupferbootstrap.chroot.abstract import Chroot from chroot.abstract import Chroot
from kupferbootstrap.constants import Arch, QEMU_ARCHES from constants import Arch, QEMU_ARCHES
from kupferbootstrap.exec.cmd import run_root_cmd, CompletedProcess from exec.cmd import run_root_cmd, CompletedProcess
from kupferbootstrap.utils import mount from utils import mount
def binfmt_info(chroot: Optional[Chroot] = None): def binfmt_info(chroot: Optional[Chroot] = None):

View file

@ -3,7 +3,7 @@ import os
from typing import Optional from typing import Optional
from kupferbootstrap.constants import Arch, ARCHES from constants import Arch, ARCHES
from .binfmt import binfmt_unregister, binfmt_is_registered from .binfmt import binfmt_unregister, binfmt_is_registered
@ -15,7 +15,7 @@ arches_arg_optional = click.argument('arches', type=click.Choice(ARCHES), nargs=
@cmd_binfmt.command('register', help='Register a binfmt handler with the kernel') @cmd_binfmt.command('register', help='Register a binfmt handler with the kernel')
@arches_arg @arches_arg
def cmd_register(arches: list[Arch], disable_chroot: bool = False): def cmd_register(arches: list[Arch], disable_chroot: bool = False):
from ..packages.build import build_enable_qemu_binfmt from packages.build import build_enable_qemu_binfmt
for arch in arches: for arch in arches:
build_enable_qemu_binfmt(arch) build_enable_qemu_binfmt(arch)

View file

@ -2,11 +2,11 @@ import click
import os import os
import logging import logging
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import CHROOT_PATHS from constants import CHROOT_PATHS
from kupferbootstrap.exec.file import remove_file from exec.file import remove_file
from kupferbootstrap.packages.cli import cmd_clean as cmd_clean_pkgbuilds from packages.cli import cmd_clean as cmd_clean_pkgbuilds
from kupferbootstrap.wrapper import enforce_wrap from wrapper import enforce_wrap
PATHS = list(CHROOT_PATHS.keys()) PATHS = list(CHROOT_PATHS.keys())

View file

@ -9,13 +9,13 @@ from shlex import quote as shell_quote
from typing import ClassVar, Iterable, Protocol, Union, Optional, Mapping from typing import ClassVar, Iterable, Protocol, Union, Optional, Mapping
from uuid import uuid4 from uuid import uuid4
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import Arch, CHROOT_PATHS, GCC_HOSTSPECS from constants import Arch, CHROOT_PATHS, GCC_HOSTSPECS
from kupferbootstrap.distro.distro import get_base_distro, get_kupfer_local, RepoInfo from distro.distro import get_base_distro, get_kupfer_local, RepoInfo
from kupferbootstrap.exec.cmd import FileDescriptor, run_root_cmd, generate_env_cmd, flatten_shell_script, wrap_in_bash, generate_cmd_su from exec.cmd import FileDescriptor, run_root_cmd, generate_env_cmd, flatten_shell_script, wrap_in_bash, generate_cmd_su
from kupferbootstrap.exec.file import makedir, root_makedir, root_write_file, write_file from exec.file import makedir, root_makedir, root_write_file, write_file
from kupferbootstrap.generator import generate_makepkg_conf from generator import generate_makepkg_conf
from kupferbootstrap.utils import mount, umount, check_findmnt, log_or_exception from utils import mount, umount, check_findmnt, log_or_exception
from .helpers import BASE_CHROOT_PREFIX, BASIC_MOUNTS, base_chroot_name, make_abs_path from .helpers import BASE_CHROOT_PREFIX, BASIC_MOUNTS, base_chroot_name, make_abs_path

View file

@ -6,10 +6,10 @@ from glob import glob
from shutil import rmtree from shutil import rmtree
from typing import ClassVar from typing import ClassVar
from kupferbootstrap.constants import Arch from constants import Arch
from kupferbootstrap.exec.cmd import run_root_cmd from exec.cmd import run_root_cmd
from kupferbootstrap.exec.file import makedir, root_makedir from exec.file import makedir, root_makedir
from kupferbootstrap.config.state import config from config.state import config
from .abstract import Chroot, get_chroot from .abstract import Chroot, get_chroot
from .helpers import base_chroot_name from .helpers import base_chroot_name

View file

@ -4,11 +4,11 @@ import subprocess
from glob import glob from glob import glob
from typing import ClassVar, Optional from typing import ClassVar, Optional
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import Arch, GCC_HOSTSPECS, CROSSDIRECT_PKGS, CHROOT_PATHS from constants import Arch, GCC_HOSTSPECS, CROSSDIRECT_PKGS, CHROOT_PATHS
from kupferbootstrap.distro.distro import get_kupfer_local from distro.distro import get_kupfer_local
from kupferbootstrap.exec.cmd import run_root_cmd from exec.cmd import run_root_cmd
from kupferbootstrap.exec.file import makedir, remove_file, root_makedir, root_write_file, symlink from exec.file import makedir, remove_file, root_makedir, root_write_file, symlink
from .abstract import Chroot, get_chroot from .abstract import Chroot, get_chroot
from .helpers import build_chroot_name from .helpers import build_chroot_name

View file

@ -4,9 +4,9 @@ import os
from typing import Optional from typing import Optional
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.wrapper import enforce_wrap from wrapper import enforce_wrap
from kupferbootstrap.devices.device import get_profile_device from devices.device import get_profile_device
from .abstract import Chroot from .abstract import Chroot
from .base import get_base_chroot from .base import get_base_chroot
@ -30,7 +30,7 @@ def cmd_chroot(ctx: click.Context, type: str = 'build', name: Optional[str] = No
raise Exception(f'Unknown chroot type: "{type}"') raise Exception(f'Unknown chroot type: "{type}"')
if type == 'rootfs': if type == 'rootfs':
from ..image.image import cmd_inspect from image.image import cmd_inspect
assert isinstance(cmd_inspect, click.Command) assert isinstance(cmd_inspect, click.Command)
ctx.invoke(cmd_inspect, profile=name, shell=True) ctx.invoke(cmd_inspect, profile=name, shell=True)
return return

View file

@ -1,14 +1,14 @@
import atexit import atexit
import os import os
from typing import ClassVar, Optional, cast from typing import ClassVar, Optional
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import Arch, BASE_PACKAGES from constants import Arch, BASE_PACKAGES
from kupferbootstrap.distro.repo import RepoInfo from distro.repo import RepoInfo
from kupferbootstrap.distro.distro import get_kupfer_local, get_kupfer_https from distro.distro import get_kupfer_local, get_kupfer_https
from kupferbootstrap.exec.file import get_temp_dir, makedir, root_makedir from exec.file import get_temp_dir, makedir, root_makedir
from kupferbootstrap.utils import check_findmnt from utils import check_findmnt
from .base import BaseChroot from .base import BaseChroot
from .build import BuildChroot from .build import BuildChroot
@ -20,14 +20,15 @@ class DeviceChroot(BuildChroot):
_copy_base: ClassVar[bool] = False _copy_base: ClassVar[bool] = False
def create_rootfs(self, reset, pacman_conf_target, active_previously): def create_rootfs(self, reset, pacman_conf_target, active_previously):
clss = BuildChroot if self.copy_base else BaseChroot
makedir(config.get_path('chroots')) makedir(config.get_path('chroots'))
root_makedir(self.get_path()) root_makedir(self.get_path())
if not self.copy_base: if not self.copy_base:
pacman_conf_target = os.path.join(get_temp_dir(register_cleanup=True), f'pacman-{self.name}.conf') pacman_conf_target = os.path.join(get_temp_dir(register_cleanup=True), f'pacman-{self.name}.conf')
self.write_pacman_conf(in_chroot=False, absolute_path=pacman_conf_target) self.write_pacman_conf(in_chroot=False, absolute_path=pacman_conf_target)
BaseChroot.create_rootfs(cast(BaseChroot, self), reset, pacman_conf_target, active_previously)
else: clss.create_rootfs(self, reset, pacman_conf_target, active_previously)
BuildChroot.create_rootfs(self, reset, pacman_conf_target, active_previously)
def mount_rootfs(self, source_path: str, fs_type: Optional[str] = None, options: list[str] = [], allow_overlay: bool = False): def mount_rootfs(self, source_path: str, fs_type: Optional[str] = None, options: list[str] = [], allow_overlay: bool = False):
if self.active: if self.active:

View file

@ -1,8 +1,8 @@
import os import os
from typing import Optional, TypedDict from typing import Optional, TypedDict
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import Arch from constants import Arch
BIND_BUILD_DIRS = 'BINDBUILDDIRS' BIND_BUILD_DIRS = 'BINDBUILDDIRS'
BASE_CHROOT_PREFIX = 'base_' BASE_CHROOT_PREFIX = 'base_'

View file

@ -4,10 +4,10 @@ import logging
from copy import deepcopy from copy import deepcopy
from typing import Any, Callable, Iterable, Mapping, Optional, Union from typing import Any, Callable, Iterable, Mapping, Optional, Union
from kupferbootstrap.devices.device import get_devices, sanitize_device_name from devices.device import get_devices, sanitize_device_name
from kupferbootstrap.flavours.flavour import get_flavours from flavours.flavour import get_flavours
from kupferbootstrap.utils import color_bold, colors_supported, color_mark_selected from utils import color_bold, colors_supported, color_mark_selected
from kupferbootstrap.wrapper import execute_without_exit from wrapper import execute_without_exit
from .scheme import Profile from .scheme import Profile
from .profile import PROFILE_EMPTY, PROFILE_DEFAULTS, resolve_profile_attr, SparseProfile from .profile import PROFILE_EMPTY, PROFILE_DEFAULTS, resolve_profile_attr, SparseProfile
@ -205,7 +205,7 @@ def prompt_for_save(retry_ctx: Optional[click.Context] = None):
If `retry_ctx` is passed, the context's command will be reexecuted with the same arguments if the user chooses to retry. If `retry_ctx` is passed, the context's command will be reexecuted with the same arguments if the user chooses to retry.
False will still be returned as the retry is expected to either save, perform another retry or arbort. False will still be returned as the retry is expected to either save, perform another retry or arbort.
""" """
from ..wrapper import is_wrapped from wrapper import is_wrapped
if click.confirm(f'Do you want to save your changes to {config.runtime.config_file}?', default=True): if click.confirm(f'Do you want to save your changes to {config.runtime.config_file}?', default=True):
if is_wrapped(): if is_wrapped():
logging.warning("Writing to config file inside wrapper." logging.warning("Writing to config file inside wrapper."

View file

@ -3,8 +3,8 @@ from __future__ import annotations
from munch import Munch from munch import Munch
from typing import Any, Optional, Mapping, Union from typing import Any, Optional, Mapping, Union
from kupferbootstrap.dictscheme import DictScheme from dictscheme import DictScheme
from kupferbootstrap.constants import Arch from constants import Arch
class SparseProfile(DictScheme): class SparseProfile(DictScheme):

View file

@ -5,7 +5,7 @@ import toml
from copy import deepcopy from copy import deepcopy
from typing import Mapping, Optional from typing import Mapping, Optional
from kupferbootstrap.constants import DEFAULT_PACKAGE_BRANCH from constants import DEFAULT_PACKAGE_BRANCH
from .scheme import Config, ConfigLoadState, DictScheme, Profile, RuntimeConfiguration from .scheme import Config, ConfigLoadState, DictScheme, Profile, RuntimeConfiguration
from .profile import PROFILE_DEFAULTS, PROFILE_DEFAULTS_DICT, resolve_profile from .profile import PROFILE_DEFAULTS, PROFILE_DEFAULTS_DICT, resolve_profile

View file

@ -7,9 +7,9 @@ import toml
from tempfile import mktemp, gettempdir as get_system_tempdir from tempfile import mktemp, gettempdir as get_system_tempdir
from typing import Any, Optional from typing import Any, Optional
from kupferbootstrap.config.profile import PROFILE_DEFAULTS from config.profile import PROFILE_DEFAULTS
from kupferbootstrap.config.scheme import Config, Profile from config.scheme import Config, Profile
from kupferbootstrap.config.state import CONFIG_DEFAULTS, ConfigStateHolder from config.state import CONFIG_DEFAULTS, ConfigStateHolder
def get_filename(): def get_filename():

View file

@ -1,4 +1,4 @@
from .typehelpers import TypeAlias from typehelpers import TypeAlias
FASTBOOT = 'fastboot' FASTBOOT = 'fastboot'
FLASH_PARTS = { FLASH_PARTS = {

View file

@ -4,9 +4,9 @@ import logging
from json import dumps as json_dump from json import dumps as json_dump
from typing import Optional from typing import Optional
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.config.cli import resolve_profile_field from config.cli import resolve_profile_field
from kupferbootstrap.utils import color_mark_selected, colors_supported from utils import color_mark_selected, colors_supported
from .device import get_devices, get_device from .device import get_devices, get_device

View file

@ -3,13 +3,13 @@ import os
from typing import Optional from typing import Optional
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import Arch, ARCHES from constants import Arch, ARCHES
from kupferbootstrap.dictscheme import DictScheme from dictscheme import DictScheme
from kupferbootstrap.distro.distro import get_kupfer_local from distro.distro import get_kupfer_local
from kupferbootstrap.distro.package import LocalPackage from distro.package import LocalPackage
from kupferbootstrap.packages.pkgbuild import Pkgbuild, _pkgbuilds_cache, discover_pkgbuilds, get_pkgbuild_by_path, init_pkgbuilds from packages.pkgbuild import Pkgbuild, _pkgbuilds_cache, discover_pkgbuilds, get_pkgbuild_by_path, init_pkgbuilds
from kupferbootstrap.utils import read_files_from_tar, color_str from utils import read_files_from_tar, color_str
from .deviceinfo import DEFAULT_IMAGE_SECTOR_SIZE, DeviceInfo, parse_deviceinfo from .deviceinfo import DEFAULT_IMAGE_SECTOR_SIZE, DeviceInfo, parse_deviceinfo
@ -72,7 +72,7 @@ class Device(DictScheme):
def parse_deviceinfo(self, try_download: bool = True, lazy: bool = True) -> DeviceInfo: def parse_deviceinfo(self, try_download: bool = True, lazy: bool = True) -> DeviceInfo:
if not lazy or 'deviceinfo' not in self or self.deviceinfo is None: if not lazy or 'deviceinfo' not in self or self.deviceinfo is None:
# avoid import loop # avoid import loop
from kupferbootstrap.packages.build import check_package_version_built from packages.build import check_package_version_built
is_built = check_package_version_built(self.package, self.arch, try_download=try_download) is_built = check_package_version_built(self.package, self.arch, try_download=try_download)
if not is_built: if not is_built:
raise Exception(f"device package {self.package.name} for device {self.name} couldn't be acquired!") raise Exception(f"device package {self.package.name} for device {self.name} couldn't be acquired!")

View file

@ -7,9 +7,9 @@ import os
from typing import Mapping, Optional from typing import Mapping, Optional
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import Arch from constants import Arch
from kupferbootstrap.dictscheme import DictScheme from dictscheme import DictScheme
PMOS_ARCHES_OVERRIDES: dict[str, Arch] = { PMOS_ARCHES_OVERRIDES: dict[str, Arch] = {
"armv7": 'armv7h', "armv7": 'armv7h',
@ -205,12 +205,15 @@ def parse_kernel_suffix(deviceinfo: dict[str, Optional[str]], kernel: str = 'mai
https://wiki.postmarketos.org/wiki/Device_specific_package#Multiple_kernels https://wiki.postmarketos.org/wiki/Device_specific_package#Multiple_kernels
:param info: deviceinfo dict, e.g.: :param info: deviceinfo dict, e.g.:
{"a": "first", "b_mainline": "second", "b_downstream": "third"} {"a": "first",
"b_mainline": "second",
"b_downstream": "third"}
:param device: which device info belongs to :param device: which device info belongs to
:param kernel: which kernel suffix to remove (e.g. "mainline") :param kernel: which kernel suffix to remove (e.g. "mainline")
:returns: info, but with the configured kernel suffix removed, e.g: :returns: info, but with the configured kernel suffix removed, e.g:
{"a": "first", "b": "second", "b_downstream": "third"} {"a": "first",
"b": "second",
"b_downstream": "third"}
""" """
# Do nothing if the configured kernel isn't available in the kernel (e.g. # Do nothing if the configured kernel isn't available in the kernel (e.g.
# after switching from device with multiple kernels to device with only one # after switching from device with multiple kernels to device with only one

View file

@ -4,8 +4,8 @@ import os
from copy import copy from copy import copy
from kupferbootstrap.config.state import ConfigStateHolder, config from config.state import ConfigStateHolder, config
from kupferbootstrap.packages.pkgbuild import init_pkgbuilds, discover_pkgbuilds, Pkgbuild, parse_pkgbuild from packages.pkgbuild import init_pkgbuilds, discover_pkgbuilds, Pkgbuild, parse_pkgbuild
from .device import Device, DEVICE_DEPRECATIONS, get_device, get_devices, parse_device_pkg, check_devicepkg_name from .device import Device, DEVICE_DEPRECATIONS, get_device, get_devices, parse_device_pkg, check_devicepkg_name

View file

@ -1,4 +1,4 @@
from kupferbootstrap.config.state import config from config.state import config
from .deviceinfo import DeviceInfo, parse_deviceinfo from .deviceinfo import DeviceInfo, parse_deviceinfo
from .device import get_device from .device import get_device

View file

@ -7,7 +7,7 @@ from munch import Munch
from toml.encoder import TomlEncoder, TomlPreserveInlineDictEncoder from toml.encoder import TomlEncoder, TomlPreserveInlineDictEncoder
from typing import ClassVar, Generator, Optional, Union, Mapping, Any, get_type_hints, get_origin, get_args, Iterable from typing import ClassVar, Generator, Optional, Union, Mapping, Any, get_type_hints, get_origin, get_args, Iterable
from .typehelpers import UnionType, NoneType from typehelpers import UnionType, NoneType
def resolve_type_hint(hint: type, ignore_origins: list[type] = []) -> Iterable[type]: def resolve_type_hint(hint: type, ignore_origins: list[type] = []) -> Iterable[type]:

View file

@ -3,9 +3,9 @@ import logging
from enum import IntFlag from enum import IntFlag
from typing import Generic, Mapping, Optional, TypeVar from typing import Generic, Mapping, Optional, TypeVar
from kupferbootstrap.constants import Arch, ARCHES, REPOSITORIES, KUPFER_BRANCH_MARKER, KUPFER_HTTPS, CHROOT_PATHS from constants import Arch, ARCHES, REPOSITORIES, KUPFER_BRANCH_MARKER, KUPFER_HTTPS, CHROOT_PATHS
from kupferbootstrap.generator import generate_pacman_conf_body from generator import generate_pacman_conf_body
from kupferbootstrap.config.state import config from config.state import config
from .repo import BinaryPackageType, RepoInfo, Repo, LocalRepo, RemoteRepo from .repo import BinaryPackageType, RepoInfo, Repo, LocalRepo, RemoteRepo
from .repo_config import AbstrRepoConfig, BaseDistro, ReposConfigFile, REPOS_CONFIG_DEFAULT, get_repo_config as _get_repo_config from .repo_config import AbstrRepoConfig, BaseDistro, ReposConfigFile, REPOS_CONFIG_DEFAULT, get_repo_config as _get_repo_config

View file

@ -5,7 +5,7 @@ from shutil import copyfileobj
from typing import Optional, Union from typing import Optional, Union
from urllib.request import urlopen from urllib.request import urlopen
from kupferbootstrap.exec.file import get_temp_dir, makedir from exec.file import get_temp_dir, makedir
class PackageInfo: class PackageInfo:

View file

@ -5,9 +5,9 @@ import tarfile
from typing import Generic, TypeVar from typing import Generic, TypeVar
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.exec.file import get_temp_dir from exec.file import get_temp_dir
from kupferbootstrap.utils import download_file from utils import download_file
from .package import BinaryPackage, LocalPackage, RemotePackage from .package import BinaryPackage, LocalPackage, RemotePackage

View file

@ -8,10 +8,10 @@ import yaml
from copy import deepcopy from copy import deepcopy
from typing import ClassVar, Optional, Mapping, Union from typing import ClassVar, Optional, Mapping, Union
from ..config.state import config from config.state import config
from ..constants import Arch, BASE_DISTROS, KUPFER_HTTPS, REPOS_CONFIG_FILE, REPOSITORIES from constants import Arch, BASE_DISTROS, KUPFER_HTTPS, REPOS_CONFIG_FILE, REPOSITORIES
from ..dictscheme import DictScheme, toml_inline_dicts, TomlPreserveInlineDictEncoder from dictscheme import DictScheme, toml_inline_dicts, TomlPreserveInlineDictEncoder
from ..utils import sha256sum from utils import sha256sum
REPOS_KEY = 'repos' REPOS_KEY = 'repos'
REMOTEURL_KEY = 'remote_url' REMOTEURL_KEY = 'remote_url'
@ -142,7 +142,7 @@ def get_repo_config(
config_exists = os.path.exists(repo_config_file_path) config_exists = os.path.exists(repo_config_file_path)
if not config_exists and _current_config is None: if not config_exists and _current_config is None:
if initialize_pkgbuilds: if initialize_pkgbuilds:
from ..packages.pkgbuild import init_pkgbuilds from packages.pkgbuild import init_pkgbuilds
init_pkgbuilds(update=False) init_pkgbuilds(update=False)
return get_repo_config(initialize_pkgbuilds=False, repo_config_file=repo_config_file) return get_repo_config(initialize_pkgbuilds=False, repo_config_file=repo_config_file)
if repo_config_file is not None: if repo_config_file is not None:

View file

@ -1 +0,0 @@
BUILD

1
docs/.gitignore vendored
View file

@ -2,7 +2,6 @@
.doctrees .doctrees
html html
source/cli source/cli
source/code
checkouts checkouts
versions versions
archived archived

View file

@ -14,7 +14,7 @@ cleanbuild:
@$(MAKE) html @$(MAKE) html
clean: clean:
rm -rf html source/cli source/code .buildinfo .doctrees versions checkouts rm -rf html source/cli .buildinfo .doctrees versions checkouts
html: html:
sphinx-build $(SPHINXARGS) $(buildargs) html sphinx-build $(SPHINXARGS) $(buildargs) html

View file

@ -1,7 +1,7 @@
# CLI Interface # CLI Interface
```{eval-rst} ```{eval-rst}
.. click:: kupferbootstrap.main:cli .. click:: main:cli
:nested: none :nested: none
:prog: kupferbootstrap :prog: kupferbootstrap

View file

@ -6,7 +6,6 @@ orphan: true
only used to trigger builds of the submodule docs! only used to trigger builds of the submodule docs!
```{eval-rst} ```{eval-rst}
.. currentmodule:: kupferbootstrap
.. autosummary:: .. autosummary::
:toctree: cli :toctree: cli
:template: command.rst :template: command.rst

View file

@ -1,9 +0,0 @@
# Code
Code documentation is available here
```{toctree}
:glob: true
code/kupferbootstrap
```

View file

@ -1,8 +0,0 @@
:nosearch:
:orphan:
.. autosummary::
:toctree: code
:recursive:
kupferbootstrap

View file

@ -1,14 +1,10 @@
import logging
import os import os
from sphinx.config import getenv import sys
from kupferbootstrap.utils import git
#sys.path.insert(0, os.path.abspath('../..')) sys.path.insert(0, os.path.abspath('../..'))
extensions = [ extensions = [
'sphinx_click', 'sphinx_click',
"sphinx.ext.autodoc", 'sphinx.ext.autosummary', # Create neat summary tables
'sphinx.ext.autosummary',
"sphinx.ext.linkcode",
'myst_parser' 'myst_parser'
] ]
myst_all_links_external = True myst_all_links_external = True
@ -33,45 +29,4 @@ html_theme_options = {
"color-brand-content": "#eba38d", "color-brand-content": "#eba38d",
"color-problematic": "#ff7564", "color-problematic": "#ff7564",
}, },
"source_repository": "https://gitlab.com/kupfer/kupferbootstrap",
"source_directory": "docs/source/",
} }
autosummary_generate = True
autodoc_default_options = {
"members": True,
"undoc-members": True,
"show-inheritance": True,
"inherited-members": True,
}
autodoc_preserve_defaults = True
def get_version():
try:
res = git(
["rev-parse", "HEAD"],
dir=os.path.join(os.path.dirname(__file__), "../.."),
use_git_dir=True,
capture_output=True,
)
res.check_returncode()
ver = res.stdout.decode().strip()
logging.info(f"Detected git {ver=}")
return ver
except Exception as ex:
logging.warning("Couldn't get git branch:", exc_info=ex)
return "HEAD"
version = getenv("version") or get_version()
def linkcode_resolve(domain, info):
if domain != 'py':
return None
if not info['module']:
return None
filename = info['module'].replace('.', '/')
return "%s/-/blob/%s/src/%s.py" % (html_theme_options["source_repository"], version, filename)

View file

@ -1,2 +0,0 @@
Module Index
============

View file

@ -8,6 +8,4 @@ a tool to build and flash packages and images for the [Kupfer](https://gitlab.co
```{toctree} ```{toctree}
usage/index usage/index
cli cli
code
genindex
``` ```

View file

@ -1,36 +0,0 @@
{% set reduced_name = fullname.split(".", 1)[-1] if fullname.startswith("kupferbootstrap.") else fullname %}
{{ fullname | escape | underline }}
.. rubric:: Description
.. automodule:: {{ fullname }}
:members:
:undoc-members:
.. currentmodule:: {{ fullname }}
{% if classes %}
.. rubric:: Classes
.. autosummary::
:toctree: .
{% for class in classes %}
{{ class }}
{% endfor %}
{% endif %}
{% if functions %}
.. rubric:: Functions
.. autosummary::
:toctree: .
{% for function in functions %}
{{ function }}
{% endfor %}
{% endif %}

View file

@ -1,9 +1,6 @@
{% set reduced_name = fullname.split(".", 1)[-1] if fullname.startswith("kupferbootstrap.") else fullname %} .. title: {{fullname}}
.. title: {{reduced_name}}
.. click:: {% if fullname == 'main' %}main:cli{% else %}{{fullname}}.cli:cmd_{{fullname}}{% endif %}
.. currentmodule:: {{ fullname }} :prog: kupferbootstrap {{fullname}}
.. click:: {% if fullname == 'main' %}kupferbootstrap.main:cli{% else %}{{fullname}}.cli:cmd_{{reduced_name}}{% endif %}
:prog: kupferbootstrap {{reduced_name}}
:nested: full :nested: full

View file

@ -7,7 +7,7 @@ from subprocess import CompletedProcess # make it easy for users of this module
from shlex import quote as shell_quote from shlex import quote as shell_quote
from typing import IO, Optional, Union from typing import IO, Optional, Union
from kupferbootstrap.typehelpers import TypeAlias from typehelpers import TypeAlias
ElevationMethod: TypeAlias = str ElevationMethod: TypeAlias = str

View file

@ -9,7 +9,7 @@ from tempfile import mkdtemp
from typing import Optional, Union from typing import Optional, Union
from .cmd import run_cmd, run_root_cmd, elevation_noop, generate_cmd_su, wrap_in_bash, shell_quote from .cmd import run_cmd, run_root_cmd, elevation_noop, generate_cmd_su, wrap_in_bash, shell_quote
from kupferbootstrap.utils import get_user_name, get_group_name from utils import get_user_name, get_group_name
def try_native_filewrite(path: str, content: Union[str, bytes], chmod: Optional[str] = None) -> Optional[Exception]: def try_native_filewrite(path: str, content: Union[str, bytes], chmod: Optional[str] = None) -> Optional[Exception]:

View file

@ -8,7 +8,7 @@ from dataclasses import dataclass
from .cmd import run_root_cmd from .cmd import run_root_cmd
from .file import chmod, chown, get_temp_dir, write_file from .file import chmod, chown, get_temp_dir, write_file
from kupferbootstrap.utils import get_gid, get_uid from utils import get_gid, get_uid
TEMPDIR_MODE = 0o755 TEMPDIR_MODE = 0o755

View file

@ -4,9 +4,9 @@ import logging
from json import dumps as json_dump from json import dumps as json_dump
from typing import Optional from typing import Optional
from kupferbootstrap.config.cli import resolve_profile_field from config.cli import resolve_profile_field
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.utils import color_mark_selected, colors_supported from utils import color_mark_selected, colors_supported
from .flavour import get_flavours, get_flavour from .flavour import get_flavours, get_flavour

View file

@ -6,11 +6,11 @@ import os
from typing import Optional from typing import Optional
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import FLAVOUR_DESCRIPTION_PREFIX, FLAVOUR_INFO_FILE from constants import FLAVOUR_DESCRIPTION_PREFIX, FLAVOUR_INFO_FILE
from kupferbootstrap.dictscheme import DictScheme from dictscheme import DictScheme
from kupferbootstrap.packages.pkgbuild import discover_pkgbuilds, get_pkgbuild_by_name, init_pkgbuilds, Pkgbuild from packages.pkgbuild import discover_pkgbuilds, get_pkgbuild_by_name, init_pkgbuilds, Pkgbuild
from kupferbootstrap.utils import color_str from utils import color_str
class FlavourInfo(DictScheme): class FlavourInfo(DictScheme):

View file

@ -6,7 +6,7 @@ autoflake_args=('--recursive' '--remove-unused-variables' '--remove-all-unused-i
format() { format() {
files=("$@") files=("$@")
if [[ -z "${files[*]}" ]]; then if [[ -z "${files[*]}" ]]; then
files=(*.py "src") files=(".")
fi fi
yapf "${yapf_args[@]}" "${files[@]}" yapf "${yapf_args[@]}" "${files[@]}"

View file

@ -1,7 +1,7 @@
from typing import Optional from typing import Optional
from .constants import Arch, CFLAGS_ARCHES, CFLAGS_GENERAL, COMPILE_ARCHES, GCC_HOSTSPECS from constants import Arch, CFLAGS_ARCHES, CFLAGS_GENERAL, COMPILE_ARCHES, GCC_HOSTSPECS
from .config.state import config from config.state import config
def generate_makepkg_conf(arch: Arch, cross: bool = False, chroot: Optional[str] = None) -> str: def generate_makepkg_conf(arch: Arch, cross: bool = False, chroot: Optional[str] = None) -> str:

View file

@ -4,13 +4,13 @@ import click
from typing import Optional from typing import Optional
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import FLASH_PARTS, FASTBOOT, JUMPDRIVE, JUMPDRIVE_VERSION from constants import FLASH_PARTS, FASTBOOT, JUMPDRIVE, JUMPDRIVE_VERSION
from kupferbootstrap.exec.file import makedir from exec.file import makedir
from kupferbootstrap.devices.device import get_profile_device from devices.device import get_profile_device
from kupferbootstrap.flavours.flavour import get_profile_flavour from flavours.flavour import get_profile_flavour
from kupferbootstrap.flavours.cli import profile_option from flavours.cli import profile_option
from kupferbootstrap.wrapper import enforce_wrap from wrapper import enforce_wrap
from .fastboot import fastboot_boot, fastboot_erase from .fastboot import fastboot_boot, fastboot_erase
from .image import get_device_name, losetup_rootfs_image, get_image_path, dump_aboot, dump_lk2nd from .image import get_device_name, losetup_rootfs_image, get_image_path, dump_aboot, dump_lk2nd

View file

@ -1,7 +1,7 @@
import click import click
import logging import logging
from kupferbootstrap.exec.cmd import run_cmd, CompletedProcess from exec.cmd import run_cmd, CompletedProcess
from typing import Optional from typing import Optional

View file

@ -5,13 +5,13 @@ import logging
from typing import Optional from typing import Optional
from kupferbootstrap.constants import FLASH_PARTS, LOCATIONS, FASTBOOT, JUMPDRIVE from constants import FLASH_PARTS, LOCATIONS, FASTBOOT, JUMPDRIVE
from kupferbootstrap.exec.cmd import run_root_cmd from exec.cmd import run_root_cmd
from kupferbootstrap.exec.file import get_temp_dir from exec.file import get_temp_dir
from kupferbootstrap.devices.device import get_profile_device from devices.device import get_profile_device
from kupferbootstrap.flavours.flavour import get_profile_flavour from flavours.flavour import get_profile_flavour
from kupferbootstrap.flavours.cli import profile_option from flavours.cli import profile_option
from kupferbootstrap.wrapper import enforce_wrap from wrapper import enforce_wrap
from .fastboot import fastboot_flash from .fastboot import fastboot_flash
from .image import dd_image, dump_aboot, dump_lk2nd, dump_qhypstub, get_image_path, losetup_destroy, losetup_rootfs_image, partprobe, shrink_fs from .image import dd_image, dump_aboot, dump_lk2nd, dump_qhypstub, get_image_path, losetup_destroy, losetup_rootfs_image, partprobe, shrink_fs

View file

@ -9,17 +9,17 @@ from signal import pause
from subprocess import CompletedProcess from subprocess import CompletedProcess
from typing import Optional, Union from typing import Optional, Union
from kupferbootstrap.config.state import config, Profile from config.state import config, Profile
from kupferbootstrap.chroot.device import DeviceChroot, get_device_chroot from chroot.device import DeviceChroot, get_device_chroot
from kupferbootstrap.constants import Arch, BASE_LOCAL_PACKAGES, BASE_PACKAGES, POST_INSTALL_CMDS from constants import Arch, BASE_LOCAL_PACKAGES, BASE_PACKAGES, POST_INSTALL_CMDS
from kupferbootstrap.distro.distro import get_base_distro, get_kupfer_https from distro.distro import get_base_distro, get_kupfer_https
from kupferbootstrap.devices.device import Device, get_profile_device from devices.device import Device, get_profile_device
from kupferbootstrap.exec.cmd import run_root_cmd, generate_cmd_su from exec.cmd import run_root_cmd, generate_cmd_su
from kupferbootstrap.exec.file import get_temp_dir, root_write_file, root_makedir, makedir from exec.file import get_temp_dir, root_write_file, root_makedir, makedir
from kupferbootstrap.flavours.flavour import Flavour, get_profile_flavour from flavours.flavour import Flavour, get_profile_flavour
from kupferbootstrap.net.ssh import copy_ssh_keys from net.ssh import copy_ssh_keys
from kupferbootstrap.packages.build import build_enable_qemu_binfmt, build_packages, filter_pkgbuilds from packages.build import build_enable_qemu_binfmt, build_packages, filter_pkgbuilds
from kupferbootstrap.wrapper import enforce_wrap from wrapper import enforce_wrap
# image files need to be slightly smaller than partitions to fit # image files need to be slightly smaller than partitions to fit
IMG_FILE_ROOT_DEFAULT_SIZE = "1800M" IMG_FILE_ROOT_DEFAULT_SIZE = "1800M"

View file

@ -5,13 +5,13 @@ import pytest
from glob import glob from glob import glob
from subprocess import CompletedProcess from subprocess import CompletedProcess
from kupferbootstrap.config.state import config, CONFIG_DEFAULTS from config.state import config, CONFIG_DEFAULTS
from kupferbootstrap.constants import SRCINFO_METADATA_FILE from constants import SRCINFO_METADATA_FILE
from kupferbootstrap.exec.cmd import run_cmd from exec.cmd import run_cmd
from kupferbootstrap.exec.file import get_temp_dir from exec.file import get_temp_dir
from kupferbootstrap.logger import setup_logging from logger import setup_logging
from kupferbootstrap.packages.cli import SRCINFO_CACHE_FILES, cmd_build, cmd_clean, cmd_init, cmd_update from packages.cli import SRCINFO_CACHE_FILES, cmd_build, cmd_clean, cmd_init, cmd_update
from kupferbootstrap.utils import git_get_branch from utils import git_get_branch
tempdir = None tempdir = None
config.try_load_file() config.try_load_file()
@ -38,7 +38,7 @@ def ctx() -> click.Context:
def test_main_import(): def test_main_import():
from kupferbootstrap.main import cli from main import cli
assert cli assert cli
@ -52,8 +52,7 @@ def test_config_load(ctx: click.Context):
def test_packages_update(ctx: click.Context): def test_packages_update(ctx: click.Context):
pkgbuilds_path = config.get_path('pkgbuilds') pkgbuilds_path = config.get_path('pkgbuilds')
assert config.runtime.script_source_dir kbs_branch = git_get_branch(config.runtime.script_source_dir)
kbs_branch = git_get_branch(os.path.join(config.runtime.script_source_dir, "../.."))
# Gitlab CI integration: the CI checks out a detached commit, branch comes back empty. # Gitlab CI integration: the CI checks out a detached commit, branch comes back empty.
if not kbs_branch and os.environ.get('CI', 'false') == 'true': if not kbs_branch and os.environ.get('CI', 'false') == 'true':
kbs_branch = os.environ.get('CI_COMMIT_BRANCH', '') kbs_branch = os.environ.get('CI_COMMIT_BRANCH', '')

View file

@ -7,19 +7,19 @@ from os import isatty
from traceback import format_exc, format_exception_only, format_tb from traceback import format_exc, format_exception_only, format_tb
from typing import Optional from typing import Optional
from .logger import color_option, logging, quiet_option, setup_logging, verbose_option from logger import color_option, logging, quiet_option, setup_logging, verbose_option
from .wrapper import get_wrapper_type, enforce_wrap, nowrapper_option from wrapper import get_wrapper_type, enforce_wrap, nowrapper_option
from .progressbar import progress_bars_option from progressbar import progress_bars_option
from .binfmt.cli import cmd_binfmt from binfmt.cli import cmd_binfmt
from .config.cli import config, config_option, cmd_config from config.cli import config, config_option, cmd_config
from .packages.cli import cmd_packages from packages.cli import cmd_packages
from .flavours.cli import cmd_flavours from flavours.cli import cmd_flavours
from .devices.cli import cmd_devices from devices.cli import cmd_devices
from .net.cli import cmd_net from net.cli import cmd_net
from .chroot.cli import cmd_chroot from chroot.cli import cmd_chroot
from .cache.cli import cmd_cache from cache.cli import cmd_cache
from .image.cli import cmd_image from image.cli import cmd_image
@click.group() @click.group()

View file

@ -1,8 +1,8 @@
import click import click
import logging import logging
from kupferbootstrap.exec.cmd import run_root_cmd from exec.cmd import run_root_cmd
from kupferbootstrap.wrapper import check_programs_wrap from wrapper import check_programs_wrap
from .ssh import run_ssh_command from .ssh import run_ssh_command

View file

@ -4,12 +4,12 @@ import os
import pathlib import pathlib
import click import click
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import SSH_COMMON_OPTIONS, SSH_DEFAULT_HOST, SSH_DEFAULT_PORT from constants import SSH_COMMON_OPTIONS, SSH_DEFAULT_HOST, SSH_DEFAULT_PORT
from kupferbootstrap.exec.cmd import run_cmd from chroot.abstract import Chroot
from kupferbootstrap.exec.file import write_file from exec.cmd import run_cmd
from kupferbootstrap.chroot.abstract import Chroot from exec.file import write_file
from kupferbootstrap.wrapper import check_programs_wrap from wrapper import check_programs_wrap
@click.command(name='ssh') @click.command(name='ssh')

View file

@ -1,6 +1,6 @@
import subprocess import subprocess
import click import click
from kupferbootstrap.wrapper import check_programs_wrap from wrapper import check_programs_wrap
@click.command(name='telnet') @click.command(name='telnet')

View file

@ -9,18 +9,18 @@ from copy import deepcopy
from urllib.error import HTTPError from urllib.error import HTTPError
from typing import Iterable, Iterator, Optional from typing import Iterable, Iterator, Optional
from kupferbootstrap.binfmt.binfmt import binfmt_is_registered, binfmt_register from binfmt.binfmt import binfmt_is_registered, binfmt_register
from kupferbootstrap.constants import CROSSDIRECT_PKGS, QEMU_BINFMT_PKGS, GCC_HOSTSPECS, ARCHES, Arch, CHROOT_PATHS, MAKEPKG_CMD from constants import CROSSDIRECT_PKGS, QEMU_BINFMT_PKGS, GCC_HOSTSPECS, ARCHES, Arch, CHROOT_PATHS, MAKEPKG_CMD
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.exec.cmd import run_cmd, run_root_cmd from exec.cmd import run_cmd, run_root_cmd
from kupferbootstrap.exec.file import makedir, remove_file, symlink from exec.file import makedir, remove_file, symlink
from kupferbootstrap.chroot.build import get_build_chroot, BuildChroot from chroot.build import get_build_chroot, BuildChroot
from kupferbootstrap.distro.distro import get_kupfer_https, get_kupfer_local, get_kupfer_repo_names from distro.distro import get_kupfer_https, get_kupfer_local, get_kupfer_repo_names
from kupferbootstrap.distro.package import RemotePackage, LocalPackage from distro.package import RemotePackage, LocalPackage
from kupferbootstrap.distro.repo import LocalRepo from distro.repo import LocalRepo
from kupferbootstrap.progressbar import BAR_PADDING, get_levels_bar from progressbar import BAR_PADDING, get_levels_bar
from kupferbootstrap.wrapper import check_programs_wrap, is_wrapped from wrapper import check_programs_wrap, is_wrapped
from kupferbootstrap.utils import ellipsize, sha256sum from utils import ellipsize, sha256sum
from .pkgbuild import discover_pkgbuilds, filter_pkgbuilds, Pkgbase, Pkgbuild, SubPkgbuild from .pkgbuild import discover_pkgbuilds, filter_pkgbuilds, Pkgbase, Pkgbuild, SubPkgbuild

View file

@ -6,16 +6,16 @@ import os
from glob import glob from glob import glob
from typing import Iterable, Optional from typing import Iterable, Optional
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import Arch, ARCHES, SRCINFO_FILE, SRCINFO_INITIALISED_FILE, SRCINFO_METADATA_FILE, SRCINFO_TARBALL_FILE, SRCINFO_TARBALL_URL from constants import Arch, ARCHES, SRCINFO_FILE, SRCINFO_INITIALISED_FILE, SRCINFO_METADATA_FILE, SRCINFO_TARBALL_FILE, SRCINFO_TARBALL_URL
from kupferbootstrap.exec.cmd import run_cmd, shell_quote, CompletedProcess from exec.cmd import run_cmd, shell_quote, CompletedProcess
from kupferbootstrap.exec.file import get_temp_dir, makedir, remove_file from exec.file import get_temp_dir, makedir, remove_file
from kupferbootstrap.devices.device import get_profile_device from devices.device import get_profile_device
from kupferbootstrap.distro.distro import get_kupfer_local, get_kupfer_url, get_kupfer_repo_names from distro.distro import get_kupfer_local, get_kupfer_url, get_kupfer_repo_names
from kupferbootstrap.distro.package import LocalPackage from distro.package import LocalPackage
from kupferbootstrap.net.ssh import run_ssh_command, scp_put_files from net.ssh import run_ssh_command, scp_put_files
from kupferbootstrap.utils import download_file, git, sha256sum from utils import download_file, git, sha256sum
from kupferbootstrap.wrapper import check_programs_wrap, enforce_wrap from wrapper import check_programs_wrap, enforce_wrap
from .build import build_packages_by_paths, init_prebuilts from .build import build_packages_by_paths, init_prebuilts
from .pkgbuild import discover_pkgbuilds, filter_pkgbuilds, get_pkgbuild_dirs, init_pkgbuilds from .pkgbuild import discover_pkgbuilds, filter_pkgbuilds, get_pkgbuild_dirs, init_pkgbuilds

View file

@ -8,15 +8,15 @@ import os
from joblib import Parallel, delayed from joblib import Parallel, delayed
from typing import Iterable, Optional from typing import Iterable, Optional
from kupferbootstrap.config.state import config, ConfigStateHolder from config.state import config, ConfigStateHolder
from kupferbootstrap.constants import Arch from constants import Arch
from kupferbootstrap.distro.distro import get_kupfer_repo_names from distro.distro import get_kupfer_repo_names
from kupferbootstrap.distro.package import PackageInfo from distro.package import PackageInfo
from kupferbootstrap.exec.file import remove_file from exec.file import remove_file
from kupferbootstrap.logger import setup_logging from logger import setup_logging
from kupferbootstrap.utils import git, git_get_branch from utils import git, git_get_branch
from kupferbootstrap.wrapper import check_programs_wrap from wrapper import check_programs_wrap
from kupferbootstrap.typehelpers import TypeAlias from typehelpers import TypeAlias
from .srcinfo_cache import SrcinfoMetaFile from .srcinfo_cache import SrcinfoMetaFile

View file

@ -7,11 +7,11 @@ import subprocess
from typing import Any, ClassVar, Optional from typing import Any, ClassVar, Optional
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import MAKEPKG_CMD, SRCINFO_FILE, SRCINFO_METADATA_FILE, SRCINFO_INITIALISED_FILE from constants import MAKEPKG_CMD, SRCINFO_FILE, SRCINFO_METADATA_FILE, SRCINFO_INITIALISED_FILE
from kupferbootstrap.dictscheme import DictScheme from dictscheme import DictScheme
from kupferbootstrap.exec.cmd import run_cmd from exec.cmd import run_cmd
from kupferbootstrap.utils import sha256sum from utils import sha256sum
SRCINFO_CHECKSUM_FILES = ['PKGBUILD', SRCINFO_FILE] SRCINFO_CHECKSUM_FILES = ['PKGBUILD', SRCINFO_FILE]

View file

@ -4,7 +4,7 @@ import sys
from enlighten import Counter, Manager, get_manager as _getmanager from enlighten import Counter, Manager, get_manager as _getmanager
from typing import Hashable, Optional from typing import Hashable, Optional
from .config.state import config from config.state import config
BAR_PADDING = 25 BAR_PADDING = 25
DEFAULT_OUTPUT = sys.stderr DEFAULT_OUTPUT = sys.stderr

View file

@ -1,29 +0,0 @@
[project]
name = "kupferbootstrap"
dependencies = [
"click>=8.0.1",
"appdirs>=1.4.4",
"joblib>=1.0.1",
"toml",
"typing_extensions",
"coloredlogs",
"munch",
"requests",
"python-dateutil",
"enlighten",
"PyYAML",
]
dynamic = ["version"]
[project.scripts]
kupferbootstrap = "kupferbootstrap.main:main"
[tool.setuptools.package-data]
"*" = ["version.txt"]
[build-system]
requires = [ "setuptools>=41", "wheel", "setuptools-git-versioning<2", ]
build-backend = "setuptools.build_meta"
[tool.setuptools-git-versioning]
enabled = true

View file

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
sudo -v sudo -v
python -m pytest -v --cov=. --cov-branch --cov-report=term "$@" src/kupferbootstrap python -m pytest -v --cov=. --cov-branch --cov-report=term "$@" ./*/test_*.py

View file

@ -1 +1,12 @@
-e . click>=8.0.1
appdirs>=1.4.4
joblib>=1.0.1
toml
typing_extensions
coloredlogs
munch
setuptools # required by munch
requests
python-dateutil
enlighten
PyYAML

View file

@ -14,7 +14,7 @@ from dateutil.parser import parse as parsedate
from shutil import which from shutil import which
from typing import Any, Generator, IO, Optional, Union, Sequence from typing import Any, Generator, IO, Optional, Union, Sequence
from .exec.cmd import run_cmd, run_root_cmd from exec.cmd import run_cmd, run_root_cmd
_programs_available = dict[str, bool]() _programs_available = dict[str, bool]()

1
version.txt Normal file
View file

@ -0,0 +1 @@
dev

View file

@ -3,9 +3,9 @@ import logging
from typing import Optional, Sequence, Union from typing import Optional, Sequence, Union
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.constants import Arch from constants import Arch
from kupferbootstrap.utils import programs_available from utils import programs_available
from .docker import DockerWrapper from .docker import DockerWrapper
from .wrapper import Wrapper from .wrapper import Wrapper
@ -57,12 +57,10 @@ def wrap_if_foreign_arch(arch: Arch):
def execute_without_exit(f, argv_override: Optional[list[str]], *args, **kwargs): def execute_without_exit(f, argv_override: Optional[list[str]], *args, **kwargs):
""" """If no wrap is needed, executes and returns f(*args, **kwargs).
If no wrap is needed, executes and returns `f(*args, **kwargs)`.
If a wrap is determined to be necessary, force a wrap with argv_override applied. If a wrap is determined to be necessary, force a wrap with argv_override applied.
If a wrap was forced, None is returned. If a wrap was forced, None is returned.
WARNING: No protection against f() returning None is taken. WARNING: No protection against f() returning None is taken."""
"""
if not needs_wrap(): if not needs_wrap():
return f(*args, **kwargs) return f(*args, **kwargs)
assert get_wrapper_type() != 'none', "needs_wrap() should've returned False" assert get_wrapper_type() != 'none', "needs_wrap() should've returned False"

View file

@ -4,13 +4,11 @@ import pathlib
import subprocess import subprocess
import sys import sys
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.exec.file import makedir from exec.file import makedir
from .wrapper import Wrapper, WRAPPER_PATHS from .wrapper import Wrapper, WRAPPER_PATHS
VERSION_FILE = "docker_version.txt"
DOCKER_FILE = "Dockerfile"
DOCKER_PATHS = WRAPPER_PATHS.copy() DOCKER_PATHS = WRAPPER_PATHS.copy()
@ -28,39 +26,10 @@ class DockerWrapper(Wrapper):
super().wrap() super().wrap()
script_path = config.runtime.script_source_dir script_path = config.runtime.script_source_dir
assert script_path assert script_path
docker_path = script_path with open(os.path.join(script_path, 'version.txt')) as version_file:
tried = [docker_path] version = version_file.read().replace('\n', '')
if not os.path.exists(os.path.join(docker_path, DOCKER_FILE)):
docker_path = os.path.realpath(os.path.join(script_path, "../.."))
tried.append(docker_path)
if not os.path.exists(os.path.join(docker_path, DOCKER_FILE)):
_par_dir = os.path.dirname(script_path)
# handle venv
if os.path.basename(_par_dir) == "site-packages":
_path = os.path.join(_par_dir, "../../../..")
docker_path = os.path.realpath(_path)
tried.append(f"{_path} => {docker_path}")
logging.debug(f"{DOCKER_FILE!r} not found at {script_path!r}, trying {docker_path!r}")
version_file = os.path.join(script_path, '../..', VERSION_FILE)
if not os.path.exists(version_file):
_vfile = os.path.join(docker_path, VERSION_FILE)
logging.warning(f"{VERSION_FILE} not found at {version_file!r}."
f"\nTrying {_vfile!r}"
"\nDid you use `pip install .` instead of `pip install -e .`?")
if os.path.exists(_vfile):
version_file = _vfile
if os.path.exists(version_file):
with open(version_file) as fd:
version = fd.read().replace('\n', '').strip()
logging.debug(f"Read docker tag {version} from {version_file}")
else:
version = "BUILD"
logging.error(f"'{script_path}/{VERSION_FILE}' doesn't exist, defaulting docker tag to {version}!"
"\nThis installation is potentially broken!"
"\nDid you use `pip install .` instead of `pip install -e .` to install kupferboostrap?"
f"Tried locations: {[version_file, _vfile]}")
tag = f'registry.gitlab.com/kupfer/kupferbootstrap:{version}' tag = f'registry.gitlab.com/kupfer/kupferbootstrap:{version}'
if version == 'BUILD': if version == 'dev':
logging.info(f'Building docker image "{tag}"') logging.info(f'Building docker image "{tag}"')
cmd = [ cmd = [
'docker', 'docker',
@ -69,15 +38,11 @@ class DockerWrapper(Wrapper):
'-t', '-t',
tag, tag,
] + (['-q'] if not config.runtime.verbose else []) ] + (['-q'] if not config.runtime.verbose else [])
_dfile = os.path.join(docker_path, DOCKER_FILE) logging.debug('Running docker cmd: ' + ' '.join(cmd))
if not os.path.exists(_dfile):
_sep = "\n -"
raise Exception(f'{DOCKER_FILE!r} not found. Tried locations:' + (_sep.join(["", *[repr(f"{p}/{DOCKER_FILE}") for p in tried]])))
logging.debug(f'Running docker cmd (chdir={script_path!r}) : ' + ' '.join(cmd))
mute_docker = not config.runtime.verbose mute_docker = not config.runtime.verbose
result = subprocess.run( result = subprocess.run(
cmd, cmd,
cwd=docker_path, cwd=script_path,
capture_output=mute_docker, capture_output=mute_docker,
) )
if result.returncode != 0: if result.returncode != 0:

View file

@ -5,9 +5,9 @@ import pathlib
from typing import Optional, Protocol from typing import Optional, Protocol
from kupferbootstrap.config.state import config from config.state import config
from kupferbootstrap.config.state import dump_file as dump_config_file from config.state import dump_file as dump_config_file
from kupferbootstrap.constants import CHROOT_PATHS, WRAPPER_ENV_VAR from constants import CHROOT_PATHS, WRAPPER_ENV_VAR
WRAPPER_PATHS = CHROOT_PATHS | { WRAPPER_PATHS = CHROOT_PATHS | {
'ccache': '/ccache', 'ccache': '/ccache',

View file

@ -1,14 +1,14 @@
#!/usr/bin/env python3 #!/bin/python3
import click import click
import pwd import pwd
import os import os
from kupferbootstrap.logger import logging, setup_logging from logger import logging, setup_logging
from kupferbootstrap.constants import WRAPPER_ENV_VAR from constants import WRAPPER_ENV_VAR
from kupferbootstrap.exec.cmd import run_cmd, flatten_shell_script from exec.cmd import run_cmd, flatten_shell_script
from kupferbootstrap.exec.file import chown from exec.file import chown
@click.command('kupferbootstrap_su') @click.command('kupferbootstrap_su')