diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4d3fbad --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +/venv +/build +__pycache__ +.mypy_cache +*.xml diff --git a/Dockerfile b/Dockerfile index 2606f4e..ced9696 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,16 +17,14 @@ RUN yes | pacman -Scc RUN sed -i "s/SigLevel.*/SigLevel = Never/g" /etc/pacman.conf ENV KUPFERBOOTSTRAP_WRAPPED=DOCKER -ENV PATH=/app/bin:/app/venv/bin:$PATH +ENV PATH=/app/bin:/app/local/bin:/app/venv/bin:$PATH WORKDIR /app -COPY requirements.txt . -RUN python3 -m venv venv -RUN venv/bin/pip3 install -r requirements.txt - COPY . . +RUN python3 -m venv /app/venv +RUN /app/venv/bin/pip3 install -r requirements.txt -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 /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 RUN useradd -m -g users kupfer RUN echo "kupfer ALL=(ALL) NOPASSWD: ALL" | tee /etc/sudoers.d/kupfer diff --git a/README.md b/README.md index 61e6949..36866f1 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,26 @@ This will run a webserver on localhost:9999. Access it like `firefox http://loca ## Installation -Install Docker, Python 3 with the libraries from `requirements.txt` and put `bin/` into your `PATH`. -Then use `kupferbootstrap`. +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. +1. Craate a python venv: `python3 -m venv venv` +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 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` ## 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`. diff --git a/bin/kupferbootstrap b/bin/kupferbootstrap deleted file mode 100755 index 0744f9e..0000000 --- a/bin/kupferbootstrap +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -# shellcheck disable=SC2068 -python3 "$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")/main.py" $@ diff --git a/docker_version.txt b/docker_version.txt new file mode 100644 index 0000000..89620f3 --- /dev/null +++ b/docker_version.txt @@ -0,0 +1 @@ +BUILD diff --git a/pyproject.toml b/pyproject.toml index bec3ae8..6dba5bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,9 @@ 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" diff --git a/src/kupferbootstrap/version.txt b/src/kupferbootstrap/version.txt deleted file mode 100644 index 38f8e88..0000000 --- a/src/kupferbootstrap/version.txt +++ /dev/null @@ -1 +0,0 @@ -dev diff --git a/src/kupferbootstrap/wrapper/docker.py b/src/kupferbootstrap/wrapper/docker.py index 04f34d9..d3fe799 100644 --- a/src/kupferbootstrap/wrapper/docker.py +++ b/src/kupferbootstrap/wrapper/docker.py @@ -9,6 +9,8 @@ from kupferbootstrap.exec.file import makedir from .wrapper import Wrapper, WRAPPER_PATHS +VERSION_FILE = "docker_version.txt" +DOCKER_FILE = "Dockerfile" DOCKER_PATHS = WRAPPER_PATHS.copy() @@ -26,10 +28,39 @@ class DockerWrapper(Wrapper): super().wrap() script_path = config.runtime.script_source_dir assert script_path - with open(os.path.join(script_path, 'version.txt')) as version_file: - version = version_file.read().replace('\n', '') + docker_path = script_path + tried = [docker_path] + 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}' - if version == 'dev': + if version == 'BUILD': logging.info(f'Building docker image "{tag}"') cmd = [ 'docker', @@ -38,11 +69,15 @@ class DockerWrapper(Wrapper): '-t', tag, ] + (['-q'] if not config.runtime.verbose else []) - logging.debug('Running docker cmd: ' + ' '.join(cmd)) + _dfile = os.path.join(docker_path, DOCKER_FILE) + 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 result = subprocess.run( cmd, - cwd=script_path, + cwd=docker_path, capture_output=mute_docker, ) if result.returncode != 0: diff --git a/wrapper_su_helper.py b/wrapper_su_helper.py index 7bf130b..a79a442 100644 --- a/wrapper_su_helper.py +++ b/wrapper_su_helper.py @@ -1,14 +1,14 @@ -#!/bin/python3 +#!/usr/bin/env python3 import click import pwd import os -from logger import logging, setup_logging +from kupferbootstrap.logger import logging, setup_logging -from constants import WRAPPER_ENV_VAR -from exec.cmd import run_cmd, flatten_shell_script -from exec.file import chown +from kupferbootstrap.constants import WRAPPER_ENV_VAR +from kupferbootstrap.exec.cmd import run_cmd, flatten_shell_script +from kupferbootstrap.exec.file import chown @click.command('kupferbootstrap_su')