-
Notifications
You must be signed in to change notification settings - Fork 337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
context bundles #1029
Merged
Merged
context bundles #1029
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
6cfdb7d
-context retargeting implemented
f99572d
debugging failing test on osx
373f423
account for fs symlinks in context retarget unit test
550b303
support disabling of memcaching in filesystem pkg repo
c039255
-first pass context bundling implemented
2d69f75
added bundled context test
90170b0
fix for resource mismatch when symlinks present in bundle path
b3c5d8b
docs update
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import os | ||
import os.path | ||
|
||
from rez.exceptions import ContextBundleError | ||
from rez.utils.logging_ import print_info, print_warning | ||
from rez.utils.yaml import save_yaml | ||
from rez.package_copy import copy_package | ||
|
||
|
||
def bundle_context(context, dest_dir, force=False, skip_non_relocatable=False, | ||
quiet=False, verbose=False): | ||
"""Bundle a context and its variants into a relocatable dir. | ||
|
||
This creates a copy of a context with its variants retargeted to a local | ||
package repository containing only the variants the context uses. The | ||
generated file structure looks like so: | ||
|
||
/dest_dir/ | ||
/context.rxt | ||
/packages/ | ||
/foo/1.1.1/package.py | ||
/...(payload)... | ||
/bah/4.5.6/package.py | ||
/...(payload)... | ||
|
||
Args: | ||
context (`ResolvedContext`): Context to bundle | ||
dest_dir (str): Destination directory. Must not exist. | ||
force (bool): If True, relocate package even if non-relocatable. Use at | ||
your own risk. Overrides `skip_non_relocatable`. | ||
skip_non_relocatable (bool): If True, leave non-relocatable packages | ||
unchanged. Normally this will raise a `PackageCopyError`. | ||
quiet (bool): Suppress all output | ||
verbose (bool): Verbose mode (quiet will override) | ||
""" | ||
if quiet: | ||
verbose = False | ||
if force: | ||
skip_non_relocatable = False | ||
|
||
if os.path.exists(dest_dir): | ||
raise ContextBundleError("Dest dir must not exist: %s" % dest_dir) | ||
|
||
if not quiet: | ||
label = context.load_path or "context" | ||
print_info("Bundling %s into %s...", label, dest_dir) | ||
|
||
os.mkdir(dest_dir) | ||
|
||
_init_bundle(dest_dir) | ||
|
||
relocated_package_names = _copy_variants( | ||
context=context, | ||
bundle_dir=dest_dir, | ||
force=force, | ||
skip_non_relocatable=skip_non_relocatable, | ||
verbose=verbose | ||
) | ||
|
||
rxt_filepath = _write_retargeted_context( | ||
context=context, | ||
bundle_dir=dest_dir, | ||
relocated_package_names=relocated_package_names | ||
) | ||
|
||
if verbose: | ||
print_info("Context bundled to %s", rxt_filepath) | ||
|
||
|
||
def _init_bundle(bundle_dir): | ||
# Create bundle conf file. It doesn't contain anything at time of writing, | ||
# but its presence on disk signifies that this is a context bundle. | ||
# | ||
bundle_filepath = os.path.join(bundle_dir, "bundle.yaml") | ||
save_yaml(bundle_filepath) | ||
|
||
# init pkg repo | ||
repo_path = os.path.join(bundle_dir, "packages") | ||
os.mkdir(repo_path) | ||
|
||
# Bundled repos are always memcached disabled because they're on local disk | ||
# (so access should be fast); but also, local repo paths written to shared | ||
# memcached instance could easily clash. | ||
# | ||
settings_filepath = os.path.join(bundle_dir, "packages", "settings.yaml") | ||
save_yaml(settings_filepath, disable_memcached=True) | ||
|
||
|
||
def _copy_variants(context, bundle_dir, force=False, skip_non_relocatable=False, | ||
verbose=False): | ||
relocated_package_names = [] | ||
repo_path = os.path.join(bundle_dir, "packages") | ||
|
||
for variant in context.resolved_packages: | ||
package = variant.parent | ||
|
||
if skip_non_relocatable and not package.is_relocatable: | ||
if verbose: | ||
print_warning( | ||
"Skipped bundling of non-relocatable package %s", | ||
package.qualified_name | ||
) | ||
continue | ||
|
||
copy_package( | ||
package=package, | ||
dest_repository=repo_path, | ||
variants=[variant.index], | ||
force=force, | ||
keep_timestamp=True, | ||
verbose=verbose | ||
) | ||
|
||
relocated_package_names.append(package.name) | ||
|
||
return relocated_package_names | ||
|
||
|
||
def _write_retargeted_context(context, bundle_dir, relocated_package_names): | ||
repo_path = os.path.join(bundle_dir, "packages") | ||
rxt_filepath = os.path.join(bundle_dir, "context.rxt") | ||
|
||
bundled_context = context.retargeted( | ||
package_paths=[repo_path], | ||
package_names=relocated_package_names, | ||
skip_missing=True | ||
) | ||
|
||
bundled_context.save(rxt_filepath) | ||
return rxt_filepath |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,7 @@ | |
"test": {}, | ||
"view": {}, | ||
"yaml2py": {}, | ||
"bundle": {} | ||
} | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
''' | ||
Bundle a context and its packages into a relocatable dir. | ||
''' | ||
from __future__ import print_function | ||
|
||
import os | ||
import os.path | ||
import sys | ||
|
||
|
||
def setup_parser(parser, completions=False): | ||
group = parser.add_mutually_exclusive_group() | ||
group.add_argument( | ||
"-s", "--skip-non-relocatable", action="store_true", | ||
help="leave non-relocatable packages non-bundled, rather than raise an error") | ||
group.add_argument( | ||
"-f", "--force", action="store_true", | ||
help="bundle package even if it isn't relocatable (use at your own risk)") | ||
parser.add_argument( | ||
"RXT", | ||
help="context to bundle") | ||
parser.add_argument( | ||
"DEST_DIR", | ||
help="directory to create bundle in; must not exist") | ||
|
||
|
||
def command(opts, parser, extra_arg_groups=None): | ||
from rez.utils.logging_ import print_error | ||
from rez.bundle_context import bundle_context | ||
from rez.resolved_context import ResolvedContext | ||
|
||
rxt_filepath = os.path.abspath(os.path.expanduser(opts.RXT)) | ||
dest_dir = os.path.abspath(os.path.expanduser(opts.DEST_DIR)) | ||
|
||
# sanity checks | ||
if not os.path.exists(rxt_filepath): | ||
print_error("File does not exist: %s", rxt_filepath) | ||
sys.exit(1) | ||
|
||
context = ResolvedContext.load(rxt_filepath) | ||
|
||
bundle_context( | ||
context=context, | ||
dest_dir=dest_dir, | ||
force=opts.force, | ||
skip_non_relocatable=opts.skip_non_relocatable, | ||
verbose=opts.verbose | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small py3 compat issue I ran into