diff --git a/README.md b/README.md index 72a2c402..0a1f50fe 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Package build scripts live in the [`pmaports`](https://gitlab.com/postmarketOS/p * [Linux kernel 3.17 or higher](https://postmarketos.org/oldkernel) * Python 3.4+ * OpenSSL +* git ## Usage Examples Please refer to the [postmarketOS wiki](https://wiki.postmarketos.org) for in-depth coverage of topics such as [porting to a new device](https://wiki.postmarketos.org/wiki/Porting_to_a_new_device) or [installation](https://wiki.postmarketos.org/wiki/Installation_guide). The help output (`pmbootstrap -h`) has detailed usage instructions for every command. Read on for some generic examples of what can be done with `pmbootstrap`. diff --git a/pmb/aportgen/core.py b/pmb/aportgen/core.py index d8d60816..ce689f7c 100644 --- a/pmb/aportgen/core.py +++ b/pmb/aportgen/core.py @@ -206,9 +206,8 @@ def get_upstream_aport(args, pkgname): # APKBUILD < binary if compare == -1: - raise RuntimeError("You can update your local checkout with:" - " 'pmbootstrap chroot --add=git --user -- git -C" - " /mnt/pmbootstrap-git/aports_upstream pull'") + raise RuntimeError("You can update your local checkout with: 'git -C" + "\"{}\" pull'".format(aports_upstream_path)) # APKBUILD > binary raise RuntimeError("You can force an update of your binary package" " APKINDEX files with: 'pmbootstrap update'") diff --git a/pmb/config/__init__.py b/pmb/config/__init__.py index b60c386d..619cb093 100644 --- a/pmb/config/__init__.py +++ b/pmb/config/__init__.py @@ -45,12 +45,12 @@ pmaports_min_version = "4" # Version of the work folder (as asked during 'pmbootstrap init'). Increase # this number, whenever migration is required and provide the migration code, # see migrate_work_folder()). -work_version = 3 +work_version = 4 # Programs that pmbootstrap expects to be available from the host system. Keep # in sync with README.md, and try to keep the list as small as possible. The # idea is to run almost everything in Alpine chroots. -required_programs = ["openssl", "ps"] +required_programs = ["git", "openssl", "ps"] # Keys saved in the config file (mostly what we ask in 'pmbootstrap init') config_keys = ["ccache_size", "device", "extra_packages", "hostname", "jobs", diff --git a/pmb/config/init.py b/pmb/config/init.py index 68a10955..7a480ef8 100644 --- a/pmb/config/init.py +++ b/pmb/config/init.py @@ -78,8 +78,9 @@ def ask_for_work_path(args): with open(work + "/version", "w") as handle: handle.write(str(pmb.config.work_version) + "\n") - # Make sure, that we can write into it - os.makedirs(work + "/cache_http", 0o700, True) + # Create cache_git dir, so it is owned by the host system's user + # (otherwise pmb.helpers.mount.bind would create it as root) + os.makedirs(work + "/cache_git", 0o700, True) return (work, exists) except OSError: logging.fatal("ERROR: Could not create this folder, or write" diff --git a/pmb/config/pmaports.py b/pmb/config/pmaports.py index 49ec4e07..d9259af3 100644 --- a/pmb/config/pmaports.py +++ b/pmb/config/pmaports.py @@ -49,7 +49,7 @@ def clone(args): " recipes (pmaports)...") # Set up the native chroot and clone pmaports - pmb.helpers.git.clone(args, "pmaports", False, True) + pmb.helpers.git.clone(args, "pmaports", False) def symlink(args): diff --git a/pmb/helpers/git.py b/pmb/helpers/git.py index eccc3322..a71bd8db 100644 --- a/pmb/helpers/git.py +++ b/pmb/helpers/git.py @@ -18,7 +18,6 @@ along with pmbootstrap. If not, see . """ import logging import os -import shutil import pmb.build import pmb.chroot.apk @@ -26,55 +25,37 @@ import pmb.config import pmb.helpers.run -def clone(args, name_repo, shallow=True, chown_to_user=False): +def clone(args, name_repo, shallow=True): + """ Clone a git repository to $WORK/cache_git/$name_repo. + + :param name_repo: short alias used for the repository name, from + pmb.config.git_repos (e.g. "aports_upstream", + "pmaports") + :param shallow: only clone the last revision of the repository, instead + of the entire repository (faster, saves bandwith) """ # Check for repo name in the config if name_repo not in pmb.config.git_repos: raise ValueError("No git repository configured for " + name_repo) # Skip if already checked out - if os.path.exists(args.work + "/cache_git/" + name_repo): + path = args.work + "/cache_git/" + name_repo + if os.path.exists(path): return - # Check out to temp folder - name_temp = name_repo + ".temp" - if not os.path.exists(args.work + "/cache_git/" + name_temp): - # Set up chroot and install git - pmb.chroot.apk.install(args, ["git"]) - logging.info("(native) git clone " + pmb.config.git_repos[name_repo]) + # Build git command + url = pmb.config.git_repos[name_repo] + command = ["git", "clone"] + if shallow: + command += ["--depth=1"] + command += [url, path] - # git options - options = [] - if shallow: - options += ["--depth=1"] - - # Run the command - pmb.chroot.user(args, ["git", "clone"] + options + - [pmb.config.git_repos[name_repo], name_temp], - working_dir="/home/pmos/git/", check=False, - output="stdout") - if not os.path.exists(args.work + "/cache_git/" + name_temp): - logging.info("NOTE: cloning from git is known to fail when the" - " host linux kernel is older than 3.17:" - " ") - raise RuntimeError("git clone failed!") - - # Chown to user's UID and GID - if chown_to_user: - uid_gid = "{}:{}".format(os.getuid(), os.getgid()) - pmb.helpers.run.root(args, ["chown", "-R", uid_gid, args.work + - "/cache_git/" + name_temp]) - - # Rename the temp folder - pmb.helpers.run.root(args, ["mv", name_temp, name_repo], - args.work + "/cache_git") + # Create parent dir and clone + logging.info("Clone git repository: " + url) + os.makedirs(args.work + "/cache_git", exist_ok=True) + pmb.helpers.run.user(args, command, output="stdout") def rev_parse(args, revision="HEAD"): - if shutil.which("git") is None: - logging.warning("WARNING: Cannot determine revision of git " + - "repository at " + args.aports + ". Command 'git' " + - "not found.") - return "" rev = pmb.helpers.run.user(args, ["git", "rev-parse", revision], args.aports, output_return=True, check=False) if rev is None: diff --git a/pmb/helpers/other.py b/pmb/helpers/other.py index 64c922e3..342f5854 100644 --- a/pmb/helpers/other.py +++ b/pmb/helpers/other.py @@ -21,6 +21,7 @@ import os import re import pmb.chroot import pmb.config +import pmb.config.init import pmb.helpers.pmaports import pmb.helpers.run @@ -154,6 +155,30 @@ def migrate_work_folder(args): migrate_success(args, 3) current = 3 + if current == 3: + # Ask for confirmation + path = args.work + "/cache_git" + logging.info("Changelog:") + logging.info("* pmbootstrap clones repositories with host system's") + logging.info(" 'git' instead of using it from an Alpine chroot") + logging.info("Migration will do the following:") + logging.info("* Check if 'git' is installed") + logging.info("* Change ownership to your user: " + path) + if not pmb.helpers.cli.confirm(args): + raise RuntimeError("Aborted.") + + # Require git, set cache_git ownership + pmb.config.init.require_programs() + if os.path.exists(path): + uid_gid = "{}:{}".format(os.getuid(), os.getgid()) + pmb.helpers.run.root(args, ["chown", "-R", uid_gid, path]) + else: + os.makedirs(path, 0o700, True) + + # Update version file + migrate_success(args, 4) + current = 4 + # Can't migrate, user must delete it if current != required: raise RuntimeError("Sorry, we can't migrate that automatically. Please"