Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 51 additions & 10 deletions lib/charms/layer/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
import sys
import re
import shutil
from contextlib import contextmanager
from collections import defaultdict
from distutils.version import LooseVersion
from pkg_resources import Requirement
from pkg_resources import Requirement, parse_requirements
from glob import glob
from subprocess import check_call, check_output, CalledProcessError
from tempfile import NamedTemporaryFile
from time import sleep

from charms import layer
Expand Down Expand Up @@ -217,15 +220,29 @@ def bootstrap_charm_deps():
# This ensures that pip 20.3.4+ will install the packages from the
# wheelhouse without (erroneously) flagging an error.
pkgs = _add_back_versions(_pkgs_set, _versions)
reinstall_flag = '--force-reinstall'
# if not cfg.get('use_venv', True) and pre_eoan:
if not cfg.get('use_venv', True):
reinstall_flag = '--ignore-installed'
if not pkgs:
continue
check_call([pip, 'install', '-U', reinstall_flag, '--no-index',
'--no-cache-dir', '-f', 'wheelhouse'] + list(pkgs),
env=_get_subprocess_env())
with _marked_requirements(pkgs) as marked_file:
reinstall_flag = '--force-reinstall'
# if not cfg.get('use_venv', True) and pre_eoan:
if not cfg.get('use_venv', True):
reinstall_flag = '--ignore-installed'
if not pkgs:
continue
check_call(
[
pip,
'install',
'-U',
reinstall_flag,
'--no-index',
'--no-cache-dir',
'-f',
'wheelhouse',
'-r',
marked_file
],
env=_get_subprocess_env()
)

# re-enable installation from pypi
os.remove('/root/.pydistutils.cfg')

Expand Down Expand Up @@ -358,6 +375,30 @@ def _maybe_add_version(pkg):
return [_maybe_add_version(pkg) for pkg in pkgs]


@contextmanager
def _marked_requirements(pkgs):
"""Apply any custom markers from wheelhouse.txt to list of packages."""
wheelhouse_reqs = defaultdict(list)
with open("wheelhouse.txt") as wheelhouse:
for req in parse_requirements(wheelhouse.read()):
wheelhouse_reqs[req.project_name].append(req)

reqs = [
str(mark) + "\n"
for pkg in pkgs
for mark in wheelhouse_reqs.get(
# use each matching marker by project_name
Requirement(pkg).project_name,
# or default to using the incoming pkg
[pkg]
)
]
with NamedTemporaryFile(mode='w') as requirements:
requirements.writelines(reqs)
requirements.flush()
yield requirements.name


def _update_if_newer(pip, pkgs):
installed = _load_installed_versions(pip)
wheelhouse = _load_wheelhouse_versions()
Expand Down