manifest.py revision 2144
106N/A# The contents of this file are subject to the terms of the 106N/A# Common Development and Distribution License (the "License"). 106N/A# You may not use this file except in compliance with the License. 106N/A# See the License for the specific language governing permissions 106N/A# and limitations under the License. 106N/A# When distributing Covered Code, include this CDDL HEADER in each 106N/A# If applicable, add the following below this CDDL HEADER, with the 106N/A# fields enclosed by brackets "[]" replaced with your own identifying 106N/A# information: Portions Copyright [yyyy] [name of copyright owner] 106N/A# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 4561N/A """A Manifest is the representation of the actions composing a specific 4561N/A package version on both the client and the repository. Both purposes 4561N/A utilize the same storage format. 4561N/A The serialized structure of a manifest is an unordered list of actions. 3996N/A The special action, "set", represents a package attribute. 1247N/A The reserved attribute, "fmri", represents the package and version 1247N/A described by this manifest. It is available as a string via the 1247N/A attributes dictionary, and as an FMRI object from the fmri member. 1874N/A The list of manifest-wide reserved attributes is 1874N/A base_directory Default base directory, for non-user images. 1247N/A isa Package is intended for a list of ISAs. 1247N/A platform Package is intended for a list of platforms. 106N/A relocatable Suitable for User Image. 1874N/A All non-prefixed attributes are reserved to the framework. Third 106N/A parties may prefix their attributes with a reversed domain name, domain 1874N/A name, or stock symbol. An example might be 1247N/A as an indicator that a specific package version is supported by the 1247N/A manifest.null is provided as the null manifest. Differences against the 1247N/A null manifest result in the complete set of attributes and actions of 1247N/A the non-null manifest, meaning that all operations can be viewed as 1247N/A tranitions between the manifest being installed and the manifest already 1247N/A present in the image (which may be the null manifest). r +=
"set name=pkg.fmri value=%s\n" %
self.
fmri """A generator function that returns the unsorted manifest contents as lines of text.""" yield "set name=pkg.fmri value=%s\n" %
self.
fmri """Return three lists of action pairs representing origin and destination actions. The first list contains the pairs representing additions, the second list contains the pairs representing updates, and the third list contains the pairs representing removals. All three lists are in the order in which they should be executed.""" # XXX Do we need to find some way to assert that the keys are # No origin was provided, so nothing has been changed or # removed; only added. In addition, this doesn't need # to be sorted since the caller likely already does """handle key values that may be lists""" # XXX Do changed actions need to be sorted at all? This is # likely to be the largest list, so we might save significant # time by not sorting. Should we sort above? Insert into a # singlesort = lambda x: x[0] or x[1] """Like the unix utility comm, except that this function takes an arbitrary number of manifests and compares them, returning a tuple consisting of each manifest's actions that are not the same for all manifests, followed by a list of actions that are the same in each manifest.""" # construct list of dictionaries of actions in each # manifest, indexed by unique keys # construct list of key sets in each dict # determine which common_keys have common actions """Where difference() returns three lists, combined_difference() returns a single list of the concatenation of the three.""" """Output expects that self is newer than other. Use of sets requires that we convert the action objects into some marshalled form, otherwise set member identities are derived from the object pointers, rather than the contents.""" """Generate actions in manifest through ordered callable list""" """Generate actions in the manifest of type "type" through ordered callable list""" """Generate the value of the key atrribute for each action of type "type" in the manifest.""" """Find actions in the manifest which are duplicates (i.e., represent the same object) but which are not identical (i.e., have all the same attributes).""" """Return a key on which actions can be sorted.""" # Get an iterable for the string. if l.
endswith(
"\\"):
# allow continuation chars if not l
or l[
0] ==
"#":
# ignore blank lines & comments # Accumulate errors and continue so that as # much of the action data as possible can be """Populate the manifest with actions. 'content' is an optional value containing either the text representation of the manifest or an iterable of 'excludes' is an optional list of variants to exclude from the 'pathname' is an optional filename containing the location of 'signatures' is an optional boolean value that indicates whether a manifest signature should be generated. This is only possible when 'content' is a string or 'pathname' is provided. # So we could build up here the type/key_attr dictionaries like # sdict and odict in difference() above, and have that be our # main datastore, rather than the simple list we have now. If # we do that here, we can even assert that the "same" action # can't be in a manifest twice. (The problem of having the same # action more than once in packages that can be installed # together has to be solved somewhere else, though.) # Generate manifest signature based upon # input content, but only if signatures """Remove any actions from the manifest which should be """Performs any needed transformations on the action then adds The "action" parameter is the action object that should be The "excludes" parameter is the variants to exclude from the # XXX handle legacy transition issues; not needed after # 2009.06 release & republication are complete. # Translate old action to new. # add any set actions to attributes # append any variants and facets to manifest dict """Fill attribute array w/ set action contents.""" except KeyError:
# ignore broken set actions """Produces the search dictionary for a specific manifest. A dictionary is constructed which maps a tuple of token, action type, key, and the value that matched the token to the byte offset into the manifest file. file_path is the path to the manifest file. excludes is the variants which should be allowed in this image. return_line is a debugging flag which makes the function map the information to the string of the line, rather than the byte offset to allow """Translates what actions.generate_indices produces into a dictionary mapping token, action_name, key, and the value that should be displayed for matching that token to byte offsets into the manifest file. The "lst" parameter is the data to be converted. The "cp" parameter is the byte offset into the file for the action which produced lst.""" log((_(
"%(fp)s:\n%(e)s") %
"""This method takes a string representing the on-disk manifest content, and returns a hash value.""" # Byte stream expected, so pass encoded. """Verifies whether the signatures for the contents of the manifest match the specified signature data. Raises the 'BadManifestSignatures' exception on failure.""" """Store the manifest contents to disk.""" # We specifically avoid sorting manifests before writing # them to disk-- there's really no point in doing so, since # we'll sort actions globally during packaging operations. """Return a dictionary mapping variant tags to their values.""" """Returns the boolean of the value of the attribute 'key'.""" raise ValueError(_(
"Attribute value '%s' not 'true' or " """Returns an integer representing the total size, in bytes, of the Manifest's data payload. 'excludes' is a list of variants which should be allowed when """Return the value for the package attribute 'key'.""" """Set the value for the package attribute 'key' to 'value'.""" """This class serves as a wrapper for the Manifest class for callers that need efficient access to package data on a per-action type basis. It achieves this by partitioning the manifest into multiple files (one per action type) and then storing an on-disk cache of the directories explictly and implicitly referenced by the manifest each tagged with """Raises KeyError exception if factored manifest is not present and contents are None; delays reading of manifest until required if cache file is present. 'fmri' is a PkgFmri object representing the identity of the 'cache_root' is the pathname of the directory where the manifest and cache files should be stored or loaded from. 'contents' is an optional string to use as the contents of the manifest if a cached copy does not already exist. 'excludes' is an optional list of excludes to apply to the 'pathname' is an optional string containing the pathname of a manifest. If not provided, it is assumed that the manifest is stored in a file named 'manifest' in the directory indicated by 'cache_root'. If provided, and contents is also provided, then 'contents' will be stored in 'pathname' if it does not already # Do we have a cached copy? # we have no cached copy; save one # don't specify excludes so on-disk copy has # we have a cached copy of the manifest # have we computed the dircache? """Load all manifest contents from on-disk copy of manifest""" """Unload manifest; used to reduce peak memory comsumption when downloading new manifests""" """Finish loading.... this part of initialization is common to multiple code paths""" """ store the current action set; also create per-type caches. Return True if data was saved, False if not""" # this allows us to try to cache new manifests # when non-root w/o failures. """ create manifest.<typename> files to accelerate partial parsing of manifests. Separate from __storeback code to allow upgrade to reuse existing on disk manifests""" # Ensure target cache directory and intermediates exist. # create per-action type cache; use rename to avoid # corrupt files if ^C'd in the middle """ from a dictionary of paths, generate contents of dircache yield "dir path=%s %s\n" % \
(d,
" ".
join(
"%s=%s" % t \
""" create dictionary of all directories referenced by actions explicitly or implicitly from self.actions... include variants as values; collapse variants where possible""" # build a dictionary containing all directories tagged w/ # remove any tags if any entries are always installed (NULL) # could collapse dirs where all variants are present """Remove all manifest cache files found in the given directory (excluding the manifest itself). """ return a list of directories implicitly or explicitly referenced by this object""" # generate actions that contain directories # we have cached copy on disk; use it """ generate actions of the specified type; use already in-memory stuff if already loaded, otherwise use per-action types files""" if self.
loaded:
#if already loaded, use in-memory cached version # invoke subclass method to generate action by action # invoke subclass method to generate action by action # we have a cached copy - use it return # no such action in this manifest """Load attributes dictionary from cached set actions; this speeds up pkg info a lot""" """No assignments to factored manifests allowed.""" assert "FactoredManifests are not dicts" """The absolute pathname of the file containing the manifest.""" """Special class for pkgplan's need for a empty manifest; the regular null manifest doesn't support get_directories and making the factored manifest code handle this case is """Return three lists of action pairs representing origin and destination actions. The first list contains the pairs representing additions, the second list contains the pairs representing updates, and the third list contains the pairs representing removals. All three lists are in the order in which they should be executed.""" # The difference for this case is simply everything in the # origin has been removed. This is an optimization for