common.py revision 3025
# linked image properties # properties that never get saved # special linked image name values (PROP_NAME) # linked image model values (PROP_MODEL) # files which contain linked image data # we define PATH_TRANSFORM_NONE as a tuple instead of just None because this # will prevent it from being accidently serialized to json. """Sanity check a linked image operation return value tuple. The format of said tuple is: LinkedImageException exception (optional) json dictionary containing planned image changes # make sure we're using the LI_RVTuple class # any exception returned must be a LinkedImageException # if specified, p_dict must be a dictionary # some child return codes should never be associated with an exception # a p_dict can only be returned if the child returned EXIT_OK # return the value that was passed in """Given a linked image return value dictionary, sanity check all the (
"Unexpected rvdict key: ", k)
# return the value that was passed in """Given a linked image return value dictionary, return a list of any exceptions that were encountered while processing children.""" # get a list of exceptions """If an exception was encountered while operating on a linked child then raise that exception. If multiple exceptions were encountered while operating on multiple children, then bundle those exceptions together and raise them.""" # get a list of exceptions # one exception encountered # multiple exceptions encountered """This class is a template that all linked image plugins should inherit from. Linked image plugins derived from this class are designed to manage linked aspects of the current image (vs managing linked aspects of a specific child of the current image). All the interfaces exported by this class and its descendants are private to the linked image subsystem and should not be called directly by any other subsystem.""" # Unused argument; pylint: disable=W0613 """Initialize a linked image plugin. 'pname' is the name of the plugin class derived from this 'linked' is the LinkedImage object initializing this plugin. """Called when the path to the image that we're operating on is changing. This normally occurs when we clone an image after we've planned and prepared to do an operation.""" """If the linked image plugin is able to detect that we're operating on an image in an alternate root then return an transform that can be used to translate between the original image path and the current one.""" # return value: string or None """Return a list of the child images and paths associated with the current image. The paths that are returned should be absolute paths to the original child image locations.""" """Get the linked image properties associated with the specified child image.""" """Attach the specified child image. This operation should only affect in-memory state of the current image. It should not update any persistent on-disk linked image state or access the child image in any way. This routine should assume that the linked image properties have already been validated.""" """Detach the specified child image. This operation should only affect in-memory state of the current image. It should not update any persistent on-disk linked image state or access the child image in any way.""" """Sync out the in-memory linked image state of this image to # return value: LI_RVTuple() """This class is a template that all linked image child plugins should inherit from. Linked image child plugins derived from this class are designed to manage linked aspects of children of the current image. (vs managing linked aspects of the current image itself). All the interfaces exported by this class and its descendants are private to the linked image subsystem and should not be called directly by any other subsystem.""" """Initialize a linked image child plugin. 'lic' is the LinkedImageChild object initializing this plugin. """Called before a parent image saves linked image properties into a child image. Gives the linked image child plugin a chance to update the properties that will be saved within the """A class for naming child linked images. Linked image names are used for all child images (and only child images), and they encode two pieces of information. The name of the plugin used to manage the image and a linked image name. Linked image names have the following format "<linked_image_plugin>:<linked_image_name>""" """Returns the serialized state of this object in a format that that can be easily stored using JSON, pickle, etc.""" # Unused argument; pylint: disable=W0613 """Allocate a new object using previously serialized state obtained via getstate().""" # Unused argument; pylint: disable=W0613 """A LinkedImage object is used to manage the linked image aspects of an image. This image could be a child image, a parent image, or both a parent and child. This object allows for access to linked image properties and also provides routines that allow operations to be performed on child images.""" # Properties that a parent image with push children should save locally. # Properties that a pull child image should save locally. # Properties that a parent image with push children should save in # make sure there is no invalid overlap """Initialize a new LinkedImage object.""" # variables reset by self.__update_props() # variables reset by self.__recursion_init() # variables reset by self._init_root() # initialize with no properties # initialize linked image plugin objects # if the image has a path setup, we can load data from it. """Get a pointer to the image object associated with this """Called during object initialization and by image.py`__set_root() to let us know when we're changing the root location of the image. (The only time we change the root path is when changes BEs during operations which clone BEs. So when this happens most our metadata shouldn't actually # Check if this is our first time accessing the current image # or if we're just re-initializing ourselves. # figure out the new root image path # initialize paths for linked image data files # if this isn't a reset, then load data from the image # the first time around we load non-temporary data (if # there is any) so that we can audit ourselves and see # if we're in currently in sync. # now re-load all the data taking into account any # temporary new data associated with an in-progress # if we're not linked we're done # if this is a reset, update temporal properties # Tell linked image plugins about the updated paths # Unused variable 'plugin'; pylint: disable=W0612 # Tell linked image children about the updated paths """Internal helper routine used when we want to update any linked image properties. This routine sanity check the new properties, updates them, and resets any cached state that is affected by property values.""" # all temporal properties must exist # PROP_CURRENT_PARENT_PATH can only be set if # we have PROP_PARENT_PATH. """Perform internal consistency checks for a set of linked image properties. Don't update any state.""" # if we're not a child image ourselves, then we're done # make sure PROP_MODEL was specified # validate the linked image name # make sure PROP_MODEL was specified """Given a new path_transform, update path properties.""" "no temporal properties are set: %s" %
props "temporal properties already set: %s" %
props # Either 'path' or 'current_path' must be specified. """Given a set of linked image properties, the image paths stored within those properties may not match the actual image paths if we're executing within an alternate root environment. To deal with this situation we create temporal in-memory properties that represent the current path to the image, and a transform that allows us to translate between the current path and the original path.""" """If we're initializing parent linked image properties for the first time (or if those properties somehow got deleted) then we need to know if the parent image that we're currently operating on is located within an alternate root. One way to do this is to ask our linked image plugins if they can determine this (the zones linked image plugin usually can if the image is a global zone).""" # ask each plugin if we're operating in an alternate root # no transform suggested by plugins # check for conflicting transforms # Unused variable; pylint: disable=W0612 # we have a transform from our plugins # we have conflicting transforms, time to die """Fabricate the minimum set of properties required for a # ask our plugins if we're operating with alternate image paths """Load linked image properties from disk and return them to the caller. We sanity check the properties, but we don't update any internal linked image state. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have ".<runid>" appended to them.""" # read the linked image properties from disk # make sure there are no saved temporal properties # convert PROP_NAME into a linked image name obj # sanity check our properties """Load linked image inherited facets from disk. Don't update any internal state. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have ".<runid>" appended to them.""" # W0212 Access to a protected member """Load linked image parent packages from disk. Don't update any internal state. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have ".<runid>" appended to them.""" """Load linked image parent publishers from disk. Don't update any internal state. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have ".<runid>" appended to them.""" """Load linked image properties and constraints from disk. Update the linked image internal state with the loaded data.""" # Normally, if we're a parent image we'll have linked image # properties stored on disk. So load those now. # If no properties are loaded, we may still be a parent image # that is just missing it's metadata. (oops.) We attempt to # detect this situation by invoking __isparent(), which will # ask each child if there are any children. This is a best # effort attempt, so when we do this we ignore any plugin # runtime errors since we really want Image object # initialization to succeed. If we don't have any linked # image metadata, and we're having runtime errors querying for # children, then we'll allow initialization here, but any # subsequent operation that tries to access children will fail # and the caller will have to specify that they want to ignore # all children to allow the operation to succeed. # Oops. We're a parent image with no properties # stored on disk. Rather than throwing an exception # try to fabricate up some props with reasonably # guessed values which the user can subsequently # load parent packages. if parent package data is missing just # continue along and hope for the best. # load inherited facets. if inherited facet data is missing # just continue along and hope for the best. # load parent publisher data. if publisher data is missing # continue along and we'll just skip the publisher checks, # it's better than failing and preventing any image updates. """Verify property value for PROP_RECURSE.""" """Validate user supplied linked image attach properties. Don't update any internal state.""" # make sure that only attach time options have been # specified, and that they have allowed values. # check each property the user specified. # did the user specify an allowable property? # did the user specify a valid property value? # is this property valid for this type of image? """Initialize an Image object which can be used to access a """If our in-memory linked image state matches the on-disk linked image state then there's nothing to do. If the state differs then there is stuff to do since the new state needs # check if we're not a linked image. # if any linked image metadata files exist they need # compare in-memory and on-disk properties # linked image metadata files with inherited data # check if we're just a parent image. # parent images only have properties. if any linked # image metadata files that contain inherited # information exist they need to be deleted. # if we're missing any metadata files then there's work todo # compare in-memory and on-disk inherited facets # compare in-memory and on-disk parent packages # compare in-memory and on-disk parent publishers """If we're a child image's, verify that the parent image publisher configuration is a subset of the child images publisher configuration. This means that all publishers configured within the parent image must also be configured within the child image with the same: - sticky and disabled settings The child image may have additional publishers configured but they must all be lower ranked than the parent's publishers. # if we're not a child image then bail # if we're using the sysrepo then don't bother # parent publisher data is missing, press on and hope # child image needs at least as many publishers as the parent # check rank, sticky, and disabled settings """Update linked image constraint, publisher data, and state from our parent image.""" # we're not a child image, nothing to do # parent pushes data to us, nothing to do # initialize the parent image # get metadata from our parent image """Update linked image constraint, publisher data, and state from our parent image. If catch_exception is true catch any linked image exceptions and pack them up in a linked image """Write in-memory linked image state to disk.""" # create a list of metadata file paths # cleanup any temporary files # we're no longer linked; delete metadata # save our properties, but first remove any temporal properties # if we're not a child we don't have parent data # we're a child so save our latest constraints """If the current image is a child image, this function returns a linked image name object which represents the name """Indicates whether the current image is a child image.""" """Indicates whether the current image is a parent image. 'ignore_plugin_errors' ignore plugin runtime errors when trying to determine if we're a parent image. """Indicates whether the current image is a parent image.""" """Indicates wether the current image is already linked.""" """Return the current path transform property.""" """Check if we're accessing a linked image at an alternate """Report our current image path.""" """Report our current image path.""" """If we know where our parent should be, report it's expected """Return a dictionary which represents the linked image properties associated with a linked image. 'lin' is the name of the child image. If lin is None then the current image is assumed to be a linked image and it's Always returns a copy of the properties in case the caller # If we're not linked we'll return an empty # make sure the specified child exists # make a copy of the props in case they are updated # add temporal properties """Raise an exception because the current image is not a child """Check if a specific child image exists.""" "%s == LinkedImageName" %
type(
lin)
"""Given a list of linked image name objects, make sure all "type(lin_list) == %s, str(lin_list) == %s" % \
"""Facets inherited from our parent image.""" """A set of the fmris installed in our parent image.""" # We return None since frozenset() would indicate # that there are no packages installed in the parent """Given a string representing a linked image child name, returns linked image name object representing the same name. 'allow_unknown' indicates whether the name must represent actual children or simply be syntactically correct.""" """Returns a list of linked child images associated with the 'li_ignore' see list_related() for a description. The returned value is a list of tuples where each tuple contains (<li name>, <li path>).""" # sort by linked image name # don't ignore any children """Returns a list of linked images associated with the current image. This includes both child and parent images. 'li_ignore' is either None or a list. If it's None (the default), all children will be listed. If it's an empty list no children will be listed. Otherwise, any children listed in li_ignore will be ommited from the results. The returned value is a list of tuples where each tuple contains (<li name>, <relationship>, <li path>).""" # we're linked so append ourself to the list # if we have a path to our parent then append that as well. # sort by linked image name """We only update in-memory state; nothing is written to disk, to sync linked image state to disk call syncmd.""" # Path must be an absolute path. # we don't bother to cleanup the path to the parent image here # because when we allocate an Image object for the parent # image, it will do that work for us. # get the cleaned up parent image path. # Make sure our parent image is at it's default path. (We # don't allow attaching new images if an image is located at # make a copy of the properties and update them # If we're in an alternate root, the parent must also be within # Set path related properties. We use self.__root in place of # current_path() since we may not actually be linked yet. # this prop doesn't apply to pull images """We only update in memory state; nothing is written to disk, to sync linked image state to disk call syncmd.""" # Generate a new set of linked image properties. If we have # no children then we don't need any more properties. # If we have children we'll need to keep some properties. # Update our linked image properties. """Determine if an image is in sync with its constraints.""" # get parent dependencies from the catalog if a.
name ==
"depend" and \
a.
attrs[
"type"] ==
"parent" # create a dictionary of packages installed in the parent """If the current image is a child image, this function audits the current image to see if it's in sync with its # we don't use the latest linked image metadata. # instead return cached insync value which was # computed using the initial linked image metadata # that we loaded from disk. """A convenience wrapper for audit_self(). Note that we consider non-child images as always in sync and ignore """Internal helper function that takes a dictionary returned from an operations on multiple children and merges the results into a single return code.""" # keep track of all the return values that are mapped # the mappings better have included pkgdefs.EXIT_OK # if we had errors for unmapped return values, bundle them up # we have one consistent return value """Convenience function that takes a dictionary returned from an operations on multiple children and merges the results into """Convenience function that takes a dictionary returned from an operations on multiple children and merges the results into """Convenience function that takes a dictionary returned from an operations on multiple children and merges the results into """Sanity check the parameters associated with a child image that we are trying to attach.""" # check the name to make sure it doesn't already exist # Path must be an absolute path. # If we're in an alternate root, the child must also be within # Does the parent image (ourselves) reside in clonable BE? # Unused variable 'be_uuid'; pylint: disable=W0612 # If the parent image is clonable then the new child image # must be nested within the parents filesystem namespace. # Child image should not already be linked # W0212 Access to a protected member """Make sure there are no additional images in between the parent and the child. For example, this prevents linking of images if one of the images is nested within another unrelated image. This is done by looking at all the parent directories for both the parent and the child image until we reach a # Make sure each path has a trailing '/'. # Make sure we're not linking to ourselves. # The parent image can't be nested nested within child. # Make sure we're not linking the root image as a child. # Make sure our current image is at it's default path. (We # don't allow attaching new images if an image is located at """Raise an exception if directory 'd' contains an # W0212 Access to a protected member # Find the common parent directory of the both parent and the # Test the common parent. # First check the parent directories of the child. # Then check the parent directories of the parent. """Attach an image as a child to the current image (the current image will become a parent image. This operation results in attempting to sync the child image with the parent For descriptions of parameters please see the descriptions in # Path must be an absolute path. # if the current image isn't linked yet then we need to # generate some linked image properties for ourselves # make a copy of the options and start updating them # set path related properties # fill in any missing defaults options # attach the child in memory # we've validated parameters, nothing else to do # commit child image property updates # save parent image properties # The recursive child operation may have returned NOP, but # since we always update our own image metadata, we always """Audit one or more children of the current image to see if they are in sync with this image.""" """Sync one or more children of the current image.""" """Detach one or more children from the current image. This operation results in the removal of any constraint package from the child images.""" # check if we support detach for these children. we don't use # iteritems() when walking lic_dict because we might modify # we can't detach this type of image. # if any of the children successfully detached, then we want # to discard our metadata for that child. # if the detach failed leave metadata in parent # detach the child in memory # commit child image property updates # don't overwrite previous errors # we're not linked anymore, so delete all our linked """Wrapper for __children_op_vec() to stay compatible with old callers which only support one operation for all linked images. '_pkg_op' is the pkg.1 operation that we're going to perform '_lic_list' is a list of linked image child objects to perform '_ignore_syncmd_nop' a boolean that indicates if we should always recurse into a child even if the linked image meta data See __children_op_vec() for an explanation of the remaining """An iterator function which performs a linked image operation on multiple children in parallel. '_lic_op_vectors' is a list of tuples containing the operation to perform, the list of linked images the operation is to be performed on, the kwargs for this operation and if the metadata sync nop should be ignored in the following form: [(pkg_op, lin_list, kwargs, ignore_syncmd_nop), ...] '_rvdict' is a dictionary, indexed by linked image name, which contains rvtuples of the result of the operation for each '_prograck' is a ProgressTracker pointer. '_failfast' is a boolean. If True and we encounter a failure operating on a child then we raise an exception immediately. If False then we'll attempt to perform the operation on all children and rvdict will contain a LI_RVTuple result for all '_expect_plan' is a boolean that indicates if we expect this operation to generate an image plan. '_syncmd_tmp' a boolean that indicates if we should write linked image metadata in a temporary location in child images, or just overwrite any existing data. '_pd' a PlanDescription pointer.""" # make sure we don't have any duplicate LICs or duplicate LINs # At the moment the PT doesn't seem to really use the operation # type for display reasons. It only uses it to treat pubcheck # differently. Therefore it should be sufficient to skip the # operation type in case we have different operations going on # Additionally, if the operation is the same for all children # we can use some optimizations. # These operations are cheap so ideally we'd # like to use full parallelism. But if the user # specified a concurrency limit we should # No limit was specified, use full # If we have a plan for the current image that means linked # image metadata is probably changing so we always save it to # a temporary file (and we don't overwrite the existing # metadata until after we execute the plan). # get parent metadata common to all child images # setup operation for each child # if _failfast is true, then throw an exception if we failed # to setup any of the children. if _failfast is false we'll # continue to perform the operation on any children that # successfully initialized and we'll report setup errors along # with the final results for all children. # before we raise an exception we need to cleanup any # children that we setup. """An iterator function invoked when a child has 'lic' is the child that has finished execution. 'lic_list' a list of children to remove 'lic' from. See __children_op() for an explanation of the other # check if we should raise an exception # we're going to raise an exception. abort # the remaining children. # only display child output if there was no # error (otherwise the exception includes the # output so we'll display it twice.) # check if we should yield a plan. # check if we did everything we needed to do during child # setup. (this can happen if we're just doing an implicit # syncmd during setup we discover the linked image metadata # isn't changing.) we iterate over a copy of lic_setup to # allow __child_op_finish() to remove elements from lic_setup # while we're walking through it. # keep track of currently running children # keep going as long as there are children to process # start processing on a child # display progress on children # poll on all the linked image children and see which # ones have pending output. # a child finished processing """Initialize LinkedImageChild objects for children specified in 'lin_list'. If 'lin_list' is not specified, then initialize objects for all children (excluding any being ignored via 'li_ignore').""" # you can't specify children to operate on and children to be # ignored at the same time # if no children we listed, build a list of children """Initialize child objects used during recursive packaging """Initialize planning state. If we're a child image we save our current state (which may reflect a planned state that we have not committed to disk) into the plan. We also initialize all our children to prepare to recurse into them.""" # we don't want to recurse # we don't need to recurse # if we have any children we don't support operations using # temporary repositories. """Do a recursive publisher check""" # get a list of of children to recurse into. # do a publisher check on all of them # raise an exception if one or more children failed the """This is an iterator function. It recurses into linked image children to perform the specified operation. # get a pointer to the current image plan # get a list of of children to recurse into. # if we're ignoring all children then we can't be recursing # sanity check the plan description state # the state should be uninitialized # if we ignored all children, we better not have # recursed into any children. # there shouldn't be any overloap between sets of # make sure set of child handles matches the set of # previously planned children. # if we're in the planning stage, we should pass the current # image plan onto the child and also expect an image plan from # Assemble list of LICs from LINs in pd.child_op_vectors and # create new lic_op_vectors to pass to __children_op_vec(). # For the prepare and execute phase we # remove children for which there is # nothing to do from self.__lic_dict. # So ignore those we can't find. # check for children that don't need any updates # record the children that are done planning """Determine what pkg command to use when recursing into child # given the api operation being performed on the current # image, figure out what api operation should be performed on # the recursion policy which hard coded here is that if we do # an pkg update in the parent image without any packages # specified (ie, we want to update everything) then when we # recurse we'll also do an update of everything. but if we're # doing any other operation like install, uninstall, an update # of specific packages, etc, then when we recurse we'll do a # To improve performance we assume the child is already in sync, # so if its linked image metadata isn't changing then the child # won't need any updates so there will be no need to recurse # If we are doing an explict sync, we do have to make # sure we actually recurse into the child and sync """Determine what pkg command arguments to use when recursing # when we recurse we always accept all new licenses (for now). # ultimately (when start yielding back plan descriptions for # children) in addition to accepting licenses on the plan for # the current image the api client will also have to # explicitly accept licenses for all child images. but until # that happens we'll just assume that the parent image license # space is a superset of the child image license space (and # since the api consumer must accept licenses in the parent # before we'll do anything, we'll assume licenses in the child # option specific to: attach, set-property-linked, sync # option specific to: install # option specific to: change-variant # option specific to: change-facet # option specific to: uninstall kwargs[
"pkgs_to_uninstall"] = \
del kwargs[
"refresh_catalogs"]
# skip ipkg up to date check for child images """Plan child image updates.""" # Get LinkedImageNames of all children # Prepare op vector for explicit recurse operations # remove recurse children from sync list # Prepare op vector for implicit recurse operations """Prepare child image updates.""" """Execute child image updates.""" """Initialize our state in the PlanDescription.""" # if we're a child, save our parent package state into the """Reload a previously created plan.""" # make a copy of the linked image properties # generate temporal properties # load linked image state from the plan # now initialize our recursion state, this involves allocating # handles to operate on children. we don't need handles for # children that were either ignored during planning, or which # return EXIT_NOP after planning (since these children don't # merge the children that returned nop into li_ignore (since # we don't need to recurse into them). if li_ignore is [], # then we ignored all children during planning # no children were ignored during planning """Return True if there is no planned work to do on child """A LinkedImageChild object is used when a parent image wants to access a child image. These accesses may include things like: saving/pushing linked image metadata into a child image, syncing or auditing a child image, or recursing into a child image to keep it in sync with planned changes in the parent image.""" "isinstance(%s, LinkedImage)" %
type(
li)
"isinstance(%s, LinkedImageName)" %
type(
lin)
# initialize paths for linked image data files # initialize a linked image child plugin """Get the name associated with a child image.""" """Get the path associated with a child image.""" """Get a pointer to the parent image object associated with """Write data to a child image.""" # first save our data to a temporary file # Check if the data is changing. To do this # comparison we load the serialized on-disk json data # into memory because there are no guarantees about # data ordering during serialization. When loading # the data we don't bother decoding it into objects. # If we're not actually updating any data, or if we # were just doing a test to see if the data has # changed, then delete the temporary data file. """Sync linked image parent constraint data to a child image. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have ".<runid>" appended to them.""" # save the planned parent packages """Sync linked image parent facet data to a child image. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have ".<runid>" appended to them.""" # save the planned parent facets """Sync linked image properties data to a child image. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have ".<runid>" appended to them.""" # make a copy of the props we want to push # delete temporal properties """Sync linked image parent publisher data to a child image. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have ".<runid>" appended to them.""" """Sync linked image data to a child image. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have ".<runid>" appended to them.""" # unpack parent metadata tuple """Prepare to perform an operation on a child image by syncing the latest linked image data to that image. As part of this operation, if we discover that the meta data hasn't changed we may report back that there is nothing to do (EXIT_NOP). 'pmd' is a tuple that contains parent metadata that we will sync to the child image. Note this is not all the metadata that we will sync, just the set which is common to all 'ignore_syncmd_nop' a boolean that indicates if we should always recurse into a child even if the linked image meta data 'tmp' a boolean that indicates if we should save the child image meta data into temporary files (instead of overwriting the persistent meta data files). 'test' a boolean that indicates we shouldn't save any child image meta data, instead we should just test to see if the 'stage' indicates which stage of execution we should be performing on a child image.""" # we don't update metadata during all stages of operation # we successfully updated the metadata # if the metadata changed then report success # the metadata didn't change, so this operation is a NOP """Prepare to sync a child image. This involves updating the linked image metadata in the child and then possibly recursing into the child to actually update packages. For descriptions of parameters please see the descriptions in # we're not going to recurse into the child image, # we're just going to update its metadata. # we don't support updating packages in the parent # during attach metadata only sync. # first sync the metadata # if we're doing this sync as part of an attach, then # temporarily sync the metadata since we don't know yet if the # attach will succeed. if the attach doesn't succeed this # means we don't have to delete any metadata. if the attach # succeeds the child will make the temporary metadata # permanent as part of the commit. # we don't support updating packages in the parent # the update failed or the metadata didn't change """Prepare to update a child image.""" # first sync the metadata # the update failed or the metadata didn't change # We need to make sure we don't pass None as pargs in """Prepare to install a pkg in a child image.""" # first sync the metadata # the update failed or the metadata didn't change """Prepare to install a pkg in a child image.""" # first sync the metadata # the update failed or the metadata didn't change """Prepare to install a pkg in a child image.""" # first sync the metadata # the update failed or the metadata didn't change # need to transform varcets back to string list """Prepare to detach a child image.""" """Prepare to a check if a child's publishers are in sync.""" # first sync the metadata # a pubcheck should never update persistent meta data # setup recursion into the child image """Prepare to a child image to see if it's in sync with its # first sync the metadata # setup recursion into the child image """Public interface to abort an operation on a child image.""" """Public interface to setup an operation that we'd like to perform on a child image.""" "Unsupported package client op: %s" %
_pkg_op)
"""Public interface to start an operation on a child image.""" # if we have a return value this operation is done """Public interface to query if an operation on a child image # if we have a return value this operation is done # make sure there is some data from the child """Public interface to get the result of an operation on a 'expect_plan' boolean indicating if the child is performing a planning operation. this is needed because if we're running in parsable output mode then the child will emit a parsable json version of the plan on stdout, and we'll verify it by running it through the json parser. # The child op is now done, so we reset __child_op to make sure # we don't accidentally reuse the LIC without properly setting # it up again. However, we still need the op type in this # function so we make a copy. # if we have a return value this operation is done # make sure we're not going to block # if we got an exception, or a return value other than OK or # NOP, then return an exception. # If a plan was created and we're in parsable output mode then # parse the plan that should have been displayed to stdout. # JSON raises a subclass of ValueError when it """Return the progress pipe associated with the PkgRemote instance that is operating on a child image.""" """Our image path is being updated, so figure out our new child image paths. This interface only gets invoked when: - We're doing a packaging operation on a parent image and we've just cloned that parent to create a new BE that we're going to update. This clone also cloned all the children and so now we need to update our paths to point to the newly - We tried to update a cloned image (as described above) and our update failed, hence we're changing paths back to the original images that were the source of the clone.""" # PROP_PARENT_PATH better not be present because # LinkedImageChild objects are only used with push child # Remove any path transform and reapply. # --------------------------------------------------------------------------- # Interfaces to obtain linked image metadata from an image """Return publisher information for the specified image. Publisher information is returned in a sorted list of lists <publisher name>, <sticky> <publisher name> is a string The tuples are sorted by publisher rank. """Figure out the current (or planned) list of packages in img.""" # if there's an image plan the we need to update the installed # packages based on that plan. """Get Facets from an image that a child should inherit. We only want to sync facets which affect packages that have parent dependencies on themselves. In practice this essentially limits us to "facet.version-lock.*" facets.""" # get installed (or planned) parent packages and facets # create a packages dictionary indexed by package stem. # iterate through all installed (or planned) package incorporation # dependency actions and find those that are affected by image facets. # we don't check for package-wide facets here because they don't do # anything. (ie, facets defined via "set" actions in a package have # no effect on other actions within that package.) # we're only interested in incorporate dependencies # check if any image facets affect this dependency # W0212 Access to a protected member # if all the matching facets are true we don't care # save this set of facets. # For each faceted incorporation dependency, check if it affects a # package that has parent dependencies on itself. This is really a # best effort in that we don't follow package renames or obsoletions, # To limit the number of packages we inspect, we'll try to match the # incorporation dependency fmri targets packages by stem to packages # which are installed (or planned) within the parent image. This # allows us to quickly get a fully qualified fmri and check against a # package for which we have already downloaded a manifest. # If we can't match the dependency fmri package stem against packages # installed (or planned) in the parent image, we don't bother # searching for allowable packages in the catalog, because even if we # found them in the catalog and they did have a parent dependency, # they'd all still be uninstallable in any children because there # would be no way to satisfy the parent dependency. (as we already # stated the package is not installed in the parent.) # check if this package has a dependency on itself in # Create a set of all facets which affect incorporation dependencies # Note that we can't limit ourselves to only passing on facets that # affect dependencies which have been disabled. Doing this could lead # to incorrect results because facets allow for pattern matching. So # for example say we had the following dependencies on synced # depend type=incorporation fmri=some_synced_pkg1 facet.123456=true # depend type=incorporation fmri=some_synced_pkg2 facet.456789=true # and the following image facets: # if we only passed through facets which affected disabled packages # we'd just pass through "facet.*456*", but this would result in # disabling both dependencies above, not just the second dependency. # W0212 Access to a protected member # --------------------------------------------------------------------------- """Save JSON encoded linked image metadata to a file.""" # make sure the directory we're about to save data into exists. # write the output to a temporary file # atomically create the desired file # W0212 Access to a protected member """Load JSON encoded linked image metadata from a file.""" # W0212 Access to a protected member """Utility class used when json encoding linked image metadata.""" # E0202 An attribute inherited from JSONEncoder hide this method """Required routine that overrides the default base class version. This routine must serialize 'obj' when attempting to save 'obj' json format.""" """Utility class used when json decoding linked image metadata.""" # convert boolean strings values back into booleans elif v.
lower() ==
"false":
"""Remove a set of keys from a dictionary.""" """Oops. We hit a runtime error. Die with a nice informative message. Note that runtime errors should never happen and usually indicate bugs (or possibly corrupted linked image metadata), so they are not localized (just like asserts are not localized).""" err =
"Invalid linked content policy: %s" %
bad_cp err =
"Invalid linked image update policy: %s" %
bad_iup err =
"Invalid linked property value: %s=%s" %
bad_prop err =
"Missing required linked properties: %s" % \
err =
"Multiple plugins reported different path transforms:" err =
"Found saved temporal linked properties: %s" % \
# --------------------------------------------------------------------------- # Functions for accessing files in the current root """Simple wrapper for accessing files in the current root.""" # W0212 Access to a protected member """Simple wrapper for accessing files in the current root.""" # W0212 Access to a protected member """Simple wrapper for accessing files in the current root.""" # W0212 Access to a protected member """Simple wrapper for accessing files in the current root.""" # W0212 Access to a protected member # --------------------------------------------------------------------------- # Functions for managing images which may be in alternate roots """Check if 'path_transform' can be applied to 'path'.""" # Make sure path has a leading and trailing os.sep. # If there is no transform, then any any translation is valid. # check for nested or equal paths """Check if 'path_transform' has been applied to 'path'.""" # Make sure path has a leading and trailing os.sep. """Apply the 'path_transform' to 'path'.""" # Make sure path has a leading and trailing os.sep. """Unapply the 'path_transform' from 'path'.""" """Given an two paths create a transform that can be used to translate # Make sure all paths have a leading and trailing os.sep. # Remove the longest common path suffix. Do this by reversing the # path strings, finding the longest common prefix, removing the common # prefix, and reversing the paths strings again. Make sure there is a # Old root and new root should start and end with a '/'. # Return the altroot transform tuple.