pmb.helpers.git.clone: use git from host system (!1845)
Do not install git in the native chroot and use it from there. Remove the chown_to_user argument from pmb.helpers.git.clone(), the resulting dir is now always owned by the user. While at it, refactor the function and display the clone URL. Previously we had cloned aports_upstream (from Alpine) with chown_to_user=False (legacy) and pmaports with chown_to_user=True. pmb.helpers.git.rev_parse() would only work after chown_to_user=True. Check if git is installed in "pmbootstrap init", and remove the same check from rev_parse(). Add a new work dir version, that checks for git and changes ownership of already checked out aports_upstream to the host system's user. When creating a new work dir, create cache_git instead of cache_http. cache_http is created on demand already, with proper permissions. But cache_git must be created, otherwise pmb.helpers.mount.bind will create it as root. This is in preparation for the "pmbootstrap pull" feature, as it allows using the host system's git in all new code paths. We will be able to handle repositories even if they were cloned outside of the work dir (which we do in a few CI scripts for example). Related: #1858
This commit is contained in:
parent
cba37d5d79
commit
02e514f4d3
|
@ -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`.
|
||||
|
|
|
@ -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'")
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -18,7 +18,6 @@ along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
|
|||
"""
|
||||
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:"
|
||||
" <https://postmarketos.org/oldkernel>")
|
||||
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:
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue