manifest.py revision 1044
39N/A# The contents of this file are subject to the terms of the 39N/A# Common Development and Distribution License (the "License"). 39N/A# You may not use this file except in compliance with the License. 39N/A# See the License for the specific language governing permissions 39N/A# and limitations under the License. 39N/A# When distributing Covered Code, include this CDDL HEADER in each 39N/A# If applicable, add the following below this CDDL HEADER, with the 39N/A# fields enclosed by brackets "[]" replaced with your own identifying 39N/A# information: Portions Copyright [yyyy] [name of copyright owner] 926N/A# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 39N/A# Use is subject to license terms. 39N/A """A Manifest is the representation of the actions composing a specific 39N/A package version on both the client and the repository. Both purposes 39N/A utilize the same storage format. 205N/A The serialized structure of a manifest is an unordered list of actions. 205N/A The special action, "set", represents a package attribute. 39N/A The reserved attribute, "fmri", represents the package and version 39N/A described by this manifest. It is available as a string via the 39N/A attributes dictionary, and as an FMRI object from the fmri member. 39N/A The list of manifest-wide reserved attributes is 39N/A base_directory Default base directory, for non-user images. 39N/A isa Package is intended for a list of ISAs. 39N/A platform Package is intended for a list of platforms. 39N/A relocatable Suitable for User Image. 39N/A All non-prefixed attributes are reserved to the framework. Third 39N/A parties may prefix their attributes with a reversed domain name, domain 39N/A name, or stock symbol. An example might be 39N/A com.example,supported 39N/A as an indicator that a specific package version is supported by the 39N/A vendor, example.com. 48N/A manifest.null is provided as the null manifest. Differences against the 48N/A null manifest result in the complete set of attributes and actions of 48N/A the non-null manifest, meaning that all operations can be viewed as 48N/A tranitions between the manifest being installed and the manifest already 48N/A present in the image (which may be the null manifest). 203N/A """Return three lists of action pairs representing origin and 203N/A destination actions. The first list contains the pairs 203N/A representing additions, the second list contains the pairs 203N/A representing updates, and the third list contains the pairs 203N/A represnting removals. All three lists are in the order in which 203N/A they should be executed.""" 72N/A # XXX Do we need to find some way to assert that the keys are 307N/A # XXX for now, we force license actions to always be 307N/A # different to insure that existing license files for 307N/A # new versions are always installed 72N/A # XXX Do changed actions need to be sorted at all? This is 72N/A # likely to be the largest list, so we might save significant 72N/A # time by not sorting. Should we sort above? Insert into a 72N/A # singlesort = lambda x: x[0] or x[1] 838N/A """Like the unix utility comm, except that this function 838N/A takes an arbitrary number of manifests and compares them, 838N/A returning a tuple consisting of each manifest's actions 926N/A that are not the same for all manifests, followed by a 838N/A list of actions that are the same in each manifest.""" 838N/A # construct list of dictionaries of actions in each 838N/A # manifest, indexed by unique keys 838N/A # construct list of key sets in each dict 838N/A # determine which common_keys have common actions 203N/A """Where difference() returns three lists, combined_difference() 315N/A returns a single list of the concatenation of the three.""" 48N/A """Output expects that self is newer than other. Use of sets 48N/A requires that we convert the action objects into some marshalled 48N/A form, otherwise set member identities are derived from the 48N/A object pointers, rather than the contents.""" 838N/A """Generate actions in manifest through ordered callable list""" 838N/A """Generate actions in the manifest of type "type" 838N/A through ordered callable list""" 615N/A """Generate the value of the key atrribute for each action 615N/A of type "type" in the manifest.""" 111N/A """Find actions in the manifest which are duplicates (i.e., 111N/A represent the same object) but which are not identical (i.e., 111N/A have all the same attributes).""" 111N/A """Return a key on which actions can be sorted.""" 926N/A """content is the text representation of the manifest""" 72N/A # sdict and odict in difference() above, and have that be our 72N/A # main datastore, rather than the simple list we have now. If 72N/A # we do that here, we can even assert that the "same" action 72N/A # can't be in a manifest twice. (The problem of having the same 72N/A # action more than once in packages that can be installed 72N/A # together has to be solved somewhere else, though.) 146N/A if not l
or l[
0] ==
"#":
591N/A # Add the FMRI to the exception and re-raise 926N/A # Translate old action to new. 838N/A # add any set actions to attributes 838N/A # append any variants and facets to manifest dict 956N/A """Fill attribute array w/ set action contents.""" 1007N/A """Produces the search dictionary for a specific manifest. 1007N/A A dictionary is constructed which maps a tuple of token, 1007N/A action type, key, and the value that matched the token to 1007N/A the byte offset into the manifest file. file_path is the 1007N/A path to the manifest file. excludes is the variants which 1007N/A should be allowed in this image. return_line is a debugging 1007N/A flag which makes the function map the information to the 1007N/A string of the line, rather than the byte offset to allow 429N/A """Store the manifest contents to disk.""" 315N/A # We specifically avoid sorting manifests before writing 315N/A # them to disk-- there's really no point in doing so, since 315N/A # we'll sort actions globally during packaging operations. 1044N/A """Returns an integer representing the total size, in bytes, of 1044N/A the Manifest's data payload. 1044N/A 'excludes' is a list of variants which should be allowed when 838N/A """Return the value for the package attribute 'key'.""" 296N/A """Set the value for the package attribute 'key' to 'value'.""" 956N/A """This class handles a cache of manifests for the client; 956N/A it partitions the manifest into multiple files (one per 956N/A action type) and also builds an on-disk cache of the 956N/A directories explictly and implicitly referenced by the 956N/A """Raises KeyError exception if cached manifest 956N/A is not present and contents are None; delays 956N/A reading of manifest until required if cache file 956N/A # Do we have a cached copy? 956N/A # we have no cached copy; save one 956N/A # don't specify excludes so on-disk copy has 956N/A # we have a cached copy of the manifest 956N/A # have we computed the dircache? 956N/A """Load all manifest contents from on-disk copy of manifest""" 967N/A """Unload manifest; used to reduce peak memory comsumption 967N/A when downloading new manifests""" 956N/A """Finish loading.... this part of initialization is common 956N/A to multiple code paths""" 956N/A # this needs to change; we should not modify on-disk manifest 956N/A """ store the current action set; also create per-type 967N/A caches. Return True if data was saved, False if not""" 956N/A # this allows us to try to cache new manifests 956N/A # when non-root w/o failures 956N/A """ create manifest.<typename> files to accelerate partial 956N/A parsing of manifests. Separate from __storeback code to 956N/A allow upgrade to reuse existing on disk manifests""" 956N/A # create per-action type cache; use rename to avoid 956N/A # corrupt files if ^C'd in the middle 956N/A # XXX consider use of per-process tmp file names 956N/A """ from a dictionary of paths, generate contents of dircache 956N/A yield "dir path=%s %s\n" % \
956N/A """ create dictionary of all directories referenced 956N/A by actions explicitly or implicitly from self.actions... 956N/A include variants as values; collapse variants where possible""" 956N/A # build a dictionary containing all directories tagged w/ 956N/A # remove any tags if any entries are always installed (NULL) 956N/A # could collapse dirs where all variants are present 956N/A """ return a list of directories implicitly or 956N/A explicitly referenced by this object""" 956N/A # need to load from disk 956N/A # generate actions that contain directories 956N/A # we have cached copy on disk; use it 956N/A """ generate actions of the specified type; 956N/A use already in-memory stuff if already loaded, 956N/A otherwise use per-action types files""" 956N/A # invoke subclass method to generate action by action 956N/A # get manifest from disk 956N/A # invoke subclass method to generate action by action 956N/A # we have a cached copy - use it 956N/A return # no such action in this manifest 956N/A """Load attributes dictionary from cached set actions; 956N/A this speeds up pkg info a lot""" 956N/A """No assignments to cached manifests allowed.""" 956N/A assert "CachedManifests are not dicts" 964N/A """Special class for pkgplan's need for a empty manifest; 964N/A the regular null manifest doesn't support get_directories 964N/A and making the cached manifest code handle this case is